Reflection cleanup + inline union types for couple of param docs (#330)

This commit is contained in:
Tomas Votruba 2021-06-29 15:25:57 +02:00 committed by GitHub
parent 75c77576a5
commit 2a394c750f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 133 additions and 224 deletions

View File

@ -70,7 +70,10 @@ final class PhpDocTypeChanger
}
// override existing type
$newPHPStanPhpDocType = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode($newType, TypeKind::KIND_RETURN);
$newPHPStanPhpDocType = $this->staticTypeMapper->mapPHPStanTypeToPHPStanPhpDocTypeNode(
$newType,
TypeKind::KIND_RETURN
);
$currentReturnTagValueNode = $phpDocInfo->getReturnTagValue();
if ($currentReturnTagValueNode !== null) {

View File

@ -155,8 +155,7 @@ final class FamilyRelationsAnalyzer
ClassMethod $classMethod,
string $propertyName,
string $kindPropertyFetch
): bool
{
): bool {
if ($classMethod->stmts === null) {
return false;
}

View File

@ -19,10 +19,7 @@ final class ParentScopeFinder
) {
}
/**
* @return ClassMethod|Function_|Class_|Namespace_|Closure|null
*/
public function find(Node $node): ?Node
public function find(Node $node): ClassMethod | Function_ | Class_ | Namespace_ | Closure | null
{
return $this->betterNodeFinder->findParentTypes($node, [
Closure::class,

View File

@ -63,19 +63,16 @@ final class NodeRemover
}
}
/**
* @param Closure|ClassMethod|Function_ $node
*/
public function removeStmt(Node $node, int $key): void
public function removeStmt(Closure | ClassMethod | Function_ $functionLike, int $key): void
{
if ($node->stmts === null) {
if ($functionLike->stmts === null) {
throw new ShouldNotHappenException();
}
// notify about remove node
$this->rectorChangeCollector->notifyNodeFileInfo($node->stmts[$key]);
$this->rectorChangeCollector->notifyNodeFileInfo($functionLike->stmts[$key]);
unset($node->stmts[$key]);
unset($functionLike->stmts[$key]);
}
public function removeParam(ClassMethod $classMethod, int | Param $keyOrParam): void

View File

@ -24,11 +24,8 @@ final class ArgumentDefaultValueReplacer
) {
}
/**
* @param MethodCall|StaticCall|ClassMethod|Expr\FuncCall $node
*/
public function processReplaces(
Node $node,
MethodCall | StaticCall | ClassMethod | FuncCall $node,
ReplaceArgumentDefaultValueInterface $replaceArgumentDefaultValue
): ?Node {
if ($node instanceof ClassMethod) {

View File

@ -186,11 +186,10 @@ CODE_SAMPLE
}
}
/**
* @param ClassMethod|MethodCall|StaticCall $node
*/
private function shouldSkipParameter(Node $node, ArgumentAdder $argumentAdder): bool
{
private function shouldSkipParameter(
ClassMethod | MethodCall | StaticCall $node,
ArgumentAdder $argumentAdder
): bool {
$position = $argumentAdder->getPosition();
$argumentName = $argumentAdder->getArgumentName();

View File

@ -8,7 +8,6 @@ use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
@ -88,10 +87,7 @@ CODE_SAMPLE
return $node;
}
/**
* @param ClassMethod|Function_ $functionLike
*/
private function matchFuncGetArgsVariableAssign(FunctionLike $functionLike): ?Assign
private function matchFuncGetArgsVariableAssign(ClassMethod | Function_ $functionLike): ?Assign
{
/** @var Assign[] $assigns */
$assigns = $this->betterNodeFinder->findInstanceOf((array) $functionLike->stmts, Assign::class);

View File

@ -126,11 +126,11 @@ CODE_SAMPLE
return null;
}
/**
* @param ClassMethod|Function_|Closure $node
*/
private function shouldAddEmptyLine(?string $currentStmtVariableName, Node $node, int $key): bool
{
private function shouldAddEmptyLine(
?string $currentStmtVariableName,
ClassMethod | Function_ | Closure $node,
int $key
): bool {
if (! $this->isNewVariableThanBefore($currentStmtVariableName)) {
return false;
}
@ -173,10 +173,7 @@ CODE_SAMPLE
return $this->previousStmtVariableName !== $currentStmtVariableName;
}
/**
* @param ClassMethod|Function_|Closure $node
*/
private function isPrecededByEmptyLine(Node $node, int $key): bool
private function isPrecededByEmptyLine(ClassMethod | Function_ | Closure $node, int $key): bool
{
if ($node->stmts === null) {
return false;

View File

@ -6,7 +6,6 @@ namespace Rector\DowngradePhp71\Rector\FunctionLike;
use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
@ -105,10 +104,7 @@ CODE_SAMPLE
return $param->type instanceof NullableType;
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
private function refactorParamType(Param $param, FunctionLike $functionLike): bool
private function refactorParamType(Param $param, ClassMethod | Function_ | Closure $functionLike): bool
{
if (! $this->isNullableParam($param)) {
return false;
@ -120,10 +116,7 @@ CODE_SAMPLE
return true;
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
private function decorateWithDocBlock(FunctionLike $functionLike, Param $param): void
private function decorateWithDocBlock(ClassMethod | Function_ | Closure $functionLike, Param $param): void
{
if ($param->type === null) {
return;

View File

@ -6,7 +6,6 @@ namespace Rector\DowngradePhp71\TypeDeclaration;
use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
@ -30,10 +29,9 @@ final class PhpDocFromTypeDeclarationDecorator
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return bool True if node was changed
*/
public function decorate(FunctionLike $functionLike): bool
public function decorate(ClassMethod | Function_ | Closure $functionLike): bool
{
if ($functionLike->returnType === null) {
return false;
@ -49,11 +47,13 @@ final class PhpDocFromTypeDeclarationDecorator
}
/**
* @param ClassMethod|Function_ $functionLike
* @param array<class-string<Type>> $requiredTypes
*/
public function decorateParam(Param $param, FunctionLike $functionLike, array $requiredTypes): void
{
public function decorateParam(
Param $param,
ClassMethod | Function_ | Closure $functionLike,
array $requiredTypes
): void {
if ($param->type === null) {
return;
}
@ -67,12 +67,9 @@ final class PhpDocFromTypeDeclarationDecorator
$this->moveParamTypeToParamDoc($functionLike, $param, $type);
}
/**
* @param ClassMethod|Function_ $functionLike
*/
public function decorateParamWithSpecificType(
Param $param,
FunctionLike $functionLike,
ClassMethod | Function_ | Closure $functionLike,
Type $requireType
): void {
if ($param->type === null) {
@ -88,11 +85,12 @@ final class PhpDocFromTypeDeclarationDecorator
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return bool True if node was changed
*/
public function decorateReturnWithSpecificType(FunctionLike $functionLike, Type $requireType): bool
{
public function decorateReturnWithSpecificType(
ClassMethod | Function_ | Closure $functionLike,
Type $requireType
): bool {
if ($functionLike->returnType === null) {
return false;
}
@ -115,11 +113,11 @@ final class PhpDocFromTypeDeclarationDecorator
return is_a($returnType, $requireType::class, true);
}
/**
* @param ClassMethod|Function_ $functionLike
*/
private function moveParamTypeToParamDoc(FunctionLike $functionLike, Param $param, Type $type): void
{
private function moveParamTypeToParamDoc(
ClassMethod | Function_ | Closure $functionLike,
Param $param,
Type $type
): void {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($functionLike);
$paramName = $this->nodeNameResolver->getName($param);
$this->phpDocTypeChanger->changeParamType($phpDocInfo, $type, $param, $paramName);

View File

@ -227,10 +227,7 @@ CODE_SAMPLE
return null;
}
/**
* @param ClassMethod|Function_ $functionLike
*/
private function refactorParam(Param $param, FunctionLike $functionLike): void
private function refactorParam(Param $param, ClassMethod | Function_ $functionLike): void
{
if (! $this->isNullableParam($param, $functionLike)) {
return;
@ -240,10 +237,7 @@ CODE_SAMPLE
$param->type = null;
}
/**
* @param ClassMethod|Function_ $functionLike
*/
private function decorateWithDocBlock(FunctionLike $functionLike, Param $param): void
private function decorateWithDocBlock(ClassMethod | Function_ $functionLike, Param $param): void
{
if ($param->type === null) {
return;

View File

@ -136,10 +136,7 @@ CODE_SAMPLE
$this->cleanTrailingComma($node, $node->uses);
}
/**
* @param ClassMethod|Function_|Closure $node
*/
private function processParams(Node $node): ?Node
private function processParams(ClassMethod | Function_ | Closure $node): ?Node
{
if ($node->params === []) {
return null;

View File

@ -9,7 +9,6 @@ use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Foreach_;
@ -47,13 +46,10 @@ final class BreakingVariableRenameGuard
) {
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
public function shouldSkipVariable(
string $currentName,
string $expectedName,
FunctionLike $functionLike,
ClassMethod | Function_ | Closure $functionLike,
Variable $variable
): bool {
// is the suffix? → also accepted
@ -152,19 +148,15 @@ final class BreakingVariableRenameGuard
return $trinaryLogic->maybe();
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
private function skipOnConflictOtherVariable(FunctionLike $functionLike, string $newName): bool
private function skipOnConflictOtherVariable(ClassMethod | Function_ | Closure $functionLike, string $newName): bool
{
return $this->betterNodeFinder->hasInstanceOfName((array) $functionLike->stmts, Variable::class, $newName);
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
private function isUsedInClosureUsesName(string $expectedName, FunctionLike $functionLike): bool
{
private function isUsedInClosureUsesName(
string $expectedName,
ClassMethod | Function_ | Closure $functionLike
): bool {
if (! $functionLike instanceof Closure) {
return false;
}

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Rector\Naming\Matcher;
use PhpParser\Node;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
@ -47,10 +46,7 @@ final class ForeachMatcher
return new VariableAndCallForeach($foreach->valueVar, $call, $variableName, $functionLike);
}
/**
* @return ClassMethod|Function_|Closure|null
*/
private function getFunctionLike(Foreach_ $foreach): ?Node
private function getFunctionLike(Foreach_ $foreach): ClassMethod | Function_ | Closure | null
{
return $this->betterNodeFinder->findParentTypes(
$foreach,

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Rector\Naming\Matcher;
use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
@ -48,10 +47,7 @@ final class VariableAndCallAssignMatcher
return new VariableAndCallAssign($assign->var, $call, $assign, $variableName, $functionLike);
}
/**
* @return ClassMethod|Function_|Closure|null
*/
private function getFunctionLike(Assign $assign): ?Node
private function getFunctionLike(Assign $assign): ClassMethod | Function_ | Closure | null
{
return $this->betterNodeFinder->findParentTypes(
$assign,

View File

@ -6,7 +6,6 @@ namespace Rector\Naming\Naming;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
@ -48,20 +47,18 @@ final class ConflictingNameResolver
return $this->arrayFilter->filterWithAtLeastTwoOccurences($expectedNames);
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
public function checkNameIsInFunctionLike(string $variableName, FunctionLike $functionLike): bool
{
public function checkNameIsInFunctionLike(
string $variableName,
ClassMethod | Function_ | Closure $functionLike
): bool {
$conflictingVariableNames = $this->resolveConflictingVariableNamesForNew($functionLike);
return in_array($variableName, $conflictingVariableNames, true);
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return string[]
*/
private function resolveConflictingVariableNamesForNew(FunctionLike $functionLike): array
private function resolveConflictingVariableNamesForNew(ClassMethod | Function_ | Closure $functionLike): array
{
// cache it!
$classMethodHash = spl_object_hash($functionLike);
@ -83,10 +80,9 @@ final class ConflictingNameResolver
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return string[]
*/
private function collectParamNames(FunctionLike $functionLike): array
private function collectParamNames(ClassMethod | Function_ | Closure $functionLike): array
{
$paramNames = [];
@ -99,10 +95,9 @@ final class ConflictingNameResolver
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return string[]
*/
private function resolveForNewAssigns(FunctionLike $functionLike): array
private function resolveForNewAssigns(ClassMethod | Function_ | Closure $functionLike): array
{
$names = [];
@ -121,10 +116,9 @@ final class ConflictingNameResolver
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return string[]
*/
private function resolveForNonNewAssigns(FunctionLike $functionLike): array
private function resolveForNonNewAssigns(ClassMethod | Function_ | Closure $functionLike): array
{
$names = [];

View File

@ -7,7 +7,6 @@ namespace Rector\Naming\Naming;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
@ -28,11 +27,10 @@ final class OverridenExistingNamesResolver
) {
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
public function checkNameInClassMethodForNew(string $variableName, FunctionLike $functionLike): bool
{
public function checkNameInClassMethodForNew(
string $variableName,
ClassMethod | Function_ | Closure $functionLike
): bool {
$overridenVariableNames = $this->resolveOveriddenNamesForNew($functionLike);
return in_array($variableName, $overridenVariableNames, true);
}
@ -59,10 +57,9 @@ final class OverridenExistingNamesResolver
}
/**
* @param ClassMethod|Function_|Closure $functionLike
* @return string[]
*/
private function resolveOveriddenNamesForNew(FunctionLike $functionLike): array
private function resolveOveriddenNamesForNew(ClassMethod | Function_ | Closure $functionLike): array
{
$classMethodHash = spl_object_hash($functionLike);

View File

@ -6,7 +6,6 @@ namespace Rector\Naming\ValueObject;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
@ -14,15 +13,12 @@ use Rector\Naming\Contract\RenameParamValueObjectInterface;
final class ParamRename implements RenameParamValueObjectInterface
{
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
public function __construct(
private string $currentName,
private string $expectedName,
private Param $param,
private Variable $variable,
private FunctionLike $functionLike
private ClassMethod | Function_ | Closure $functionLike
) {
}
@ -36,10 +32,7 @@ final class ParamRename implements RenameParamValueObjectInterface
return $this->expectedName;
}
/**
* @return ClassMethod|Function_|Closure
*/
public function getFunctionLike(): FunctionLike
public function getFunctionLike(): ClassMethod | Function_ | Closure
{
return $this->functionLike;
}

View File

@ -4,29 +4,23 @@ declare(strict_types=1);
namespace Rector\Naming\ValueObject;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
final class VariableAndCallAssign
{
/**
* @param FuncCall|StaticCall|MethodCall $expr
* @param ClassMethod|Function_|Closure $functionLike
*/
public function __construct(
private Variable $variable,
private Expr $expr,
private FuncCall | StaticCall | MethodCall $expr,
private Assign $assign,
private string $variableName,
private FunctionLike $functionLike
private ClassMethod | Function_ | Closure $functionLike
) {
}

View File

@ -4,27 +4,21 @@ declare(strict_types=1);
namespace Rector\Naming\ValueObject;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
final class VariableAndCallForeach
{
/**
* @param FuncCall|StaticCall|MethodCall $expr
* @param ClassMethod|Function_|Closure $functionLike
*/
public function __construct(
private Variable $variable,
private Expr $expr,
private FuncCall | StaticCall | MethodCall $expr,
private string $variableName,
private FunctionLike $functionLike
private ClassMethod | Function_ | Closure $functionLike
) {
}

View File

@ -8,7 +8,6 @@ use PhpParser\Node;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
@ -31,11 +30,8 @@ final class VariableRenamer
) {
}
/**
* @param ClassMethod|Function_|Closure $functionLike
*/
public function renameVariableInFunctionLike(
FunctionLike $functionLike,
ClassMethod | Function_ | Closure $functionLike,
string $oldName,
string $expectedName,
?Assign $assign = null

View File

@ -117,10 +117,9 @@ CODE_SAMPLE
}
/**
* @param ClassMethod|Function_|Closure $node
* @return string[]
*/
private function collectUndefinedVariableScope(Node $node): array
private function collectUndefinedVariableScope(ClassMethod | Function_ | Closure $node): array
{
$undefinedVariables = [];

View File

@ -112,7 +112,7 @@ CODE_SAMPLE
return null;
}
if (! $this->valueResolver->areValues([$node->if, $nestedTernary->if, $nestedTernary->else], [-1, 1, 0])) {
if (! $this->valueResolver->areValuesEqual([$node->if, $nestedTernary->if, $nestedTernary->else], [-1, 1, 0])) {
return null;
}
@ -132,7 +132,7 @@ CODE_SAMPLE
return null;
}
if (! $this->valueResolver->areValues([$node->if, $nestedTernary->if, $nestedTernary->else], [-1, 1, 0])) {
if (! $this->valueResolver->areValuesEqual([$node->if, $nestedTernary->if, $nestedTernary->else], [-1, 1, 0])) {
return null;
}

View File

@ -140,10 +140,12 @@ CODE_SAMPLE
/**
* @param array<PhpDocTagNode> $tags
* @param Class_|Property|ClassMethod|Function_|Closure|ArrowFunction $node
*/
private function processApplyAttrGroups(array $tags, PhpDocInfo $phpDocInfo, Node $node): bool
{
private function processApplyAttrGroups(
array $tags,
PhpDocInfo $phpDocInfo,
Class_ | Property | ClassMethod | Function_ | Closure | ArrowFunction $node
): bool {
$hasNewAttrGroups = false;
foreach ($tags as $tag) {
foreach ($this->annotationsToAttributes as $annotationToAttribute) {

View File

@ -9,7 +9,6 @@ use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\Stmt\Function_;
@ -117,10 +116,7 @@ CODE_SAMPLE
$this->replaceGetNameOrGetValue($classMethodOrFunction, $assign->var);
}
/**
* @param ClassMethod|Function_ $functionLike
*/
private function replaceGetNameOrGetValue(FunctionLike $functionLike, Expr $assignedExpr): void
private function replaceGetNameOrGetValue(ClassMethod | Function_ $functionLike, Expr $assignedExpr): void
{
$tokensForeaches = $this->findForeachesOverTokenVariable($functionLike, $assignedExpr);
foreach ($tokensForeaches as $tokenForeach) {
@ -129,10 +125,9 @@ CODE_SAMPLE
}
/**
* @param ClassMethod|Function_ $functionLike
* @return Foreach_[]
*/
private function findForeachesOverTokenVariable(FunctionLike $functionLike, Expr $assignedExpr): array
private function findForeachesOverTokenVariable(ClassMethod | Function_ $functionLike, Expr $assignedExpr): array
{
return $this->betterNodeFinder->find((array) $functionLike->stmts, function (Node $node) use (
$assignedExpr

View File

@ -7,7 +7,6 @@ namespace Rector\Php80\Rector\FunctionLike;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
@ -82,7 +81,7 @@ CODE_SAMPLE
}
/**
* @param ClassMethod|Function_|Closure|ArrowFunction $node
* @param ClassMethod | Function_ | Closure | ArrowFunction $node
*/
public function refactor(Node $node): ?Node
{
@ -101,11 +100,10 @@ CODE_SAMPLE
return $node;
}
/**
* @param ClassMethod|Function_|Closure|ArrowFunction $functionLike
*/
private function refactorParamTypes(FunctionLike $functionLike, PhpDocInfo $phpDocInfo): void
{
private function refactorParamTypes(
ClassMethod | Function_ | Closure | ArrowFunction $functionLike,
PhpDocInfo $phpDocInfo
): void {
if ($functionLike instanceof ClassMethod && $this->classMethodParamVendorLockResolver->isVendorLocked(
$functionLike
)) {
@ -152,11 +150,10 @@ CODE_SAMPLE
$param->type = new Name('object');
}
/**
* @param ClassMethod|Function_|Closure|ArrowFunction $functionLike
*/
private function refactorReturnType(FunctionLike $functionLike, PhpDocInfo $phpDocInfo): void
{
private function refactorReturnType(
ClassMethod | Function_ | Closure | ArrowFunction $functionLike,
PhpDocInfo $phpDocInfo
): void {
// do not override existing return type
if ($functionLike->getReturnType() !== null) {
return;

View File

@ -21,26 +21,17 @@ final class VisibilityManipulator
*/
private const ALLOWED_NODE_TYPES = [ClassMethod::class, Property::class, ClassConst::class, Class_::class];
/**
* @param ClassMethod|Property|ClassConst $node
*/
public function makeStatic(Node $node): void
public function makeStatic(ClassMethod | Property | ClassConst $node): void
{
$this->addVisibilityFlag($node, Visibility::STATIC);
}
/**
* @param ClassMethod|Class_ $node
*/
public function makeAbstract(Node $node): void
public function makeAbstract(ClassMethod | Class_ $node): void
{
$this->addVisibilityFlag($node, Visibility::ABSTRACT);
}
/**
* @param ClassMethod|Property $node
*/
public function makeNonStatic(Node $node): void
public function makeNonStatic(ClassMethod | Property $node): void
{
if (! $node->isStatic()) {
return;

View File

@ -95,36 +95,32 @@ CODE_SAMPLE
return $node;
}
/**
* @param ClassMethod|Function_ $node
*/
private function shouldSkip($node):bool {
private function shouldSkip(ClassMethod | Function_ $node): bool
{
$returns = $this->betterNodeFinder->findInstanceOf($node, Return_::class);
if ($returns !== []) {
return true;
}
$notNeverNodes = $this->betterNodeFinder->findInstancesOf($node, [Yield_::class]);
$notNeverNodes = $this->betterNodeFinder->findInstanceOf($node, Yield_::class);
if ($notNeverNodes !== []) {
return true;
}
$neverNodes = $this->betterNodeFinder->findInstancesOf($node, [Node\Expr\Throw_::class, Throw_::class]);
$hasNeverFuncCall = $this->resolveHasNeverFuncCall($node);
if ($neverNodes === [] && ! $hasNeverFuncCall) {
return true;
}
if ($node instanceof ClassMethod && ! $this->parentClassMethodTypeOverrideGuard->isReturnTypeChangeAllowed(
$node
)) {
$node
)) {
return true;
}
if ($node->returnType && $this->isName($node->returnType, 'never')) {
return true;
}
return false;
return $node->returnType && $this->isName($node->returnType, 'never');
}
/**

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Rector\Core\Contract\PHPStan\Reflection\TypeToCallReflectionResolver;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\Type;
@ -16,5 +16,5 @@ interface TypeToCallReflectionResolverInterface
/**
* @return FunctionReflection|MethodReflection|null
*/
public function resolve(Type $type, ClassMemberAccessAnswerer $classMemberAccessAnswerer);
public function resolve(Type $type, Scope $scope);
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\Native\NativeFunctionReflection;
use PHPStan\TrinaryLogic;
use PHPStan\Type\ClosureType;
@ -21,11 +21,11 @@ final class ClosureTypeToCallReflectionResolver implements TypeToCallReflectionR
/**
* @param ClosureType $type
*/
public function resolve(Type $type, ClassMemberAccessAnswerer $classMemberAccessAnswerer): NativeFunctionReflection
public function resolve(Type $type, Scope $scope): NativeFunctionReflection
{
return new NativeFunctionReflection(
'{closure}',
$type->getCallableParametersAcceptors($classMemberAccessAnswerer),
$type->getCallableParametersAcceptors($scope),
null,
TrinaryLogic::createMaybe()
);

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\Constant\ConstantArrayType;
@ -34,7 +34,7 @@ final class ConstantArrayTypeToCallReflectionResolver implements TypeToCallRefle
/**
* @param ConstantArrayType $type
*/
public function resolve(Type $type, ClassMemberAccessAnswerer $classMemberAccessAnswerer): ?MethodReflection
public function resolve(Type $type, Scope $scope): ?MethodReflection
{
$constantArrayTypeAndMethod = $this->findTypeAndMethodName($type);
if (! $constantArrayTypeAndMethod instanceof ConstantArrayTypeAndMethod) {
@ -49,11 +49,8 @@ final class ConstantArrayTypeToCallReflectionResolver implements TypeToCallRefle
$constantArrayType = $constantArrayTypeAndMethod->getType();
$methodReflection = $constantArrayType->getMethod(
$constantArrayTypeAndMethod->getMethod(),
$classMemberAccessAnswerer
);
if (! $classMemberAccessAnswerer->canCallMethod($methodReflection)) {
$methodReflection = $constantArrayType->getMethod($constantArrayTypeAndMethod->getMethod(), $scope);
if (! $scope->canCallMethod($methodReflection)) {
return null;
}

View File

@ -6,7 +6,7 @@ namespace Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver;
use Nette\Utils\Strings;
use PhpParser\Node\Name;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ReflectionProvider;
@ -26,10 +26,20 @@ final class ConstantStringTypeToCallReflectionResolver implements TypeToCallRefl
*
* @var string
*/
private const STATIC_METHOD_REGEX = '#^(?<class>[a-zA-Z_\\x7f-\\xff\\\\][a-zA-Z0-9_\\x7f-\\xff\\\\]*)::(?<method>[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\\z#';
private const STATIC_METHOD_REGEX = '#^(?<' . self::CLASS_KEY . '>[a-zA-Z_\\x7f-\\xff\\\\][a-zA-Z0-9_\\x7f-\\xff\\\\]*)::(?<' . self::METHOD_KEY . '>[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\\z#';
/**
* @var string
*/
private const CLASS_KEY = 'class';
/**
* @var string
*/
private const METHOD_KEY = 'method';
public function __construct(
private ReflectionProvider $reflectionProvider
private ReflectionProvider $reflectionProvider,
) {
}
@ -42,7 +52,7 @@ final class ConstantStringTypeToCallReflectionResolver implements TypeToCallRefl
* @param ConstantStringType $type
* @return FunctionReflection|MethodReflection|null
*/
public function resolve(Type $type, ClassMemberAccessAnswerer $classMemberAccessAnswerer)
public function resolve(Type $type, Scope $scope)
{
$value = $type->getValue();
@ -58,15 +68,18 @@ final class ConstantStringTypeToCallReflectionResolver implements TypeToCallRefl
return null;
}
if (! $this->reflectionProvider->hasClass($matches['class'])) {
$class = $matches[self::CLASS_KEY];
if (! $this->reflectionProvider->hasClass($class)) {
return null;
}
$classReflection = $this->reflectionProvider->getClass($matches['class']);
if (! $classReflection->hasMethod($matches['method'])) {
$classReflection = $this->reflectionProvider->getClass($class);
$method = $matches[self::METHOD_KEY];
if (! $classReflection->hasMethod($method)) {
return null;
}
return $classReflection->getMethod($matches['method'], $classMemberAccessAnswerer);
return $classReflection->getMethod($method, $scope);
}
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ObjectType;
@ -29,7 +29,7 @@ final class ObjectTypeToCallReflectionResolver implements TypeToCallReflectionRe
/**
* @param ObjectType $type
*/
public function resolve(Type $type, ClassMemberAccessAnswerer $classMemberAccessAnswerer): ?MethodReflection
public function resolve(Type $type, Scope $scope): ?MethodReflection
{
$className = $type->getClassName();
if (! $this->reflectionProvider->hasClass($className)) {

View File

@ -134,7 +134,7 @@ final class ValueResolver
* @param Expr[]|null[] $nodes
* @param mixed[] $expectedValues
*/
public function areValues(array $nodes, array $expectedValues): bool
public function areValuesEqual(array $nodes, array $expectedValues): bool
{
foreach ($nodes as $i => $node) {
if ($node === null) {