Updated Rector to commit 2b35d2e75ea03ffe643c012485952ec6df3ea2ba

2b35d2e75e [TypeDeclaration] Move Rector Enterprise TypeDeclaration rules here (#3125)
This commit is contained in:
Tomas Votruba 2022-11-28 20:42:41 +00:00
parent 789d270789
commit cbd1da8466
27 changed files with 774 additions and 50 deletions

View File

@ -17,10 +17,13 @@ use Rector\TypeDeclaration\Rector\ClassMethod\ParamAnnotationIncorrectNullableRe
use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByMethodCallTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByParentCallTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnAnnotationIncorrectNullableRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnDirectArrayRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnNewRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictBoolReturnExprRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictConstantReturnRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictNativeCallRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictNewArrayRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedPropertyRector;
use Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector;
use Rector\TypeDeclaration\Rector\FunctionLike\AddParamTypeSplFixedArrayRector;
@ -32,5 +35,5 @@ use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictGetterMethodRe
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictSetUpRector;
use Rector\TypeDeclaration\Rector\Property\VarAnnotationIncorrectNullableRector;
return static function (RectorConfig $rectorConfig) : void {
$rectorConfig->rules([AddClosureReturnTypeRector::class, AddArrowFunctionReturnTypeRector::class, AddArrayReturnDocTypeRector::class, ParamTypeByMethodCallTypeRector::class, TypedPropertyFromAssignsRector::class, ReturnAnnotationIncorrectNullableRector::class, VarAnnotationIncorrectNullableRector::class, ParamAnnotationIncorrectNullableRector::class, AddReturnTypeDeclarationBasedOnParentClassMethodRector::class, ReturnTypeFromStrictTypedPropertyRector::class, TypedPropertyFromStrictConstructorRector::class, ParamTypeFromStrictTypedPropertyRector::class, AddVoidReturnTypeWhereNoReturnRector::class, ReturnTypeFromReturnNewRector::class, TypedPropertyFromStrictGetterMethodReturnTypeRector::class, AddMethodCallBasedStrictParamTypeRector::class, ArrayShapeFromConstantArrayReturnRector::class, ReturnTypeFromStrictBoolReturnExprRector::class, ReturnTypeFromStrictNativeCallRector::class, ReturnTypeFromStrictNewArrayRector::class, ReturnTypeFromStrictScalarReturnExprRector::class, TypedPropertyFromStrictSetUpRector::class, ParamTypeByParentCallTypeRector::class, AddParamTypeSplFixedArrayRector::class, AddParamTypeBasedOnPHPUnitDataProviderRector::class, AddParamTypeFromPropertyTypeRector::class, AddReturnTypeDeclarationFromYieldsRector::class]);
$rectorConfig->rules([AddClosureReturnTypeRector::class, AddArrowFunctionReturnTypeRector::class, AddArrayReturnDocTypeRector::class, ParamTypeByMethodCallTypeRector::class, TypedPropertyFromAssignsRector::class, ReturnAnnotationIncorrectNullableRector::class, VarAnnotationIncorrectNullableRector::class, ParamAnnotationIncorrectNullableRector::class, AddReturnTypeDeclarationBasedOnParentClassMethodRector::class, ReturnTypeFromStrictTypedPropertyRector::class, TypedPropertyFromStrictConstructorRector::class, ParamTypeFromStrictTypedPropertyRector::class, AddVoidReturnTypeWhereNoReturnRector::class, ReturnTypeFromReturnNewRector::class, TypedPropertyFromStrictGetterMethodReturnTypeRector::class, AddMethodCallBasedStrictParamTypeRector::class, ArrayShapeFromConstantArrayReturnRector::class, ReturnTypeFromStrictBoolReturnExprRector::class, ReturnTypeFromStrictNativeCallRector::class, ReturnTypeFromStrictNewArrayRector::class, ReturnTypeFromStrictScalarReturnExprRector::class, TypedPropertyFromStrictSetUpRector::class, ParamTypeByParentCallTypeRector::class, AddParamTypeSplFixedArrayRector::class, AddParamTypeBasedOnPHPUnitDataProviderRector::class, AddParamTypeFromPropertyTypeRector::class, AddReturnTypeDeclarationFromYieldsRector::class, ReturnTypeFromReturnDirectArrayRector::class, ReturnTypeFromStrictConstantReturnRector::class, ReturnTypeFromStrictTypedCallRector::class]);
};

View File

@ -0,0 +1,61 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\UnionType;
use Rector\Core\PhpParser\Comparing\NodeComparator;
final class TypeNodeUnwrapper
{
/**
* @readonly
* @var \Rector\Core\PhpParser\Comparing\NodeComparator
*/
private $nodeComparator;
public function __construct(NodeComparator $nodeComparator)
{
$this->nodeComparator = $nodeComparator;
}
/**
* @param array<UnionType|NullableType|Name|Identifier|IntersectionType> $typeNodes
* @return array<Name|Identifier>
*/
public function unwrapNullableUnionTypes(array $typeNodes) : array
{
$unwrappedTypeNodes = [];
foreach ($typeNodes as $typeNode) {
if ($typeNode instanceof UnionType) {
$unwrappedTypeNodes = \array_merge($unwrappedTypeNodes, $this->unwrapNullableUnionTypes($typeNode->types));
} elseif ($typeNode instanceof NullableType) {
$unwrappedTypeNodes[] = $typeNode->type;
$unwrappedTypeNodes[] = new Identifier('null');
} elseif ($typeNode instanceof IntersectionType) {
$unwrappedTypeNodes = \array_merge($unwrappedTypeNodes, $this->unwrapNullableUnionTypes($typeNode->types));
} else {
$unwrappedTypeNodes[] = $typeNode;
}
}
return $this->uniquateNodes($unwrappedTypeNodes);
}
/**
* @template TNode as Node
*
* @param TNode[] $nodes
* @return TNode[]
*/
public function uniquateNodes(array $nodes) : array
{
$uniqueNodes = [];
foreach ($nodes as $node) {
$uniqueHash = $this->nodeComparator->printWithoutComments($node);
$uniqueNodes[$uniqueHash] = $node;
}
// reset keys from 0, for further compatibility
return \array_values($uniqueNodes);
}
}

View File

@ -0,0 +1,104 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromReturnDirectArrayRector\ReturnTypeFromReturnDirectArrayRectorTest
*/
final class ReturnTypeFromReturnDirectArrayRector extends AbstractRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add return type from return direct array', [new CodeSample(<<<'CODE_SAMPLE'
final class AddReturnArray
{
public function getArray()
{
return [1, 2, 3];
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class AddReturnArray
{
public function getArray(): array
{
return [1, 2, 3];
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class, Closure::class, ArrowFunction::class];
}
/**
* @param ClassMethod|Function_|ArrowFunction $node
*/
public function refactor(Node $node) : ?Node
{
if ($node->returnType !== null) {
return null;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}
if (!$this->hasReturnArray($node)) {
return null;
}
$node->returnType = new Identifier('array');
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::SCALAR_TYPES;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $functionLike
*/
private function hasReturnArray($functionLike) : bool
{
$stmts = $functionLike instanceof ArrowFunction ? $functionLike->getStmts() : $functionLike->stmts;
if (!\is_array($stmts)) {
return \false;
}
foreach ($stmts as $stmt) {
if (!$stmt instanceof Return_) {
continue;
}
if (!$stmt->expr instanceof Array_) {
continue;
}
return \true;
}
return \false;
}
}

View File

@ -26,6 +26,7 @@ use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\StaticTypeMapper\ValueObject\Type\SelfStaticType;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictReturnNewAnalyzer;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -54,12 +55,18 @@ final class ReturnTypeFromReturnNewRector extends AbstractRector implements MinP
* @var \Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictReturnNewAnalyzer
*/
private $strictReturnNewAnalyzer;
public function __construct(TypeFactory $typeFactory, ReflectionProvider $reflectionProvider, ReflectionResolver $reflectionResolver, StrictReturnNewAnalyzer $strictReturnNewAnalyzer)
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(TypeFactory $typeFactory, ReflectionProvider $reflectionProvider, ReflectionResolver $reflectionResolver, StrictReturnNewAnalyzer $strictReturnNewAnalyzer, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->typeFactory = $typeFactory;
$this->reflectionProvider = $reflectionProvider;
$this->reflectionResolver = $reflectionResolver;
$this->strictReturnNewAnalyzer = $strictReturnNewAnalyzer;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
@ -98,6 +105,9 @@ CODE_SAMPLE
if ($node->returnType !== null) {
return null;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}
if (!$node instanceof ArrowFunction) {
$returnedNewClassName = $this->strictReturnNewAnalyzer->matchAlwaysReturnVariableNew($node);
if (\is_string($returnedNewClassName)) {

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Stmt\Function_;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersion;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictBoolReturnTypeAnalyzer;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -24,9 +25,15 @@ final class ReturnTypeFromStrictBoolReturnExprRector extends AbstractRector impl
* @var \Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictBoolReturnTypeAnalyzer
*/
private $strictBoolReturnTypeAnalyzer;
public function __construct(StrictBoolReturnTypeAnalyzer $strictBoolReturnTypeAnalyzer)
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(StrictBoolReturnTypeAnalyzer $strictBoolReturnTypeAnalyzer, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->strictBoolReturnTypeAnalyzer = $strictBoolReturnTypeAnalyzer;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
@ -65,6 +72,9 @@ CODE_SAMPLE
if ($node->returnType !== null) {
return null;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}
if (!$this->strictBoolReturnTypeAnalyzer->hasAlwaysStrictBoolReturn($node)) {
return null;
}

View File

@ -0,0 +1,99 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\Type;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersion;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\TypeDeclaration\TypeAnalyzer\StrictReturnClassConstReturnTypeAnalyzer;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictConstantReturnRector\ReturnTypeFromStrictConstantReturnRectorTest
*/
final class ReturnTypeFromStrictConstantReturnRector extends AbstractRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\TypeDeclaration\TypeAnalyzer\StrictReturnClassConstReturnTypeAnalyzer
*/
private $strictReturnClassConstReturnTypeAnalyzer;
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(StrictReturnClassConstReturnTypeAnalyzer $strictReturnClassConstReturnTypeAnalyzer, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->strictReturnClassConstReturnTypeAnalyzer = $strictReturnClassConstReturnTypeAnalyzer;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add strict type declaration based on returned constants', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public const NAME = 'name';
public function run()
{
return self::NAME;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public const NAME = 'name';
public function run(): string
{
return self::NAME;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node) : ?Node
{
if ($node->returnType instanceof Node) {
return null;
}
if ($this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}
$matchedType = $this->strictReturnClassConstReturnTypeAnalyzer->matchAlwaysReturnConstFetch($node);
if (!$matchedType instanceof Type) {
return null;
}
$returnTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($matchedType, TypeKind::RETURN);
if (!$returnTypeNode instanceof Node) {
return null;
}
$node->returnType = $returnTypeNode;
return $node;
}
/**
* @return PhpVersion::*
*/
public function provideMinPhpVersion() : int
{
return PhpVersion::PHP_70;
}
}

View File

@ -13,6 +13,7 @@ use Rector\Core\ValueObject\PhpVersion;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictNativeFunctionReturnTypeAnalyzer;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -31,10 +32,16 @@ final class ReturnTypeFromStrictNativeCallRector extends AbstractRector implemen
* @var \Rector\NodeTypeResolver\PHPStan\Type\TypeFactory
*/
private $typeFactory;
public function __construct(StrictNativeFunctionReturnTypeAnalyzer $strictNativeFunctionReturnTypeAnalyzer, TypeFactory $typeFactory)
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(StrictNativeFunctionReturnTypeAnalyzer $strictNativeFunctionReturnTypeAnalyzer, TypeFactory $typeFactory, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->strictNativeFunctionReturnTypeAnalyzer = $strictNativeFunctionReturnTypeAnalyzer;
$this->typeFactory = $typeFactory;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
@ -73,6 +80,9 @@ CODE_SAMPLE
if ($node->returnType !== null) {
return null;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}
$nativeCallLikes = $this->strictNativeFunctionReturnTypeAnalyzer->matchAlwaysReturnNativeCallLikes($node);
if ($nativeCallLikes === null) {
return null;

View File

@ -26,6 +26,7 @@ use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersion;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -44,10 +45,16 @@ final class ReturnTypeFromStrictNewArrayRector extends AbstractRector implements
* @var \Rector\NodeTypeResolver\TypeComparator\TypeComparator
*/
private $typeComparator;
public function __construct(PhpDocTypeChanger $phpDocTypeChanger, TypeComparator $typeComparator)
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(PhpDocTypeChanger $phpDocTypeChanger, TypeComparator $typeComparator, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->typeComparator = $typeComparator;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
@ -87,7 +94,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node) : ?Node
{
if ($node->returnType !== null) {
if ($this->shouldSkip($node)) {
return null;
}
// 1. is variable instantiated with array
@ -135,6 +142,16 @@ CODE_SAMPLE
{
return PhpVersion::PHP_70;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $node
*/
private function shouldSkip($node) : bool
{
if ($node->returnType !== null) {
return \true;
}
return $node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node);
}
private function changeReturnType(Node $node, Type $exprType) : void
{
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);

View File

@ -0,0 +1,235 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PhpParser\Node\UnionType as PhpParserUnionType;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\UnionType;
use PHPStan\Type\VoidType;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\TypeDeclaration\NodeAnalyzer\TypeNodeUnwrapper;
use Rector\TypeDeclaration\TypeAnalyzer\ReturnStrictTypeAnalyzer;
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector\ReturnTypeFromStrictTypedCallRectorTest
*/
final class ReturnTypeFromStrictTypedCallRector extends AbstractRector
{
/**
* @readonly
* @var \Rector\TypeDeclaration\NodeAnalyzer\TypeNodeUnwrapper
*/
private $typeNodeUnwrapper;
/**
* @readonly
* @var \Rector\TypeDeclaration\TypeAnalyzer\ReturnStrictTypeAnalyzer
*/
private $returnStrictTypeAnalyzer;
/**
* @readonly
* @var \Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer
*/
private $returnTypeInferer;
/**
* @readonly
* @var \Rector\Core\Php\PhpVersionProvider
*/
private $phpVersionProvider;
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(TypeNodeUnwrapper $typeNodeUnwrapper, ReturnStrictTypeAnalyzer $returnStrictTypeAnalyzer, ReturnTypeInferer $returnTypeInferer, PhpVersionProvider $phpVersionProvider, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->typeNodeUnwrapper = $typeNodeUnwrapper;
$this->returnStrictTypeAnalyzer = $returnStrictTypeAnalyzer;
$this->returnTypeInferer = $returnTypeInferer;
$this->phpVersionProvider = $phpVersionProvider;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add return type from strict return type of call', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function getData()
{
return $this->getNumber();
}
private function getNumber(): int
{
return 1000;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function getData(): int
{
return $this->getNumber();
}
private function getNumber(): int
{
return 1000;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class, Closure::class, ArrowFunction::class];
}
/**
* @param ClassMethod|Function_|Closure|ArrowFunction $node
*/
public function refactor(Node $node) : ?Node
{
if ($this->isSkipped($node)) {
return null;
}
if ($node instanceof ArrowFunction) {
return $this->processArrowFunction($node);
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->find((array) $node->stmts, function (Node $subNode) use($node) : bool {
$currentFunctionLike = $this->betterNodeFinder->findParentType($subNode, FunctionLike::class);
if ($currentFunctionLike === $node) {
return $subNode instanceof Return_;
}
$currentReturn = $this->betterNodeFinder->findParentType($subNode, Return_::class);
if (!$currentReturn instanceof Return_) {
return \false;
}
$currentFunctionLike = $this->betterNodeFinder->findParentType($currentReturn, FunctionLike::class);
if ($currentFunctionLike !== $node) {
return \false;
}
return $subNode instanceof Return_;
});
$returnedStrictTypes = $this->returnStrictTypeAnalyzer->collectStrictReturnTypes($returns);
if ($returnedStrictTypes === []) {
return null;
}
if (\count($returnedStrictTypes) === 1) {
return $this->refactorSingleReturnType($returns[0], $returnedStrictTypes[0], $node);
}
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::UNION_TYPES)) {
/** @var PhpParserUnionType[] $returnedStrictTypes */
$unwrappedTypes = $this->typeNodeUnwrapper->unwrapNullableUnionTypes($returnedStrictTypes);
$node->returnType = new PhpParserUnionType($unwrappedTypes);
return $node;
}
return null;
}
private function processArrowFunction(ArrowFunction $arrowFunction) : ?ArrowFunction
{
$resolvedType = $this->nodeTypeResolver->getType($arrowFunction->expr);
// void type is not accepted for arrow functions - https://www.php.net/manual/en/functions.arrow.php#125673
if ($resolvedType instanceof VoidType) {
return null;
}
$returnType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($resolvedType, TypeKind::RETURN);
if (!$returnType instanceof Node) {
return null;
}
$arrowFunction->returnType = $returnType;
return $arrowFunction;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $node
*/
private function isUnionPossibleReturnsVoid($node) : bool
{
$inferReturnType = $this->returnTypeInferer->inferFunctionLike($node);
if ($inferReturnType instanceof UnionType) {
foreach ($inferReturnType->getTypes() as $type) {
if ($type instanceof VoidType) {
return \true;
}
}
}
return \false;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $node
* @return \PhpParser\Node\Expr\Closure|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_
*/
private function processSingleUnionType($node, UnionType $unionType, NullableType $nullableType)
{
$types = $unionType->getTypes();
$returnType = $types[0] instanceof ObjectType && $types[1] instanceof NullType ? new NullableType(new FullyQualified($types[0]->getClassName())) : $nullableType;
$node->returnType = $returnType;
return $node;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure|\PhpParser\Node\Expr\ArrowFunction $node
*/
private function isSkipped($node) : bool
{
if (!$this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::SCALAR_TYPES)) {
return \true;
}
if ($node instanceof ArrowFunction) {
return $node->returnType !== null;
}
if ($node->returnType !== null) {
return \true;
}
if (!$node instanceof ClassMethod) {
return $this->isUnionPossibleReturnsVoid($node);
}
if ($this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return \true;
}
if (!$node->isMagic()) {
return $this->isUnionPossibleReturnsVoid($node);
}
return \true;
}
/**
* @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|\PhpParser\Node\NullableType $returnedStrictTypeNode
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $functionLike
* @return \PhpParser\Node\Expr\Closure|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_
*/
private function refactorSingleReturnType(Return_ $return, $returnedStrictTypeNode, $functionLike)
{
$resolvedType = $this->nodeTypeResolver->getType($return);
if ($resolvedType instanceof UnionType) {
if (!$returnedStrictTypeNode instanceof NullableType) {
return $functionLike;
}
return $this->processSingleUnionType($functionLike, $resolvedType, $returnedStrictTypeNode);
}
/** @var Name $returnType */
$returnType = $resolvedType instanceof ObjectType ? new FullyQualified($resolvedType->getClassName()) : $returnedStrictTypeNode;
$functionLike->returnType = $returnType;
return $functionLike;
}
}

View File

@ -15,6 +15,7 @@ use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -33,10 +34,16 @@ final class ReturnTypeFromStrictTypedPropertyRector extends AbstractRector imple
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
public function __construct(TypeFactory $typeFactory, ReflectionResolver $reflectionResolver)
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(TypeFactory $typeFactory, ReflectionResolver $reflectionResolver, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->typeFactory = $typeFactory;
$this->reflectionResolver = $reflectionResolver;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
@ -79,6 +86,9 @@ CODE_SAMPLE
if ($node->returnType !== null) {
return null;
}
if ($this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node)) {
return null;
}
$propertyTypes = $this->resolveReturnPropertyType($node);
if ($propertyTypes === []) {
return null;

View File

@ -0,0 +1,88 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\TypeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Reflection\FunctionVariantWithPhpDocs;
use PHPStan\Type\MixedType;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\TypeDeclaration\NodeAnalyzer\TypeNodeUnwrapper;
final class ReturnStrictTypeAnalyzer
{
/**
* @readonly
* @var \Rector\Core\Reflection\ReflectionResolver
*/
private $reflectionResolver;
/**
* @readonly
* @var \Rector\TypeDeclaration\NodeAnalyzer\TypeNodeUnwrapper
*/
private $typeNodeUnwrapper;
/**
* @readonly
* @var \Rector\StaticTypeMapper\StaticTypeMapper
*/
private $staticTypeMapper;
public function __construct(ReflectionResolver $reflectionResolver, TypeNodeUnwrapper $typeNodeUnwrapper, StaticTypeMapper $staticTypeMapper)
{
$this->reflectionResolver = $reflectionResolver;
$this->typeNodeUnwrapper = $typeNodeUnwrapper;
$this->staticTypeMapper = $staticTypeMapper;
}
/**
* @param Return_[] $returns
* @return array<Identifier|Name|NullableType>
*/
public function collectStrictReturnTypes(array $returns) : array
{
$returnedStrictTypeNodes = [];
foreach ($returns as $return) {
if ($return->expr === null) {
return [];
}
$returnedExpr = $return->expr;
if ($returnedExpr instanceof MethodCall || $returnedExpr instanceof StaticCall || $returnedExpr instanceof FuncCall) {
$returnNode = $this->resolveMethodCallReturnNode($returnedExpr);
} else {
return [];
}
if (!$returnNode instanceof Node) {
return [];
}
$returnedStrictTypeNodes[] = $returnNode;
}
return $this->typeNodeUnwrapper->uniquateNodes($returnedStrictTypeNodes);
}
/**
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $call
*/
private function resolveMethodCallReturnNode($call) : ?Node
{
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($call);
if ($methodReflection === null) {
return null;
}
$parametersAcceptor = $methodReflection->getVariants()[0];
if ($parametersAcceptor instanceof FunctionVariantWithPhpDocs) {
// native return type is needed, as docblock can be false
$returnType = $parametersAcceptor->getNativeReturnType();
} else {
$returnType = $parametersAcceptor->getReturnType();
}
if ($returnType instanceof MixedType) {
return null;
}
return $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($returnType, TypeKind::RETURN);
}
}

View File

@ -0,0 +1,51 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\TypeAnalyzer;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\Type;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\AlwaysStrictReturnAnalyzer;
final class StrictReturnClassConstReturnTypeAnalyzer
{
/**
* @readonly
* @var \Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\AlwaysStrictReturnAnalyzer
*/
private $alwaysStrictReturnAnalyzer;
/**
* @readonly
* @var \Rector\NodeTypeResolver\NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @readonly
* @var \Rector\NodeTypeResolver\PHPStan\Type\TypeFactory
*/
private $typeFactory;
public function __construct(AlwaysStrictReturnAnalyzer $alwaysStrictReturnAnalyzer, NodeTypeResolver $nodeTypeResolver, TypeFactory $typeFactory)
{
$this->alwaysStrictReturnAnalyzer = $alwaysStrictReturnAnalyzer;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->typeFactory = $typeFactory;
}
public function matchAlwaysReturnConstFetch(ClassMethod $classMethod) : ?Type
{
$returns = $this->alwaysStrictReturnAnalyzer->matchAlwaysStrictReturns($classMethod);
if ($returns === null) {
return null;
}
$classConstFetchTypes = [];
foreach ($returns as $return) {
// @todo ~30 mins paid
if (!$return->expr instanceof ClassConstFetch) {
return null;
}
$classConstFetchTypes[] = $this->nodeTypeResolver->getType($return->expr);
}
return $this->typeFactory->createMixedPassedOrUnionType($classConstFetchTypes);
}
}

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'ecec40ce9d1b075c65dbbbabe38dbd70d5a50df5';
public const PACKAGE_VERSION = '2b35d2e75ea03ffe643c012485952ec6df3ea2ba';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-11-28 16:07:51';
public const RELEASE_DATE = '2022-11-28 21:37:23';
/**
* @var int
*/

2
vendor/autoload.php vendored
View File

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

View File

@ -2677,6 +2677,7 @@ return array(
'Rector\\TypeDeclaration\\NodeAnalyzer\\ReturnTypeAnalyzer\\StrictNativeFunctionReturnTypeAnalyzer' => $baseDir . '/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictNativeFunctionReturnTypeAnalyzer.php',
'Rector\\TypeDeclaration\\NodeAnalyzer\\ReturnTypeAnalyzer\\StrictReturnNewAnalyzer' => $baseDir . '/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php',
'Rector\\TypeDeclaration\\NodeAnalyzer\\ReturnTypeAnalyzer\\StrictScalarReturnTypeAnalyzer' => $baseDir . '/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictScalarReturnTypeAnalyzer.php',
'Rector\\TypeDeclaration\\NodeAnalyzer\\TypeNodeUnwrapper' => $baseDir . '/rules/TypeDeclaration/NodeAnalyzer/TypeNodeUnwrapper.php',
'Rector\\TypeDeclaration\\NodeTypeAnalyzer\\DetailedTypeAnalyzer' => $baseDir . '/rules/TypeDeclaration/NodeTypeAnalyzer/DetailedTypeAnalyzer.php',
'Rector\\TypeDeclaration\\NodeTypeAnalyzer\\PropertyTypeDecorator' => $baseDir . '/rules/TypeDeclaration/NodeTypeAnalyzer/PropertyTypeDecorator.php',
'Rector\\TypeDeclaration\\PHPStan\\ObjectTypeSpecifier' => $baseDir . '/rules/TypeDeclaration/PHPStan/ObjectTypeSpecifier.php',
@ -2699,10 +2700,13 @@ return array(
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByParentCallTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByParentCallTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnAnnotationIncorrectNullableRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnAnnotationIncorrectNullableRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnNeverTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromReturnDirectArrayRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnDirectArrayRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromReturnNewRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictBoolReturnExprRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictBoolReturnExprRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictConstantReturnRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictConstantReturnRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNativeCallRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNativeCallRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNewArrayRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNewArrayRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedCallRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedCallRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedPropertyRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php',
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureReturnTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/Closure/AddClosureReturnTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\FunctionLike\\AddParamTypeSplFixedArrayRector' => $baseDir . '/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeSplFixedArrayRector.php',
@ -2722,6 +2726,8 @@ return array(
'Rector\\TypeDeclaration\\TypeAnalyzer\\AlwaysStrictScalarExprAnalyzer' => $baseDir . '/rules/TypeDeclaration/TypeAnalyzer/AlwaysStrictScalarExprAnalyzer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\GenericClassStringTypeNormalizer' => $baseDir . '/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\IterableTypeAnalyzer' => $baseDir . '/rules/TypeDeclaration/TypeAnalyzer/IterableTypeAnalyzer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\ReturnStrictTypeAnalyzer' => $baseDir . '/rules/TypeDeclaration/TypeAnalyzer/ReturnStrictTypeAnalyzer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\StrictReturnClassConstReturnTypeAnalyzer' => $baseDir . '/rules/TypeDeclaration/TypeAnalyzer/StrictReturnClassConstReturnTypeAnalyzer.php',
'Rector\\TypeDeclaration\\TypeInferer\\AssignToPropertyTypeInferer' => $baseDir . '/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php',
'Rector\\TypeDeclaration\\TypeInferer\\PropertyTypeInferer\\AllAssignNodePropertyTypeInferer' => $baseDir . '/rules/TypeDeclaration/TypeInferer/PropertyTypeInferer/AllAssignNodePropertyTypeInferer.php',
'Rector\\TypeDeclaration\\TypeInferer\\PropertyTypeInferer\\GetterTypeDeclarationPropertyTypeInferer' => $baseDir . '/rules/TypeDeclaration/TypeInferer/PropertyTypeInferer/GetterTypeDeclarationPropertyTypeInferer.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit1d895023c888ab4399bbaf51e5db00c5
class ComposerAutoloaderInita4bc420cd27c7f7d2a53d52fd2855213
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInit1d895023c888ab4399bbaf51e5db00c5
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit1d895023c888ab4399bbaf51e5db00c5', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInita4bc420cd27c7f7d2a53d52fd2855213', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit1d895023c888ab4399bbaf51e5db00c5', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInita4bc420cd27c7f7d2a53d52fd2855213', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInita4bc420cd27c7f7d2a53d52fd2855213::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInita4bc420cd27c7f7d2a53d52fd2855213::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire1d895023c888ab4399bbaf51e5db00c5($fileIdentifier, $file);
composerRequirea4bc420cd27c7f7d2a53d52fd2855213($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInit1d895023c888ab4399bbaf51e5db00c5
* @param string $file
* @return void
*/
function composerRequire1d895023c888ab4399bbaf51e5db00c5($fileIdentifier, $file)
function composerRequirea4bc420cd27c7f7d2a53d52fd2855213($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 ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5
class ComposerStaticInita4bc420cd27c7f7d2a53d52fd2855213
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -2922,6 +2922,7 @@ class ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5
'Rector\\TypeDeclaration\\NodeAnalyzer\\ReturnTypeAnalyzer\\StrictNativeFunctionReturnTypeAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictNativeFunctionReturnTypeAnalyzer.php',
'Rector\\TypeDeclaration\\NodeAnalyzer\\ReturnTypeAnalyzer\\StrictReturnNewAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php',
'Rector\\TypeDeclaration\\NodeAnalyzer\\ReturnTypeAnalyzer\\StrictScalarReturnTypeAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictScalarReturnTypeAnalyzer.php',
'Rector\\TypeDeclaration\\NodeAnalyzer\\TypeNodeUnwrapper' => __DIR__ . '/../..' . '/rules/TypeDeclaration/NodeAnalyzer/TypeNodeUnwrapper.php',
'Rector\\TypeDeclaration\\NodeTypeAnalyzer\\DetailedTypeAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/NodeTypeAnalyzer/DetailedTypeAnalyzer.php',
'Rector\\TypeDeclaration\\NodeTypeAnalyzer\\PropertyTypeDecorator' => __DIR__ . '/../..' . '/rules/TypeDeclaration/NodeTypeAnalyzer/PropertyTypeDecorator.php',
'Rector\\TypeDeclaration\\PHPStan\\ObjectTypeSpecifier' => __DIR__ . '/../..' . '/rules/TypeDeclaration/PHPStan/ObjectTypeSpecifier.php',
@ -2944,10 +2945,13 @@ class ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByParentCallTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByParentCallTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnAnnotationIncorrectNullableRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnAnnotationIncorrectNullableRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnNeverTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromReturnDirectArrayRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnDirectArrayRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromReturnNewRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnNewRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictBoolReturnExprRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictBoolReturnExprRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictConstantReturnRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictConstantReturnRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNativeCallRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNativeCallRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNewArrayRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNewArrayRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedCallRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedCallRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedPropertyRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php',
'Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureReturnTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Closure/AddClosureReturnTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\FunctionLike\\AddParamTypeSplFixedArrayRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeSplFixedArrayRector.php',
@ -2967,6 +2971,8 @@ class ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5
'Rector\\TypeDeclaration\\TypeAnalyzer\\AlwaysStrictScalarExprAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeAnalyzer/AlwaysStrictScalarExprAnalyzer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\GenericClassStringTypeNormalizer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\IterableTypeAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeAnalyzer/IterableTypeAnalyzer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\ReturnStrictTypeAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeAnalyzer/ReturnStrictTypeAnalyzer.php',
'Rector\\TypeDeclaration\\TypeAnalyzer\\StrictReturnClassConstReturnTypeAnalyzer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeAnalyzer/StrictReturnClassConstReturnTypeAnalyzer.php',
'Rector\\TypeDeclaration\\TypeInferer\\AssignToPropertyTypeInferer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php',
'Rector\\TypeDeclaration\\TypeInferer\\PropertyTypeInferer\\AllAssignNodePropertyTypeInferer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeInferer/PropertyTypeInferer/AllAssignNodePropertyTypeInferer.php',
'Rector\\TypeDeclaration\\TypeInferer\\PropertyTypeInferer\\GetterTypeDeclarationPropertyTypeInferer' => __DIR__ . '/../..' . '/rules/TypeDeclaration/TypeInferer/PropertyTypeInferer/GetterTypeDeclarationPropertyTypeInferer.php',
@ -3013,9 +3019,9 @@ class ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInit1d895023c888ab4399bbaf51e5db00c5::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInita4bc420cd27c7f7d2a53d52fd2855213::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInita4bc420cd27c7f7d2a53d52fd2855213::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInita4bc420cd27c7f7d2a53d52fd2855213::$classMap;
}, null, ClassLoader::class);
}

View File

@ -2278,17 +2278,17 @@
},
{
"name": "symfony\/console",
"version": "v6.1.7",
"version_normalized": "6.1.7.0",
"version": "v6.1.8",
"version_normalized": "6.1.8.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/symfony\/console.git",
"reference": "a1282bd0c096e0bdb8800b104177e2ce404d8815"
"reference": "a71863ea74f444d93c768deb3e314e1f750cf20d"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/a1282bd0c096e0bdb8800b104177e2ce404d8815",
"reference": "a1282bd0c096e0bdb8800b104177e2ce404d8815",
"url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/a71863ea74f444d93c768deb3e314e1f750cf20d",
"reference": "a71863ea74f444d93c768deb3e314e1f750cf20d",
"shasum": ""
},
"require": {
@ -2323,7 +2323,7 @@
"symfony\/lock": "",
"symfony\/process": ""
},
"time": "2022-10-26T21:42:49+00:00",
"time": "2022-11-25T18:59:16+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@ -2357,7 +2357,7 @@
"terminal"
],
"support": {
"source": "https:\/\/github.com\/symfony\/console\/tree\/v6.1.7"
"source": "https:\/\/github.com\/symfony\/console\/tree\/v6.1.8"
},
"funding": [
{
@ -2481,17 +2481,17 @@
},
{
"name": "symfony\/dependency-injection",
"version": "v6.1.5",
"version_normalized": "6.1.5.0",
"version": "v6.1.8",
"version_normalized": "6.1.8.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/symfony\/dependency-injection.git",
"reference": "b9c797c9d56afc290d4265854bafd01b4e379240"
"reference": "11e33ed84db0ced77511a23b35168db127909f0e"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/symfony\/dependency-injection\/zipball\/b9c797c9d56afc290d4265854bafd01b4e379240",
"reference": "b9c797c9d56afc290d4265854bafd01b4e379240",
"url": "https:\/\/api.github.com\/repos\/symfony\/dependency-injection\/zipball\/11e33ed84db0ced77511a23b35168db127909f0e",
"reference": "11e33ed84db0ced77511a23b35168db127909f0e",
"shasum": ""
},
"require": {
@ -2523,7 +2523,7 @@
"symfony\/proxy-manager-bridge": "Generate service proxies to lazy load them",
"symfony\/yaml": ""
},
"time": "2022-09-28T16:00:52+00:00",
"time": "2022-11-25T07:34:52+00:00",
"type": "library",
"extra": {
"patches_applied": [
@ -2557,7 +2557,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https:\/\/symfony.com",
"support": {
"source": "https:\/\/github.com\/symfony\/dependency-injection\/tree\/v6.1.5"
"source": "https:\/\/github.com\/symfony\/dependency-injection\/tree\/v6.1.8"
},
"funding": [
{

File diff suppressed because one or more lines are too long

View File

@ -873,9 +873,6 @@ class Application implements ResetInterface
});
}
}
foreach ($commandSignals as $signal) {
$this->signalRegistry->register($signal, [$command, 'handleSignal']);
}
}
if (null !== $this->dispatcher) {
foreach ($this->signalsToDispatchEvent as $signal) {
@ -891,6 +888,9 @@ class Application implements ResetInterface
});
}
}
foreach ($commandSignals as $signal) {
$this->signalRegistry->register($signal, [$command, 'handleSignal']);
}
}
if (null === $this->dispatcher) {
return $command->run($input, $output);

View File

@ -92,7 +92,14 @@ EOH
$completionFile = __DIR__ . '/../Resources/completion.' . $shell;
if (!\file_exists($completionFile)) {
$supportedShells = $this->getSupportedShells();
($output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output)->writeln(\sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, \implode('", "', $supportedShells)));
if ($output instanceof ConsoleOutputInterface) {
$output = $output->getErrorOutput();
}
if ($shell) {
$output->writeln(\sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, \implode('", "', $supportedShells)));
} else {
$output->writeln(\sprintf('<error>Shell not detected, Symfony shell completion only supports "%s").</>', \implode('", "', $supportedShells)));
}
return self::INVALID;
}
$output->write(\str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], \file_get_contents($completionFile)));

View File

@ -11,7 +11,7 @@
namespace RectorPrefix202211\Symfony\Component\Console\Exception;
/**
* Represents an incorrect option name typed in the console.
* Represents an incorrect option name or value typed in the console.
*
* @author Jérôme Tamarelle <jerome@tamarelle.net>
*/

View File

@ -468,10 +468,13 @@ final class ProgressBar
}
$this->output->clear($lineCount);
} else {
for ($i = 0; $i < $this->formatLineCount; ++$i) {
$this->cursor->moveToColumn(1);
$this->cursor->clearLine();
$this->cursor->moveUp();
if ('' !== $this->previousMessage) {
// only clear upper lines when last call was not a clear
for ($i = 0; $i < $this->formatLineCount; ++$i) {
$this->cursor->moveToColumn(1);
$this->cursor->clearLine();
$this->cursor->moveUp();
}
}
$this->cursor->moveToColumn(1);
$this->cursor->clearLine();

View File

@ -11,13 +11,14 @@ _sf_{{ COMMAND_NAME }}() {
local sf_cmd="${COMP_WORDS[0]}"
# for an alias, get the real script behind it
if [[ $(type -t $sf_cmd) == "alias" ]]; then
sf_cmd_type=$(type -t $sf_cmd)
if [[ $sf_cmd_type == "alias" ]]; then
sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/")
else
elif [[ $sf_cmd_type == "file" ]]; then
sf_cmd=$(type -p $sf_cmd)
fi
if [ ! -x "$sf_cmd" ]; then
if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then
return 1
fi

View File

@ -36,7 +36,7 @@ class DecoratorServicePass extends AbstractRecursivePass
$definitions->insert([$id, $definition], [$decorated[2], --$order]);
}
$decoratingDefinitions = [];
$tagsToKeep = $container->hasParameter('container.behavior_describing_tags') ? $container->getParameter('container.behavior_describing_tags') : ['container.do_not_inline', 'container.service_locator', 'container.service_subscriber'];
$tagsToKeep = $container->hasParameter('container.behavior_describing_tags') ? $container->getParameter('container.behavior_describing_tags') : ['container.do_not_inline', 'container.service_locator', 'container.service_subscriber', 'container.service_subscriber.locator'];
foreach ($definitions as [$id, $definition]) {
$decoratedService = $definition->getDecoratedService();
[$inner, $renamedId] = $decoratedService;

View File

@ -109,7 +109,7 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface
foreach ($instanceofTags[$i] as $k => $v) {
if (null === $definition->getDecoratedService() || \in_array($k, $tagsToKeep, \true)) {
foreach ($v as $v) {
if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
if ($definition->hasTag($k) && (!$v || \in_array($v, $definition->getTag($k)))) {
continue;
}
$definition->addTag($k, $v);

View File

@ -39,6 +39,9 @@ final class ServiceLocatorTagPass extends AbstractRecursivePass
}
return self::register($this->container, $value->getValues());
}
if ($value instanceof Definition) {
$value->setBindings(parent::processValue($value->getBindings()));
}
if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) {
return parent::processValue($value, $isRoot);
}