Skip to content

Commit c612b2d

Browse files
authored
[console] [7.3] Add implicit boolean type in InputOption::VALUE_NONE option (#844)
* add fixture * [console] [7.3] Add implicit boolean type
1 parent d20ea2f commit c612b2d

File tree

17 files changed

+144
-23
lines changed

17 files changed

+144
-23
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Rector\Symfony\Tests\Symfony51\Rector\ClassMethod\RouteCollectionBuilderToRoutingConfiguratorRector\Fixture;
4+
5+
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
6+
use Symfony\Component\Config\Loader\LoaderInterface;
7+
use Symfony\Component\HttpKernel\Kernel;
8+
use Symfony\Component\Routing\RouteCollectionBuilder;
9+
10+
final class ConcreteMicroKernel extends Kernel
11+
{
12+
use MicroKernelTrait;
13+
14+
protected function configureRoutes(RouteCollectionBuilder $routes)
15+
{
16+
$routes->add('/admin', 'App\Controller\AdminController::dashboard', 'admin_dashboard');
17+
}
18+
19+
public function registerBundles()
20+
{
21+
}
22+
23+
public function registerContainerConfiguration(LoaderInterface $loader)
24+
{
25+
}
26+
}
27+
28+
?>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace Rector\Symfony\Tests\Symfony73\Rector\Class_\InvokableCommandInputAttributeRector\Fixture\DefaultValue;
4+
5+
use Symfony\Component\Console\Attribute\AsCommand;
6+
use Symfony\Component\Console\Command\Command;
7+
use Symfony\Component\Console\Input\InputArgument;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Input\InputOption;
10+
use Symfony\Component\Console\Output\OutputInterface;
11+
12+
#[AsCommand(
13+
name: 'app:hello',
14+
)]
15+
class ImplicitNoValueBoolOption extends Command
16+
{
17+
protected function configure(): void
18+
{
19+
$this->addOption('third', null, InputOption::VALUE_NONE);
20+
}
21+
protected function execute(InputInterface $input, OutputInterface $output): int
22+
{
23+
}
24+
}
25+
26+
?>
27+
-----
28+
<?php
29+
30+
namespace Rector\Symfony\Tests\Symfony73\Rector\Class_\InvokableCommandInputAttributeRector\Fixture\DefaultValue;
31+
32+
use Symfony\Component\Console\Attribute\AsCommand;
33+
use Symfony\Component\Console\Command\Command;
34+
use Symfony\Component\Console\Input\InputArgument;
35+
use Symfony\Component\Console\Input\InputInterface;
36+
use Symfony\Component\Console\Input\InputOption;
37+
use Symfony\Component\Console\Output\OutputInterface;
38+
39+
#[AsCommand(
40+
name: 'app:hello',
41+
)]
42+
class ImplicitNoValueBoolOption
43+
{
44+
public function __invoke(
45+
#[\Symfony\Component\Console\Attribute\Option(name: 'third', mode: InputOption::VALUE_NONE)]
46+
bool $third = false
47+
): int
48+
{
49+
}
50+
}
51+
52+
?>

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command.php.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ final class SomeCommand
4747
{
4848
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
4949
string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
50-
$option): int
50+
bool $option = false): int
5151
{
5252
$someArgument = $argument;
5353
$someOption = $option;

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_method_chaining.php.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ final class SomeCommandWithMethodChaining
4848
{
4949
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
5050
string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
51-
$option): int
51+
bool $option = false): int
5252
{
5353
$someArgument = $argument;
5454
$someOption = $option;

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_set_help.php.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ final class SomeCommandWithSetHelp
5353

5454
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
5555
string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
56-
$option): int
56+
bool $option = false): int
5757
{
5858
$someArgument = $argument;
5959
$someOption = $option;

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/with_multiple_arguments_options_fluent.php.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ final class WithMultipleArgumentsOptionsFluent
5757
#[\Symfony\Component\Console\Attribute\Argument(name: 'argument2', description: 'Argument2 description')]
5858
string $argument2,
5959
#[\Symfony\Component\Console\Attribute\Option(name: 'option1', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option1 description')]
60-
$option1,
60+
bool $option1 = false,
6161
#[\Symfony\Component\Console\Attribute\Option(name: 'option2', shortcut: 'p', mode: InputOption::VALUE_NONE, description: 'Option2 description')]
62-
$option2
62+
bool $option2 = false
6363
): int
6464
{
6565
$arg1 = $argument1;

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/with_multiple_arguments_options_no_fluent.php.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ final class WithMultipleArgumentsOptionsNotFluent
6262
#[\Symfony\Component\Console\Attribute\Argument(name: 'argument2', description: 'Argument2 description')]
6363
string $argument2,
6464
#[\Symfony\Component\Console\Attribute\Option(name: 'option1', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option1 description')]
65-
$option1,
65+
bool $option1 = false,
6666
#[\Symfony\Component\Console\Attribute\Option(name: 'option2', shortcut: 'p', mode: InputOption::VALUE_NONE, description: 'Option2 description')]
67-
$option2
67+
bool $option2 = false
6868
): int
6969
{
7070
$arg1 = $argument1;

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/with_optional_argument.php.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ final class WithOptionalArgument
4747
{
4848
public function __invoke(#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
4949
?string $argument, #[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
50-
$option): int
50+
bool $option = false): int
5151
{
5252
$someArgument = $argument;
5353
$someOption = $option;

rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/with_override.php.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ final class WithOverride
5151
#[\Symfony\Component\Console\Attribute\Argument(name: 'argument', description: 'Argument description')]
5252
string $argument,
5353
#[\Symfony\Component\Console\Attribute\Option(name: 'option', shortcut: 'o', mode: InputOption::VALUE_NONE, description: 'Option description')]
54-
$option
54+
bool $option = false
5555
): int
5656
{
5757
$someArgument = $argument;

rules/Symfony73/NodeAnalyzer/CommandOptionsResolver.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public function resolve(ClassMethod $configureClassMethod): array
3636

3737
$optionName = $this->valueResolver->getValue($addOptionArgs[0]->value);
3838

39+
$isImplicitBoolean = $this->isImplicitBoolean($addOptionArgs);
40+
3941
$commandOptions[] = new CommandOption(
4042
$optionName,
4143
$addOptionArgs[0]->value,
@@ -44,6 +46,7 @@ public function resolve(ClassMethod $configureClassMethod): array
4446
$addOptionArgs[3]->value ?? null,
4547
$addOptionArgs[4]->value ?? null,
4648
$this->isArrayMode($addOptionArgs),
49+
$isImplicitBoolean,
4750
$this->resolveDefaultType($addOptionArgs)
4851
);
4952
}
@@ -75,7 +78,22 @@ private function isArrayMode(array $args): bool
7578
}
7679

7780
$modeValue = $this->valueResolver->getValue($modeExpr);
78-
// binary check for InputOptions::VALUE_IS_ARRAY
81+
// binary check for InputOption::VALUE_IS_ARRAY
7982
return (bool) ($modeValue & 8);
8083
}
84+
85+
/**
86+
* @param Arg[] $args
87+
*/
88+
private function isImplicitBoolean(array $args): bool
89+
{
90+
$modeExpr = $args[2]->value ?? null;
91+
if (! $modeExpr instanceof Expr) {
92+
return false;
93+
}
94+
95+
$modeValue = $this->valueResolver->getValue($modeExpr);
96+
// binary check for InputOption::VALUE_NONE
97+
return (bool) ($modeValue & 1);
98+
}
8199
}

0 commit comments

Comments
 (0)