diff --git a/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/add_help_concatenated_string.php.inc b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/add_help_concatenated_string.php.inc new file mode 100644 index 000000000..8037f191b --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/add_help_concatenated_string.php.inc @@ -0,0 +1,46 @@ +setHelp("First line of help.\n" + . "Second line of help.\n" + . "Third line of help.") + ->addOption('run', null, InputOption::VALUE_NONE, 'Run mode'); + } +} + +?> +----- +addOption('run', null, InputOption::VALUE_NONE, 'Run mode'); + } +} + +?> diff --git a/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php b/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php index ff0be791b..0c0e09a09 100644 --- a/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php +++ b/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php @@ -8,6 +8,7 @@ use PhpParser\Node\Arg; use PhpParser\Node\Attribute; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\BinaryOp\Concat; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Identifier; @@ -150,6 +151,7 @@ public function refactor(Node $node): ?Node /** * Returns the argument passed to setHelp() and removes the MethodCall node. + * Supports plain string literals and concatenated string expressions. */ private function findAndRemoveSetHelpExpr(ClassMethod $configureClassMethod): ?String_ { @@ -174,12 +176,14 @@ function (Node $node) use (&$helpString): int|null|Expr { return null; } - $argExpr = $node->getArgs()[0] - ->value; - if ($argExpr instanceof String_) { - $helpString = $argExpr; + $argExpr = $node->getArgs()[0]->value; + $resolvedValue = $this->resolveStringExpr($argExpr); + if ($resolvedValue === null) { + return null; } + $helpString = new String_($resolvedValue); + $parent = $node->getAttribute('parent'); if ($parent instanceof Expression) { unset($parent); @@ -198,6 +202,31 @@ function (Node $node) use (&$helpString): int|null|Expr { return $helpString; } + /** + * Resolves a scalar string expression — a plain String_ literal or a tree + * of Concat nodes — to its runtime string value. Returns null for any + * expression that contains non-literal parts (variables, function calls, …). + */ + private function resolveStringExpr(Expr $expr): ?string + { + if ($expr instanceof String_) { + return $expr->value; + } + + if ($expr instanceof Concat) { + $left = $this->resolveStringExpr($expr->left); + $right = $this->resolveStringExpr($expr->right); + + if ($left === null || $right === null) { + return null; + } + + return $left . $right; + } + + return null; + } + private function isExpressionVariableThis(Stmt $stmt): bool { if (! $stmt instanceof Expression) {