diff --git a/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Fixture/has_default_value.php.inc b/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Fixture/has_default_value.php.inc new file mode 100644 index 00000000000..2105be9cd56 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Fixture/has_default_value.php.inc @@ -0,0 +1,41 @@ + +----- +run($a, $b); + }), + ]; + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Fixture/has_default_value2.php.inc b/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Fixture/has_default_value2.php.inc new file mode 100644 index 00000000000..8dfcf1386fa --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Fixture/has_default_value2.php.inc @@ -0,0 +1,51 @@ + +----- +run($a, $b); + }), + ]; + } + + public function run($a, $b = "test") + { + return $a . $b; + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Source/SomeClassWithDefaultParamValue.php b/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Source/SomeClassWithDefaultParamValue.php new file mode 100644 index 00000000000..0f659cb3ab2 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Array_/CallableThisArrayToAnonymousFunctionRector/Source/SomeClassWithDefaultParamValue.php @@ -0,0 +1,11 @@ +getVariants()); $anonymousFunction = new Closure(); - $newParams = $this->createParams($functionVariantWithPhpDoc->getParameters()); + $newParams = $this->createParams($phpMethodReflection, $functionVariantWithPhpDoc->getParameters()); $anonymousFunction->params = $newParams; @@ -121,11 +128,9 @@ public function createFromPhpMethodReflection(PhpMethodReflection $phpMethodRefl } // does method return something? - if (! $functionVariantWithPhpDoc->getReturnType() instanceof VoidType) { - $anonymousFunction->stmts[] = new Return_($innerMethodCall); - } else { - $anonymousFunction->stmts[] = new Expression($innerMethodCall); - } + $anonymousFunction->stmts[] = $functionVariantWithPhpDoc->getReturnType() instanceof VoidType + ? new Expression($innerMethodCall) + : new Return_($innerMethodCall); if ($expr instanceof Variable && ! $this->nodeNameResolver->isName($expr, 'this')) { $anonymousFunction->uses[] = new ClosureUse($expr); @@ -247,17 +252,27 @@ private function collectUsesEqual(Closure $closure, array $uses, Variable $useVa } /** - * @param Node[] $nodes * @param Param[] $paramNodes - * @return Variable[] + * @return string[] */ - private function createUseVariablesFromParams(array $nodes, array $paramNodes): array + private function collectParamNames(array $paramNodes): array { $paramNames = []; foreach ($paramNodes as $paramNode) { $paramNames[] = $this->nodeNameResolver->getName($paramNode); } + return $paramNames; + } + + /** + * @param Node[] $nodes + * @param Param[] $paramNodes + * @return Variable[] + */ + private function createUseVariablesFromParams(array $nodes, array $paramNodes): array + { + $paramNames = $this->collectParamNames($paramNodes); $variableNodes = $this->betterNodeFinder->findInstanceOf($nodes, Variable::class); /** @var Variable[] $filteredVariables */ @@ -279,19 +294,17 @@ private function createUseVariablesFromParams(array $nodes, array $paramNodes): } $parentNode = $variableNode->getAttribute(AttributeKey::PARENT_NODE); - if ( - $parentNode instanceof Assign - || $parentNode instanceof Foreach_ - || $parentNode instanceof Param - ) { + if ($parentNode instanceof Node && in_array( + $parentNode::class, + [Assign::class, Foreach_::class, Param::class], + true + )) { $alreadyAssignedVariables[] = $variableName; } - if ($this->nodeNameResolver->isNames($variableNode, $alreadyAssignedVariables)) { - continue; + if (! $this->nodeNameResolver->isNames($variableNode, $alreadyAssignedVariables)) { + $filteredVariables[$variableName] = $variableNode; } - - $filteredVariables[$variableName] = $variableNode; } return $filteredVariables; @@ -301,18 +314,19 @@ private function createUseVariablesFromParams(array $nodes, array $paramNodes): * @param ParameterReflection[] $parameterReflections * @return Param[] */ - private function createParams(array $parameterReflections): array + private function createParams(PhpMethodReflection $phpMethodReflection, array $parameterReflections): array { + $classReflection = $phpMethodReflection->getDeclaringClass(); + $className = $classReflection->getName(); + $methodName = $phpMethodReflection->getName(); + /** @var ClassMethod $classMethod */ + $classMethod = $this->astResolver->resolveClassMethod($className, $methodName); + $params = []; - foreach ($parameterReflections as $parameterReflection) { + foreach ($parameterReflections as $key => $parameterReflection) { $param = new Param(new Variable($parameterReflection->getName())); - - if (! $parameterReflection->getType() instanceof MixedType) { - $param->type = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode( - $parameterReflection->getType(), - TypeKind::PARAM() - ); - } + $this->applyParamType($param, $parameterReflection); + $this->applyParamDefaultValue($param, $parameterReflection, $key, $classMethod); $params[] = $param; } @@ -320,6 +334,32 @@ private function createParams(array $parameterReflections): array return $params; } + private function applyParamType(Param $param, ParameterReflection $parameterReflection): void + { + if ($parameterReflection->getType() instanceof MixedType) { + return; + } + + $param->type = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode( + $parameterReflection->getType(), + TypeKind::PARAM() + ); + } + + private function applyParamDefaultValue( + Param $param, + ParameterReflection $parameterReflection, + int $key, + ClassMethod $classMethod + ): void { + if (! $parameterReflection->getDefaultValue() instanceof Type) { + return; + } + + $printDefaultValue = $this->betterStandardPrinter->print($classMethod->params[$key]->default); + $param->default = new ConstFetch(new Name($printDefaultValue)); + } + /** * @param Param[] $params */ @@ -366,11 +406,9 @@ private function normalizeClassConstFetchForStatic(Expr $expr): null | Name | Fu } $name = new Name($className); - if ($name->isSpecialClassName()) { - return $name; - } - - return new FullyQualified($className); + return $name->isSpecialClassName() + ? $name + : new FullyQualified($className); } private function resolveExpr(Expr $expr): New_ | Expr | null @@ -385,10 +423,8 @@ private function resolveExpr(Expr $expr): New_ | Expr | null // dynamic name, nothing we can do $className = $this->nodeNameResolver->getName($expr->class); - if ($className === null) { - return null; - } - - return new New_(new FullyQualified($className)); + return $className === null + ? null + : new New_(new FullyQualified($className)); } }