Updated Rector to commit 2c1ae9bc46b3c8d31b1a45dcaac57c7d1522a8c1

2c1ae9bc46 Split StringReturnTypeFromStrictScalarReturnsRector into string, bool and numeric scalar + strict return type rules (#6113)
This commit is contained in:
Tomas Votruba 2024-07-03 20:14:45 +00:00
parent 3839c795dc
commit cd6dafbe86
21 changed files with 863 additions and 91 deletions

View File

@ -1,4 +1,4 @@
# 377 Rules Overview
# 380 Rules Overview
<br>
@ -60,7 +60,7 @@
- [Transform](#transform) (25)
- [TypeDeclaration](#typedeclaration) (51)
- [TypeDeclaration](#typedeclaration) (56)
- [Visibility](#visibility) (3)
@ -6769,11 +6769,34 @@ Change && and || between nullable objects to instanceof compares
<br>
### BoolReturnTypeFromStrictScalarReturnsRector
### BoolReturnTypeFromBooleanConstReturnsRector
Change return type based on strict returns type operations
Add return bool, based on direct true/false returns
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromStrictScalarReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromStrictScalarReturnsRector.php)
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanConstReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromBooleanConstReturnsRector.php)
```diff
class SomeClass
{
- public function resolve($value)
+ public function resolve($value): bool
{
if ($value) {
return false;
}
return true;
}
}
```
<br>
### BoolReturnTypeFromBooleanStrictReturnsRector
Add bool return type based on strict bool returns type operations
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanStrictReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromBooleanStrictReturnsRector.php)
```diff
class SomeClass
@ -6781,10 +6804,6 @@ Change return type based on strict returns type operations
- public function resolve($first, $second)
+ public function resolve($first, $second): bool
{
if ($first) {
return false;
}
return $first > $second;
}
}
@ -6909,19 +6928,38 @@ Set DateTime to DateTimeInterface for DateTime property with DateTimeInterface d
<br>
### NumericReturnTypeFromStrictReturnsRector
Add int/float return type based on strict typed returns
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\NumericReturnTypeFromStrictReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/NumericReturnTypeFromStrictReturnsRector.php)
```diff
class SomeClass
{
- public function increase($value)
+ public function increase($value): int
{
return ++$value;
}
}
```
<br>
### NumericReturnTypeFromStrictScalarReturnsRector
Change numeric return type based on strict returns type operations
Add int/float return type based on strict scalar returns type
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\NumericReturnTypeFromStrictScalarReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/NumericReturnTypeFromStrictScalarReturnsRector.php)
```diff
class SomeClass
{
- public function resolve(int $first, int $second)
+ public function resolve(int $first, int $second): int
- public function getNumber()
+ public function getNumber(): int
{
return $first - $second;
return 200;
}
}
```
@ -7383,6 +7421,52 @@ Add string type based on concat use
<br>
### StringReturnTypeFromStrictScalarReturnsRector
Add string return type based on returned string scalar values
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\StringReturnTypeFromStrictScalarReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/StringReturnTypeFromStrictScalarReturnsRector.php)
```diff
final class SomeClass
{
- public function foo($condition)
+ public function foo($condition): string;
{
if ($condition) {
return 'yes';
}
return 'no';
}
}
```
<br>
### StringReturnTypeFromStrictStringReturnsRector
Add string return type based on returned strict string values
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\StringReturnTypeFromStrictStringReturnsRector`](../rules/TypeDeclaration/Rector/ClassMethod/StringReturnTypeFromStrictStringReturnsRector.php)
```diff
final class SomeClass
{
- public function foo($condition, $value)
+ public function foo($condition, $value): string;
{
if ($value) {
return 'yes';
}
return strtoupper($value);
}
}
```
<br>
### TypedPropertyFromAssignsRector
Add typed property from assigned types

View File

@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\ClassConst;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Enum_;
use PhpParser\Node\Stmt\EnumCase;
use PhpParser\Node\Stmt\Return_;
use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
@ -142,8 +141,7 @@ final class EnumFactory
if (!$classMethod instanceof ClassMethod) {
return [];
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($classMethod, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($classMethod);
/** @var array<int|string, mixed> $mapping */
$mapping = [];
foreach ($returns as $return) {

View File

@ -40,7 +40,7 @@ final class AlwaysStrictReturnAnalyzer
return [];
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($functionLike);
if ($returns === []) {
return [];
}

View File

@ -8,7 +8,6 @@ use PhpParser\Node\Expr\Yield_;
use PhpParser\Node\Expr\YieldFrom;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnAnalyzer;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnFilter\ExclusiveNativeCallLikeReturnMatcher;
@ -47,8 +46,7 @@ final class StrictNativeFunctionReturnTypeAnalyzer
if ($this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($functionLike, [Yield_::class, YieldFrom::class])) {
return null;
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($functionLike);
if ($returns === []) {
return null;
}

View File

@ -13,7 +13,6 @@ use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -60,8 +59,7 @@ final class StrictReturnNewAnalyzer
if ($this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($functionLike, [Yield_::class, YieldFrom::class])) {
return null;
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($functionLike);
if ($returns === []) {
return null;
}

View File

@ -165,8 +165,7 @@ CODE_SAMPLE
if (!$dataProviderClassMethod instanceof ClassMethod) {
return new MixedType();
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($dataProviderClassMethod, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($dataProviderClassMethod);
if ($returns !== []) {
return $this->resolveReturnStaticArrayTypeByParameterPosition($returns, $parameterPosition);
}

View File

@ -0,0 +1,133 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\PhpParser\Node\Value\ValueResolver;
use Rector\Rector\AbstractScopeAwareRector;
use Rector\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\BoolReturnTypeFromBooleanConstReturnsRector\BoolReturnTypeFromBooleanConstReturnsRectorTest
*/
final class BoolReturnTypeFromBooleanConstReturnsRector extends AbstractScopeAwareRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\PhpParser\Node\Value\ValueResolver
*/
private $valueResolver;
/**
* @readonly
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(ValueResolver $valueResolver, BetterNodeFinder $betterNodeFinder, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->valueResolver = $valueResolver;
$this->betterNodeFinder = $betterNodeFinder;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add return bool, based on direct true/false returns', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function resolve($value)
{
if ($value) {
return false;
}
return true;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function resolve($value): bool
{
if ($value) {
return false;
}
return true;
}
}
CODE_SAMPLE
)]);
}
/**
* @funcCall array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
{
if ($this->shouldSkip($node, $scope)) {
return null;
}
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if (!$this->hasOnlyBooleanConstExprs($returns)) {
return null;
}
$node->returnType = new Identifier('bool');
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::SCALAR_TYPES;
}
/**
* @param ClassMethod|Function_|Closure $node
*/
private function shouldSkip(Node $node, Scope $scope) : bool
{
// already has the type, skip
if ($node->returnType instanceof Node) {
return \true;
}
return $node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope);
}
/**
* @param Return_[] $returns
*/
private function hasOnlyBooleanConstExprs(array $returns) : bool
{
if ($returns === []) {
return \false;
}
foreach ($returns as $return) {
if (!$return->expr instanceof ConstFetch) {
return \false;
}
if (!$this->valueResolver->isTrueOrFalse($return->expr)) {
return \false;
}
}
return \true;
}
}

View File

@ -0,0 +1,216 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Greater;
use PhpParser\Node\Expr\BinaryOp\GreaterOrEqual;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotEqual;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BinaryOp\Smaller;
use PhpParser\Node\Expr\BinaryOp\SmallerOrEqual;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\BooleanType;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\PhpParser\Node\Value\ValueResolver;
use Rector\Rector\AbstractScopeAwareRector;
use Rector\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\BoolReturnTypeFromBooleanStrictReturnsRector\BoolReturnTypeFromBooleanStrictReturnsRectorTest
*/
final class BoolReturnTypeFromBooleanStrictReturnsRector extends AbstractScopeAwareRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \PHPStan\Reflection\ReflectionProvider
*/
private $reflectionProvider;
/**
* @readonly
* @var \Rector\PhpParser\Node\Value\ValueResolver
*/
private $valueResolver;
/**
* @readonly
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
public function __construct(ReflectionProvider $reflectionProvider, ValueResolver $valueResolver, BetterNodeFinder $betterNodeFinder, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard)
{
$this->reflectionProvider = $reflectionProvider;
$this->valueResolver = $valueResolver;
$this->betterNodeFinder = $betterNodeFinder;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add bool return type based on strict bool returns type operations', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function resolve($first, $second)
{
return $first > $second;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function resolve($first, $second): bool
{
return $first > $second;
}
}
CODE_SAMPLE
)]);
}
/**
* @funcCall array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
{
if ($this->shouldSkip($node, $scope)) {
return null;
}
$returns = $this->betterNodeFinder->findReturnsScoped($node);
// handled in another rule
if ($this->hasOnlyBooleanConstExprs($returns)) {
return null;
}
// handled in another rule
if (!$this->hasOnlyBoolScalarReturnExprs($returns)) {
return null;
}
$node->returnType = new Identifier('bool');
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::SCALAR_TYPES;
}
/**
* @param ClassMethod|Function_|Closure $node
*/
private function shouldSkip(Node $node, Scope $scope) : bool
{
// already has the type, skip
if ($node->returnType instanceof Node) {
return \true;
}
return $node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope);
}
/**
* @param Return_[] $returns
*/
private function hasOnlyBoolScalarReturnExprs(array $returns) : bool
{
foreach ($returns as $return) {
if (!$return->expr instanceof Expr) {
return \false;
}
if ($this->isBooleanBinaryOp($return->expr)) {
continue;
}
if ($return->expr instanceof FuncCall && $this->isNativeBooleanReturnTypeFuncCall($return->expr)) {
continue;
}
return \false;
}
return \true;
}
private function isNativeBooleanReturnTypeFuncCall(FuncCall $funcCall) : bool
{
$functionName = $this->getName($funcCall);
if (!\is_string($functionName)) {
return \false;
}
$functionReflection = $this->reflectionProvider->getFunction(new Name($functionName), null);
if (!$functionReflection->isBuiltin()) {
return \false;
}
foreach ($functionReflection->getVariants() as $parametersAcceptorWithPhpDoc) {
return $parametersAcceptorWithPhpDoc->getNativeReturnType() instanceof BooleanType;
}
return \false;
}
private function isBooleanBinaryOp(Expr $expr) : bool
{
if ($expr instanceof Smaller) {
return \true;
}
if ($expr instanceof SmallerOrEqual) {
return \true;
}
if ($expr instanceof Greater) {
return \true;
}
if ($expr instanceof GreaterOrEqual) {
return \true;
}
if ($expr instanceof BooleanOr) {
return \true;
}
if ($expr instanceof BooleanAnd) {
return \true;
}
if ($expr instanceof Identical) {
return \true;
}
if ($expr instanceof NotIdentical) {
return \true;
}
if ($expr instanceof Equal) {
return \true;
}
return $expr instanceof NotEqual;
}
/**
* @param Return_[] $returns
*/
private function hasOnlyBooleanConstExprs(array $returns) : bool
{
if ($returns === []) {
return \false;
}
foreach ($returns as $return) {
if (!$return->expr instanceof ConstFetch) {
return \false;
}
if (!$this->valueResolver->isTrueOrFalse($return->expr)) {
return \false;
}
}
return \true;
}
}

View File

@ -35,6 +35,9 @@ use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @deprecated Since 1.2.1, as name is invalid and work with native constants, not scalars. Use
* @see BoolReturnTypeFromBooleanConstReturnsRector instead.
*
* @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromStrictScalarReturnsRector\BoolReturnTypeFromStrictScalarReturnsRectorTest
*/
final class BoolReturnTypeFromStrictScalarReturnsRector extends AbstractScopeAwareRector implements MinPhpVersionInterface

View File

@ -0,0 +1,153 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\DNumber;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Rector\AbstractScopeAwareRector;
use Rector\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\NumericReturnTypeFromStrictReturnsRector\NumericReturnTypeFromStrictReturnsRectorTest
*/
final class NumericReturnTypeFromStrictReturnsRector extends AbstractScopeAwareRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
/**
* @readonly
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard, BetterNodeFinder $betterNodeFinder)
{
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
$this->betterNodeFinder = $betterNodeFinder;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add int/float return type based on strict typed returns', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function increase($value)
{
return ++$value;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function increase($value): int
{
return ++$value;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
{
if ($this->shouldSkip($node, $scope)) {
return null;
}
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if ($returns === []) {
return null;
}
// handled by another rule
if ($this->isAlwaysNumeric($returns)) {
return null;
}
$isAlwaysIntType = \true;
$isAlwaysFloatType = \true;
foreach ($returns as $return) {
if (!$return->expr instanceof Expr) {
return null;
}
$exprType = $this->nodeTypeResolver->getType($return->expr);
if (!$exprType->isInteger()->yes()) {
$isAlwaysIntType = \false;
}
if (!$exprType->isFloat()->yes()) {
$isAlwaysFloatType = \false;
}
}
if ($isAlwaysFloatType) {
$node->returnType = new Identifier('float');
return $node;
}
if ($isAlwaysIntType) {
$node->returnType = new Identifier('int');
return $node;
}
return null;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::SCALAR_TYPES;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
private function shouldSkip($functionLike, Scope $scope) : bool
{
// type is already known, skip
if ($functionLike->returnType instanceof Node) {
return \true;
}
// empty, nothing to find
if ($functionLike->stmts === null || $functionLike->stmts === []) {
return \true;
}
if (!$functionLike instanceof ClassMethod) {
return \false;
}
return $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($functionLike, $scope);
}
/**
* @param Return_[] $returns
*/
private function isAlwaysNumeric(array $returns) : bool
{
$isAlwaysFloat = \true;
$isAlwaysInt = \true;
foreach ($returns as $return) {
if (!$return->expr instanceof DNumber) {
$isAlwaysFloat = \false;
}
if (!$return->expr instanceof LNumber) {
$isAlwaysInt = \false;
}
}
if ($isAlwaysFloat) {
return \true;
}
return $isAlwaysInt;
}
}

View File

@ -5,11 +5,13 @@ namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\DNumber;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Analyser\Scope;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Rector\AbstractScopeAwareRector;
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
use Rector\ValueObject\PhpVersionFeature;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
@ -27,31 +29,31 @@ final class NumericReturnTypeFromStrictScalarReturnsRector extends AbstractScope
private $classMethodReturnTypeOverrideGuard;
/**
* @readonly
* @var \Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $returnTypeInferer;
public function __construct(ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard, ReturnTypeInferer $returnTypeInferer)
private $betterNodeFinder;
public function __construct(ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard, BetterNodeFinder $betterNodeFinder)
{
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
$this->returnTypeInferer = $returnTypeInferer;
$this->betterNodeFinder = $betterNodeFinder;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change numeric return type based on strict returns type operations', [new CodeSample(<<<'CODE_SAMPLE'
return new RuleDefinition('Add int/float return type based on strict scalar returns type', [new CodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function resolve(int $first, int $second)
public function getNumber()
{
return $first - $second;
return 200;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function resolve(int $first, int $second): int
public function getNumber(): int
{
return $first - $second;
return 200;
}
}
CODE_SAMPLE
@ -69,21 +71,28 @@ CODE_SAMPLE
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
{
if ($node->returnType instanceof Node) {
if ($this->shouldSkip($node, $scope)) {
return null;
}
if ($node->stmts === null) {
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if ($returns === []) {
return null;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope)) {
return null;
$isAlwaysInt = \true;
$isAlwaysFloat = \true;
foreach ($returns as $return) {
if (!$return->expr instanceof DNumber) {
$isAlwaysFloat = \false;
}
if (!$return->expr instanceof LNumber) {
$isAlwaysInt = \false;
}
}
$returnType = $this->returnTypeInferer->inferFunctionLike($node);
if ($returnType->isFloat()->yes()) {
if ($isAlwaysFloat) {
$node->returnType = new Identifier('float');
return $node;
}
if ($returnType->isInteger()->yes()) {
if ($isAlwaysInt) {
$node->returnType = new Identifier('int');
return $node;
}
@ -93,4 +102,22 @@ CODE_SAMPLE
{
return PhpVersionFeature::SCALAR_TYPES;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
private function shouldSkip($functionLike, Scope $scope) : bool
{
// type is already known, skip
if ($functionLike->returnType instanceof Node) {
return \true;
}
// empty, nothing to ifnd
if ($functionLike->stmts === null || $functionLike->stmts === []) {
return \true;
}
if (!$functionLike instanceof ClassMethod) {
return \false;
}
return $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($functionLike, $scope);
}
}

View File

@ -15,7 +15,6 @@ use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantArrayType;
@ -105,7 +104,7 @@ CODE_SAMPLE
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_|Closure $node
* @param ClassMethod|Function_ $node
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
{
@ -125,8 +124,7 @@ CODE_SAMPLE
if ($this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($node, [Yield_::class, YieldFrom::class])) {
return null;
}
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($node, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if ($returns === []) {
return null;
}
@ -199,7 +197,7 @@ CODE_SAMPLE
/**
* @param Variable[] $variables
* @return Variable[]
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $functionLike
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
private function matchVariableNotOverriddenByNonArray($functionLike, array $variables) : array
{

View File

@ -8,7 +8,6 @@ use PhpParser\Node\Expr;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\Php\PhpPropertyReflection;
use PHPStan\Type\MixedType;
@ -131,8 +130,7 @@ CODE_SAMPLE
*/
private function resolveReturnPropertyType(ClassMethod $classMethod) : array
{
/** @var Return_[] $returns */
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($classMethod, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($classMethod);
$propertyTypes = [];
foreach ($returns as $return) {
if (!$return->expr instanceof Expr) {

View File

@ -3,15 +3,15 @@
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PHPStan\Type\Type;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\Encapsed;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Analyser\Scope;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Rector\AbstractScopeAwareRector;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictScalarReturnTypeAnalyzer;
use Rector\ValueObject\PhpVersion;
use Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
@ -22,11 +22,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class StringReturnTypeFromStrictScalarReturnsRector extends AbstractScopeAwareRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer\StrictScalarReturnTypeAnalyzer
*/
private $strictScalarReturnTypeAnalyzer;
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
@ -34,40 +29,39 @@ final class StringReturnTypeFromStrictScalarReturnsRector extends AbstractScopeA
private $classMethodReturnTypeOverrideGuard;
/**
* @readonly
* @var \Rector\StaticTypeMapper\StaticTypeMapper
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $staticTypeMapper;
public function __construct(StrictScalarReturnTypeAnalyzer $strictScalarReturnTypeAnalyzer, ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard, StaticTypeMapper $staticTypeMapper)
private $betterNodeFinder;
public function __construct(ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard, BetterNodeFinder $betterNodeFinder)
{
$this->strictScalarReturnTypeAnalyzer = $strictScalarReturnTypeAnalyzer;
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
$this->staticTypeMapper = $staticTypeMapper;
$this->betterNodeFinder = $betterNodeFinder;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Change return type based on strict string scalar returns', [new CodeSample(<<<'CODE_SAMPLE'
return new RuleDefinition('Add string return type based on returned string scalar values', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function foo($condition, $value)
public function foo($condition)
{
if ($value) {
if ($condition) {
return 'yes';
}
return strtoupper($value);
return 'no';
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function foo($condition, $value): string;
public function foo($condition): string;
{
if ($value) {
if ($condition) {
return 'yes';
}
return strtoupper($value);
return 'no';
}
}
CODE_SAMPLE
@ -89,26 +83,35 @@ CODE_SAMPLE
if ($node->returnType instanceof Node) {
return null;
}
$scalarReturnType = $this->strictScalarReturnTypeAnalyzer->matchAlwaysScalarReturnType($node);
if (!$scalarReturnType instanceof Type) {
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if ($returns === []) {
// void
return null;
}
// must be string type
if (!$scalarReturnType->isString()->yes()) {
foreach ($returns as $return) {
// we need exact string "value" return
if (!$return->expr instanceof String_ && !$return->expr instanceof Encapsed) {
return null;
}
}
if ($this->shouldSkipClassMethodForOverride($node, $scope)) {
return null;
}
$returnTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($scalarReturnType, TypeKind::RETURN);
if (!$returnTypeNode instanceof Node) {
return null;
}
if ($node instanceof ClassMethod && $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope)) {
return null;
}
$node->returnType = $returnTypeNode;
$node->returnType = new Identifier('string');
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersion::PHP_70;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
private function shouldSkipClassMethodForOverride($functionLike, Scope $scope) : bool
{
if (!$functionLike instanceof ClassMethod) {
return \false;
}
return $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($functionLike, $scope);
}
}

View File

@ -0,0 +1,151 @@
<?php
declare (strict_types=1);
namespace Rector\TypeDeclaration\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\Encapsed;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\Rector\AbstractScopeAwareRector;
use Rector\ValueObject\PhpVersion;
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\StringReturnTypeFromStrictStringReturnsRector\StringReturnTypeFromStrictStringReturnsRectorTest
*/
final class StringReturnTypeFromStrictStringReturnsRector extends AbstractScopeAwareRector implements MinPhpVersionInterface
{
/**
* @readonly
* @var \Rector\VendorLocker\NodeVendorLocker\ClassMethodReturnTypeOverrideGuard
*/
private $classMethodReturnTypeOverrideGuard;
/**
* @readonly
* @var \Rector\PhpParser\Node\BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(ClassMethodReturnTypeOverrideGuard $classMethodReturnTypeOverrideGuard, BetterNodeFinder $betterNodeFinder)
{
$this->classMethodReturnTypeOverrideGuard = $classMethodReturnTypeOverrideGuard;
$this->betterNodeFinder = $betterNodeFinder;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Add string return type based on returned strict string values', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
public function foo($condition, $value)
{
if ($value) {
return 'yes';
}
return strtoupper($value);
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
public function foo($condition, $value): string;
{
if ($value) {
return 'yes';
}
return strtoupper($value);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
*/
public function refactorWithScope(Node $node, Scope $scope) : ?Node
{
// already added → skip
if ($node->returnType instanceof Node) {
return null;
}
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if ($returns === []) {
// void
return null;
}
// handled by another rule
if ($this->hasAlwaysStringScalarReturn($returns)) {
return null;
}
// anything that return strict string, but no strings only
if (!$this->isAlwaysStringStrictType($returns)) {
return null;
}
if ($this->shouldSkipClassMethodForOverride($node, $scope)) {
return null;
}
$node->returnType = new Identifier('string');
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersion::PHP_70;
}
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike
*/
private function shouldSkipClassMethodForOverride($functionLike, Scope $scope) : bool
{
if (!$functionLike instanceof ClassMethod) {
return \false;
}
return $this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($functionLike, $scope);
}
/**
* @param Return_[] $returns
*/
private function hasAlwaysStringScalarReturn(array $returns) : bool
{
foreach ($returns as $return) {
// we need exact string "value" return
if (!$return->expr instanceof String_ && !$return->expr instanceof Encapsed) {
return \false;
}
}
return \true;
}
/**
* @param Return_[] $returns
*/
private function isAlwaysStringStrictType(array $returns) : bool
{
foreach ($returns as $return) {
// void return
if (!$return->expr instanceof Expr) {
return \false;
}
$exprType = $this->nodeTypeResolver->getNativeType($return->expr);
if (!$exprType->isString()->yes()) {
return \false;
}
}
return \true;
}
}

View File

@ -7,7 +7,6 @@ use PhpParser\Node;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use PHPStan\Type\MixedType;
use PHPStan\Type\TypeCombinator;
@ -95,7 +94,7 @@ CODE_SAMPLE
if ($node->stmts === null) {
return null;
}
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($node, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($node);
if (\count($returns) !== 1) {
return null;
}

View File

@ -180,7 +180,7 @@ final class ReturnTypeInferer
return $unionType;
}
if (!$functionLike instanceof ArrowFunction) {
$returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class);
$returns = $this->betterNodeFinder->findReturnsScoped($functionLike);
$returnsWithExpr = \array_filter($returns, static function (Return_ $return) : bool {
return $return->expr instanceof Expr;
});

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'd8400c7cf1b75378603c7276c95393e2fd74c5b5';
public const PACKAGE_VERSION = '2c1ae9bc46b3c8d31b1a45dcaac57c7d1522a8c1';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2024-07-03 18:39:31';
public const RELEASE_DATE = '2024-07-03 20:12:05';
/**
* @var int
*/

View File

@ -16,7 +16,9 @@ use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeBasedOnPHPUnitDataProv
use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeFromPropertyTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector;
use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector;
use Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromStrictScalarReturnsRector;
use Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanConstReturnsRector;
use Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanStrictReturnsRector;
use Rector\TypeDeclaration\Rector\ClassMethod\NumericReturnTypeFromStrictReturnsRector;
use Rector\TypeDeclaration\Rector\ClassMethod\NumericReturnTypeFromStrictScalarReturnsRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByMethodCallTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ParamTypeByParentCallTypeRector;
@ -38,6 +40,7 @@ use Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector;
use Rector\TypeDeclaration\Rector\ClassMethod\StrictArrayParamDimFetchRector;
use Rector\TypeDeclaration\Rector\ClassMethod\StrictStringParamConcatRector;
use Rector\TypeDeclaration\Rector\ClassMethod\StringReturnTypeFromStrictScalarReturnsRector;
use Rector\TypeDeclaration\Rector\ClassMethod\StringReturnTypeFromStrictStringReturnsRector;
use Rector\TypeDeclaration\Rector\Closure\AddClosureNeverReturnTypeRector;
use Rector\TypeDeclaration\Rector\Closure\AddClosureVoidReturnTypeWhereNoReturnRector;
use Rector\TypeDeclaration\Rector\Closure\ClosureReturnTypeRector;
@ -66,9 +69,12 @@ final class TypeDeclarationLevel
ReturnTypeFromStrictNewArrayRector::class,
ReturnTypeFromStrictBoolReturnExprRector::class,
// scalar values
BoolReturnTypeFromStrictScalarReturnsRector::class,
NumericReturnTypeFromStrictScalarReturnsRector::class,
BoolReturnTypeFromBooleanConstReturnsRector::class,
StringReturnTypeFromStrictScalarReturnsRector::class,
NumericReturnTypeFromStrictScalarReturnsRector::class,
BoolReturnTypeFromBooleanStrictReturnsRector::class,
StringReturnTypeFromStrictStringReturnsRector::class,
NumericReturnTypeFromStrictReturnsRector::class,
ReturnTypeFromStrictTernaryRector::class,
ReturnTypeFromReturnDirectArrayRector::class,
ReturnTypeFromReturnNewRector::class,

View File

@ -2417,7 +2417,10 @@ return array(
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddReturnTypeDeclarationRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeDeclarationRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddTypeFromResourceDocblockRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/AddTypeFromResourceDocblockRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddVoidReturnTypeWhereNoReturnRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/AddVoidReturnTypeWhereNoReturnRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\BoolReturnTypeFromBooleanConstReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromBooleanConstReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\BoolReturnTypeFromBooleanStrictReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromBooleanStrictReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\BoolReturnTypeFromStrictScalarReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromStrictScalarReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\NumericReturnTypeFromStrictReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/NumericReturnTypeFromStrictReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\NumericReturnTypeFromStrictScalarReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/NumericReturnTypeFromStrictScalarReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByMethodCallTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByParentCallTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByParentCallTypeRector.php',
@ -2440,6 +2443,7 @@ return array(
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictArrayParamDimFetchRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/StrictArrayParamDimFetchRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictStringParamConcatRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StringReturnTypeFromStrictScalarReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/StringReturnTypeFromStrictScalarReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StringReturnTypeFromStrictStringReturnsRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/StringReturnTypeFromStrictStringReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\AddTestsVoidReturnTypeWhereNoReturnRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/AddTestsVoidReturnTypeWhereNoReturnRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\ChildDoctrineRepositoryClassTypeRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\MergeDateTimePropertyTypeDeclarationRector' => $baseDir . '/rules/TypeDeclaration/Rector/Class_/MergeDateTimePropertyTypeDeclarationRector.php',

View File

@ -2636,7 +2636,10 @@ class ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddReturnTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeDeclarationRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddTypeFromResourceDocblockRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/AddTypeFromResourceDocblockRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddVoidReturnTypeWhereNoReturnRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/AddVoidReturnTypeWhereNoReturnRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\BoolReturnTypeFromBooleanConstReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromBooleanConstReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\BoolReturnTypeFromBooleanStrictReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromBooleanStrictReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\BoolReturnTypeFromStrictScalarReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/BoolReturnTypeFromStrictScalarReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\NumericReturnTypeFromStrictReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/NumericReturnTypeFromStrictReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\NumericReturnTypeFromStrictScalarReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/NumericReturnTypeFromStrictScalarReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByMethodCallTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByParentCallTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByParentCallTypeRector.php',
@ -2659,6 +2662,7 @@ class ComposerStaticInit2971ea952332f12bcefd9fbb21b5c118
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictArrayParamDimFetchRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/StrictArrayParamDimFetchRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictStringParamConcatRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StringReturnTypeFromStrictScalarReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/StringReturnTypeFromStrictScalarReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StringReturnTypeFromStrictStringReturnsRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/StringReturnTypeFromStrictStringReturnsRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\AddTestsVoidReturnTypeWhereNoReturnRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/AddTestsVoidReturnTypeWhereNoReturnRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\ChildDoctrineRepositoryClassTypeRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/ChildDoctrineRepositoryClassTypeRector.php',
'Rector\\TypeDeclaration\\Rector\\Class_\\MergeDateTimePropertyTypeDeclarationRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/Class_/MergeDateTimePropertyTypeDeclarationRector.php',