Skip to content

Commit

Permalink
Add support for negatable input options
Browse files Browse the repository at this point in the history
Since symfony/console 5.3, input options can be marked as negatable.
The appropriate return type when calling `$input->getOption()` can
be either a boolean or null. With this change, support for return
types of such negatable input options is added.
  • Loading branch information
eliashaeussler authored and ondrejmirtes committed Aug 25, 2022
1 parent 82d54e8 commit a14d467
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/Type/Symfony/GetOptionTypeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
use Symfony\Component\Console\Input\InputOption;

class GetOptionTypeHelper
Expand All @@ -18,6 +19,10 @@ class GetOptionTypeHelper
public function getOptionType(Scope $scope, InputOption $option): Type
{
if (!$option->acceptValue()) {
if ($option->isNegatable()) {
return new UnionType([new BooleanType(), new NullType()]);
}

return new BooleanType();
}

Expand Down
4 changes: 3 additions & 1 deletion tests/Type/Symfony/data/ExampleOptionCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ protected function configure(): void
$this->addOption('c', null, InputOption::VALUE_REQUIRED);
$this->addOption('d', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL);
$this->addOption('e', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED);
$this->addOption('f', null, InputOption::VALUE_NEGATABLE);

$this->addOption('bb', null, InputOption::VALUE_OPTIONAL, '', 1);
$this->addOption('cc', null, InputOption::VALUE_REQUIRED, '', 1);
Expand All @@ -35,13 +36,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
assertType('string|null', $input->getOption('c'));
assertType('array<int, string|null>', $input->getOption('d'));
assertType('array<int, string>', $input->getOption('e'));
assertType('bool|null', $input->getOption('f'));

assertType('1|string|null', $input->getOption('bb'));
assertType('1|string', $input->getOption('cc'));
assertType('array<int, 1|string|null>', $input->getOption('dd'));
assertType('array<int, 1|string>', $input->getOption('ee'));

assertType('array{a: bool, b: string|null, c: string|null, d: array<int, string|null>, e: array<int, string>, bb: 1|string|null, cc: 1|string, dd: array<int, 1|string|null>, ee: array<int, 1|string>, help: bool, quiet: bool, verbose: bool, version: bool, ansi: bool, no-interaction: bool}', $input->getOptions());
assertType('array{a: bool, b: string|null, c: string|null, d: array<int, string|null>, e: array<int, string>, f: bool|null, bb: 1|string|null, cc: 1|string, dd: array<int, 1|string|null>, ee: array<int, 1|string>, help: bool, quiet: bool, verbose: bool, version: bool, ansi: bool|null, no-interaction: bool}', $input->getOptions());
}

}
4 changes: 3 additions & 1 deletion tests/Type/Symfony/data/ExampleOptionLazyCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ protected function configure(): void
$this->addOption('c', null, InputOption::VALUE_REQUIRED);
$this->addOption('d', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL);
$this->addOption('e', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED);
$this->addOption('f', null, InputOption::VALUE_NEGATABLE);

$this->addOption('bb', null, InputOption::VALUE_OPTIONAL, '', 1);
$this->addOption('cc', null, InputOption::VALUE_REQUIRED, '', 1);
Expand All @@ -37,13 +38,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
assertType('string|null', $input->getOption('c'));
assertType('array<int, string|null>', $input->getOption('d'));
assertType('array<int, string>', $input->getOption('e'));
assertType('bool|null', $input->getOption('f'));

assertType('1|string|null', $input->getOption('bb'));
assertType('1|string', $input->getOption('cc'));
assertType('array<int, 1|string|null>', $input->getOption('dd'));
assertType('array<int, 1|string>', $input->getOption('ee'));

assertType('array{a: bool, b: string|null, c: string|null, d: array<int, string|null>, e: array<int, string>, bb: 1|string|null, cc: 1|string, dd: array<int, 1|string|null>, ee: array<int, 1|string>, help: bool, quiet: bool, verbose: bool, version: bool, ansi: bool, no-interaction: bool}', $input->getOptions());
assertType('array{a: bool, b: string|null, c: string|null, d: array<int, string|null>, e: array<int, string>, f: bool|null, bb: 1|string|null, cc: 1|string, dd: array<int, 1|string|null>, ee: array<int, 1|string>, help: bool, quiet: bool, verbose: bool, version: bool, ansi: bool|null, no-interaction: bool}', $input->getOptions());
}

}

0 comments on commit a14d467

Please sign in to comment.