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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"symfony/security-http": "^6.4",
"symfony/validator": "^6.4",
"symfony/web-link": "^6.4",
"symplify/phpstan-extensions": "^12.0",
"symplify/phpstan-rules": "^14.6",
"symplify/vendor-patches": "^11.3",
"tomasvotruba/class-leak": "^2.0",
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ rules:

parameters:
level: 8
errorFormat: symplify

reportUnmatchedIgnoredErrors: false
treatPhpDocTypesAsCertain: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use Symfony\Component\Console\Output\OutputInterface;
class NameWithHyphen
{
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument-with-hyphen', description: 'Argument description')]
?string $argument_with_hyphen, #[\Symfony\Component\Console\Attribute\Option]
?string $argument_with_hyphen, #[\Symfony\Component\Console\Attribute\Option(name: 'option-with-hyphen')]
$option_with_hyphen): int
{
$argument = $argument_with_hyphen;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use Symfony\Component\Console\Input\InputOption;
final class SomeCommand
{
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
string $argument, #[\Symfony\Component\Console\Attribute\Option]
string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
$option): int
{
$someArgument = $argument;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use Symfony\Component\Console\Input\InputOption;
final class SomeCommandWithMethodChaining
{
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
string $argument, #[\Symfony\Component\Console\Attribute\Option]
string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
$option): int
{
$someArgument = $argument;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ final class SomeCommandWithSetHelp
}

public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
string $argument, #[\Symfony\Component\Console\Attribute\Option]
string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
$option): int
{
$someArgument = $argument;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ final class WithMultipleArgumentsOptionsFluent
string $argument1,
#[\Symfony\Component\Console\Attribute\Argument(name: 'argument2', description: 'Argument2 description')]
string $argument2,
#[\Symfony\Component\Console\Attribute\Option]
#[\Symfony\Component\Console\Attribute\Option(name: 'option1', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option1 description')]
$option1,
#[\Symfony\Component\Console\Attribute\Option]
#[\Symfony\Component\Console\Attribute\Option(name: 'option2', shortcut: 'p', mode: InputOption::VALUE_NONE, description: 'Option2 description')]
$option2
): int
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ final class WithMultipleArgumentsOptionsNotFluent
string $argument1,
#[\Symfony\Component\Console\Attribute\Argument(name: 'argument2', description: 'Argument2 description')]
string $argument2,
#[\Symfony\Component\Console\Attribute\Option]
#[\Symfony\Component\Console\Attribute\Option(name: 'option1', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option1 description')]
$option1,
#[\Symfony\Component\Console\Attribute\Option]
#[\Symfony\Component\Console\Attribute\Option(name: 'option2', shortcut: 'p', mode: InputOption::VALUE_NONE, description: 'Option2 description')]
$option2
): int
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use Symfony\Component\Console\Input\InputOption;
final class WithOptionalArgument
{
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
?string $argument, #[\Symfony\Component\Console\Attribute\Option]
?string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
$option): int
{
$someArgument = $argument;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ final class WithOverride
public function __invoke(
#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
string $argument,
#[\Symfony\Component\Console\Attribute\Option]
#[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
$option
): int
{
Expand Down
131 changes: 0 additions & 131 deletions rules/Symfony73/NodeAnalyzer/CommandArgumentsAndOptionsResolver.php

This file was deleted.

38 changes: 38 additions & 0 deletions rules/Symfony73/NodeAnalyzer/CommandArgumentsResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Rector\Symfony\Symfony73\NodeAnalyzer;

use PhpParser\Node\Stmt\ClassMethod;
use Rector\Symfony\Symfony73\NodeFinder\MethodCallFinder;
use Rector\Symfony\Symfony73\ValueObject\CommandArgument;

final readonly class CommandArgumentsResolver
{
public function __construct(
private MethodCallFinder $methodCallFinder,
) {
}

/**
* @return CommandArgument[]
*/
public function resolve(ClassMethod $configureClassMethod): array
{
$addArgumentMethodCalls = $this->methodCallFinder->find($configureClassMethod, 'addArgument');

$commandArguments = [];
foreach ($addArgumentMethodCalls as $addArgumentMethodCall) {
$addArgumentArgs = $addArgumentMethodCall->getArgs();

$commandArguments[] = new CommandArgument(
$addArgumentArgs[0]->value,
$addArgumentArgs[1]->value ?? null,
$addArgumentArgs[2]->value ?? null,
);
}

return $commandArguments;
}
}
47 changes: 47 additions & 0 deletions rules/Symfony73/NodeAnalyzer/CommandOptionsResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Rector\Symfony\Symfony73\NodeAnalyzer;

use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Exception\ShouldNotHappenException;
use Rector\Symfony\Symfony73\NodeFinder\MethodCallFinder;
use Rector\Symfony\Symfony73\ValueObject\CommandOption;

final readonly class CommandOptionsResolver
{
public function __construct(
private MethodCallFinder $methodCallFinder,
) {
}

/**
* @return CommandOption[]
*/
public function resolve(ClassMethod $configureClassMethod): array
{
$addOptionMethodCalls = $this->methodCallFinder->find($configureClassMethod, 'addOption');

$commandOptions = [];

foreach ($addOptionMethodCalls as $addOptionMethodCall) {
$addOptionArgs = $addOptionMethodCall->getArgs();

$nameArgValue = $addOptionArgs[0]->value;
if (! $nameArgValue instanceof String_) {
// we need string value, otherwise param will not have a name
throw new ShouldNotHappenException('Option name is required');
}

$shortcutExpr = $addOptionArgs[1]->value ?? null;
$modeExpr = $addOptionArgs[2]->value ?? null;
$descriptionExpr = $addOptionArgs[3]->value ?? null;

$commandOptions[] = new CommandOption($nameArgValue, $shortcutExpr, $modeExpr, $descriptionExpr);
}

return $commandOptions;
}
}
21 changes: 18 additions & 3 deletions rules/Symfony73/NodeFactory/CommandInvokeParamsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Arg;
use PhpParser\Node\Attribute;
use PhpParser\Node\AttributeGroup;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
Expand Down Expand Up @@ -86,13 +87,27 @@ private function createOptionParams(array $commandOptions): array
$optionParams = [];

foreach ($commandOptions as $commandOption) {
$optionName = $commandOption->getName();
$optionName = $commandOption->getStringName();
$variableName = str_replace('-', '_', $optionName);

$optionParam = new Param(new Variable($variableName));
// @todo fill type or default value

$optionArgs = [new Arg(value: $commandOption->getName(), name: new Identifier('name'))];

if ($commandOption->getShortcut() instanceof Expr) {
$optionArgs[] = new Arg(value: $commandOption->getShortcut(), name: new Identifier('shortcut'));
}

if ($commandOption->getMode() instanceof Expr) {
$optionArgs[] = new Arg(value: $commandOption->getMode(), name: new Identifier('mode'));
}

if ($commandOption->getDescription() instanceof Expr) {
$optionArgs[] = new Arg(value: $commandOption->getDescription(), name: new Identifier('description'));
}

$optionParam->attrGroups[] = new AttributeGroup([
new Attribute(new FullyQualified(SymfonyAttribute::COMMAND_OPTION)),
new Attribute(new FullyQualified(SymfonyAttribute::COMMAND_OPTION), $optionArgs),
]);

$optionParams[] = $optionParam;
Expand Down
Loading