Updated Rector to commit 84012e4ac915dd5d8e7527bffdec302d53dc222e

84012e4ac9 Static type improvements (#2662)
This commit is contained in:
Tomas Votruba 2022-07-15 08:14:37 +00:00
parent f75d563163
commit ead00ac355
19 changed files with 72 additions and 87 deletions

View File

@ -5,7 +5,6 @@ namespace Rector\CodingStyle\NodeAnalyzer;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParameterReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
@ -14,12 +13,11 @@ final class SpreadVariablesCollector
{
/**
* @return array<int, ParameterReflection>
* @param \PHPStan\Reflection\MethodReflection|\PHPStan\Reflection\FunctionReflection $functionLikeReflection
*/
public function resolveFromMethodReflection($functionLikeReflection) : array
public function resolveFromMethodReflection(MethodReflection $methodReflection) : array
{
$spreadParameterReflections = [];
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($functionLikeReflection->getVariants());
$parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants());
foreach ($parametersAcceptor->getParameters() as $key => $parameterReflection) {
if (!$parameterReflection->isVariadic()) {
continue;

View File

@ -4,7 +4,6 @@ declare (strict_types=1);
namespace Rector\Naming\Guard\PropertyConflictingNameGuard;
use PhpParser\Node\Stmt\ClassLike;
use Rector\Naming\Contract\RenameValueObjectInterface;
use Rector\Naming\ExpectedNameResolver\MatchPropertyTypeExpectedNameResolver;
use Rector\Naming\PhpArray\ArrayFilter;
use Rector\Naming\ValueObject\PropertyRename;
@ -32,13 +31,10 @@ final class MatchPropertyTypeConflictingNameGuard
$this->nodeNameResolver = $nodeNameResolver;
$this->arrayFilter = $arrayFilter;
}
/**
* @param PropertyRename $renameValueObject
*/
public function isConflicting(RenameValueObjectInterface $renameValueObject) : bool
public function isConflicting(PropertyRename $propertyRename) : bool
{
$conflictingPropertyNames = $this->resolve($renameValueObject->getClassLike());
return \in_array($renameValueObject->getExpectedName(), $conflictingPropertyNames, \true);
$conflictingPropertyNames = $this->resolve($propertyRename->getClassLike());
return \in_array($propertyRename->getExpectedName(), $conflictingPropertyNames, \true);
}
/**
* @return string[]

View File

@ -79,6 +79,9 @@ final class VariableNaming
}
return $valueName;
}
/**
* @api
*/
public function resolveFromFuncCallFirstArgumentWithSuffix(FuncCall $funcCall, string $suffix, string $fallbackName, ?Scope $scope) : string
{
$bareName = $this->resolveBareFuncCallArgumentName($funcCall, $fallbackName, $suffix);

View File

@ -4,7 +4,7 @@ declare (strict_types=1);
namespace Rector\Naming\RenameGuard;
use Rector\Naming\Contract\Guard\ConflictingNameGuardInterface;
use Rector\Naming\Contract\RenameValueObjectInterface;
use Rector\Naming\ValueObject\PropertyRename;
final class PropertyRenameGuard
{
/**
@ -19,10 +19,10 @@ final class PropertyRenameGuard
{
$this->conflictingNameGuards = $conflictingNameGuards;
}
public function shouldSkip(RenameValueObjectInterface $renameValueObject) : bool
public function shouldSkip(PropertyRename $propertyRename) : bool
{
foreach ($this->conflictingNameGuards as $conflictingNameGuard) {
if ($conflictingNameGuard->isConflicting($renameValueObject)) {
if ($conflictingNameGuard->isConflicting($propertyRename)) {
return \true;
}
}

View File

@ -49,9 +49,9 @@ final class PhpAttributeAnalyzer
}
return \false;
}
public function hasInheritedPhpAttribute(ClassLike $classLike, string $attributeClass) : bool
public function hasInheritedPhpAttribute(Class_ $class, string $attributeClass) : bool
{
$className = (string) $this->nodeNameResolver->getName($classLike);
$className = (string) $this->nodeNameResolver->getName($class);
if (!$this->reflectionProvider->hasClass($className)) {
return \false;
}
@ -59,11 +59,11 @@ final class PhpAttributeAnalyzer
$ancestorClassReflections = \array_merge($classReflection->getParents(), $classReflection->getInterfaces());
foreach ($ancestorClassReflections as $ancestorClassReflection) {
$ancestorClassName = $ancestorClassReflection->getName();
$class = $this->astResolver->resolveClassFromName($ancestorClassName);
if (!$class instanceof Class_) {
$resolvedClass = $this->astResolver->resolveClassFromName($ancestorClassName);
if (!$resolvedClass instanceof Class_) {
continue;
}
if ($this->hasPhpAttribute($class, $attributeClass)) {
if ($this->hasPhpAttribute($resolvedClass, $attributeClass)) {
return \true;
}
}

View File

@ -81,9 +81,9 @@ final class TokenManipulator
/**
* @param Node[] $nodes
*/
public function refactorArrayToken(array $nodes, Expr $singleTokenExpr) : void
public function refactorArrayToken(array $nodes, Variable $singleTokenVariable) : void
{
$this->replaceTokenDimFetchZeroWithGetTokenName($nodes, $singleTokenExpr);
$this->replaceTokenDimFetchZeroWithGetTokenName($nodes, $singleTokenVariable);
// replace "$token[1]"; with "$token->value"
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) : ?PropertyFetch {
if (!$node instanceof ArrayDimFetch) {
@ -102,24 +102,24 @@ final class TokenManipulator
/**
* @param Node[] $nodes
*/
public function refactorNonArrayToken(array $nodes, Expr $singleTokenExpr) : void
public function refactorNonArrayToken(array $nodes, Variable $singleTokenVariable) : void
{
// replace "$content = $token;" → "$content = $token->text;"
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenExpr) {
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenVariable) {
if (!$node instanceof Assign) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($node->expr, $singleTokenExpr)) {
if (!$this->nodeComparator->areNodesEqual($node->expr, $singleTokenVariable)) {
return null;
}
$tokenStaticType = $this->nodeTypeResolver->getType($node->expr);
if ($tokenStaticType instanceof ArrayType) {
return null;
}
$node->expr = new PropertyFetch($singleTokenExpr, 'text');
$node->expr = new PropertyFetch($singleTokenVariable, 'text');
});
// replace "$name = null;" → "$name = $token->getTokenName();"
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenExpr) : ?Assign {
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenVariable) : ?Assign {
if (!$node instanceof Assign) {
return null;
}
@ -136,16 +136,16 @@ final class TokenManipulator
if (!$this->valueResolver->isValue($node->expr, 'null')) {
return null;
}
$node->expr = new MethodCall($singleTokenExpr, 'getTokenName');
$node->expr = new MethodCall($singleTokenVariable, 'getTokenName');
return $node;
});
}
/**
* @param Node[] $nodes
*/
public function refactorTokenIsKind(array $nodes, Expr $singleTokenExpr) : void
public function refactorTokenIsKind(array $nodes, Variable $singleTokenVariable) : void
{
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenExpr) : ?MethodCall {
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenVariable) : ?MethodCall {
if (!$node instanceof Identical) {
return null;
}
@ -158,7 +158,7 @@ final class TokenManipulator
}
$arrayDimFetch = $arrayDimFetchAndConstFetch->getArrayDimFetch();
$constFetch = $arrayDimFetchAndConstFetch->getConstFetch();
if (!$this->nodeComparator->areNodesEqual($arrayDimFetch->var, $singleTokenExpr)) {
if (!$this->nodeComparator->areNodesEqual($arrayDimFetch->var, $singleTokenVariable)) {
return null;
}
$constName = $this->nodeNameResolver->getName($constFetch);
@ -204,9 +204,9 @@ final class TokenManipulator
*
* @param Node[] $nodes
*/
private function replaceTokenDimFetchZeroWithGetTokenName(array $nodes, Expr $singleTokenExpr) : void
private function replaceTokenDimFetchZeroWithGetTokenName(array $nodes, Variable $singleTokenVariable) : void
{
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenExpr) : ?MethodCall {
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use($singleTokenVariable) : ?MethodCall {
if (!$node instanceof FuncCall) {
return null;
}
@ -232,7 +232,7 @@ final class TokenManipulator
if (!$this->valueResolver->isValue($possibleTokenArray->dim, 0)) {
return null;
}
if (!$this->nodeComparator->areNodesEqual($possibleTokenArray->var, $singleTokenExpr)) {
if (!$this->nodeComparator->areNodesEqual($possibleTokenArray->var, $singleTokenVariable)) {
return null;
}
// save token variable name for later
@ -240,7 +240,7 @@ final class TokenManipulator
if ($parentNode instanceof Assign) {
$this->assignedNameExpr = $parentNode->var;
}
return new MethodCall($singleTokenExpr, 'getTokenName');
return new MethodCall($singleTokenVariable, 'getTokenName');
});
}
private function isArrayDimFetchWithDimIntegerValue(ArrayDimFetch $arrayDimFetch, int $value) : bool

View File

@ -8,6 +8,8 @@ use RectorPrefix202207\Symplify\Astral\PhpDocParser\PhpDocNodeTraverser;
final class PhpDocNodeFinder
{
/**
* @api
*
* @template TNode as Node
* @param class-string<TNode> $nodeType
* @return TNode[]

View File

@ -18,10 +18,7 @@ final class ConstantNaming
{
$this->nodeNameResolver = $nodeNameResolver;
}
/**
* @param \PhpParser\Node\Stmt\PropertyProperty|\PhpParser\Node\Expr\Variable $propertyProperty
*/
public function createFromProperty($propertyProperty) : string
public function createFromProperty(PropertyProperty $propertyProperty) : string
{
/** @var string $propertyName */
$propertyName = $this->nodeNameResolver->getName($propertyProperty);

View File

@ -23,6 +23,7 @@ final class VisibilityManipulator
return (bool) ($node->flags & $visibility);
}
/**
* @api
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst $node
*/
public function makeStatic($node) : void
@ -145,6 +146,7 @@ final class VisibilityManipulator
$this->removeVisibilityFlag($node, Visibility::READONLY);
}
/**
* @api
* @param \PhpParser\Node\Stmt\Class_|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Property|\PhpParser\Node\Stmt\ClassConst|\PhpParser\Node\Param $node
*/
private function addVisibilityFlag($node, int $visibility) : void

View File

@ -59,15 +59,14 @@ final class FuncCallStaticCallToMethodCallAnalyzer
$this->propertyToAddCollector = $propertyToAddCollector;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\Variable
*/
public function matchTypeProvidingExpr(Class_ $class, $functionLike, ObjectType $objectType)
public function matchTypeProvidingExpr(Class_ $class, ClassMethod $classMethod, ObjectType $objectType)
{
$expr = $this->typeProvidingExprFromClassResolver->resolveTypeProvidingExprFromClass($class, $functionLike, $objectType);
$expr = $this->typeProvidingExprFromClassResolver->resolveTypeProvidingExprFromClass($class, $classMethod, $objectType);
if ($expr !== null) {
if ($expr instanceof Variable) {
$this->addClassMethodParamForVariable($expr, $objectType, $functionLike);
$this->addClassMethodParamForVariable($expr, $objectType, $classMethod);
}
return $expr;
}

View File

@ -9,7 +9,6 @@ use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
@ -56,9 +55,8 @@ final class TypeProvidingExprFromClassResolver
}
/**
* @return MethodCall|PropertyFetch|Variable|null
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
public function resolveTypeProvidingExprFromClass(Class_ $class, $functionLike, ObjectType $objectType) : ?Expr
public function resolveTypeProvidingExprFromClass(Class_ $class, ClassMethod $classMethod, ObjectType $objectType) : ?Expr
{
$className = (string) $this->nodeNameResolver->getName($class);
// A. match a method
@ -77,7 +75,7 @@ final class TypeProvidingExprFromClassResolver
return $propertyFetch;
}
// C. param in constructor?
return $this->resolveConstructorParamProvidingType($functionLike, $objectType);
return $this->resolveConstructorParamProvidingType($classMethod, $objectType);
}
private function resolveMethodCallProvidingType(ClassReflection $classReflection, ObjectType $objectType) : ?MethodCall
{
@ -107,15 +105,9 @@ final class TypeProvidingExprFromClassResolver
}
return null;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
private function resolveConstructorParamProvidingType($functionLike, ObjectType $objectType) : ?Variable
private function resolveConstructorParamProvidingType(ClassMethod $classMethod, ObjectType $objectType) : ?Variable
{
if (!$functionLike instanceof ClassMethod) {
return null;
}
if (!$this->nodeNameResolver->isName($functionLike, MethodName::CONSTRUCT)) {
if (!$this->nodeNameResolver->isName($classMethod, MethodName::CONSTRUCT)) {
return null;
}
$variableName = $this->propertyNaming->fqnToVariableName($objectType);

View File

@ -62,6 +62,8 @@ final class TypeNormalizer
return $this->createArrayTypeFromNonConstantValueTypes($nonConstantValueTypes);
}
/**
* @api
*
* Turn nested array union types to unique ones:
* e.g. int[]|string[][]|bool[][]|string[][]
*

View File

@ -55,6 +55,9 @@ final class RemovedAndAddedFilesCollector
}
return \false;
}
/**
* @api
*/
public function addAddedFile(AddedFileInterface $addedFile) : void
{
$this->addedFiles[] = $addedFile;

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '8a6b70456e536174d88a29c865bed73a6fa89534';
public const PACKAGE_VERSION = '84012e4ac915dd5d8e7527bffdec302d53dc222e';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-07-15 09:58:12';
public const RELEASE_DATE = '2022-07-15 08:09:29';
/**
* @var int
*/

View File

@ -114,23 +114,17 @@ final class PropertyFetchAnalyzer
return $parentClassLike === $classLike;
});
}
/**
* @param \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch $expr
*/
public function isPropertyToSelf($expr) : bool
public function isPropertyToSelf(PropertyFetch $propertyFetch) : bool
{
if ($expr instanceof PropertyFetch && !$this->nodeNameResolver->isName($expr->var, self::THIS)) {
if (!$this->nodeNameResolver->isName($propertyFetch->var, self::THIS)) {
return \false;
}
if ($expr instanceof StaticPropertyFetch && !$this->nodeNameResolver->isName($expr->class, ObjectReference::SELF)) {
return \false;
}
$class = $this->betterNodeFinder->findParentType($expr, Class_::class);
$class = $this->betterNodeFinder->findParentType($propertyFetch, Class_::class);
if (!$class instanceof Class_) {
return \false;
}
foreach ($class->getProperties() as $property) {
if (!$this->nodeNameResolver->areNamesEqual($property->props[0], $expr)) {
if (!$this->nodeNameResolver->areNamesEqual($property->props[0], $propertyFetch)) {
continue;
}
return \true;
@ -148,18 +142,15 @@ final class PropertyFetchAnalyzer
* Matches:
* "$this->someValue = $<variableName>;"
*/
public function isVariableAssignToThisPropertyFetch(Node $node, string $variableName) : bool
public function isVariableAssignToThisPropertyFetch(Assign $assign, string $variableName) : bool
{
if (!$node instanceof Assign) {
if (!$assign->expr instanceof Variable) {
return \false;
}
if (!$node->expr instanceof Variable) {
if (!$this->nodeNameResolver->isName($assign->expr, $variableName)) {
return \false;
}
if (!$this->nodeNameResolver->isName($node->expr, $variableName)) {
return \false;
}
return $this->isLocalPropertyFetch($node->var);
return $this->isLocalPropertyFetch($assign->var);
}
public function isFilledViaMethodCallInConstructStmts(ClassLike $classLike, string $propertyName) : bool
{

View File

@ -150,9 +150,9 @@ final class BetterNodeFinder
return (bool) $this->findInstanceOfName($nodes, $type, $name);
}
/**
* @param \PhpParser\Node|mixed[] $nodes
* @param Node[] $nodes
*/
public function hasVariableOfName($nodes, string $name) : bool
public function hasVariableOfName(array $nodes, string $name) : bool
{
return $this->findVariableOfName($nodes, $name) instanceof Node;
}

2
vendor/autoload.php vendored
View File

@ -9,4 +9,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit2f41ba1298ddb3612058eed888b9022a::getLoader();
return ComposerAutoloaderInit1c19a86165ab4a7b731a7672884ff4d1::getLoader();

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit2f41ba1298ddb3612058eed888b9022a
class ComposerAutoloaderInit1c19a86165ab4a7b731a7672884ff4d1
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInit2f41ba1298ddb3612058eed888b9022a
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit2f41ba1298ddb3612058eed888b9022a', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit1c19a86165ab4a7b731a7672884ff4d1', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit2f41ba1298ddb3612058eed888b9022a', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit1c19a86165ab4a7b731a7672884ff4d1', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit2f41ba1298ddb3612058eed888b9022a::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInit1c19a86165ab4a7b731a7672884ff4d1::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit2f41ba1298ddb3612058eed888b9022a::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInit1c19a86165ab4a7b731a7672884ff4d1::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire2f41ba1298ddb3612058eed888b9022a($fileIdentifier, $file);
composerRequire1c19a86165ab4a7b731a7672884ff4d1($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInit2f41ba1298ddb3612058eed888b9022a
* @param string $file
* @return void
*/
function composerRequire2f41ba1298ddb3612058eed888b9022a($fileIdentifier, $file)
function composerRequire1c19a86165ab4a7b731a7672884ff4d1($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInit2f41ba1298ddb3612058eed888b9022a
class ComposerStaticInit1c19a86165ab4a7b731a7672884ff4d1
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@ -3416,9 +3416,9 @@ class ComposerStaticInit2f41ba1298ddb3612058eed888b9022a
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit2f41ba1298ddb3612058eed888b9022a::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit2f41ba1298ddb3612058eed888b9022a::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit2f41ba1298ddb3612058eed888b9022a::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInit1c19a86165ab4a7b731a7672884ff4d1::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1c19a86165ab4a7b731a7672884ff4d1::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1c19a86165ab4a7b731a7672884ff4d1::$classMap;
}, null, ClassLoader::class);
}