mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-28 23:10:51 +00:00
[TypeDeclaration] Removing NodeRepository from ParamTypeDeclarationRector (#597)
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
3eb503653f
commit
ad15c5f694
|
@ -6,7 +6,6 @@ namespace Rector\NodeCollector\NodeCollector;
|
|||
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
@ -58,15 +57,6 @@ final class NodeRepository
|
|||
return $traits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class_[]|Interface_[]
|
||||
* @deprecated Use static reflection instead
|
||||
*/
|
||||
public function findClassesAndInterfacesByType(string $type): array
|
||||
{
|
||||
return array_merge($this->findChildrenOfClass($type), $this->findImplementersOfInterface($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use static reflection instead
|
||||
*
|
||||
|
@ -89,16 +79,6 @@ final class NodeRepository
|
|||
return $childrenClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use static reflection instead
|
||||
*
|
||||
* @param class-string $class
|
||||
*/
|
||||
public function findInterface(string $class): ?Interface_
|
||||
{
|
||||
return $this->parsedNodeCollector->findInterface($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use static reflection instead
|
||||
*
|
||||
|
@ -132,24 +112,4 @@ final class NodeRepository
|
|||
|
||||
return $currentClassName !== $desiredClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Interface_[]
|
||||
*/
|
||||
private function findImplementersOfInterface(string $interface): array
|
||||
{
|
||||
$implementerInterfaces = [];
|
||||
|
||||
foreach ($this->parsedNodeCollector->getInterfaces() as $interfaceNode) {
|
||||
$className = $interfaceNode->getAttribute(AttributeKey::CLASS_NAME);
|
||||
|
||||
if (! $this->isChildOrEqualClassLike($interface, $className)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$implementerInterfaces[] = $interfaceNode;
|
||||
}
|
||||
|
||||
return $implementerInterfaces;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,11 +64,6 @@ final class ParsedNodeCollector
|
|||
return $this->classes[$name] ?? null;
|
||||
}
|
||||
|
||||
public function findInterface(string $name): ?Interface_
|
||||
{
|
||||
return $this->interfaces[$name] ?? null;
|
||||
}
|
||||
|
||||
public function findTrait(string $name): ?Trait_
|
||||
{
|
||||
return $this->traits[$name] ?? null;
|
||||
|
|
|
@ -6,14 +6,21 @@ namespace Rector\VendorLocker\NodeVendorLocker;
|
|||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\BetterReflection\Reflection\ReflectionClass;
|
||||
use PHPStan\Reflection\ClassReflection;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\PackageBuilder\Reflection\PrivatesAccessor;
|
||||
use Symplify\SmartFileSystem\Normalizer\PathNormalizer;
|
||||
|
||||
final class ClassMethodParamVendorLockResolver
|
||||
{
|
||||
public function __construct(
|
||||
private NodeNameResolver $nodeNameResolver
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private PathNormalizer $pathNormalizer,
|
||||
private ReflectionProvider $reflectionProvider,
|
||||
private PrivatesAccessor $privatesAccessor
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -23,14 +30,21 @@ final class ClassMethodParamVendorLockResolver
|
|||
return true;
|
||||
}
|
||||
|
||||
$scope = $classMethod->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
$classReflection = $this->resolveClassReflection($classMethod);
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classReflection = $scope->getClassReflection();
|
||||
if (! $classReflection instanceof ClassReflection) {
|
||||
return false;
|
||||
/** @var string $methodName */
|
||||
$methodName = $this->nodeNameResolver->getName($classMethod);
|
||||
|
||||
if ($this->hasTraitMethodVendorLock($classReflection, $methodName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// has interface vendor lock? → better skip it, as PHPStan has access only to just analyzed classes
|
||||
if ($this->hasParentInterfaceMethod($classReflection, $methodName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$methodName = $this->nodeNameResolver->getName($classMethod);
|
||||
|
@ -41,7 +55,86 @@ final class ClassMethodParamVendorLockResolver
|
|||
}
|
||||
|
||||
// parent type
|
||||
if ($ancestorClassReflection->hasNativeMethod($methodName)) {
|
||||
if (! $ancestorClassReflection->hasNativeMethod($methodName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// is file in vendor?
|
||||
$fileName = $ancestorClassReflection->getFileName();
|
||||
// probably internal class
|
||||
if ($fileName === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$normalizedFileName = $this->pathNormalizer->normalizePath($fileName);
|
||||
return str_contains($normalizedFileName, '/vendor/');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ReflectionClass[]
|
||||
*/
|
||||
private function findRelatedClassReflections(ClassReflection $classReflection): array
|
||||
{
|
||||
// @todo decouple to some reflection family finder?
|
||||
|
||||
/** @var ReflectionClass[] $reflectionClasses */
|
||||
$reflectionClasses = $this->privatesAccessor->getPrivateProperty($this->reflectionProvider, 'classes');
|
||||
|
||||
$relatedClassReflections = [];
|
||||
foreach ($reflectionClasses as $reflectionClass) {
|
||||
if ($reflectionClass->getName() === $classReflection->getName()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// is related?
|
||||
if (! $reflectionClass->isSubclassOf($classReflection->getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relatedClassReflections[] = $reflectionClass;
|
||||
}
|
||||
|
||||
return $relatedClassReflections;
|
||||
}
|
||||
|
||||
private function hasTraitMethodVendorLock(ClassReflection $classReflection, string $methodName): bool
|
||||
{
|
||||
$relatedReflectionClasses = $this->findRelatedClassReflections($classReflection);
|
||||
|
||||
foreach ($relatedReflectionClasses as $relatedReflectionClass) {
|
||||
foreach ($relatedReflectionClass->getTraits() as $traitReflectionClass) {
|
||||
/** @var ClassReflection $traitReflectionClass */
|
||||
if ($traitReflectionClass->hasMethod($methodName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resolveClassReflection(ClassMethod $classMethod): ClassReflection|null
|
||||
{
|
||||
$scope = $classMethod->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $scope->getClassReflection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Has interface even in our project?
|
||||
* Better skip it, as PHPStan has access only to just analyzed classes.
|
||||
* This might change type, that works for current class, but breaks another implementer.
|
||||
*/
|
||||
private function hasParentInterfaceMethod(ClassReflection $classReflection, string $methodName): bool
|
||||
{
|
||||
foreach ($classReflection->getInterfaces() as $interfaceClassReflection) {
|
||||
if ($interfaceClassReflection->hasMethod($methodName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Fixture;
|
||||
|
||||
use Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Source\ParentClassWithMethod;
|
||||
use Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Source\vendor\ParentClassWithMethod;
|
||||
|
||||
final class Child extends ParentClassWithMethod
|
||||
{
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Source;
|
||||
namespace Rector\Tests\Php80\Rector\FunctionLike\UnionTypesRector\Source\vendor;
|
||||
|
||||
class ParentClassWithMethod
|
||||
abstract class ParentClassWithMethod
|
||||
{
|
||||
public function enqueueAt($at)
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
use Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\AbstractParentClass;
|
||||
use Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\vendor\AbstractParentClass;
|
||||
|
||||
final class ChildClass extends AbstractParentClass
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ final class ChildClass extends AbstractParentClass
|
|||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
use Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\AbstractParentClass;
|
||||
use Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\vendor\AbstractParentClass;
|
||||
|
||||
final class ChildClass extends AbstractParentClass
|
||||
{
|
||||
|
|
|
@ -41,9 +41,6 @@ final class LocalChildClass extends AbstractLocalParentClass
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $number
|
||||
*/
|
||||
public function changeToo(int $number)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
interface SniffInterface
|
||||
{
|
||||
/**
|
||||
* @param int $position
|
||||
*/
|
||||
public function process(string $file, $position);
|
||||
}
|
||||
|
||||
final class CoolSniffWithLocalinterface implements SniffInterface
|
||||
{
|
||||
/**
|
||||
* @param int $position
|
||||
*/
|
||||
public function process(string $file, $position)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
interface SniffInterface
|
||||
{
|
||||
public function process(string $file, int $position);
|
||||
}
|
||||
|
||||
final class CoolSniffWithLocalinterface implements SniffInterface
|
||||
{
|
||||
/**
|
||||
* @param int $position
|
||||
*/
|
||||
public function process(string $file, int $position)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
trait SkipTraitWithInterfaceImplementation
|
||||
{
|
||||
public function getCount($items)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
/**
|
||||
* @param array $items
|
||||
* @return int
|
||||
*/
|
||||
public function getCount($items);
|
||||
}
|
||||
|
||||
class SomeClassWithInterfaceAndTrait implements SomeInterface
|
||||
{
|
||||
use SkipTraitWithInterfaceImplementation;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
use Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\SniffInterface;
|
||||
use Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\vendor\SniffInterface;
|
||||
|
||||
final class SkipVendorLocatedTypes implements SniffInterface
|
||||
{
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
trait TraitWithInterfaceImplementation
|
||||
{
|
||||
public function getCount($items)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
/**
|
||||
* @param array $items
|
||||
* @return int
|
||||
*/
|
||||
public function getCount($items);
|
||||
}
|
||||
|
||||
class SomeClassWithInterfaceAndTrait implements SomeInterface
|
||||
{
|
||||
use TraitWithInterfaceImplementation;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Fixture;
|
||||
|
||||
trait TraitWithInterfaceImplementation
|
||||
{
|
||||
public function getCount(array $items)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getCount(array $items);
|
||||
}
|
||||
|
||||
class SomeClassWithInterfaceAndTrait implements SomeInterface
|
||||
{
|
||||
use TraitWithInterfaceImplementation;
|
||||
}
|
||||
|
||||
?>
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source;
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\vendor;
|
||||
|
||||
abstract class AbstractParentClass
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source;
|
||||
namespace Rector\Tests\TypeDeclaration\Rector\FunctionLike\ParamTypeDeclarationRector\Source\vendor;
|
||||
|
||||
interface SniffInterface
|
||||
{
|
|
@ -239,7 +239,8 @@ final class EregToPcreTransformer
|
|||
$cls .= $this->_ere2pcre_escape($a) . '\-';
|
||||
break;
|
||||
} elseif (ord($a) > ord($b)) {
|
||||
throw new InvalidEregException(sprintf('an invalid character range %d-%d"', $a, $b));
|
||||
$errorMessage = sprintf('an invalid character range %d-%d"', (int) $a, (int) $b);
|
||||
throw new InvalidEregException($errorMessage);
|
||||
}
|
||||
$cls .= $this->_ere2pcre_escape($a) . '-' . $this->_ere2pcre_escape($b);
|
||||
} else {
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\ChildPopulator;
|
||||
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PHPStanStaticTypeMapper\ValueObject\TypeKind;
|
||||
use Rector\TypeDeclaration\NodeTypeAnalyzer\ChildTypeResolver;
|
||||
use Rector\TypeDeclaration\ValueObject\NewType;
|
||||
|
||||
final class ChildParamPopulator
|
||||
{
|
||||
public function __construct(
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private RectorChangeCollector $rectorChangeCollector,
|
||||
private NodeRepository $nodeRepository,
|
||||
private ChildTypeResolver $childTypeResolver
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add typehint to all children
|
||||
*/
|
||||
public function populateChildClassMethod(
|
||||
ClassMethod | Function_ $functionLike,
|
||||
int $position,
|
||||
Type $paramType
|
||||
): void {
|
||||
if (! $functionLike instanceof ClassMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var string|null $className */
|
||||
$className = $functionLike->getAttribute(AttributeKey::CLASS_NAME);
|
||||
// anonymous class
|
||||
if ($className === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$childrenClassLikes = $this->nodeRepository->findClassesAndInterfacesByType($className);
|
||||
|
||||
// update their methods as well
|
||||
foreach ($childrenClassLikes as $childClassLike) {
|
||||
if ($childClassLike instanceof Class_) {
|
||||
$usedTraits = $this->nodeRepository->findUsedTraitsInClass($childClassLike);
|
||||
|
||||
foreach ($usedTraits as $usedTrait) {
|
||||
$this->addParamTypeToMethod($usedTrait, $position, $functionLike, $paramType);
|
||||
}
|
||||
}
|
||||
|
||||
$this->addParamTypeToMethod($childClassLike, $position, $functionLike, $paramType);
|
||||
}
|
||||
}
|
||||
|
||||
private function addParamTypeToMethod(
|
||||
ClassLike $classLike,
|
||||
int $position,
|
||||
ClassMethod $classMethod,
|
||||
Type $paramType
|
||||
): void {
|
||||
$methodName = $this->nodeNameResolver->getName($classMethod);
|
||||
|
||||
$currentClassMethod = $classLike->getMethod($methodName);
|
||||
if (! $currentClassMethod instanceof ClassMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset($currentClassMethod->params[$position])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$paramNode = $currentClassMethod->params[$position];
|
||||
|
||||
// already has a type
|
||||
if ($paramNode->type !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$resolvedChildType = $this->childTypeResolver->resolveChildTypeNode($paramType, TypeKind::PARAM());
|
||||
if ($resolvedChildType === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// let the method know it was changed now
|
||||
$paramNode->type = $resolvedChildType;
|
||||
$paramNode->type->setAttribute(NewType::HAS_NEW_INHERITED_TYPE, true);
|
||||
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($paramNode);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ declare(strict_types=1);
|
|||
namespace Rector\TypeDeclaration\Rector\FunctionLike;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
|
@ -16,7 +15,6 @@ use Rector\Core\ValueObject\PhpVersionFeature;
|
|||
use Rector\DeadCode\PhpDoc\TagRemover\ParamTagRemover;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PHPStanStaticTypeMapper\ValueObject\TypeKind;
|
||||
use Rector\TypeDeclaration\ChildPopulator\ChildParamPopulator;
|
||||
use Rector\TypeDeclaration\NodeTypeAnalyzer\TraitTypeAnalyzer;
|
||||
use Rector\TypeDeclaration\TypeInferer\ParamTypeInferer;
|
||||
use Rector\TypeDeclaration\ValueObject\NewType;
|
||||
|
@ -37,7 +35,7 @@ final class ParamTypeDeclarationRector extends AbstractRector implements MinPhpV
|
|||
{
|
||||
public function __construct(
|
||||
private VendorLockResolver $vendorLockResolver,
|
||||
private ChildParamPopulator $childParamPopulator,
|
||||
//private ChildParamPopulator $childParamPopulator,
|
||||
private ParamTypeInferer $paramTypeInferer,
|
||||
private TraitTypeAnalyzer $traitTypeAnalyzer,
|
||||
private ParamTagRemover $paramTagRemover
|
||||
|
@ -59,7 +57,7 @@ final class ParamTypeDeclarationRector extends AbstractRector implements MinPhpV
|
|||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class ParentClass
|
||||
abstract class VendorParentClass
|
||||
{
|
||||
/**
|
||||
* @param int $number
|
||||
|
@ -69,7 +67,7 @@ class ParentClass
|
|||
}
|
||||
}
|
||||
|
||||
final class ChildClass extends ParentClass
|
||||
final class ChildClass extends VendorParentClass
|
||||
{
|
||||
/**
|
||||
* @param int $number
|
||||
|
@ -88,7 +86,7 @@ final class ChildClass extends ParentClass
|
|||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class ParentClass
|
||||
abstract class VendorParentClass
|
||||
{
|
||||
/**
|
||||
* @param int $number
|
||||
|
@ -98,7 +96,7 @@ class ParentClass
|
|||
}
|
||||
}
|
||||
|
||||
final class ChildClass extends ParentClass
|
||||
final class ChildClass extends VendorParentClass
|
||||
{
|
||||
/**
|
||||
* @param int $number
|
||||
|
@ -126,8 +124,10 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
foreach ($node->params as $position => $param) {
|
||||
$this->refactorParam($param, $node, (int) $position);
|
||||
// @todo subscribe to Param node directly? narrow scope the better, right?
|
||||
|
||||
foreach ($node->params as $param) {
|
||||
$this->refactorParam($param, $node);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -138,7 +138,7 @@ CODE_SAMPLE
|
|||
return PhpVersionFeature::SCALAR_TYPES;
|
||||
}
|
||||
|
||||
private function refactorParam(Param $param, ClassMethod | Function_ $functionLike, int $position): void
|
||||
private function refactorParam(Param $param, ClassMethod | Function_ $functionLike): void
|
||||
{
|
||||
if ($this->shouldSkipParam($param, $functionLike)) {
|
||||
return;
|
||||
|
@ -154,7 +154,6 @@ CODE_SAMPLE
|
|||
}
|
||||
|
||||
$paramTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($inferedType, TypeKind::PARAM());
|
||||
|
||||
if (! $paramTypeNode instanceof Node) {
|
||||
return;
|
||||
}
|
||||
|
@ -168,11 +167,9 @@ CODE_SAMPLE
|
|||
|
||||
$functionLikePhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($functionLike);
|
||||
$this->paramTagRemover->removeParamTagsIfUseless($functionLikePhpDocInfo, $functionLike);
|
||||
|
||||
$this->childParamPopulator->populateChildClassMethod($functionLike, $position, $inferedType);
|
||||
}
|
||||
|
||||
private function shouldSkipParam(Param $param, FunctionLike $functionLike): bool
|
||||
private function shouldSkipParam(Param $param, ClassMethod | Function_ $functionLike): bool
|
||||
{
|
||||
if ($param->variadic) {
|
||||
return true;
|
||||
|
|
|
@ -8,6 +8,7 @@ use Rector\Core\Configuration\Option;
|
|||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Throwable;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
final class BootstrapFilesIncluder
|
||||
{
|
||||
|
@ -24,6 +25,9 @@ final class BootstrapFilesIncluder
|
|||
{
|
||||
$bootstrapFiles = $this->parameterProvider->provideArrayParameter(Option::BOOTSTRAP_FILES);
|
||||
|
||||
Assert::allString($bootstrapFiles);
|
||||
|
||||
/** @var string[] $bootstrapFiles */
|
||||
foreach ($bootstrapFiles as $bootstrapFile) {
|
||||
if (! is_file($bootstrapFile)) {
|
||||
throw new ShouldNotHappenException(sprintf('Bootstrap file "%s" does not exist.', $bootstrapFile));
|
||||
|
|
|
@ -63,7 +63,7 @@ final class ExtensionConfigResolver
|
|||
$includedFilePath = sprintf(
|
||||
'%s/%s/%s',
|
||||
$generatedConfigDirectory,
|
||||
$extensionConfig['relative_install_path'],
|
||||
(string) $extensionConfig['relative_install_path'],
|
||||
$includedFile
|
||||
);
|
||||
if (! file_exists($includedFilePath)) {
|
||||
|
|
|
@ -92,7 +92,7 @@ final class ConsoleApplication extends Application
|
|||
private function getNewWorkingDir(InputInterface $input): string
|
||||
{
|
||||
$workingDir = $input->getParameterOption('--working-dir');
|
||||
if ($workingDir !== false && ! is_dir($workingDir)) {
|
||||
if (is_string($workingDir) && ! is_dir($workingDir)) {
|
||||
$errorMessage = sprintf('Invalid working directory specified, "%s" does not exist.', $workingDir);
|
||||
throw new InvalidConfigurationException($errorMessage);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ final class ShouldNotHappenException extends Exception
|
|||
$debugBacktrace = debug_backtrace();
|
||||
|
||||
$class = $debugBacktrace[2]['class'] ?? null;
|
||||
$function = $debugBacktrace[2]['function'];
|
||||
$line = $debugBacktrace[1]['line'];
|
||||
$function = (string) $debugBacktrace[2]['function'];
|
||||
$line = (int) $debugBacktrace[1]['line'];
|
||||
|
||||
$method = $class ? ($class . '::' . $function) : $function;
|
||||
|
||||
|
|
|
@ -613,7 +613,7 @@ final class NodeFactory
|
|||
throw new NotImplementedYetException(sprintf(
|
||||
'Not implemented yet. Go to "%s()" and add check for "%s" node.',
|
||||
__METHOD__,
|
||||
$nodeClass
|
||||
(string) $nodeClass
|
||||
));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user