Giter Site home page Giter Site logo

phpstan / phpstan-deprecation-rules Goto Github PK

View Code? Open in Web Editor NEW
351.0 5.0 17.0 199 KB

PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.

PHP 99.31% Makefile 0.69%
phpstan static-code-analysis static-analysis deprecations php php7

phpstan-deprecation-rules's Introduction

PHPStan - PHP Static Analysis Tool

PHPStan

Build Status Latest Stable Version Total Downloads License PHPStan Enabled


PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code can be checked before you run the actual line.

Read more about PHPStan »

Try out PHPStan on the on-line playground! »

Sponsors

TheCodingMachine     Private Packagist
CDN77     Blackfire.io
iO     Amezmo
ShipMonk     Togetter
RightCapital     ContentKing
ZOL     Psyonix
Shopware     Craft CMS
Worksome     campoint AG
Crisp.nl     Inviqa
GetResponse     EdgeNext
Fame Helsinki

You can now sponsor my open-source work on PHPStan through GitHub Sponsors.

Does GitHub already have your 💳? Do you use PHPStan to find 🐛 before they reach production? Send a couple of 💸 a month my way too. Thank you!

One-time donations through PayPal are also accepted. To request an invoice, contact me through e-mail.

Documentation

All the documentation lives on the phpstan.org website:

PHPStan Pro

PHPStan Pro is a paid add-on on top of open-source PHPStan Static Analysis Tool with these premium features:

  • Web UI for browsing found errors, you can click and open your editor of choice on the offending line.
  • Continuous analysis (watch mode): scans changed files in the background, refreshes the UI automatically.

Try it on PHPStan 0.12.45 or later by running it with the --pro option. You can create an account either by following the on-screen instructions, or by visiting account.phpstan.com.

After 30-day free trial period it costs 7 EUR for individuals monthly, 70 EUR for teams (up to 25 members). By paying for PHPStan Pro, you're supporting the development of open-source PHPStan.

You can read more about it on PHPStan's website.

Code of Conduct

This project adheres to a Contributor Code of Conduct. By participating in this project and its community, you are expected to uphold this code.

Contributing

Any contributions are welcome. PHPStan's source code open to pull requests lives at phpstan/phpstan-src.

phpstan-deprecation-rules's People

Contributors

backendtea avatar clxmstaab avatar cs278 avatar dependabot[bot] avatar eiriksm avatar herndlm avatar iluuu1994 avatar khartir avatar kocal avatar localheinz avatar mglaman avatar ondrejmirtes avatar paxal avatar renovate-bot avatar renovate[bot] avatar ruudk avatar staabm avatar szepeviktor avatar tomasvotruba avatar villfa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

phpstan-deprecation-rules's Issues

#[IgnoreDeprecations] is not being identified as a marker of deprecated scope

PHPUnit 10.5 introduced a new #[IgnoreDeprecations] attribute sebastianbergmann/phpunit#5532 to signal that a test is exercising deprecated code paths i.e. that calls to deprecated methods/functions are expected.

PHPStan however is reporting calls to deprecated functions in that test as errors.

Recently, a similar issue was reported for Symfony's PHPUnit-bridge definition of @group legacy annotated tests, #64

Issue found in Drupal's https://www.drupal.org/project/drupal/issues/3417066

AnonymousClass6a85eed1b3aeaa3b7eaea1eb536990ed

for https://github.com/doctrine/dbal/blob/3.5.1/src/Platforms/AbstractPlatform.php#L225 this lib currently emit:

Call to deprecated method getVarcharTypeDeclarationSQL() of class AnonymousClass6a85eed1b3aeaa3b7eaea1eb536990ed:
Use {@link getStringTypeDeclarationSQL()} instead.

from AnonymousClass6a85eed1b3aeaa3b7eaea1eb536990ed it is very hard to tell which class and also I double the name is stable for error ignore.

I would expect anonymous name like from native phpstan https://phpstan.org/r/7f7ac916-f7fe-4c4d-8035-337e837344ae, ie. class@anonymous/tmp.php:7 istead of AnonymousClass6a85eed1b3aeaa3b7eaea1eb536990ed.

Test failures with PHPStan dev-master

Hi @eiriksm, after your latest changes in phpstan-src, there are now failures in this repo:

1) PHPStan\Rules\Deprecations\CallToDeprecatedMethodRuleTest::testDeprecatedMethodCall
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
 '07: Call to deprecated method deprecatedFoo() of class CheckDeprecatedMethodCall\Foo.
+10: Call to deprecated method deprecatedFoo() of class CheckDeprecatedMethodCall\Bar.
 11: Call to deprecated method deprecatedFoo2() of class CheckDeprecatedMethodCall\Foo.
 14: Call to deprecated method deprecatedFooFromTrait() of class CheckDeprecatedMethodCall\Foo.
 15: Call to deprecated method deprecatedWithDescription() of class CheckDeprecatedMethodCall\Foo:
 Call a different method instead.
 '

phar:///home/runner/work/phpstan/phpstan/extension/vendor/phpstan/phpstan/phpstan.phar/src/Testing/RuleTestCase.php:84
/home/runner/work/phpstan/phpstan/extension/tests/Rules/Deprecations/CallToDeprecatedMethodRuleTest.php:23

2) PHPStan\Rules\Deprecations\CallToDeprecatedStaticMethodRuleTest::testDeprecatedStaticMethodCall
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
 '06: Call to deprecated method deprecatedFoo() of class CheckDeprecatedStaticMethodCall\Foo.
+08: Call to deprecated method deprecatedFoo() of class CheckDeprecatedStaticMethodCall\Bar.
 09: Call to deprecated method deprecatedFoo2() of class CheckDeprecatedStaticMethodCall\Foo.
 11: Call to method foo() of deprecated class CheckDeprecatedStaticMethodCall\Foo.
 12: Call to method deprecatedFoo() of deprecated class CheckDeprecatedStaticMethodCall\Foo.
@@ @@
 Do not touch this at all.
 16: Call to deprecated method deprecatedWithDescription() of class CheckDeprecatedStaticMethodCall\Foo:
 This is probably a singleton.
-24: Call to deprecated method deprecatedFoo() of class CheckDeprecatedStaticMethodCall\Foo.
 '

Can you please look into it so we know what needs fixing? If the tests asserts here are reasonable then phpstan-src needs fixing, or these asserts need to be edited.

Detecting deprecated methods from an interface

Hi there. First of all. Thanks so much for this, it has been so helpful in our projects.

I encountered an issue today that surprised me. If you are calling a class method that is deprecated on the interface level, phpstan does not complain. It surprised me only because my IDE shows me this, and I never thought about checking if this was detected in phpstan as well.

Here is a minimal example:

<?php

class Foo implements FooInterface
{
    /**
     * {@inheritdoc}
     */
    public function createBar() {}
}

interface FooInterface
{
    /**
     * @deprecated Don't use this plz.
     */
    public function createBar();
}


$var = new Foo();
$var->createBar(); // I expect this to be an error, but it's not.

/** @var \FooInterface $var */
$var = $var;
$var->createBar(); // I also expect this to be an error, and it is.

Attached also a picture of my IDE where this is clearly identified. Not that I am saying phpstan and Phpstorm should obviously have the same feature set, just for completion on this issue report :)

Screenshot from 2021-11-19 11-31-39

Here is also the phpstan.neon file:

parameters:
    level: 1
includes:
    - vendor/phpstan/phpstan-deprecation-rules/rules.neon

Using phpstan/phpstan 1.2.0 and phpstan/phpstan-deprecation-rules 1.0.0

Question: Is it possible to have this check excluded for e.g. tests?

Hi,

I really like this option to test for usage of deprecated functions.
I have quite some tests that runs the deprecated code and would prefer to keep it like that till the deprecated code is removed.

Is it possible to exclude the deprecation rules for some files/folders, without excluding it completely from PHPStan check?

Add detection of deprecated Attributes usage

Hello,

would it be possible to also report a case where code uses an Attribute which is marked with @deprecated?

e.g. Given I have a following code:

<?php
/**
 * @deprecated 
 */
#[\Attribute]
final class DoSomethingTheOldWay
{
}


final class SomeDTO 
{
    #[\DoSomethingTheOldWay]
    public readonly string $property;
}

When I run this plugin.
Then the output will warn me that SomeDTO::$property is using a deprecated Attribute.

PHPStan reports wrongly a method as deprecated, because the overwriting method from a trait is not detected

Bug report

I am using phpstan in combination with phpstan-deprecation-rules and getting false-positives in my test classes since a deprecation annotation has been added to PHPUnit.

The code detecting deprecations in phpstan-deprecation-rules looks good:

$classReflection = $this->reflectionProvider->getClass($referencedClass);
$methodReflection = $classReflection->getMethod($methodName, $scope);

if (!$methodReflection->isDeprecated()->yes()) {
    continue;
}

But the $methodReflection is pointing to the method defined in the (TestCase) base class instead of the overwriting method in the ProphecyTrait.

To reproduce this issue easily, I have created a minimal setup.

source file to check

<?php

declare(strict_types=1);

trait MyTrait
{
    protected function prophesize(): void
    {
        echo 'Trait';
    }
}

abstract class MyBaseClass
{
    /** @deprecated Use MyTrait::prophesize() */
    protected function prophesize(): void
    {
        echo 'Base';
    }
}

final class MyClass extends MyBaseClass
{
    use MyTrait;

    public function callProphesize(): void
    {
        $this->prophesize(); // wrongly detected deprecation
    }
}

phpstan.neon

parameters:
    level: max
    paths:
        - src

includes:
    - %rootDir%/../../phpstan/phpstan-deprecation-rules/rules.neon

Expected output

I am expectiong that the $methodReflection variable is pointing to MyTrait::prophesize() so that $methodReflection->isDeprecated()->yes() returns false and no deprecation is detected by phpstan-deprecation-rules.

Did PHPStan help you today? Did it make you happy in any way?

phpstan is a great tool that helps a lot in daily work.

Allow flagging a node with an "ignore deprecation" attribute via NodeVisitorAbstract to skip deprecation errors

A common pattern is to use if/else statements for backward compatibility with deprecated methods to provide support between versions before the deprecation was introduced and to provide a fix for after.

One example can be found here: mglaman/phpstan-drupal#461

if (method_exists($this->moduleHandler, 'invokeAllWIth')) {
    // use the new invokeAllWIth method
} else {
    // use legacy getImplementations method
}

The easiest fix is to add // @phpstan-ignore-next-line whenever using backward compatible code. But I was trying to see if it'd be possible to use a node visitor to detect the if/else to set an attribute flag. Which it does seem possible (whether it is right or wrong.)

Would this package accept a check of checking for an attribute to imply a deprecated scope?

$node->getAttribute('inDeprecatedScope', false)

I don't know how other frameworks are handling this kind of bridge, I need to look.

Show deprecation text in the error message

When we deprecate a function or method, we also document the replacement to use. For example,

/**
 * @deprecated Use bar instead
 */
function foo() {}

Currently when foo is used in the code, this rule only says foo is deprecated.

Call to deprecated function foo()

It would be very useful if it shows the deprecation text Use bar instead in the message as well.

Call to deprecated function foo(). Use bar instead.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

composer
composer.json
  • php ^7.2 || ^8.0
  • php-parallel-lint/php-parallel-lint ^1.2
  • phpstan/phpstan-phpunit ^1.0
  • phpunit/phpunit ^9.5
github-actions
.github/workflows/build.yml
  • actions/checkout v4
  • shivammathur/setup-php v2
  • actions/checkout v4
  • actions/checkout v4
  • shivammathur/setup-php v2
  • actions/checkout v4
  • shivammathur/setup-php v2
  • actions/checkout v4
  • shivammathur/setup-php v2
.github/workflows/create-tag.yml
  • actions/checkout v4
  • WyriHaximus/github-action-get-previous-tag v1
  • WyriHaximus/github-action-next-semvers v1
  • rickstaa/action-create-tag v1
  • rickstaa/action-create-tag v1
.github/workflows/lock-closed-issues.yml
  • dessant/lock-threads v5
.github/workflows/release-toot.yml
  • cbrgm/mastodon-github-action v2
.github/workflows/release-tweet.yml
  • Eomm/why-don-t-you-tweet v1
.github/workflows/release.yml
  • actions/checkout v4
  • metcalfc/changelog-generator v4.3.1
  • actions/create-release v1

  • Check this box to trigger a request for Renovate to run again on this repository

Report deprecations as warnings instead of errors

I think using a deprecated class/method/property/whatever (let's name those as entity) shouldn't be reported as an error but as a warning. The key differences I see here are:

  • The code using a deprecated entity will run, it just might break one day, but PHPStan will then trigger an error about the entity being unknown.
  • Reporting a warning instead of an error should not make the CLI exit with a status code different than 0, but it should still output the deprecation message.

Sometimes I deprecate some classes/methods in my code until I'm sure I don't use them anymore, however PHPStan will then complain about them, so I must ignore the errors, which defeats the purpose of using those deprecation rules.

What do you think about this?

Add detection of overridden deprecated properties

Feature request: When overriding a class property in a child class, that is marked as deprecated in the parent class, a warning should be given. Currently only accessing such properties within methods of the child class triggers this warning.

This would be particularly useful for cases where an upstream package marks a property as deprecated, and where the intended method of setting the property is through overriding it with a new (default) value within the child class, without explicitly accessing it in any method on the child class.

A real world example of such a case is the planned removal of the dates property in Laravel, which won't be detected as a deprecated property currently when overriding it. A code example that currently does not yield any warning:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Foo extends Model
{
    protected $dates = ['foo'];
}

Deprecated internal PHP properties and constants

phpstorm-stubs sometimes mark properties and constants as deprecated, but PHP reflection doesn't have methods to surface that information. Fortunately BetterReflection can surface that, although we might have to check method_exists before calling ->isDeprecated().

Adding node information to DeprecatedScopeResolver::isScopeDeprecated?

I wonder, sometimes I need more context while determining if a node in a scope is deprecated. Mostly to 'undeprecate' sometime. Would you mind if node was added as context/information to DeprecatedScopeResolver::isScopeDeprecated?

I'm trying to target the deprecated_function() in the following code:

        \Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.1.0', fn() => deprecated_function_call(), fn() => count([]));

        DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.1.0', fn() => deprecated_function_call(), fn() => count([]));

        DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.1.0', function() {
            deprecated_function_call();
        }, function() {
            count([]);
        });

I also tried other avenues, like, trying to pragmaticly add lines to ignore through a visitor. I could also use NodeVisitor and then NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN, but that means no code checks in all of the children.

I'm kinda stumped right now, but would love to be able to only exclude deprecations from those node (be it anonimous functions, or whatever).

Add a config option to ignore self-deprecations

When exposing a library, you need to respect semantic versioning and avoid BC-break.

Let's say you have some code

class Foo
{
     /** @deprecated */
     protected $foo;

     private $newFoo;

     public getFoo():
     {
          return $this->foo ?? $this->newFoo;
     }
}

An error is reported because $this->foo; is used but changing this/removing it would be a BC break.

But the phpstan-deprecation-rules would still be useful to detect when I use a deprecated method from another library.

Is it possible to add an option in order to

  • Turn off errors if the deprecated Method/Interface/Property/Class/... is from my project
  • Keep the erros if the deprecated Method/Interface/Property/Class/... is coming from a vendor

?

support deprecation of external classes/a vendor package

this rules - as is - support phasing out deprecated functinality which was marked as @deprecated beforehand (which implies that I rather own the code and can mark it deprecated, or I agree with the deprecations of a external person and follow their judgment).

it would be great if phpstan-deprecation-rules could support more advanced use-cases like phasing out a dependency/package.

lets say we want to soft-migrate a existing codebase with a legacy http client to a more modern http client.
that means we want to make sure, new code which gets implemented should use the new client.
existing code-sites should be reported by phpstan as usage of deprecated functionality.

both - the new and the old http client - are 3rd party libraries and therefore we don't have control over annotating the sources.

I guess this could work with some kind of composer-package-name based deprecation rules, or mabye php namespace based ones.

Child function inheriting deprecated state?

Hi!

this is a bug report/question.

In doctrine persistence LifecycleEventArgs class as parentclass and doctrine orm LifecycleEventArgs as child class

the method getEntity is deprecated and will be removed in parentclass:
https://github.com/doctrine/persistence/blob/2.5.x/src/Persistence/Event/LifecycleEventArgs.php#L39

but overwritten and not deprecated and will be kept in child class:
https://github.com/doctrine/orm/blob/2.12.x/lib/Doctrine/ORM/Event/LifecycleEventArgs.php#L23

When I use phpstan with deprecation rules on my class

<?php

declare(strict_types=1);

namespace App\EventSubscriber;

use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;

class MySubscriber implements EventSubscriberInterface
{
    public function getSubscribedEvents(): array
    {
        return [Events::postPersist];
    }

    public function postPersist(LifecycleEventArgs $args): void
    {
        $entity = $args->getEntity();
        // ...
    }
}

I got the error message:

Call to deprecated method getEntity() of class Doctrine\ORM\Event\LifecycleEventArgs.

Looks like the detprecated state is inherited. Is it a bug, or is it expected?

unable to mark php-src native functions as deprecated

in our case we want to handle basename() as a deprecated function because it can have security implications.
we provide an alternative implemenation and therefore want to warn the DEV to not use basename.

to achieve the above we use a phpstan stub file:

<?php
// .tools/phpstan/deprecated.stub

/**
 * instead of `basename()` you should use `rex_path::basename()` which works across different OS
 *
 * @deprecated see https://github.com/redaxo/redaxo/issues/4069
 */
function basename():string {}

and registered it via our phpstan config file:

parameters:
  ...
    stubFiles:
        - .tools/phpstan/deprecated.stub

phptan does not report deprecation warnings though.

when declaring deprecations for other user-land classes within this stub file everything works like expected.

are php-src native phpdocs not supported to be overridden by stubFiles?
is there an alternative approach to mark php-src native functions as deprecated?

Wrong deprecation error from when parent::deprecatedMethod() called from trait

code https://github.com/atk4/data/blob/bb1c18f5dc583fca7dd372f98a0172fe66663057/src/Persistence/Sql/Postgresql/PlatformTrait.php#L115

ci https://github.com/atk4/data/runs/4342242942?check_suite_focus=true#step:11:16

 ------ ---------------------------------------------------------------------------------- 
  Line   src/Persistence/Sql/Postgresql/PlatformTrait.php (in context of anonymous class)  
 ------ ---------------------------------------------------------------------------------- 
  115    Call to method getCreateTableSQL() of deprecated class                            
         Doctrine\DBAL\Platforms\AbstractPlatform:                                         
         Use {@link PostgreSQLPlatform} instead.                                           
 ------ ---------------------------------------------------------------------------------- 

trait is implemented in anonymous class https://github.com/atk4/data/blob/bb1c18f5dc583fca7dd372f98a0172fe66663057/src/Persistence/Sql/Connection.php#L279

thus parent::getCreateTableSQL(... call inside the trait refers to (by the phpstan error recommended) PostgreSQLPlatform class

Strange behavior

Hi, I have problem with depracation rules in GitLab CI.
I have following code

<?php declare(strict_types = 1);

namespace App\Core\Controls\Base\Grid;

use Nette\ComponentModel\IContainer;
use Nette\Localization\Translator;

class GridFactory
{

	protected Translator $translator;

	public function __construct(Translator $translator)
	{
		$this->translator = $translator;
	}

	public function create(?IContainer $parent = null, ?string $name = null): Grid
	{
		$grid = new Grid($parent, $name);
		$grid->setTranslator($this->translator); // problematic line
<?php declare(strict_types = 1);

namespace App\Core\Controls\Base\Grid;

use Ublaboo\DataGrid\DataGrid;

class Grid extends DataGrid
{
}

DataGrid is external library, in setTranslator, it accepts depracated ITranslator. So i added it to ignore. On local is everthing ok, but in GitLab CI, i am getting following error.

 Ignored error pattern #^Parameter \#1 \$translator of method           
         Ublaboo\\DataGrid\\DataGrid\:\:setTranslator\(\) expects               
         Nette\\Localization\\ITranslator, Nette\\Localization\\Translator      
         given\.$#

On local and CI i have same PHP version.
Any suggestioins???

External deprecation only

I use this plugin on a library I own to detect whether my library uses some 3rd party code that's deprecated. Now I have marked some parts of my library code as deprecated (using @deprectaed annotation) to suggest to my library users that they should switch to something else, however, when I run phpstan on my library it now reports cases of deprecated code use. I cant remove the use of deprecated code just yet as it would be a breaking change. Is there anything I can do in this scenario?

deprecated constructor argument types

looks like currently deprecated constructor argument types are not detected by phpstan's deprecation rules.

not entirely sure whether this could be tested at all as it would require quite some juggling and assumptions on non-typehinted arguments?

so this is more or less a question of whether or not you want this to be part of the ruleset and whether you have any ideas on how to tackle these instances.

willing to put in some time to if necesary...

Deprecation of methods on vendor is not being shown

The merge method on Doctrine\ORM\EntityManager is marked as deprecated directly on the code (link).

But no error/waring is being prompted by the extension.

If I create the stub below with the annotation than it works as expected.

<?php

namespace Doctrine\ORM;

class EntityManager
{
    /** @deprecated */
    public function merge(object $entity): void;
}

This extension will only read deprecations that I add on my code or in stubs? Or is this a bug on the extension?

It is not that clear on the README which is the right behavior

Treat FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED as deprecated

PHP 7.3 deprecated these two constants as they have had no effect since PHP 5.2.1, it would be great if PHPStan warned against their usage.

As of PHP 5.2.1 FILTER_VALIDATE_URL implies FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED. Not only are these constants useless, they also create the incorrect impression that the scheme/host requirement can be disabled.

Proposed action: Generate a deprecation warning if the FILTER_FLAG_SCHEME_REQUIRED or FILTER_FLAG_HOST_REQUIRED flags are explicitly set in calls to filter APIs (PHP currently has no mechanism to deprecate the constants themselves). In PHP 8 the constants will be removed.

https://wiki.php.net/rfc/deprecations_php_7_3#filter_flag_scheme_required_and_filter_flag_host_required

Casting reflection type to string is not found

This may be because it is an internal type, but in the jetbrains stubs it looks like this:

class ReflectionType
{
	/* Methods */
	/**
	 * Checks if null is allowed
	 * @link https://php.net/manual/en/reflectiontype.allowsnull.php
	 * @return bool TRUE if NULL is allowed, otherwise FALSE
	 * @since 7.0
	 */
	public function allowsNull()
	{
	}

	/**
	 * Checks if it is a built-in type
	 * @link https://php.net/manual/en/reflectiontype.isbuiltin.php
	 * @return bool TRUE if it's a built-in type, otherwise FALSE
	 * @since 7.0
	 */
	public function isBuiltin()
	{
	}

	/**
	 * To string
	 * @link https://php.net/manual/en/reflectiontype.tostring.php
	 * @return string Returns the type of the parameter.
	 * @since 7.0
	 * @deprecated 7.1 Please use getName()
	 * @see \ReflectionType::getName()
	 */
	public function __toString()
	{
	}

    private final function __clone() {}

}

Function parameter has deprecated class type

Hi, I have the following snippet which is not recognized as deprecated. Is this a bug or a feature ? O:)

class ResponseEvent
{
}

/** @deprecated Use ResponseEvent instead */
class FilterResponseEvent
{
}

class SymfonyListener
{
    public function handle(FilterResponseEvent $event): void
    {
        // Should tell me FilterResponseEvent is deprecated
    }
}

Thanks !

Deprecation found that is actually the solution to the problem

I encountered a rather specific problem recently with the phpstan-deprecation-rule, more concrete with the FetchingClassConstOfDeprecatedClassRule.

When I run phpstan over a sample project I get the following message:

  5      Fetching deprecated class constant LAST_USERNAME of class       
         Symfony\Bundle\SecurityBundle\Security:                         
         since Symfony 6.2, use                                          
         \Symfony\Bundle\SecurityBundle\Security::LAST_USERNAME instead 

This is somewhat puzzling...

I have prepared a small gist that one can check out to reproduce the issue:

git clone https://gist.github.com/ddb23f85813820a24c4cd26250d844ce.git
cd ddb23f85813820a24c4cd26250d844ce
composer install
./vendor/bin/phpstan

Sadly so far I wasn't able to track down where the issue is actually happening. I only dug down so far that the \Symfony\Bundle\SecurityBundle\Security class is extending a deprecated class and the \Symfony\Bundle\SecurityBundle\Security::LAST_USERNAME const is overwriting the constant of the extended, deprecated, class.

But it looks like there is more to it as trying to reproduce that with an exaple where I recreate the classes myself didn't work. So there seems to be a bit more involved.

When I comment out the FetchingClassConstOfDeprecatedClassRule in the config file of the phpstan-deprecation-rule everything works as intended. So that one is for sure involved somehow...

Crashes with phpstan phar 0.12.33

Both versions 0.12.4 and 0.12.5 crash with phpstan 0.12.33, but work fine with 0.12.32.

In Resolver.php line 110:
                                                                                                
  [_HumbugBox69342eed62ce\Nette\DI\ServiceCreationException]                                    
  Service 'rules.81': Class PHPStan\Rules\Deprecations\AccessDeprecatedPropertyRule not found.  
                                                                                                

Exception trace:
  at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/Resolver.php:110
 _HumbugBox69342eed62ce\Nette\DI\Resolver->resolveEntityType() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/Definitions/ServiceDefinition.php:141
 _HumbugBox69342eed62ce\Nette\DI\Definitions\ServiceDefinition->resolveType() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/Resolver.php:55
 _HumbugBox69342eed62ce\Nette\DI\Resolver->resolveDefinition() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/ContainerBuilder.php:231
 _HumbugBox69342eed62ce\Nette\DI\ContainerBuilder->resolve() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/Compiler.php:199
 _HumbugBox69342eed62ce\Nette\DI\Compiler->processBeforeCompile() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/Compiler.php:159
 _HumbugBox69342eed62ce\Nette\DI\Compiler->compile() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/ContainerLoader.php:99
 _HumbugBox69342eed62ce\Nette\DI\ContainerLoader->generate() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/ContainerLoader.php:65
 _HumbugBox69342eed62ce\Nette\DI\ContainerLoader->loadFile() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/di/src/DI/ContainerLoader.php:34
 _HumbugBox69342eed62ce\Nette\DI\ContainerLoader->load() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/src/DependencyInjection/Configurator.php:31
 PHPStan\DependencyInjection\Configurator->loadContainer() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/nette/bootstrap/src/Bootstrap/Configurator.php:160
 _HumbugBox69342eed62ce\Nette\Configurator->createContainer() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/src/DependencyInjection/ContainerFactory.php:61
 PHPStan\DependencyInjection\ContainerFactory->create() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/src/Command/CommandHelper.php:183
 PHPStan\Command\CommandHelper::begin() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/src/Command/AnalyseCommand.php:78
 PHPStan\Command\AnalyseCommand->execute() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Command/Command.php:228
 _HumbugBox69342eed62ce\Symfony\Component\Console\Command\Command->run() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Application.php:848
 _HumbugBox69342eed62ce\Symfony\Component\Console\Application->doRunCommand() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Application.php:235
 _HumbugBox69342eed62ce\Symfony\Component\Console\Application->doRun() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/vendor/symfony/console/Application.php:136
 _HumbugBox69342eed62ce\Symfony\Component\Console\Application->run() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/bin/phpstan:72
 _HumbugBox69342eed62ce\{closure}() at phar:///Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan/bin/phpstan:73
 require() at /Users/graham/GitLab/StyleCI/CLI/vendor-bin/rector/vendor/phpstan/phpstan/phpstan:6

analyse [--paths-file PATHS-FILE] [-c|--configuration CONFIGURATION] [-l|--level LEVEL] [--no-progress] [--debug] [-a|--autoload-file AUTOLOAD-FILE] [--error-format ERROR-FORMAT] [--generate-baseline [GENERATE-BASELINE]] [--memory-limit MEMORY-LIMIT] [--xdebug] [--] [<paths>...]

Example composer.json to replicate this:

{
    "require": {
        "phpstan/phpstan": "0.12.33",
        "phpstan/phpstan-deprecation-rules": "0.12.4"
    }
}

Allow ignoring "@group legacy" annotated test methods when Symfony PHPUnit bridge is in use

It would be useful to allow skipping analysis of @legacy annotated PHPUnit test methods test in PHPUnit.

Drupal runs deprecation tests via PHPUnit and the Symfony's PHPUnit bridge. Current policy for runtime deprecated code is to write a @legacy annotated test that explicitly contains calls to deprecated code. PHPStan would now report these calls as errors, which is a duplicated check vs. existing tools. We cannot ignore entire files since it may well be that normal and deprecation tests are part of the same test class.

See also:

mark magic method as deprecated

we would like to mark methods which are called via magic calls as deprecated

example from zendframework 1 sources:

/**
 * ...
 * @method string serverUrl($requestUri = null)
 * @method string translate($messageid = null)
 * @method string url(array $urlOptions = array(), $name = null, $reset = false, $encode = true)
 * @method Zend_Http_UserAgent userAgent(Zend_Http_UserAgent $userAgent = null)
 */
class Zend_View extends Zend_View_Abstract
{
}

calls to $view->translate should emit a deprecation warning. is marking magic calls possible right now?

Fail on method calls to deprecated classes

If a class is deprecated, I would expect that any calls to methods in that deprecated class should also trigger a deprecation message.

For example, a change that I implemented locally in CallToDeprecatedMethodRule:

if ($classReflection->isDeprecated()) {
    $description = $methodReflection->getDeprecatedDescription();
    if ($description === null) {
        return [sprintf(
            'Call to method %s() of deprecated class %s.',
            $methodReflection->getName(),
            $methodReflection->getDeclaringClass()->getName()
        )];
    }

    return [sprintf(
        "Call to method %s() of deprecated class %s:\n%s",
        $methodReflection->getName(),
        $methodReflection->getDeclaringClass()->getName(),
        $description
    )];
}

Though maybe this makes more sense as a separate rule within this library, it works well enough for my needs.

Allow DeprecatedScopeResolvers to be aware of the node being processed

This stems from work in mglaman/phpstan-drupal#714 and mglaman/phpstan-drupal#659 in phpstan-drupal.

It's complicated, but it's based on this code:

$result = DeprecationHelper::backwardsCompatibleCall(
        currentVersion: \Drupal::VERSION,
        deprecatedVersion: '10.3',
        currentCallable: fn() => Role::loadMultiple(),
        deprecatedCallable: fn() => user_roles(),
      );

We want to use a DeprecatedScopeResolver to ensure the code called in the deprecatedCallable is within a deprecated scope. That's been accomplished in the PR with DeprecationHelperScope so far. However, it is including currentCallable (we want to find and error on deprecated code within that callable.)

Using a NodeVisitor it is possible to traverse the children in the deprecatedCallable tree and set a deprecated attribute. But, this attribute cannot be read using the Scope alone.

There are problems with backwards compatibility to modify \PHPStan\Rules\Deprecations\DeprecatedScopeResolver::isScopeDeprecated. So, this is my idea.

Introduce NodeAwareDeprecatedScopeResolver which DeprecatedScopeResolver implementations can also implement.

interface NodeAwareDeprecatedScopeResolver
{

	public function withNode(Node $node);

}

DeprecatedScopeHelper needs to be modified to support this:

	public function isScopeDeprecated(Scope $scope, Node $node): bool
	{
		foreach ($this->resolvers as $checker) {
			if ($checker instanceof NodeAwareDeprecatedScopeResolver) {
				$checker->withNode($node);
			}
			if ($checker->isScopeDeprecated($scope)) {
				return true;
			}
		}

		return false;
	}

Support for #[Deprecated()] annotation

phpstorm-stubs use JetBrains\PhpStorm\Deprecated annotation to mark method's, class e.t.c
This annotation allows for more detailed description of the problem and suggested changes.

Other projects use this annotation as well

Can deprecation-rules show it in the same way like @deprecated ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.