diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Class_/EntityTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Class_/EntityTagValueNode.php index f7a4065477ce..d3cc5f9906da 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Class_/EntityTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Class_/EntityTagValueNode.php @@ -25,11 +25,7 @@ public function getShortName(): string public function toAttributeString(): string { $items = $this->createAttributeItems(); - $items = $this->filterOutMissingItems($items); - - $content = $this->printPhpAttributeItems($items); - - return $this->printAttributeContent($content); + return $this->printItemsToAttributeString($items); } private function createAttributeItems(): array diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php index 5a9fd3919beb..bbabe05c28b1 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php @@ -34,8 +34,13 @@ public function getShortName(): string public function toAttributeString(): string { - $items = $this->filterOutMissingItems($this->items); - $items = $this->completeItemsQuotes($items); + $items = $this->createAttributeItems(); + return $this->printItemsToAttributeString($items); + } + + private function createAttributeItems(): array + { + $items = $this->items; foreach ($items as $key => $value) { if ($key !== 'unique') { @@ -49,8 +54,6 @@ public function toAttributeString(): string $items[$key] = 'ORM\Column::UNIQUE'; } - $content = $this->printPhpAttributeItems($items); - - return $this->printAttributeContent($content); + return $items; } } diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/GeneratedValueTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/GeneratedValueTagValueNode.php index 20d9bc6665fa..61c213e7a205 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/GeneratedValueTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/GeneratedValueTagValueNode.php @@ -23,8 +23,7 @@ public function getShortName(): string public function toAttributeString(): string { - // @todo add strategy - return $this->printAttributeContent(); + return $this->printItemsToAttributeString($this->items); } public function getSilentKey(): string diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/IdTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/IdTagValueNode.php index a57e7ad2256c..ea83e6999412 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/IdTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/IdTagValueNode.php @@ -19,6 +19,6 @@ public function getShortName(): string public function toAttributeString(): string { - return $this->printAttributeContent(); + return $this->printItemsToAttributeString($this->items); } } diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php index eefa4893b198..4f5043e712b8 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php @@ -56,8 +56,12 @@ public function changeShortName(string $shortName): void public function toAttributeString(): string { - $items = $this->filterOutMissingItems($this->items); - $items = $this->completeItemsQuotes($items); + return $this->printItemsToAttributeString($this->createAttributeItems()); + } + + private function createAttributeItems(): array + { + $items = $this->items; // specific for attributes foreach ($items as $key => $value) { @@ -70,8 +74,6 @@ public function toAttributeString(): string $items[$key] = 'ORM\JoinColumn::UNIQUE'; } - $content = $this->printPhpAttributeItems($items); - - return $this->printAttributeContent($content); + return $items; } } diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinTableTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinTableTagValueNode.php index a8ceaf19c767..462d2abdabb5 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinTableTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinTableTagValueNode.php @@ -108,7 +108,7 @@ public function toAttributeString(): string $content = $this->printPhpAttributeItems($items); - $joinTableAttributeContent = $this->printAttributeContent($content); + $joinTableAttributeContent = $this->printPhpAttributeContent($content); foreach ($this->joinColumns as $joinColumn) { $joinTableAttributeContent .= PHP_EOL . $joinColumn->toAttributeString(); diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ManyToManyTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ManyToManyTagValueNode.php index d625e95a4ea3..24b5257e7ecd 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ManyToManyTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ManyToManyTagValueNode.php @@ -72,11 +72,7 @@ public function getShortName(): string public function toAttributeString(): string { - $items = $this->createAttributeItems(); - $items = $this->filterOutMissingItems($items); - - $content = $this->printPhpAttributeItems($items); - return $this->printAttributeContent($content); + return $this->printItemsToAttributeString($this->createAttributeItems()); } private function createAttributeItems(): array diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertEmailTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertEmailTagValueNode.php index d061fc47bc5d..0d295313d9a1 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertEmailTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertEmailTagValueNode.php @@ -25,12 +25,7 @@ public function getShortName(): string public function toAttributeString(): string { - $items = $this->filterOutMissingItems($this->items); - $items = $this->completeItemsQuotes($items); - - $content = $this->printPhpAttributeItemsAsArray($items); - - return $this->printAttributeContent($content); + return $this->printItemsToAttributeAsArrayString($this->items); } public function getSilentKey(): string diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertRangeTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertRangeTagValueNode.php index 78bf4744877a..55473fdaa0b5 100644 --- a/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertRangeTagValueNode.php +++ b/packages/better-php-doc-parser/src/PhpDocNode/Symfony/Validator/Constraints/AssertRangeTagValueNode.php @@ -26,6 +26,6 @@ public function toAttributeString(): string $content = $this->printPhpAttributeItemsAsArray($items); - return $this->printAttributeContent($content); + return $this->printPhpAttributeContent($content); } } diff --git a/packages/better-php-doc-parser/src/Type/PreSlashStringType.php b/packages/better-php-doc-parser/src/Type/PreSlashStringType.php deleted file mode 100644 index c69ff7e46002..000000000000 --- a/packages/better-php-doc-parser/src/Type/PreSlashStringType.php +++ /dev/null @@ -1,16 +0,0 @@ -nodeNameResolver = $nodeNameResolver; + } + + /** + * Matches array like: "[$this, 'methodName']" → ['ClassName', 'methodName'] + * @return string[]|null + */ + public function match(Array_ $array): ?array + { + if (count($array->items) !== 2) { + return null; + } + + if ($array->items[0] === null) { + return null; + } + + if ($array->items[1] === null) { + return null; + } + + // $this, self, static, FQN + if (! $this->isThisVariable($array->items[0]->value)) { + return null; + } + + if (! $array->items[1]->value instanceof String_) { + return null; + } + + /** @var String_ $string */ + $string = $array->items[1]->value; + + $methodName = $string->value; + $className = $array->getAttribute(AttributeKey::CLASS_NAME); + + if ($className === null) { + return null; + } + + return [$className, $methodName]; + } + + private function isThisVariable(Node $node): bool + { + // $this + if ($node instanceof Variable && $this->nodeNameResolver->isName($node, 'this')) { + return true; + } + + if ($node instanceof ClassConstFetch) { + if (! $this->nodeNameResolver->isName($node->name, 'class')) { + return false; + } + + // self::class, static::class + if ($this->nodeNameResolver->isNames($node->class, ['self', 'static'])) { + return true; + } + + /** @var string|null $className */ + $className = $node->getAttribute(AttributeKey::CLASS_NAME); + + if ($className === null) { + return false; + } + + return $this->nodeNameResolver->isName($node->class, $className); + } + + return false; + } +} diff --git a/packages/node-collector/src/NodeCollector/ParsedFunctionLikeNodeCollector.php b/packages/node-collector/src/NodeCollector/ParsedFunctionLikeNodeCollector.php index 6b465df79277..01ebf537c9fb 100644 --- a/packages/node-collector/src/NodeCollector/ParsedFunctionLikeNodeCollector.php +++ b/packages/node-collector/src/NodeCollector/ParsedFunctionLikeNodeCollector.php @@ -6,12 +6,10 @@ use PhpParser\Node; use PhpParser\Node\Expr\Array_; -use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; use PHPStan\Type\MixedType; @@ -19,6 +17,7 @@ use PHPStan\Type\Type; use PHPStan\Type\TypeWithClassName; use PHPStan\Type\UnionType; +use Rector\NodeCollector\NodeAnalyzer\ArrayCallableClassMethodReferenceAnalyzer; use Rector\NodeCollector\ValueObject\ArrayCallable; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -65,9 +64,17 @@ final class ParsedFunctionLikeNodeCollector */ private $nodeTypeResolver; - public function __construct(NodeNameResolver $nodeNameResolver) - { + /** + * @var ArrayCallableClassMethodReferenceAnalyzer + */ + private $arrayCallableClassMethodReferenceAnalyzer; + + public function __construct( + NodeNameResolver $nodeNameResolver, + ArrayCallableClassMethodReferenceAnalyzer $arrayCallableClassMethodReferenceAnalyzer + ) { $this->nodeNameResolver = $nodeNameResolver; + $this->arrayCallableClassMethodReferenceAnalyzer = $arrayCallableClassMethodReferenceAnalyzer; } /** @@ -88,7 +95,7 @@ public function collect(Node $node): void // array callable - [$this, 'someCall'] if ($node instanceof Array_) { - $arrayCallableClassAndMethod = $this->matchArrayCallableClassAndMethod($node); + $arrayCallableClassAndMethod = $this->arrayCallableClassMethodReferenceAnalyzer->match($node); if ($arrayCallableClassAndMethod === null) { return; } @@ -172,47 +179,6 @@ private function addMethod(ClassMethod $classMethod): void $this->methodsByType[$className][$methodName] = $classMethod; } - /** - * @todo decouple to NodeAnalyzer - * Matches array like: "[$this, 'methodName']" → ['ClassName', 'methodName'] - * @return string[]|null - */ - private function matchArrayCallableClassAndMethod(Array_ $array): ?array - { - if (count($array->items) !== 2) { - return null; - } - - if ($array->items[0] === null) { - return null; - } - - // $this, self, static, FQN - if (! $this->isThisVariable($array->items[0]->value)) { - return null; - } - - if ($array->items[1] === null) { - return null; - } - - if (! $array->items[1]->value instanceof String_) { - return null; - } - - /** @var String_ $string */ - $string = $array->items[1]->value; - - $methodName = $string->value; - $className = $array->getAttribute(AttributeKey::CLASS_NAME); - - if ($className === null) { - return null; - } - - return [$className, $methodName]; - } - /** * @param MethodCall|StaticCall $node */ @@ -238,36 +204,6 @@ private function addCall(Node $node): void $this->addCallByType($node, $classType, $methodName); } - private function isThisVariable(Node $node): bool - { - // $this - if ($node instanceof Variable && $this->nodeNameResolver->isName($node, 'this')) { - return true; - } - - if ($node instanceof ClassConstFetch) { - if (! $this->nodeNameResolver->isName($node->name, 'class')) { - return false; - } - - // self::class, static::class - if ($this->nodeNameResolver->isNames($node->class, ['self', 'static'])) { - return true; - } - - /** @var string|null $className */ - $className = $node->getAttribute(AttributeKey::CLASS_NAME); - - if ($className === null) { - return false; - } - - return $this->nodeNameResolver->isName($node->class, $className); - } - - return false; - } - private function resolveNodeClassTypes(Node $node): Type { if ($node instanceof MethodCall && $node->var instanceof Variable && $node->var->name === 'this') { diff --git a/packages/node-type-resolver/src/Node/AttributeKey.php b/packages/node-type-resolver/src/Node/AttributeKey.php index b825890bea8e..5afd83d252b0 100644 --- a/packages/node-type-resolver/src/Node/AttributeKey.php +++ b/packages/node-type-resolver/src/Node/AttributeKey.php @@ -45,7 +45,6 @@ final class AttributeKey public const CLASS_SHORT_NAME = 'classShortName'; /** - * @todo split Class node, interface node and trait node, to be compatible with other SpecificNode|null, values * @var string */ public const CLASS_NODE = ClassLike::class; diff --git a/packages/node-type-resolver/src/NodeTypeResolver/ParamTypeResolver.php b/packages/node-type-resolver/src/NodeTypeResolver/ParamTypeResolver.php index 0cf1fbb7a24f..3d61ae918893 100644 --- a/packages/node-type-resolver/src/NodeTypeResolver/ParamTypeResolver.php +++ b/packages/node-type-resolver/src/NodeTypeResolver/ParamTypeResolver.php @@ -80,7 +80,7 @@ public function resolve(Node $node): Type return $this->resolveFromFunctionDocBlock($node); } - private function resolveFromType(Node $node) + private function resolveFromType(Node $node): Type { if ($node->type !== null && ! $node->type instanceof Identifier) { $resolveTypeName = $this->nodeNameResolver->getName($node->type); diff --git a/packages/php-attribute/src/AnnotationToAttributeConverter.php b/packages/php-attribute/src/AnnotationToAttributeConverter.php index f519a4274972..e3b7ca4378f9 100644 --- a/packages/php-attribute/src/AnnotationToAttributeConverter.php +++ b/packages/php-attribute/src/AnnotationToAttributeConverter.php @@ -42,7 +42,6 @@ public function convertNode(Node $node): ?Node // 0. has 0 nodes, nothing to change /** @var PhpAttributableTagNodeInterface[]&PhpDocTagValueNode[] $phpAttributableTagNodes */ - $phpAttributableTagNodes = $phpDocInfo->findAllByType(PhpAttributableTagNodeInterface::class); if ($phpAttributableTagNodes === []) { return null; diff --git a/packages/php-attribute/src/PhpDocNode/PhpAttributePhpDocNodePrintTrait.php b/packages/php-attribute/src/PhpDocNode/PhpAttributePhpDocNodePrintTrait.php index 25ce739a98bd..6005374a2838 100644 --- a/packages/php-attribute/src/PhpDocNode/PhpAttributePhpDocNodePrintTrait.php +++ b/packages/php-attribute/src/PhpDocNode/PhpAttributePhpDocNodePrintTrait.php @@ -6,14 +6,8 @@ trait PhpAttributePhpDocNodePrintTrait { - public function printAttributeContent(string $content = ''): string - { - $attributeStart = '<<' . ltrim($this->getShortName(), '@'); - return $attributeStart . $content . '>>'; - } - /** - * @param string[] $items + * @param mixed[] $items */ public function printPhpAttributeItems(array $items): string { @@ -21,13 +15,47 @@ public function printPhpAttributeItems(array $items): string return ''; } + foreach ($items as $key => $item) { + if (! is_array($item)) { + continue; + } + + $items[$key] = $this->printPhpAttributeItems($item); + } + return '(' . implode(', ', $items) . ')'; } + public function printItemsToAttributeAsArrayString(array $items): string + { + $items = $this->filterOutMissingItems($items); + $items = $this->completeItemsQuotes($items); + + $content = $this->printPhpAttributeItemsAsArray($items); + + return $this->printPhpAttributeContent($content); + } + + public function printItemsToAttributeString(array $items): string + { + $items = $this->filterOutMissingItems($items); + $items = $this->completeItemsQuotes($items); + + $content = $this->printPhpAttributeItems($items); + return $this->printPhpAttributeContent($content); + } + + protected function printPhpAttributeContent(string $content = ''): string + { + $attributeStart = '<<' . ltrim($this->getShortName(), '@'); + + return $attributeStart . $content . '>>'; + } + /** * @param string[] $items */ - public function printPhpAttributeItemsAsArray(array $items): string + protected function printPhpAttributeItemsAsArray(array $items): string { if ($items === []) { return ''; diff --git a/packages/post-rector/src/Collector/UseNodesToAddCollector.php b/packages/post-rector/src/Collector/UseNodesToAddCollector.php index 8658085a5443..1eb3c8643eae 100644 --- a/packages/post-rector/src/Collector/UseNodesToAddCollector.php +++ b/packages/post-rector/src/Collector/UseNodesToAddCollector.php @@ -16,7 +16,6 @@ final class UseNodesToAddCollector implements NodeCollectorInterface { /** - * @todo use value object * @var FullyQualifiedObjectType[][]|AliasedObjectType[][] */ private $useImportTypesInFilePath = []; @@ -28,7 +27,6 @@ final class UseNodesToAddCollector implements NodeCollectorInterface private $removedShortUsesInFilePath = []; /** - * @todo use value object * @var FullyQualifiedObjectType[][] */ private $functionUseImportTypesInFilePath = []; diff --git a/packages/static-type-mapper/src/PhpDocParser/ArrayTypeMapper.php b/packages/static-type-mapper/src/PhpDocParser/ArrayTypeMapper.php index 1229791ef200..9b33550499f1 100644 --- a/packages/static-type-mapper/src/PhpDocParser/ArrayTypeMapper.php +++ b/packages/static-type-mapper/src/PhpDocParser/ArrayTypeMapper.php @@ -41,7 +41,6 @@ public function mapToPHPStanType(TypeNode $typeNode, Node $node, NameScope $name { $nestedType = $this->phpDocTypeMapper->mapToPHPStanType($typeNode->type, $node, $nameScope); - // @todo improve for key! return new ArrayType(new MixedType(), $nestedType); } } diff --git a/packages/static-type-mapper/src/PhpDocParser/IdentifierTypeMapper.php b/packages/static-type-mapper/src/PhpDocParser/IdentifierTypeMapper.php index 31a14ee17595..259a36cdd807 100644 --- a/packages/static-type-mapper/src/PhpDocParser/IdentifierTypeMapper.php +++ b/packages/static-type-mapper/src/PhpDocParser/IdentifierTypeMapper.php @@ -15,7 +15,6 @@ use PHPStan\Type\StaticType; use PHPStan\Type\Type; use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareIdentifierTypeNode; -use Rector\BetterPhpDocParser\Type\PreSlashStringType; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\PHPStan\Type\ParentStaticType; use Rector\PHPStan\Type\SelfObjectType; @@ -60,11 +59,6 @@ public function mapToPHPStanType(TypeNode $typeNode, Node $node, NameScope $name $loweredName = strtolower($typeNode->name); - // @todo for all scalars - if ($loweredName === '\string') { - return new PreSlashStringType(); - } - if ($loweredName === 'class-string') { return new ClassStringType(); } diff --git a/rules/doctrine/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php b/rules/doctrine/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php index e643f75202bc..ca8364dfe293 100644 --- a/rules/doctrine/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php +++ b/rules/doctrine/src/Rector/Class_/RemoveRepositoryFromEntityAnnotationRector.php @@ -10,11 +10,10 @@ use Rector\Core\Rector\AbstractRector; use Rector\Core\RectorDefinition\CodeSample; use Rector\Core\RectorDefinition\RectorDefinition; -use Rector\Doctrine\Tests\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector\RemoveRepositoryFromEntityAnnotationRectorTest; use Rector\NodeTypeResolver\Node\AttributeKey; /** - * @see RemoveRepositoryFromEntityAnnotationRectorTest + * @see \Rector\Doctrine\Tests\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector\RemoveRepositoryFromEntityAnnotationRectorTest */ final class RemoveRepositoryFromEntityAnnotationRector extends AbstractRector { diff --git a/rules/doctrine/src/Rector/Property/RemoveTemporaryUuidColumnPropertyRector.php b/rules/doctrine/src/Rector/Property/RemoveTemporaryUuidColumnPropertyRector.php index 030231c0f67b..a59f9ef2d9f6 100644 --- a/rules/doctrine/src/Rector/Property/RemoveTemporaryUuidColumnPropertyRector.php +++ b/rules/doctrine/src/Rector/Property/RemoveTemporaryUuidColumnPropertyRector.php @@ -14,7 +14,7 @@ /** * @sponsor Thanks https://spaceflow.io/ for sponsoring this rule - visit them on https://github.com/SpaceFlow-app * - * @see \Rector\Doctrine\Rector\Property\RemoveTemporaryUuidColumnPropertyRector + * @see \Rector\Doctrine\Tests\Rector\Property\RemoveTemporaryUuidColumnPropertyRector\RemoveTemporaryUuidColumnPropertyRectorTest */ final class RemoveTemporaryUuidColumnPropertyRector extends AbstractRector { diff --git a/rules/nette-to-symfony/src/Rector/ClassMethod/RouterListToControllerAnnotationsRector.php b/rules/nette-to-symfony/src/Rector/ClassMethod/RouterListToControllerAnnotationsRector.php index ed4f1edca7d4..ece8205762c7 100644 --- a/rules/nette-to-symfony/src/Rector/ClassMethod/RouterListToControllerAnnotationsRector.php +++ b/rules/nette-to-symfony/src/Rector/ClassMethod/RouterListToControllerAnnotationsRector.php @@ -282,14 +282,12 @@ private function isRouteStaticCallMatch(StaticCall $staticCall): bool } $methodReflection = new ReflectionMethod($className, $methodName); - if ($methodReflection->getReturnType() !== null) { - $staticCallReturnType = (string) $methodReflection->getReturnType(); - if (is_a($staticCallReturnType, IRouter::class, true)) { - return true; - } + if ($methodReflection->getReturnType() === null) { + return false; } - return false; + $staticCallReturnType = (string) $methodReflection->getReturnType(); + return is_a($staticCallReturnType, IRouter::class, true); } private function shouldSkipClassStmt(Node $node): bool diff --git a/rules/php-office/src/Rector/MethodCall/GetDefaultStyleToGetParentRector.php b/rules/php-office/src/Rector/MethodCall/GetDefaultStyleToGetParentRector.php index 479c9d76e606..dec736c79544 100644 --- a/rules/php-office/src/Rector/MethodCall/GetDefaultStyleToGetParentRector.php +++ b/rules/php-office/src/Rector/MethodCall/GetDefaultStyleToGetParentRector.php @@ -12,6 +12,8 @@ /** * @see https://github.com/PHPOffice/PhpSpreadsheet/blob/master/docs/topics/migration-from-PHPExcel.md#dedicated-class-to-manipulate-coordinates + * + * @see \Rector\PHPOffice\Tests\Rector\MethodCall\GetDefaultStyleToGetParentRector\GetDefaultStyleToGetParentRectorTest */ final class GetDefaultStyleToGetParentRector extends AbstractRector { diff --git a/rules/php-office/src/Rector/StaticCall/CellStaticToCoordinateRector.php b/rules/php-office/src/Rector/StaticCall/CellStaticToCoordinateRector.php index 5447ae14687c..838dd0611d0a 100644 --- a/rules/php-office/src/Rector/StaticCall/CellStaticToCoordinateRector.php +++ b/rules/php-office/src/Rector/StaticCall/CellStaticToCoordinateRector.php @@ -13,6 +13,8 @@ /** * @see https://github.com/PHPOffice/PhpSpreadsheet/blob/master/docs/topics/migration-from-PHPExcel.md#dedicated-class-to-manipulate-coordinates + * + * @see \Rector\PHPOffice\Tests\Rector\StaticCall\CellStaticToCoordinateRector\CellStaticToCoordinateRectorTest */ final class CellStaticToCoordinateRector extends AbstractRector { diff --git a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/custom_matcher.php.inc b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/custom_matcher.php.inc index 5ac181a7b247..88bd3564432f 100644 --- a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/custom_matcher.php.inc +++ b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/custom_matcher.php.inc @@ -68,7 +68,7 @@ class RatesTest extends \PHPUnit\Framework\TestCase */ private $rates; /** - * @var \PHPUnit\Framework\MockObject\MockObject|Provider + * @var \PHPUnit\Framework\MockObject\MockObject|\Provider */ private $provider; protected function setUp() diff --git a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/let_create_edge.php.inc b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/let_create_edge.php.inc index 6decc36bde9b..458e109184c0 100644 --- a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/let_create_edge.php.inc +++ b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/let_create_edge.php.inc @@ -37,7 +37,7 @@ class CurrencyTest extends \PHPUnit\Framework\TestCase */ private $currency; /** - * @var CurrencyData|\PHPUnit\Framework\MockObject\MockObject + * @var \CurrencyData|\PHPUnit\Framework\MockObject\MockObject */ private $data; protected function setUp() diff --git a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/mock_properties.php.inc b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/mock_properties.php.inc index f4c4004edf2b..724fc3ae055a 100644 --- a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/mock_properties.php.inc +++ b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Fixture/mock_properties.php.inc @@ -33,7 +33,7 @@ class MockPropertiesTest extends \PHPUnit\Framework\TestCase */ private $mockProperties; /** - * @var OrderFactory|\PHPUnit\Framework\MockObject\MockObject + * @var \OrderFactory|\PHPUnit\Framework\MockObject\MockObject */ private $factory; protected function setUp() diff --git a/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Source/OrderFactory.php b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Source/OrderFactory.php new file mode 100644 index 000000000000..02d2b2b9ca44 --- /dev/null +++ b/rules/php-spec-to-phpunit/tests/Rector/Class_/PhpSpecToPHPUnitRector/Source/OrderFactory.php @@ -0,0 +1,10 @@ +builderFactory->property($name); $propertyBuilder->makePrivate(); - if ($type !== null) { - // @todo use PhpDocInfo approach - $docComment = $this->createVarDoc($type); - $propertyBuilder->setDocComment($docComment); - } - $property = $propertyBuilder->getNode(); - // add PHP_DOC_INFO $phpDocInfo = $this->phpDocInfoFactory->createFromNode($property); - $property->setAttribute(AttributeKey::PHP_DOC_INFO, $phpDocInfo); + if ($type !== null) { + $phpDocInfo->changeVarType($type); + } $this->decorateParentPropertyProperty($property); @@ -330,13 +324,6 @@ private function createArrayItem($item, $key = null): ArrayItem )); } - private function createVarDoc(Type $type): Doc - { - $docString = $this->staticTypeMapper->mapPHPStanTypeToDocString($type); - - return new Doc(sprintf('/**%s * @var %s%s */', PHP_EOL, $docString, PHP_EOL)); - } - private function decorateParentPropertyProperty(Property $property): void { // complete property property parent, needed for other operations diff --git a/utils/phpstan-extensions/src/Rule/SeeAnnotationToTestRule.php b/utils/phpstan-extensions/src/Rule/SeeAnnotationToTestRule.php index ddc303ffa893..13d25dd332ad 100644 --- a/utils/phpstan-extensions/src/Rule/SeeAnnotationToTestRule.php +++ b/utils/phpstan-extensions/src/Rule/SeeAnnotationToTestRule.php @@ -11,9 +11,12 @@ use PHPStan\Analyser\Scope; use PHPStan\Broker\Broker; use PHPStan\PhpDoc\ResolvedPhpDocBlock; +use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; +use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\Reflection\ClassReflection; use PHPStan\Rules\Rule; use PHPStan\Type\FileTypeMapper; +use PHPUnit\Framework\TestCase; use Rector\Core\Contract\Rector\PhpRectorInterface; use Rector\PostRector\Contract\Rector\PostRectorInterface; @@ -75,10 +78,10 @@ public function processNode(Node $node, Scope $scope): array $resolvedPhpDoc = $this->resolvePhpDoc($scope, $classReflection, $docComment); + /** @var PhpDocTagNode[] $seeTags */ $seeTags = $resolvedPhpDoc->getPhpDocNode()->getTagsByName('@see'); - // @todo validate to refer a TestCase class - if ($seeTags !== []) { + if ($this->containsSeeTestCase($seeTags)) { return []; } @@ -139,4 +142,22 @@ private function resolvePhpDoc(Scope $scope, ClassReflection $classReflection, D $doc->getText() ); } + + /** + * @param PhpDocTagNode[] $seeTags + */ + private function containsSeeTestCase(array $seeTags): bool + { + foreach ($seeTags as $seeTag) { + if (! $seeTag->value instanceof GenericTagValueNode) { + continue; + } + + if (is_a($seeTag->value->value, TestCase::class, true)) { + return true; + } + } + + return false; + } } diff --git a/utils/phpstan-extensions/tests/Rule/SeeAnnotationToTestRule/CorrectSeeRector.php b/utils/phpstan-extensions/tests/Rule/SeeAnnotationToTestRule/CorrectSeeRector.php new file mode 100644 index 000000000000..33f9acdb1404 --- /dev/null +++ b/utils/phpstan-extensions/tests/Rule/SeeAnnotationToTestRule/CorrectSeeRector.php @@ -0,0 +1,11 @@ +