Skip to content

Add support for negatable input options #300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 25, 2022
Merged

Add support for negatable input options #300

merged 1 commit into from
Aug 25, 2022

Conversation

eliashaeussler
Copy link
Contributor

Since symfony/console 5.3 (symfony/symfony#39642), 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.

@eliashaeussler eliashaeussler marked this pull request as draft August 15, 2022 09:02
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.
@eliashaeussler eliashaeussler marked this pull request as ready for review August 25, 2022 17:31
@ondrejmirtes ondrejmirtes merged commit a14d467 into phpstan:1.2.x Aug 25, 2022
@ondrejmirtes
Copy link
Member

Perfect, thank you!

@cafferata
Copy link

Hi @eliashaeussler, @ondrejmirtes, after merging/releasing 1.2.11 we experience problems with the older Symfony projects. I have no idea how to debug this further at this point. Can I contribute to this bug report? Would you rather have a separate issue? Please let me know. ☺️

composer info symfony/symfony | grep 'versions'
v3.4.49
composer info phpstan/phpstan-symfony | grep 'versions'
1.2.11
php -v
PHP 7.4.30 (cli) (built: Jun  9 2022 09:30:03) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.30, Copyright (c), by Zend Technologies

Symfony command

<?php

namespace CoreDomainBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

final class PhpStanErrorCommand extends Command
{
    protected function configure(): void
    {
        $this->setName('phpstan:error');
        $this->addOption('test-option');
    }

    protected function execute(
        InputInterface $input,
        OutputInterface $output
    ): ?int {
        $input->getOption('test-option');

        return 0;
    }
}

PHPStan config

parameters:
  tmpDir: var/ci/phpstan/
  level: 8
  paths:
    - src/CoreDomainBundle/Command/PhpStanErrorCommand.php
  symfony:
    consoleApplicationLoader: .phpstan/console-application.php
php ./vendor/bin/phpstan analyse --no-progress --memory-limit=-1 -v
 -- -----------------------------------------------------------------------------------------------------------------------------
     Error
 -- -----------------------------------------------------------------------------------------------------------------------------
     Internal error: Internal error: Call to undefined method Symfony\Component\Console\Input\InputOption::isNegatable() in file
     src/CoreDomainBundle/Command/PhpStanErrorCommand.php

     Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.md:
     #0
     vendor/phpstan/phpstan-symfony/src/Type/Symfony/InputInterfaceGetOptionDynamicReturnTypeExtension.p
     hp(66): PHPStan\Type\Symfony\GetOptionTypeHelper->getOptionType(Object(PHPStan\Analyser\MutatingScope),
     Object(Symfony\Component\Console\Input\InputOption))
     #1 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(3474):
     PHPStan\Type\Symfony\InputInterfaceGetOptionDynamicReturnTypeExtension->getTypeFromMethodCall(Object(PHPStan\Reflection\ResolvedMethodReflection),
     Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\MutatingScope))
     #2 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1389):
     PHPStan\Analyser\MutatingScope->methodCallReturnType(Object(PHPStan\Type\ObjectType), 'getOption', Object(PhpParser\Node\Expr\MethodCall))
     #3 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(1395):
     PHPStan\Analyser\MutatingScope->PHPStan\Analyser\{closure}()
     #4 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/MutatingScope.php(556):
     PHPStan\Analyser\MutatingScope->resolveType(Object(PhpParser\Node\Expr\MethodCall))
     #5 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1383):
     PHPStan\Analyser\MutatingScope->getType(Object(PhpParser\Node\Expr\MethodCall))
     #6 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(526):
     PHPStan\Analyser\NodeScopeResolver->findEarlyTerminatingExpr(Object(PhpParser\Node\Expr\MethodCall), Object(PHPStan\Analyser\MutatingScope))
     #7 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(332):
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Expression), Object(PHPStan\Analyser\MutatingScope),
     Object(Closure))
     #8 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(490):
     PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array, Object(PHPStan\Analyser\MutatingScope),
     Object(Closure))
     #9 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(332):
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod), Object(PHPStan\Analyser\MutatingScope),
     Object(PHPStan\Node\ClassStatementsGatherer))
     #10 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(568):
     PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array, Object(PHPStan\Analyser\MutatingScope),
     Object(PHPStan\Node\ClassStatementsGatherer))
     #11 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(332):
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_), Object(PHPStan\Analyser\MutatingScope), Object(Closure))
     #12 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(540):
     PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array, Object(PHPStan\Analyser\MutatingScope),
     Object(Closure))
     #13 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(302):
     PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_), Object(PHPStan\Analyser\MutatingScope),
     Object(Closure))
     #14 phar://vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(174):
     PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))
     #15 phar://vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(147):
     PHPStan\Analyser\FileAnalyser->analyseFile('/Users/jeffrey/...', Array, Object(PHPStan\Rules\Registry), Object(PHPStan\Collectors\Registry), NULL)
     #16
     phar://vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTra
     it.php(97): PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)
     #17 phar://vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(110):
     _PHPStan_9a6ded56a\Evenement\EventEmitter->emit('data', Array)
     #18
     phar://vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTra
     it.php(97): _PHPStan_9a6ded56a\Clue\React\NDJson\Decoder->handleData(Array)
     #19 phar://vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62):
     _PHPStan_9a6ded56a\Evenement\EventEmitter->emit('data', Array)
     #20
     phar://vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTra
     it.php(97): _PHPStan_9a6ded56a\React\Stream\Util::_PHPStan_9a6ded56a\React\Stream\{closure}('{"action":"anal...')
     #21
     phar://vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154):
     _PHPStan_9a6ded56a\Evenement\EventEmitter->emit('data', Array)
     #22
     phar://vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201):
     _PHPStan_9a6ded56a\React\Stream\DuplexResourceStream->handleData(Resource id #3901)
     #23
     phar://vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173):
     _PHPStan_9a6ded56a\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)
     #24 phar://vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(107):
     _PHPStan_9a6ded56a\React\EventLoop\StreamSelectLoop->run()
     #25 phar://vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259):
     PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))
     #26 phar://vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(865):
     _PHPStan_9a6ded56a\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))
     #27 phar://vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(259):
     _PHPStan_9a6ded56a\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand),
     Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))
     #28 phar://vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):
     _PHPStan_9a6ded56a\Symfony\Component\Console\Application->doRun(Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput),
     Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))
     #29 phar://vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(127):
     _PHPStan_9a6ded56a\Symfony\Component\Console\Application->run()
     #30 phar://vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(128): _PHPStan_9a6ded56a\{closure}()
     #31 vendor/phpstan/phpstan/phpstan(7): require('phar:///Users/j...')
     #32 vendor/bin/phpstan(115): include('/Users/jeffrey/...')
     #33 {main}
     Child process error (exit code 1):
 -- ----------------------------------------------------------------------------------------------------------------------------------------------------

 [ERROR] Found 2 errors

Used memory: 46 MB

@eliashaeussler
Copy link
Contributor Author

Hi @cafferata, thanks for your report and sorry, that I've missed that aspect. I pushed a fix, see #305.

@ondrejmirtes
Copy link
Member

@cafferata @eliashaeussler Thanks. We no longer test older Symfony versions, it should be your priority to upgrade to a supported version (5.3+). But I accepted a quickfix for this problem.

@cafferata
Copy link

Hi @cafferata, thanks for your report and sorry, that I've missed that aspect. I pushed a fix, see #305.

Hi @eliashaeussler, thanks for the quick fix! 👏

We no longer test older Symfony versions, it should be your priority to upgrade to a supported version (5.3+). But I accepted a quickfix for this problem.

This project is in the middle of a upgrade to a supported version. But in the meantime all the Composer packages are updated weekly. ☺️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants