From 4aedab1defc9ec8c036e2b077b6c470c774d0ecc Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 4 Jun 2023 19:40:18 +0200 Subject: [PATCH 1/3] Remove deprecated RESOLVED_NAME key --- packages/NodeTypeResolver/Node/AttributeKey.php | 11 ----------- .../Class_/AttributeCompatibleAnnotationRector.php | 3 +++ 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/NodeTypeResolver/Node/AttributeKey.php b/packages/NodeTypeResolver/Node/AttributeKey.php index 0cbc19cdbfa..10194305e1e 100644 --- a/packages/NodeTypeResolver/Node/AttributeKey.php +++ b/packages/NodeTypeResolver/Node/AttributeKey.php @@ -64,17 +64,6 @@ final class AttributeKey */ public const ORIGINAL_NAME = 'originalName'; - /** - * @api - * @deprecated Use $node->namespacedName instead - * - * Internal php-parser name. @see \PhpParser\NodeVisitor\NameResolver - * Do not change this even if you want! - * - * @var string - */ - public const RESOLVED_NAME = 'resolvedName'; - /** * @deprecated Refactor to a custom visitors/parent node instead, * @see https://phpstan.org/blog/preprocessing-ast-for-custom-rules diff --git a/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php b/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php index 97cb2c51eea..6c295f79700 100644 --- a/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php +++ b/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php @@ -17,6 +17,7 @@ use Rector\Compatibility\NodeFactory\ConstructorClassMethodFactory; use Rector\Compatibility\ValueObject\PropertyWithPhpDocInfo; use Rector\Core\Rector\AbstractRector; +use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer; use Rector\Php81\Enum\AttributeName; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -186,6 +187,8 @@ private function createConstructParams(array $requiredPropertiesWithPhpDocInfos) 'Doctrine\Common\Annotations\Annotation\Required' ); + dd($property->getAttribute(AttributeKey::STMT_KEY)); + $this->removeNode($property); } From 4d2dcd6a9efd8c4ee39a0587b57bf8df3a52ad5b Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 4 Jun 2023 19:40:49 +0200 Subject: [PATCH 2/3] Remove deprecated NEXT_NODE, PREVIOUS_NODE keys --- .../NodeTypeResolver/Node/AttributeKey.php | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/packages/NodeTypeResolver/Node/AttributeKey.php b/packages/NodeTypeResolver/Node/AttributeKey.php index 10194305e1e..9cd1570c447 100644 --- a/packages/NodeTypeResolver/Node/AttributeKey.php +++ b/packages/NodeTypeResolver/Node/AttributeKey.php @@ -74,26 +74,6 @@ final class AttributeKey */ public const PARENT_NODE = 'parent'; - /** - * @api - * @internal of php-parser, do not change - * @deprecated Use StmtsAwareInterface instead - * - * @see https://github.com/nikic/PHP-Parser/pull/681/files - * @var string - */ - public const PREVIOUS_NODE = 'previous'; - - /** - * @api - * @internal of php-parser, do not change - * @deprecated Use StmtsAwareInterface instead - * - * @see https://github.com/nikic/PHP-Parser/pull/681/files - * @var string - */ - public const NEXT_NODE = 'next'; - /** * Internal php-parser name. * Do not change this even if you want! From 4276cba02fc7a16c73f5cfddcbf14314eb3b0b74 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 4 Jun 2023 19:43:56 +0200 Subject: [PATCH 3/3] Remove AttributeCompatibleAnnotationRector, as only for one-time migration of private project, not suitable for general use --- .../docs/rector_rules_overview.md | 37 +--- .../PhpDocInfo/PhpDocInfo.php | 3 + ...ttributeCompatibleAnnotationRectorTest.php | 28 --- .../Fixture/nullable_property.php.inc | 37 ---- .../Fixture/some_class.php.inc | 41 ---- .../config/configured_rule.php | 10 - .../RequiredAnnotationPropertyAnalyzer.php | 50 ----- .../ConstructorClassMethodFactory.php | 45 ---- .../AttributeCompatibleAnnotationRector.php | 197 ------------------ .../ValueObject/PropertyWithPhpDocInfo.php | 42 ---- 10 files changed, 4 insertions(+), 486 deletions(-) delete mode 100644 rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/AttributeCompatibleAnnotationRectorTest.php delete mode 100644 rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/nullable_property.php.inc delete mode 100644 rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/some_class.php.inc delete mode 100644 rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/config/configured_rule.php delete mode 100644 rules/Compatibility/NodeAnalyzer/RequiredAnnotationPropertyAnalyzer.php delete mode 100644 rules/Compatibility/NodeFactory/ConstructorClassMethodFactory.php delete mode 100644 rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php delete mode 100644 rules/Compatibility/ValueObject/PropertyWithPhpDocInfo.php diff --git a/build/target-repository/docs/rector_rules_overview.md b/build/target-repository/docs/rector_rules_overview.md index 0a72ab18e9e..2db4ae5143b 100644 --- a/build/target-repository/docs/rector_rules_overview.md +++ b/build/target-repository/docs/rector_rules_overview.md @@ -1,4 +1,4 @@ -# 390 Rules Overview +# 389 Rules Overview
@@ -10,8 +10,6 @@ - [CodingStyle](#codingstyle) (34) -- [Compatibility](#compatibility) (1) - - [DeadCode](#deadcode) (46) - [DependencyInjection](#dependencyinjection) (2) @@ -2502,39 +2500,6 @@ Wrap encapsed variables in curly braces
-## Compatibility - -### AttributeCompatibleAnnotationRector - -Change annotation to attribute compatible form, see https://tomasvotruba.com/blog/doctrine-annotations-and-attributes-living-together-in-peace/ - -- class: [`Rector\Compatibility\Rector\Class_\AttributeCompatibleAnnotationRector`](../rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php) - -```diff --use Doctrine\Common\Annotations\Annotation\Required; -+use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor; - - /** - * @annotation -+ * @NamedArgumentConstructor - */ - class SomeAnnotation - { - /** -- * @var string[] -- * @Required() -+ * @param string[] $enum - */ -- public array $enum; -+ public function __construct( -+ public array $enum -+ ) { -+ } - } -``` - -
- ## DeadCode ### RecastingRemovalRector diff --git a/packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php b/packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php index 5786a101e59..fd9e83e3cea 100644 --- a/packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php +++ b/packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php @@ -229,6 +229,9 @@ public function getByAnnotationClass(string $class): ?DoctrineAnnotationTagValue return $doctrineAnnotationTagValueNodes[0] ?? null; } + /** + * @api used in tests + */ public function hasByAnnotationClass(string $class): bool { return $this->findByAnnotationClass($class) !== []; diff --git a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/AttributeCompatibleAnnotationRectorTest.php b/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/AttributeCompatibleAnnotationRectorTest.php deleted file mode 100644 index 8de0d84212e..00000000000 --- a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/AttributeCompatibleAnnotationRectorTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/nullable_property.php.inc b/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/nullable_property.php.inc deleted file mode 100644 index 8ddeb6451ea..00000000000 --- a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/nullable_property.php.inc +++ /dev/null @@ -1,37 +0,0 @@ - ------ - diff --git a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/some_class.php.inc b/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/some_class.php.inc deleted file mode 100644 index 1c54d2ab523..00000000000 --- a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/Fixture/some_class.php.inc +++ /dev/null @@ -1,41 +0,0 @@ - ------ - diff --git a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/config/configured_rule.php b/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/config/configured_rule.php deleted file mode 100644 index 0accecc4444..00000000000 --- a/rules-tests/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector/config/configured_rule.php +++ /dev/null @@ -1,10 +0,0 @@ -rule(AttributeCompatibleAnnotationRector::class); -}; diff --git a/rules/Compatibility/NodeAnalyzer/RequiredAnnotationPropertyAnalyzer.php b/rules/Compatibility/NodeAnalyzer/RequiredAnnotationPropertyAnalyzer.php deleted file mode 100644 index 6661e5d818f..00000000000 --- a/rules/Compatibility/NodeAnalyzer/RequiredAnnotationPropertyAnalyzer.php +++ /dev/null @@ -1,50 +0,0 @@ -hasByAnnotationClass('Doctrine\Common\Annotations\Annotation\Required')) { - return true; - } - - // sometimes property has default null, but @var says its not null - that's due to nullability of typed properties - // in that case, we should treat property as required - $firstProperty = $property->props[0]; - if (! $firstProperty->default instanceof Expr) { - return false; - } - - if (! $this->valueResolver->isNull($firstProperty->default)) { - return false; - } - - $varTagValueNode = $phpDocInfo->getVarTagValueNode(); - if (! $varTagValueNode instanceof VarTagValueNode) { - return false; - } - - if ($varTagValueNode->type instanceof NullableTypeNode) { - return false; - } - - return $property->type instanceof NullableType; - } -} diff --git a/rules/Compatibility/NodeFactory/ConstructorClassMethodFactory.php b/rules/Compatibility/NodeFactory/ConstructorClassMethodFactory.php deleted file mode 100644 index e1b61357d91..00000000000 --- a/rules/Compatibility/NodeFactory/ConstructorClassMethodFactory.php +++ /dev/null @@ -1,45 +0,0 @@ - Class_::MODIFIER_PUBLIC, - 'params' => $params, - ]); - - $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod); - - foreach ($requiredPropertiesWithPhpDocInfos as $requiredPropertyWithPhpDocInfo) { - $paramTagValueNode = $requiredPropertyWithPhpDocInfo->getParamTagValueNode(); - $phpDocInfo->addTagValueNode($paramTagValueNode); - } - - $this->paramTagRemover->removeParamTagsIfUseless($phpDocInfo, $classMethod); - - return $classMethod; - } -} diff --git a/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php b/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php deleted file mode 100644 index 6c295f79700..00000000000 --- a/rules/Compatibility/Rector/Class_/AttributeCompatibleAnnotationRector.php +++ /dev/null @@ -1,197 +0,0 @@ -> - */ - public function getNodeTypes(): array - { - return [Class_::class]; - } - - /** - * @param Class_ $node - */ - public function refactor(Node $node): ?Node - { - $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); - if (! $phpDocInfo instanceof PhpDocInfo) { - return null; - } - - if ($this->shouldSkipClass($phpDocInfo, $node)) { - return null; - } - - // add "NamedArgumentConstructor" - $phpDocInfo->addTagValueNode(new DoctrineAnnotationTagValueNode( - new IdentifierTypeNode('Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor') - )); - - // resolve required properties - - $requiredPropertiesWithPhpDocInfos = []; - - foreach ($node->getProperties() as $property) { - if (! $property->isPublic()) { - continue; - } - - $propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property); - if (! $this->requiredAnnotationPropertyAnalyzer->isRequiredProperty($propertyPhpDocInfo, $property)) { - continue; - } - - $propertyName = $this->getName($property); - - $requiredPropertiesWithPhpDocInfos[] = new PropertyWithPhpDocInfo( - $propertyName, - $property, - $propertyPhpDocInfo - ); - } - - $params = $this->createConstructParams($requiredPropertiesWithPhpDocInfos); - - $constructorClassMethod = $this->constructorClassMethodFactory->createConstructorClassMethod( - $requiredPropertiesWithPhpDocInfos, - $params - ); - - $node->stmts = array_merge($node->stmts, [$constructorClassMethod]); - - return $node; - } - - private function shouldSkipClass(PhpDocInfo $phpDocInfo, Class_ $class): bool - { - if (! $phpDocInfo->hasByNames(['Annotation', 'annotation'])) { - return true; - } - - if ($phpDocInfo->hasByAnnotationClass('Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor')) { - return true; - } - - // has attribute? skip it - return $this->phpAttributeAnalyzer->hasPhpAttribute($class, AttributeName::ATTRIBUTE); - } - - /** - * @param PropertyWithPhpDocInfo[] $requiredPropertiesWithPhpDocInfos - * @return Param[] - */ - private function createConstructParams(array $requiredPropertiesWithPhpDocInfos): array - { - $params = []; - foreach ($requiredPropertiesWithPhpDocInfos as $requiredPropertyWithPhpDocInfo) { - $property = $requiredPropertyWithPhpDocInfo->getProperty(); - - $propertyName = $this->getName($property); - - // unwrap nullable type, as variable is required - $propertyType = $property->type; - if ($propertyType instanceof NullableType) { - $propertyType = $propertyType->type; - } - - $params[] = new Param(new Variable($propertyName), null, $propertyType, false, false, [], $property->flags); - - $propertyPhpDocInfo = $requiredPropertyWithPhpDocInfo->getPhpDocInfo(); - - // remove required - $this->phpDocTagRemover->removeByName( - $propertyPhpDocInfo, - 'Doctrine\Common\Annotations\Annotation\Required' - ); - - dd($property->getAttribute(AttributeKey::STMT_KEY)); - - $this->removeNode($property); - } - - return $params; - } -} diff --git a/rules/Compatibility/ValueObject/PropertyWithPhpDocInfo.php b/rules/Compatibility/ValueObject/PropertyWithPhpDocInfo.php deleted file mode 100644 index a795945c303..00000000000 --- a/rules/Compatibility/ValueObject/PropertyWithPhpDocInfo.php +++ /dev/null @@ -1,42 +0,0 @@ -property; - } - - public function getPhpDocInfo(): PhpDocInfo - { - return $this->phpDocInfo; - } - - public function getParamTagValueNode(): ParamTagValueNode - { - $varTagValueNode = $this->phpDocInfo->getVarTagValueNode(); - - if (! $varTagValueNode instanceof VarTagValueNode) { - throw new ShouldNotHappenException(); - } - - return new ParamTagValueNode($varTagValueNode->type, false, '$' . $this->propertyName, ''); - } -}