Skip to content

Add support for PHPStan 2.0 extensions #4328

@llaville

Description

@llaville

Is your feature request related to a problem? Please describe.

Yesterday, I've replaced my old PHPStan baseline error file by the phpstan/phpstan-doctrine official extension.

See llaville/php-compatinfo-db@db3913d

While if works fine locally and in MegaLinter v8.1 context which have only PHPStan 1.x support, it does not work with MegaLinter v8.2 or greater that have added PHPStan 2.x support only.

PHPStan 1.x locally

phpstan1_locally

Megalinter 8.3 context

phpstan2_extension

Reproductible with PHPStan 2.x locally

phpstan2_locally

Describe the solution you'd like

I've tried to upgrade PHPStan locally for testing purpose

upgrade_phpstan

And run analysis again.
Even if PHPStan 2.0 show me more errors than PHPStan 1.12, it works as expected : the phpstan/phpstan-doctrine official extension is well detected and used.

PHPStan 2.0.2 analysis results
devilbox@php-8.1.31 in /shared/backups/bartlett/php-compatinfo-db $ composer code:check
A script named bin would override a Composer command and has been skipped
> vendor/bin/phpstan analyse --configuration .github/linters/phpstan.neon.dist --ansi --verbose
 121/121 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% 11 secs

 ------ -------------------------------------------------------------------------------------------------
  Line   Application/Command/Build/BuildHandler.php
 ------ -------------------------------------------------------------------------------------------------
  60     Call to function is_array() with array<int<0, max>, class-string> will always evaluate to true.
         🪪  function.alreadyNarrowedType
 ------ -------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Application/Kernel/AbstractKernel.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  173    Instanceof between Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface and
         Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface will always evaluate to true.
         🪪  instanceof.alwaysTrue
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  179    Instanceof between Symfony\Component\DependencyInjection\Extension\ExtensionInterface and
         Symfony\Component\DependencyInjection\Extension\ExtensionInterface will always evaluate to true.
         🪪  instanceof.alwaysTrue
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ ------------------------------------------------------------------------------------------------------------------------------------
  Line   Domain/Factory/ExtensionVersionProviderTrait.php (in context of class Bartlett\CompatInfoDb\Application\Query\ListRef\ListHandler)
 ------ ------------------------------------------------------------------------------------------------------------------------------------
  52     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  56     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  60     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  64     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  68     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  72     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  77     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  81     If condition is always true.
         🪪  if.alwaysTrue
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  85     Unreachable statement - code above always terminates.
         🪪  deadCode.unreachable
  104    If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  108    If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
 ------ ------------------------------------------------------------------------------------------------------------------------------------

 ------ ------------------------------------------------------------------------------------------------------------------------------
  Line   Domain/Factory/ExtensionVersionProviderTrait.php (in context of class Bartlett\CompatInfoDb\Domain\Factory\ExtensionFactory)
 ------ ------------------------------------------------------------------------------------------------------------------------------
  52     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  56     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  60     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  64     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  68     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  72     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  77     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  81     If condition is always true.
         🪪  if.alwaysTrue
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  85     Unreachable statement - code above always terminates.
         🪪  deadCode.unreachable
  104    If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  108    If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
 ------ ------------------------------------------------------------------------------------------------------------------------------

 ------ ---------------------------------------------------------------------------------------------------------------------------------------
  Line   Domain/Factory/ExtensionVersionProviderTrait.php (in context of class Bartlett\CompatInfoDb\Presentation\Console\Command\ListCommand)
 ------ ---------------------------------------------------------------------------------------------------------------------------------------
  52     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  56     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  60     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  64     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  68     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  72     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  77     If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  81     If condition is always true.
         🪪  if.alwaysTrue
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  85     Unreachable statement - code above always terminates.
         🪪  deadCode.unreachable
  104    If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
  108    If condition is always false.
         🪪  if.alwaysFalse
         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in
            your .github/linters/phpstan.neon.dist.
 ------ ---------------------------------------------------------------------------------------------------------------------------------------

 ------ -----------------------------------------------------------------------------------------------------------------------------------
  Line   Domain/Factory/LibraryVersionProviderTrait.php (in context of class Bartlett\CompatInfoDb\Application\Query\Doctor\DoctorHandler)
 ------ -----------------------------------------------------------------------------------------------------------------------------------
  103    Call to function method_exists() with 'Imagick' and 'getVersion' will always evaluate to true.
         🪪  function.alreadyNarrowedType
  161    Call to function method_exists() with 'sqlite3' and 'version' will always evaluate to true.
         🪪  function.alreadyNarrowedType
 ------ -----------------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------------------
  Line   Domain/Factory/LibraryVersionProviderTrait.php (in context of class Bartlett\CompatInfoDb\Presentation\Console\Command\ShowCommand)
 ------ -------------------------------------------------------------------------------------------------------------------------------------
  103    Call to function method_exists() with 'Imagick' and 'getVersion' will always evaluate to true.
         🪪  function.alreadyNarrowedType
  161    Call to function method_exists() with 'sqlite3' and 'version' will always evaluate to true.
         🪪  function.alreadyNarrowedType
 ------ -------------------------------------------------------------------------------------------------------------------------------------

 ------ --------------------------------------------------------------------------------------------------------------------------------
  Line   Infrastructure/Persistence/Doctrine/Hydrator/ClassHydrator.php
 ------ --------------------------------------------------------------------------------------------------------------------------------
  35     Method Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\ClassHydrator::extract() should return array<string,
         bool|DateTimeImmutable|string|null> but returns array<string, array<string, string|null>|bool|string|null>.
         🪪  return.type
 ------ --------------------------------------------------------------------------------------------------------------------------------

 ------ -----------------------------------------------------------------------------------------------------------------------------------
  Line   Infrastructure/Persistence/Doctrine/Hydrator/ConstantHydrator.php
 ------ -----------------------------------------------------------------------------------------------------------------------------------
  34     Method Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\ConstantHydrator::extract() should return array<string,
         bool|DateTimeImmutable|string|null> but returns array<string, array<string, string|null>|string|null>.
         🪪  return.type
 ------ -----------------------------------------------------------------------------------------------------------------------------------

 ------ -----------------------------------------------------------------------------------------------------------------------------------
  Line   Infrastructure/Persistence/Doctrine/Hydrator/FunctionHydrator.php
 ------ -----------------------------------------------------------------------------------------------------------------------------------
  36     Method Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\FunctionHydrator::extract() should return array<string,
         bool|DateTimeImmutable|string|null> but returns array<string, array<string|null>|bool|string|null>.
         🪪  return.type
 ------ -----------------------------------------------------------------------------------------------------------------------------------

 ------ -----------------------------------------------------------------------------------------------------------------------------------
  Line   Infrastructure/Persistence/Doctrine/Hydrator/IniEntryHydrator.php
 ------ -----------------------------------------------------------------------------------------------------------------------------------
  33     Method Bartlett\CompatInfoDb\Infrastructure\Persistence\Doctrine\Hydrator\IniEntryHydrator::extract() should return array<string,
         bool|DateTimeImmutable|string|null> but returns array<string, array<string, string|null>|string|null>.
         🪪  return.type
 ------ -----------------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/AboutCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  46     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/Debug/ContainerDebugCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  58     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/DiagnoseCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  70     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/DoctorCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  58     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/InitCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  64     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/ListCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  73     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/NewCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  84     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ -------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/PolyfillCommand.php
 ------ -------------------------------------------------------------------------------------------------------------------------
  74     PHPDoc tag @var with type Bartlett\CompatInfoDb\Presentation\Console\ApplicationInterface is not subtype of native type
         Symfony\Component\Console\Application|null.
         🪪  varTag.nativeType
 ------ -------------------------------------------------------------------------------------------------------------------------

 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  Line   Presentation/Console/Command/ShowCommand.php

 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  226    Call to function method_exists() with

         Bartlett\CompatInfoDb\Domain\ValueObject\Class_|Bartlett\CompatInfoDb\Domain\ValueObject\Constant_|Bartlett\CompatInfoDb\Domain\ValueObject\Function_|Bartlett\CompatInfoDb\Domain\ValueObject\IniEntry
         and 'getDeprecated' will always evaluate to true.

         🪪  function.alreadyNarrowedType

         💡 Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in

            your .github/linters/phpstan.neon.dist.

  303    Instanceof between Bartlett\CompatInfoDb\Domain\ValueObject\Class_ and Bartlett\CompatInfoDb\Domain\ValueObject\Class_ will always

         evaluate to true.

         🪪  instanceof.alwaysTrue

         💡 Remove remaining cases below this one and this error will disappear too.

 ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


 [ERROR] Found 54 errors


Elapsed time: 12 seconds
Used memory: 544 MB
Script vendor/bin/phpstan analyse --configuration .github/linters/phpstan.neon.dist --ansi --verbose handling the code:check event returned with error code 1

Describe alternatives you've considered

Add support to both PHPStan 1.x and 2.x into MegaLinter v8 to allow a smooth transition to all PHP users

Additional context

@nvuillam I've noticed old lines that we should removed too : Could you confirm this point ?
https://github.com/oxsecurity/megalinter/blob/v8.3.0/megalinter/descriptors/php.megalinter-descriptor.yml#L111-L112

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions