Skip to content
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

DIC compiler pass has() false positive #313

Open
kiler129 opened this issue Dec 5, 2022 · 1 comment
Open

DIC compiler pass has() false positive #313

kiler129 opened this issue Dec 5, 2022 · 1 comment

Comments

@kiler129
Copy link

kiler129 commented Dec 5, 2022

I have a simple compiler pass like below:

<?php
declare(strict_types=1);

namespace App\DependencyInjection\Compiler;

use Faker\Generator;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

final class AddCustomFakerGeneratorProvidersPass implements CompilerPassInterface
{
    public const TAG = 'app.faker.generator_provider';

    public function process(ContainerBuilder $container): void
    {
        if (!$container->has(Generator::class)) {
            return;
        }

        $svc = $container->findDefinition(Generator::class);
        $taggedDeps = $container->findTaggedServiceIds(self::TAG);

        foreach ($taggedDeps as $id => $tags) {
            $svc->addMethodCall('addProvider', [new Reference($id)]);
        }
    }
}

PHPStan with Symfony extension reports that has() will always return true:

 ------ ----------------------------------------------------------------------- 
  Line   DependencyInjection/Compiler/AddCustomFakerGeneratorProvidersPass.php  
 ------ ----------------------------------------------------------------------- 
  17     Negated boolean expression is always true.                             
  21     Unreachable statement - code above always terminates.                  
 ------ ----------------------------------------------------------------------- 

This is taken straight from Symfony docs at https://symfony.com/doc/current/service_container/tags.html#create-a-compiler-pass and they even add a separate warning stating "// always first check if the primary service is defined". Thus, I think this is a bug in PHPStan Symfony extension.

Here's my full PHPStan config:

includes:
    - vendor/phpstan/phpstan-symfony/extension.neon
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon
    - vendor/phpstan/phpstan-strict-rules/rules.neon

parameters:
    level: 7
    tmpDir: var/cache/_phpstan
    parallel:
        jobSize: 20
        maximumNumberOfProcesses: 16
        minimumNumberOfJobsPerProcess: 2
        processTimeout: 30.0

    symfony:
        containerXmlPath: var/cache/dev/App_KernelDevDebugContainer.xml

    excludePaths:
        - %rootDir%/../../../src/DataFixtures/*
        - %rootDir%/../../../src/Migrations/*

    universalObjectCratesClasses:
        - Faker\Generator

    ignoreErrors:
        - '#^Call to an undefined method Faker\\Generator::#'

    tipsOfTheDay: false
    polluteScopeWithLoopInitialAssignments: false
    polluteScopeWithAlwaysIterableForeach: false
    checkAlwaysTrueCheckTypeFunctionCall: true
    checkAlwaysTrueInstanceof: true
    checkAlwaysTrueStrictComparison: true
    checkExplicitMixedMissingReturn: true
    checkFunctionNameCase: true
    reportMaybesInMethodSignatures: true
    reportStaticMethodSignatures: true
    checkTooWideReturnTypesInProtectedAndPublicMethods: true
    treatPhpDocTypesAsCertain: false
    checkMissingIterableValueType: false # handled by PHPCs with more granularity
@julien-lmnr
Copy link

Indeed, same problem for me.

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

No branches or pull requests

2 participants