Added PHPStan rule that checks we don't use $this in closures.
parent
406a28708f
commit
e5b13b4c8f
|
@ -15,3 +15,4 @@
|
||||||
.travis.yml export-ignore
|
.travis.yml export-ignore
|
||||||
appveyor.yml export-ignore
|
appveyor.yml export-ignore
|
||||||
phpunit.xml.dist export-ignore
|
phpunit.xml.dist export-ignore
|
||||||
|
/phpstan/ export-ignore
|
||||||
|
|
|
@ -66,8 +66,13 @@
|
||||||
},
|
},
|
||||||
"autoload-dev": {
|
"autoload-dev": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Composer\\Test\\": "tests/Composer/Test"
|
"Composer\\Test\\": "tests/Composer/Test",
|
||||||
}
|
"Composer\\PHPStanRules\\": "phpstan/Rules/src",
|
||||||
|
"Composer\\PHPStanRulesTests\\": "phpstan/Rules/tests"
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"phpstan/Rules/tests/data"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
"bin/composer"
|
"bin/composer"
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Composer\PHPStanRules;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PHPStan\Analyser\Scope;
|
||||||
|
use PHPStan\Rules\Rule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-implements Rule<\PhpParser\Node\Expr\Variable>
|
||||||
|
*/
|
||||||
|
final class AnonymousFunctionWithThisRule implements Rule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getNodeType(): string
|
||||||
|
{
|
||||||
|
return \PhpParser\Node\Expr\Variable::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function processNode(Node $node, Scope $scope): array
|
||||||
|
{
|
||||||
|
if (!\is_string($node->name) || $node->name !== 'this') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($scope->isInClosureBind()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$scope->isInClass()) {
|
||||||
|
// reported in other standard rule on level 0
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($scope->isInAnonymousFunction()) {
|
||||||
|
return ['Using $this inside anonymous function is prohibited because of PHP 5.3 support.'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace Composer\PHPStanRulesTests;
|
||||||
|
|
||||||
|
use Composer\PHPStanRules\AnonymousFunctionWithThisRule;
|
||||||
|
use PHPStan\Testing\RuleTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-extends RuleTestCase<AnonymousFunctionWithThisRule>
|
||||||
|
*/
|
||||||
|
final class AnonymousFunctionWithThisRuleTest extends RuleTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
protected function getRule(): \PHPStan\Rules\Rule
|
||||||
|
{
|
||||||
|
return new AnonymousFunctionWithThisRule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWithThis(): void
|
||||||
|
{
|
||||||
|
$this->analyse([__DIR__ . '/data/method-with-this.php'], [
|
||||||
|
['Using $this inside anonymous function is prohibited because of PHP 5.3 support.', 13],
|
||||||
|
['Using $this inside anonymous function is prohibited because of PHP 5.3 support.', 17],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class FirstClass
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $firstProp = 9;
|
||||||
|
|
||||||
|
public function funMethod()
|
||||||
|
{
|
||||||
|
function() {
|
||||||
|
$this->firstProp;
|
||||||
|
};
|
||||||
|
|
||||||
|
call_user_func(function() {
|
||||||
|
$this->funMethod();
|
||||||
|
}, $this);
|
||||||
|
|
||||||
|
$bind = 'bind';
|
||||||
|
function() use($bind) {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function global_ok() {
|
||||||
|
$_SERVER['REMOTE_ADDR'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function global_this() {
|
||||||
|
// not checked by our rule, it is checked with standard phpstan rule on level 0
|
||||||
|
$this['REMOTE_ADDR'];
|
||||||
|
}
|
|
@ -23,6 +23,15 @@ parameters:
|
||||||
|
|
||||||
# we don't have different constructors for parent/child
|
# we don't have different constructors for parent/child
|
||||||
- '~^Unsafe usage of new static\(\)\.$~'
|
- '~^Unsafe usage of new static\(\)\.$~'
|
||||||
|
|
||||||
|
# hhvm should have support for $this in closures
|
||||||
|
-
|
||||||
|
count: 1
|
||||||
|
message: '~^Using \$this inside anonymous function is prohibited because of PHP 5\.3 support\.$~'
|
||||||
|
path: '../tests/Composer/Test/Repository/PlatformRepositoryTest.php'
|
||||||
paths:
|
paths:
|
||||||
- ../src
|
- ../src
|
||||||
- ../tests
|
- ../tests
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- Composer\PHPStanRules\AnonymousFunctionWithThisRule
|
||||||
|
|
Loading…
Reference in New Issue