Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Rector\Symfony\Tests\Symfony73\Rector\Class_\CommandHelpToAttributeRector\Fixture;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;

#[AsCommand(name: 'some_name')]
final class ConcatenatedHelpStringCommand extends Command
{
public function configure()
{
$this
->setHelp("First line of help.\n"
. "Second line of help.\n"
. "Third line of help.")
->addOption('run', null, InputOption::VALUE_NONE, 'Run mode');
}
}

?>
-----
<?php

namespace Rector\Symfony\Tests\Symfony73\Rector\Class_\CommandHelpToAttributeRector\Fixture;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;

#[AsCommand(name: 'some_name', help: <<<'TXT'
First line of help.
Second line of help.
Third line of help.
TXT)]
final class ConcatenatedHelpStringCommand extends Command
{
public function configure()
{
$this
->addOption('run', null, InputOption::VALUE_NONE, 'Run mode');
}
}

?>
37 changes: 33 additions & 4 deletions rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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_
{
Expand All @@ -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);
Expand All @@ -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) {
Expand Down
Loading