diff --git a/packages/NodeTypeResolver/NodeScopeAndMetadataDecorator.php b/packages/NodeTypeResolver/NodeScopeAndMetadataDecorator.php index 560227cfd22..d20564b684e 100644 --- a/packages/NodeTypeResolver/NodeScopeAndMetadataDecorator.php +++ b/packages/NodeTypeResolver/NodeScopeAndMetadataDecorator.php @@ -92,16 +92,16 @@ final class NodeScopeAndMetadataDecorator } /** - * @param Stmt[] $nodes + * @param Stmt[] $stmts * @return Stmt[] */ - public function decorateNodesFromString(array $nodes): array + public function decorateStmtsFromString(array $stmts): array { $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor($this->nodeConnectingVisitor); $nodeTraverser->addVisitor($this->functionMethodAndClassNodeVisitor); $nodeTraverser->addVisitor($this->statementNodeVisitor); - return $nodeTraverser->traverse($nodes); + return $nodeTraverser->traverse($stmts); } } diff --git a/phpstan.neon b/phpstan.neon index 4966aea0cbf..7772a53028d 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -40,7 +40,7 @@ parameters: reportUnmatchedIgnoredErrors: false checkGenericClassInNonGenericObjectType: false - excludes_analyse: + excludePaths: # temporary stinrgable migration from template type provider - src/Console/Command/InitCommand.php diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/return_static_nulable.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/return_static_nulable.php.inc new file mode 100644 index 00000000000..82c52e05796 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/return_static_nulable.php.inc @@ -0,0 +1,35 @@ + +----- + diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_.php.inc index c93931d3e96..b4068385621 100644 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_.php.inc +++ b/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_.php.inc @@ -2,29 +2,12 @@ namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\FixtureForPhp80; -class Static_ +final class Static_ { - /** - * @return static - */ - public function getSelf() - { - return $this; - } - public function getStatic() { return new static(); } - - public function getNullableStatic() - { - if (rand(0,1)) { - return new static(); - } - - return null; - } } ?> @@ -33,29 +16,12 @@ class Static_ namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ReturnTypeDeclarationRector\FixtureForPhp80; -class Static_ +final class Static_ { - /** - * @return static - */ - public function getSelf(): static - { - return $this; - } - public function getStatic(): static { return new static(); } - - public function getNullableStatic(): ?static - { - if (rand(0,1)) { - return new static(); - } - - return null; - } } ?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_docblock.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_docblock.php.inc new file mode 100644 index 00000000000..f8ef57513af --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/FunctionLike/ReturnTypeDeclarationRector/FixtureForPhp80/static_docblock.php.inc @@ -0,0 +1,33 @@ + +----- + diff --git a/rules/Php72/NodeFactory/AnonymousFunctionFactory.php b/rules/Php72/NodeFactory/AnonymousFunctionFactory.php index a300c21142c..e59db1bcf3c 100644 --- a/rules/Php72/NodeFactory/AnonymousFunctionFactory.php +++ b/rules/Php72/NodeFactory/AnonymousFunctionFactory.php @@ -30,7 +30,6 @@ use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Foreach_; use PhpParser\Node\Stmt\Return_; use PhpParser\Node\UnionType; -use PhpParser\Parser; use PHPStan\Reflection\FunctionVariantWithPhpDocs; use PHPStan\Reflection\ParameterReflection; use PHPStan\Reflection\ParametersAcceptorSelector; @@ -41,6 +40,7 @@ use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\PhpParser\Comparing\NodeComparator; use Rector\Core\PhpParser\Node\BetterNodeFinder; use Rector\Core\PhpParser\Node\NodeFactory; +use Rector\Core\PhpParser\Parser\SimplePhpParser; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\PHPStanStaticTypeMapper\ValueObject\TypeKind; @@ -61,7 +61,7 @@ final class AnonymousFunctionFactory private NodeFactory $nodeFactory, private StaticTypeMapper $staticTypeMapper, private SimpleCallableNodeTraverser $simpleCallableNodeTraverser, - private Parser $parser, + private SimplePhpParser $simplePhpParser, private NodeComparator $nodeComparator ) { } @@ -143,11 +143,11 @@ final class AnonymousFunctionFactory } $phpCode = 'value . ';'; - $contentNodes = (array) $this->parser->parse($phpCode); + $contentStmts = $this->simplePhpParser->parseString($phpCode); $anonymousFunction = new Closure(); - $firstNode = $contentNodes[0] ?? null; + $firstNode = $contentStmts[0] ?? null; if (! $firstNode instanceof Expression) { return null; } diff --git a/rules/TypeDeclaration/PHPStan/Type/ObjectTypeSpecifier.php b/rules/TypeDeclaration/PHPStan/Type/ObjectTypeSpecifier.php index 2cac933008a..12a9fbdf995 100644 --- a/rules/TypeDeclaration/PHPStan/Type/ObjectTypeSpecifier.php +++ b/rules/TypeDeclaration/PHPStan/Type/ObjectTypeSpecifier.php @@ -29,9 +29,6 @@ final class ObjectTypeSpecifier ) { } - /** - * @return AliasedObjectType|FullyQualifiedObjectType|ObjectType|MixedType - */ public function narrowToFullyQualifiedOrAliasedObjectType( Node $node, ObjectType $objectType diff --git a/rules/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector.php b/rules/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector.php index f2740a924dc..2c01d6a3e71 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector.php @@ -132,13 +132,13 @@ CODE_SAMPLE $this->phpDocTypeChanger->changeReturnType($phpDocInfo, $inferredReturnType); - if ($phpDocInfo->hasChanged()) { - $node->setAttribute(AttributeKey::HAS_PHP_DOC_INFO_JUST_CHANGED, true); - $this->returnTagRemover->removeReturnTagIfUseless($phpDocInfo, $node); - return $node; + if (! $phpDocInfo->hasChanged()) { + return null; } - return null; + $node->setAttribute(AttributeKey::HAS_PHP_DOC_INFO_JUST_CHANGED, true); + $this->returnTagRemover->removeReturnTagIfUseless($phpDocInfo, $node); + return $node; } private function shouldSkip(ClassMethod $classMethod, PhpDocInfo $phpDocInfo): bool @@ -163,11 +163,6 @@ CODE_SAMPLE return $currentPhpDocReturnType instanceof IterableType; } - /** - * @deprecated - * @todo merge to - * @see \Rector\TypeDeclaration\TypeAlreadyAddedChecker\ReturnTypeAlreadyAddedChecker - */ private function shouldSkipType( Type $newType, Type $currentType, diff --git a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php index 20ae98208bc..5b8b372dc60 100644 --- a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php +++ b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php @@ -197,30 +197,30 @@ final class ReturnTypeInferer private function resolveUnionStaticTypes(UnionType $unionType, bool $isSupportedStaticReturnType): UnionType|null { - $returnTypes = $unionType->getTypes(); - $types = []; + $resolvedTypes = []; $hasStatic = false; - foreach ($returnTypes as $returnType) { - if ($this->isStaticType($returnType)) { - /** @var FullyQualifiedObjectType $returnType */ - $types[] = new ThisType($returnType->getClassName()); + foreach ($unionType->getTypes() as $unionedType) { + if ($this->isStaticType($unionedType)) { + /** @var FullyQualifiedObjectType $unionedType */ + $resolvedTypes[] = new ThisType($unionedType->getClassName()); $hasStatic = true; continue; } - $types[] = $returnType; + $resolvedTypes[] = $unionedType; } if (! $hasStatic) { return $unionType; } + // has static, but it is not supported if (! $isSupportedStaticReturnType) { return null; } - return new UnionType($types); + return new UnionType($resolvedTypes); } private function resolveStaticType( diff --git a/src/PhpParser/Parser/InlineCodeParser.php b/src/PhpParser/Parser/InlineCodeParser.php index 322b487ef2f..b27146ec790 100644 --- a/src/PhpParser/Parser/InlineCodeParser.php +++ b/src/PhpParser/Parser/InlineCodeParser.php @@ -48,7 +48,7 @@ final class InlineCodeParser public function __construct( private BetterStandardPrinter $betterStandardPrinter, private NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator, - private Parser $parser, + private SimplePhpParser $simplePhpParser, private SmartFileSystem $smartFileSystem ) { } @@ -67,8 +67,8 @@ final class InlineCodeParser $content = Strings::match($content, self::OPEN_PHP_TAG_REGEX) ? $content : 'parser->parse($content); - return $this->nodeScopeAndMetadataDecorator->decorateNodesFromString($nodes); + $stmts = $this->simplePhpParser->parseString($content); + return $this->nodeScopeAndMetadataDecorator->decorateStmtsFromString($stmts); } public function stringify(Expr $expr): string diff --git a/src/PhpParser/Parser/SimplePhpParser.php b/src/PhpParser/Parser/SimplePhpParser.php index 419d372d56b..c80b85124dc 100644 --- a/src/PhpParser/Parser/SimplePhpParser.php +++ b/src/PhpParser/Parser/SimplePhpParser.php @@ -4,35 +4,46 @@ declare(strict_types=1); namespace Rector\Core\PhpParser\Parser; -use PhpParser\Node; +use PhpParser\Node\Stmt; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor\NodeConnectingVisitor; use PhpParser\Parser; +use PhpParser\ParserFactory; use Symplify\SmartFileSystem\SmartFileSystem; final class SimplePhpParser { + private Parser $phpParser; + public function __construct( - private Parser $parser, private SmartFileSystem $smartFileSystem ) { + $parserFactory = new ParserFactory(); + $this->phpParser = $parserFactory->create(ParserFactory::PREFER_PHP7); } /** - * @return Node[] + * @return Stmt[] */ public function parseFile(string $filePath): array { $fileContent = $this->smartFileSystem->readFile($filePath); - $nodes = $this->parser->parse($fileContent); + return $this->parseString($fileContent); + } - if ($nodes === null) { + /** + * @return Stmt[] + */ + public function parseString(string $fileContent): array + { + $stmts = $this->phpParser->parse($fileContent); + if ($stmts === null) { return []; } $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor(new NodeConnectingVisitor()); - return $nodeTraverser->traverse($nodes); + return $nodeTraverser->traverse($stmts); } }