mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-31 16:30:51 +00:00
Skip too wide union types on AddMethodCallBasedStrictParamTypeRector (#1097)
This commit is contained in:
parent
a5f8d529a9
commit
4c507636dc
|
@ -1,4 +1,4 @@
|
|||
# 485 Rules Overview
|
||||
# 476 Rules Overview
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -18,8 +18,6 @@
|
|||
|
||||
- [DeadCode](#deadcode) (49)
|
||||
|
||||
- [Defluent](#defluent) (9)
|
||||
|
||||
- [DependencyInjection](#dependencyinjection) (3)
|
||||
|
||||
- [DowngradePhp53](#downgradephp53) (1)
|
||||
|
@ -58,7 +56,7 @@
|
|||
|
||||
- [Php52](#php52) (2)
|
||||
|
||||
- [Php53](#php53) (4)
|
||||
- [Php53](#php53) (3)
|
||||
|
||||
- [Php54](#php54) (2)
|
||||
|
||||
|
@ -76,7 +74,7 @@
|
|||
|
||||
- [Php74](#php74) (15)
|
||||
|
||||
- [Php80](#php80) (16)
|
||||
- [Php80](#php80) (17)
|
||||
|
||||
- [Php81](#php81) (5)
|
||||
|
||||
|
@ -3949,202 +3947,6 @@ Remove php version checks if they are passed
|
|||
|
||||
<br>
|
||||
|
||||
## Defluent
|
||||
|
||||
### DefluentReturnMethodCallRector
|
||||
|
||||
Turns return of fluent, to standalone call line and return of value
|
||||
|
||||
- class: [`Rector\Defluent\Rector\Return_\DefluentReturnMethodCallRector`](../rules/Defluent/Rector/Return_/DefluentReturnMethodCallRector.php)
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-return $someClass->someFunction();
|
||||
+$someClass->someFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### FluentChainMethodCallToNormalMethodCallRector
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector`](../rules/Defluent/Rector/MethodCall/FluentChainMethodCallToNormalMethodCallRector.php)
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-$someClass->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### InArgFluentChainMethodCallToStandaloneMethodCallRector
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector`](../rules/Defluent/Rector/MethodCall/InArgFluentChainMethodCallToStandaloneMethodCallRector.php)
|
||||
|
||||
```diff
|
||||
class UsedAsParameter
|
||||
{
|
||||
public function someFunction(FluentClass $someClass)
|
||||
{
|
||||
- $this->processFluentClass($someClass->someFunction()->otherFunction());
|
||||
+ $someClass->someFunction();
|
||||
+ $someClass->otherFunction();
|
||||
+ $this->processFluentClass($someClass);
|
||||
}
|
||||
|
||||
public function processFluentClass(FluentClass $someClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### MethodCallOnSetterMethodCallToStandaloneAssignRector
|
||||
|
||||
Change method call on setter to standalone assign before the setter
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector`](../rules/Defluent/Rector/MethodCall/MethodCallOnSetterMethodCallToStandaloneAssignRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function some()
|
||||
{
|
||||
- $this->anotherMethod(new AnotherClass())
|
||||
- ->someFunction();
|
||||
+ $anotherClass = new AnotherClass();
|
||||
+ $anotherClass->someFunction();
|
||||
+ $this->anotherMethod($anotherClass);
|
||||
}
|
||||
|
||||
public function anotherMethod(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### NewFluentChainMethodCallToNonFluentRector
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector`](../rules/Defluent/Rector/MethodCall/NewFluentChainMethodCallToNonFluentRector.php)
|
||||
|
||||
```diff
|
||||
-(new SomeClass())->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass = new SomeClass();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### NormalToFluentRector
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
:wrench: **configure it!**
|
||||
|
||||
- class: [`Rector\Defluent\Rector\ClassMethod\NormalToFluentRector`](../rules/Defluent/Rector/ClassMethod/NormalToFluentRector.php)
|
||||
|
||||
```php
|
||||
use Rector\Defluent\Rector\ClassMethod\NormalToFluentRector;
|
||||
use Rector\Defluent\ValueObject\NormalToFluent;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->set(NormalToFluentRector::class)
|
||||
->call('configure', [[
|
||||
NormalToFluentRector::CALLS_TO_FLUENT => ValueObjectInliner::inline([
|
||||
new NormalToFluent('SomeClass', ['someFunction', 'otherFunction']), ]
|
||||
),
|
||||
]]);
|
||||
};
|
||||
```
|
||||
|
||||
↓
|
||||
|
||||
```diff
|
||||
$someObject = new SomeClass();
|
||||
-$someObject->someFunction();
|
||||
-$someObject->otherFunction();
|
||||
+$someObject->someFunction()
|
||||
+ ->otherFunction();
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### ReturnFluentChainMethodCallToNormalMethodCallRector
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
- class: [`Rector\Defluent\Rector\Return_\ReturnFluentChainMethodCallToNormalMethodCallRector`](../rules/Defluent/Rector/Return_/ReturnFluentChainMethodCallToNormalMethodCallRector.php)
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
|
||||
-return $someClass->someFunction()
|
||||
- ->otherFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### ReturnNewFluentChainMethodCallToNonFluentRector
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
- class: [`Rector\Defluent\Rector\Return_\ReturnNewFluentChainMethodCallToNonFluentRector`](../rules/Defluent/Rector/Return_/ReturnNewFluentChainMethodCallToNonFluentRector.php)
|
||||
|
||||
```diff
|
||||
-return (new SomeClass())->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass = new SomeClass();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### ReturnThisRemoveRector
|
||||
|
||||
Removes "return `$this;"` from *fluent interfaces* for specified classes.
|
||||
|
||||
- class: [`Rector\Defluent\Rector\ClassMethod\ReturnThisRemoveRector`](../rules/Defluent/Rector/ClassMethod/ReturnThisRemoveRector.php)
|
||||
|
||||
```diff
|
||||
class SomeExampleClass
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
- return $this;
|
||||
}
|
||||
|
||||
public function otherFunction()
|
||||
{
|
||||
- return $this;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## DependencyInjection
|
||||
|
||||
### ActionInjectionToConstructorInjectionRector
|
||||
|
@ -6367,19 +6169,6 @@ Change property modifier from `var` to `public`
|
|||
|
||||
## Php53
|
||||
|
||||
### ClearReturnNewByReferenceRector
|
||||
|
||||
Remove reference from "$assign = &new Value;"
|
||||
|
||||
- class: [`Rector\Php53\Rector\AssignRef\ClearReturnNewByReferenceRector`](../rules/Php53/Rector/AssignRef/ClearReturnNewByReferenceRector.php)
|
||||
|
||||
```diff
|
||||
-$assign = &new Value;
|
||||
+$assign = new Value;
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### DirNameFileConstantToDirConstantRector
|
||||
|
||||
Convert dirname(__FILE__) to __DIR__
|
||||
|
@ -7973,6 +7762,26 @@ Move required parameters after optional ones
|
|||
|
||||
<br>
|
||||
|
||||
### Php8ResourceReturnToObjectRector
|
||||
|
||||
Change `is_resource()` to instanceof Object
|
||||
|
||||
- class: [`Rector\Php80\Rector\FuncCall\Php8ResourceReturnToObjectRector`](../rules/Php80/Rector/FuncCall/Php8ResourceReturnToObjectRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$ch = curl_init();
|
||||
- is_resource($ch);
|
||||
+ $ch instanceof \CurlHandle;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### RemoveUnusedVariableInCatchRector
|
||||
|
||||
Remove unused variable in `catch()`
|
||||
|
@ -11560,29 +11369,21 @@ Add known return type to functions
|
|||
|
||||
### AddMethodCallBasedStrictParamTypeRector
|
||||
|
||||
Change param type to strict type of passed expression
|
||||
Change private method param type to strict type, based on passed strict types
|
||||
|
||||
- class: [`Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector`](../rules/TypeDeclaration/Rector/ClassMethod/AddMethodCallBasedStrictParamTypeRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
final class SomeClass
|
||||
{
|
||||
- public function getById($id)
|
||||
+ public function getById(int $id)
|
||||
public function run(int $value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class CallerClass
|
||||
{
|
||||
public function run(SomeClass $someClass)
|
||||
{
|
||||
$someClass->getById($this->getId());
|
||||
$this->resolve($value);
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
- private function resolve($value)
|
||||
+ private function resolve(int $value)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Whatever\Foo\Bar;
|
|||
use MyCLabs\Enum\Enum;
|
||||
|
||||
/**
|
||||
* @template-extends Enum<BrokenEnum::*>
|
||||
* @template-extends Enum<BrokenEnum>
|
||||
* @psalm-immutable
|
||||
*/
|
||||
final class BrokenEnum extends Enum
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
|
||||
final class SkipTooWideUnion
|
||||
{
|
||||
public function run(MethodCall $methodCall, StaticCall $staticCall, String_ $string, LNumber $number)
|
||||
{
|
||||
$this->someExpr($methodCall);
|
||||
$this->someExpr($staticCall);
|
||||
$this->someExpr($string);
|
||||
$this->someExpr($number);
|
||||
}
|
||||
|
||||
private function someExpr(Expr $expr)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\FixtureUnion;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
|
||||
final class NarrowUnion
|
||||
{
|
||||
public function run(MethodCall $methodCall, StaticCall $staticCall, String_ $string)
|
||||
{
|
||||
$this->someExpr($methodCall);
|
||||
$this->someExpr($staticCall);
|
||||
$this->someExpr($string);
|
||||
}
|
||||
|
||||
private function someExpr(Expr $expr)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\FixtureUnion;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
|
||||
final class NarrowUnion
|
||||
{
|
||||
public function run(MethodCall $methodCall, StaticCall $staticCall, String_ $string)
|
||||
{
|
||||
$this->someExpr($methodCall);
|
||||
$this->someExpr($staticCall);
|
||||
$this->someExpr($string);
|
||||
}
|
||||
|
||||
private function someExpr(\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Scalar\String_ $expr)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector\FixtureUnion;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Scalar\LNumber;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
|
||||
final class SkipTooWideUnion
|
||||
{
|
||||
public function run(MethodCall $methodCall, StaticCall $staticCall, String_ $string, LNumber $number)
|
||||
{
|
||||
$this->someExpr($methodCall);
|
||||
$this->someExpr($staticCall);
|
||||
$this->someExpr($string);
|
||||
$this->someExpr($number);
|
||||
}
|
||||
|
||||
private function someExpr(Expr $expr)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class UnionTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureUnion');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/union_config.php';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$parameters = $containerConfigurator->parameters();
|
||||
$parameters->set(Option::PHP_VERSION_FEATURES, PhpVersionFeature::UNION_TYPES);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(AddMethodCallBasedStrictParamTypeRector::class);
|
||||
};
|
|
@ -34,7 +34,7 @@ final class ThisCallOnStaticMethodToStaticCallRector extends AbstractRector impl
|
|||
|
||||
public function provideMinPhpVersion(): int
|
||||
{
|
||||
return PhpVersionFeature::STATIC_CALL;
|
||||
return PhpVersionFeature::STATIC_CALL_ON_NON_STATIC;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
|
|
|
@ -10,7 +10,11 @@ use PHPStan\Type\CallableType;
|
|||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
|
||||
use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeCommonTypeNarrower;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Rector\VendorLocker\NodeVendorLocker\ClassMethodParamVendorLockResolver;
|
||||
|
||||
|
@ -18,19 +22,21 @@ final class ClassMethodParamTypeCompleter
|
|||
{
|
||||
public function __construct(
|
||||
private StaticTypeMapper $staticTypeMapper,
|
||||
private ClassMethodParamVendorLockResolver $classMethodParamVendorLockResolver
|
||||
private ClassMethodParamVendorLockResolver $classMethodParamVendorLockResolver,
|
||||
private UnionTypeCommonTypeNarrower $unionTypeCommonTypeNarrower,
|
||||
private PhpVersionProvider $phpVersionProvider,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, Type> $classParameterTypes
|
||||
*/
|
||||
public function complete(ClassMethod $classMethod, array $classParameterTypes): ?ClassMethod
|
||||
public function complete(ClassMethod $classMethod, array $classParameterTypes, int $maxUnionTypes): ?ClassMethod
|
||||
{
|
||||
$hasChanged = false;
|
||||
|
||||
foreach ($classParameterTypes as $position => $argumentStaticType) {
|
||||
if ($this->shouldSkipArgumentStaticType($classMethod, $argumentStaticType, $position)) {
|
||||
if ($this->shouldSkipArgumentStaticType($classMethod, $argumentStaticType, $position, $maxUnionTypes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -58,7 +64,8 @@ final class ClassMethodParamTypeCompleter
|
|||
private function shouldSkipArgumentStaticType(
|
||||
ClassMethod $classMethod,
|
||||
Type $argumentStaticType,
|
||||
int $position
|
||||
int $position,
|
||||
int $maxUnionTypes
|
||||
): bool {
|
||||
if ($argumentStaticType instanceof MixedType) {
|
||||
return true;
|
||||
|
@ -82,12 +89,16 @@ final class ClassMethodParamTypeCompleter
|
|||
return true;
|
||||
}
|
||||
|
||||
// avoid overriding more precise type
|
||||
if ($argumentStaticType->isSuperTypeOf($currentParameterStaticType)->yes()) {
|
||||
// narrow union type in case its not supported yet
|
||||
$argumentStaticType = $this->narrowUnionTypeIfNotSupported($argumentStaticType);
|
||||
|
||||
// too many union types
|
||||
if ($this->isTooDetailedUnionType($currentParameterStaticType, $argumentStaticType, $maxUnionTypes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($currentParameterStaticType->equals($argumentStaticType)) {
|
||||
// avoid overriding more precise type
|
||||
if ($argumentStaticType->isSuperTypeOf($currentParameterStaticType)->yes()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -112,4 +123,36 @@ final class ClassMethodParamTypeCompleter
|
|||
|
||||
return $type->getClassName() === 'Closure';
|
||||
}
|
||||
|
||||
private function isTooDetailedUnionType(Type $currentType, Type $newType, int $maxUnionTypes): bool
|
||||
{
|
||||
if ($currentType instanceof MixedType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $newType instanceof UnionType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return count($newType->getTypes()) > $maxUnionTypes;
|
||||
}
|
||||
|
||||
private function narrowUnionTypeIfNotSupported(Type $type): Type
|
||||
{
|
||||
if (! $type instanceof UnionType) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
// union is supported, so it's ok
|
||||
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::UNION_TYPES)) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
$narrowedObjectType = $this->unionTypeCommonTypeNarrower->narrowToSharedObjectType($type);
|
||||
if ($narrowedObjectType instanceof ObjectType) {
|
||||
return $narrowedObjectType;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,11 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
*/
|
||||
final class AddMethodCallBasedStrictParamTypeRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private const MAX_UNION_TYPES = 3;
|
||||
|
||||
public function __construct(
|
||||
private CallTypesResolver $callTypesResolver,
|
||||
private ClassMethodParamTypeCompleter $classMethodParamTypeCompleter,
|
||||
|
@ -29,48 +34,32 @@ final class AddMethodCallBasedStrictParamTypeRector extends AbstractRector
|
|||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Change param type to strict type of passed expression', [
|
||||
return new RuleDefinition('Change private method param type to strict type, based on passed strict types', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
final class SomeClass
|
||||
{
|
||||
public function getById($id)
|
||||
public function run(int $value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class CallerClass
|
||||
{
|
||||
public function run(SomeClass $someClass)
|
||||
{
|
||||
$someClass->getById($this->getId());
|
||||
$this->resolve($value);
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
private function resolve($value)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
final class SomeClass
|
||||
{
|
||||
public function getById(int $id)
|
||||
public function run(int $value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class CallerClass
|
||||
{
|
||||
public function run(SomeClass $someClass)
|
||||
{
|
||||
$someClass->getById($this->getId());
|
||||
$this->resolve($value);
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
private function resolve(int $value)
|
||||
{
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
|
@ -102,6 +91,6 @@ CODE_SAMPLE
|
|||
$methodCalls = $this->localMethodCallFinder->match($node);
|
||||
$classMethodParameterTypes = $this->callTypesResolver->resolveStrictTypesFromCalls($methodCalls);
|
||||
|
||||
return $this->classMethodParamTypeCompleter->complete($node, $classMethodParameterTypes);
|
||||
return $this->classMethodParamTypeCompleter->complete($node, $classMethodParameterTypes, self::MAX_UNION_TYPES);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,9 +152,12 @@ final class PhpVersionFeature
|
|||
public const NO_EMPTY_LIST = PhpVersion::PHP_70;
|
||||
|
||||
/**
|
||||
* @see https://php.watch/versions/8.0/non-static-static-call-fatal-error
|
||||
* Deprecated since PHP 7.0
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public const STATIC_CALL = PhpVersion::PHP_70;
|
||||
public const STATIC_CALL_ON_NON_STATIC = PhpVersion::PHP_70;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
|
|
Loading…
Reference in New Issue
Block a user