mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 14:52:40 +01:00
Add a linter rule for incorrect use of parent scope
Summary: The following code is invalid: ``` final class MyClass { public function __construct() { parent::__construct(null); } } $x = new MyClass(); ``` Running the above code will produce a fatal error: ``` PHP Fatal error: Cannot access parent:: when current class scope has no parent ``` Test Plan: Added unit tests. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Differential Revision: https://secure.phabricator.com/D12420
This commit is contained in:
parent
a6a26bb3a3
commit
f00d4219dd
2 changed files with 49 additions and 0 deletions
|
@ -63,6 +63,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
|||
const LINT_LOWERCASE_FUNCTIONS = 61;
|
||||
const LINT_CLASS_NAME_LITERAL = 62;
|
||||
const LINT_USELESS_OVERRIDING_METHOD = 63;
|
||||
const LINT_NO_PARENT_SCOPE = 64;
|
||||
|
||||
private $blacklistedFunctions = array();
|
||||
private $naminghook;
|
||||
|
@ -197,6 +198,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
|||
=> pht('Class Name Literal'),
|
||||
self::LINT_USELESS_OVERRIDING_METHOD
|
||||
=> pht('Useless Overriding Method'),
|
||||
self::LINT_NO_PARENT_SCOPE
|
||||
=> pht('No Parent Scope'),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -405,6 +408,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
|||
'lintLowercaseFunctions' => self::LINT_LOWERCASE_FUNCTIONS,
|
||||
'lintClassNameLiteral' => self::LINT_CLASS_NAME_LITERAL,
|
||||
'lintUselessOverridingMethods' => self::LINT_USELESS_OVERRIDING_METHOD,
|
||||
'lintNoParentScope' => self::LINT_NO_PARENT_SCOPE,
|
||||
);
|
||||
|
||||
foreach ($method_codes as $method => $codes) {
|
||||
|
@ -3849,6 +3853,36 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
|||
}
|
||||
}
|
||||
|
||||
private function lintNoParentScope(XHPASTNode $root) {
|
||||
$classes = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
|
||||
|
||||
foreach ($classes as $class) {
|
||||
$methods = $class->selectDescendantsOfType('n_METHOD_DECLARATION');
|
||||
|
||||
if ($class->getChildByIndex(2)->getTypeName() == 'n_EXTENDS_LIST') {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($methods as $method) {
|
||||
$static_accesses = $method
|
||||
->selectDescendantsOfType('n_CLASS_STATIC_ACCESS');
|
||||
|
||||
foreach ($static_accesses as $static_access) {
|
||||
$called_class = $static_access->getChildOfType(0, 'n_CLASS_NAME');
|
||||
|
||||
if ($called_class->getConcreteString() == 'parent') {
|
||||
$this->raiseLintAtNode(
|
||||
$static_access,
|
||||
self::LINT_NO_PARENT_SCOPE,
|
||||
pht(
|
||||
'Cannot access %s when current class scope has no parent.',
|
||||
'parent::'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve all calls to some specified function(s).
|
||||
|
|
15
src/lint/linter/__tests__/xhpast/no-parent-scope.lint-test
Normal file
15
src/lint/linter/__tests__/xhpast/no-parent-scope.lint-test
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
final class MyValidClass extends SomeOtherClass {
|
||||
public function __construct() {
|
||||
parent::__construct(null);
|
||||
}
|
||||
}
|
||||
|
||||
final class MyInvalidClass {
|
||||
public function __construct() {
|
||||
parent::__construct(null);
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~
|
||||
error:11:5
|
Loading…
Reference in a new issue