mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-25 16:22:42 +01:00
Write a linter rule for $this
reassignment
Summary: Re-assigning `$this` is an invalid PHP construct, see https://3v4l.org/TauX9. Test Plan: Added unit tests. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D14514
This commit is contained in:
parent
426d535b13
commit
581829a99e
5 changed files with 65 additions and 0 deletions
|
@ -319,6 +319,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistTestXHPASTLintSwitchHook' => 'lint/linter/__tests__/ArcanistTestXHPASTLintSwitchHook.php',
|
'ArcanistTestXHPASTLintSwitchHook' => 'lint/linter/__tests__/ArcanistTestXHPASTLintSwitchHook.php',
|
||||||
'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php',
|
'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php',
|
||||||
'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php',
|
'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php',
|
||||||
|
'ArcanistThisReassignmentXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistThisReassignmentXHPASTLinterRule.php',
|
||||||
|
'ArcanistThisReassignmentXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistThisReassignmentXHPASTLinterRuleTestCase.php',
|
||||||
'ArcanistTimeWorkflow' => 'workflow/ArcanistTimeWorkflow.php',
|
'ArcanistTimeWorkflow' => 'workflow/ArcanistTimeWorkflow.php',
|
||||||
'ArcanistToStringExceptionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistToStringExceptionXHPASTLinterRule.php',
|
'ArcanistToStringExceptionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistToStringExceptionXHPASTLinterRule.php',
|
||||||
'ArcanistToStringExceptionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistToStringExceptionXHPASTLinterRuleTestCase.php',
|
'ArcanistToStringExceptionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistToStringExceptionXHPASTLinterRuleTestCase.php',
|
||||||
|
@ -695,6 +697,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistTestXHPASTLintSwitchHook' => 'ArcanistXHPASTLintSwitchHook',
|
'ArcanistTestXHPASTLintSwitchHook' => 'ArcanistXHPASTLintSwitchHook',
|
||||||
'ArcanistTextLinter' => 'ArcanistLinter',
|
'ArcanistTextLinter' => 'ArcanistLinter',
|
||||||
'ArcanistTextLinterTestCase' => 'ArcanistLinterTestCase',
|
'ArcanistTextLinterTestCase' => 'ArcanistLinterTestCase',
|
||||||
|
'ArcanistThisReassignmentXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
|
'ArcanistThisReassignmentXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistTimeWorkflow' => 'ArcanistPhrequentWorkflow',
|
'ArcanistTimeWorkflow' => 'ArcanistPhrequentWorkflow',
|
||||||
'ArcanistToStringExceptionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistToStringExceptionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistToStringExceptionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistToStringExceptionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistThisReassignmentXHPASTLinterRule
|
||||||
|
extends ArcanistXHPASTLinterRule {
|
||||||
|
|
||||||
|
const ID = 91;
|
||||||
|
|
||||||
|
public function getLintName() {
|
||||||
|
return pht('`%s` Reassignment', '$this');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function process(XHPASTNode $root) {
|
||||||
|
$binary_expressions = $root->selectDescendantsOfType('n_BINARY_EXPRESSION');
|
||||||
|
|
||||||
|
foreach ($binary_expressions as $binary_expression) {
|
||||||
|
$operator = $binary_expression->getChildOfType(1, 'n_OPERATOR');
|
||||||
|
|
||||||
|
if ($operator->getConcreteString() != '=') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$variable = $binary_expression->getChildByIndex(0);
|
||||||
|
|
||||||
|
if ($variable->getTypeName() != 'n_VARIABLE') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($variable->getConcreteString() == '$this') {
|
||||||
|
$this->raiseLintAtNode(
|
||||||
|
$binary_expression,
|
||||||
|
pht(
|
||||||
|
'`%s` cannot be re-assigned. '.
|
||||||
|
'This construct will cause a PHP fatal error.',
|
||||||
|
'$this'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistThisReassignmentXHPASTLinterRuleTestCase
|
||||||
|
extends ArcanistXHPASTLinterRuleTestCase {
|
||||||
|
|
||||||
|
public function testLinter() {
|
||||||
|
$this->executeTestsInDirectory(dirname(__FILE__).'/this-reassignment/');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
class SomeClass {
|
||||||
|
public function __construct() {
|
||||||
|
$this = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:4:5
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?php
|
||||||
|
$this = null;
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:2:1
|
Loading…
Reference in a new issue