Skip to content

Commit

Permalink
Add Lazy Command Support
Browse files Browse the repository at this point in the history
  • Loading branch information
jordisala1991 authored Jul 18, 2021
1 parent de268d2 commit 4ae5cbe
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Symfony/ConsoleApplicationResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,17 @@ public function findCommands(ClassReflection $classReflection): array

$commands = [];
foreach ($this->consoleApplication->all() as $name => $command) {
if (!$classType->isSuperTypeOf(new ObjectType(get_class($command)))->yes()) {
$commandClass = new ObjectType(get_class($command));
$isLazyCommand = (new ObjectType('Symfony\Component\Console\Command\LazyCommand'))->isSuperTypeOf($commandClass)->yes();

if ($isLazyCommand && method_exists($command, 'getCommand') && !$classType->isSuperTypeOf(new ObjectType(get_class($command->getCommand())))->yes()) {
continue;
}

if (!$isLazyCommand && !$classType->isSuperTypeOf($commandClass)->yes()) {
continue;
}

$commands[$name] = $command;
}

Expand Down
1 change: 1 addition & 0 deletions tests/Type/Symfony/ExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/tree_builder.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/ExampleBaseCommand.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/ExampleOptionCommand.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/ExampleOptionLazyCommand.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/kernel_interface.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/request_get_content.php');

Expand Down
11 changes: 11 additions & 0 deletions tests/Type/Symfony/console_application_loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
use PHPStan\Type\Symfony\ExampleACommand;
use PHPStan\Type\Symfony\ExampleBCommand;
use PHPStan\Type\Symfony\ExampleOptionCommand;
use PHPStan\Type\Symfony\ExampleOptionLazyCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\LazyCommand;

require_once __DIR__ . '/../../../vendor/autoload.php';

$application = new Application();
$application->add(new ExampleACommand());
$application->add(new ExampleBCommand());
$application->add(new ExampleOptionCommand());

if (class_exists(LazyCommand::class)) {
$application->add(new LazyCommand('lazy-example-option', [], '', false, function () {
return new ExampleOptionLazyCommand();
}));
} else {
$application->add(new ExampleOptionLazyCommand());
}

return $application;
47 changes: 47 additions & 0 deletions tests/Type/Symfony/data/ExampleOptionLazyCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Symfony;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use function PHPStan\Testing\assertType;

final class ExampleOptionLazyCommand extends Command
{

protected static $defaultName = 'lazy-example-option';
protected static $defaultDescription = 'lazy example description';

protected function configure(): void
{
parent::configure();

$this->addOption('a', null, InputOption::VALUE_NONE);
$this->addOption('b', null, InputOption::VALUE_OPTIONAL);
$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('bb', null, InputOption::VALUE_OPTIONAL, '', 1);
$this->addOption('cc', null, InputOption::VALUE_REQUIRED, '', 1);
$this->addOption('dd', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, '', [1]);
$this->addOption('ee', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, '', [1]);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
assertType('bool', $input->getOption('a'));
assertType('string|null', $input->getOption('b'));
assertType('string|null', $input->getOption('c'));
assertType('array<int, string|null>', $input->getOption('d'));
assertType('array<int, string>', $input->getOption('e'));

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'));
}

}

0 comments on commit 4ae5cbe

Please sign in to comment.