1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 14:52:40 +01:00

Add a linter rule to detect call-time pass-by-reference

Summary: Call-time [[http://php.net/manual/en/language.references.pass.php | pass-by-reference]] is an awful "feature" of PHP that is deprecated and removed in PHP 5.4 (see http://us1.php.net/manual/en/migration54.incompatible.php). Add a linter rule to `ArcanistXHPASTLinter` to detect the use of this feature and raise an error.

Test Plan: Added a test case for `arc unit`.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: epriestley, Korvin

Differential Revision: https://secure.phabricator.com/D10537
This commit is contained in:
Joshua Spence 2015-01-23 07:28:55 +11:00
parent 0b22838cca
commit 1a3afa4429
2 changed files with 48 additions and 1 deletions

View file

@ -52,6 +52,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
const LINT_DUPLICATE_SWITCH_CASE = 50; const LINT_DUPLICATE_SWITCH_CASE = 50;
const LINT_BLACKLISTED_FUNCTION = 51; const LINT_BLACKLISTED_FUNCTION = 51;
const LINT_IMPLICIT_VISIBILITY = 52; const LINT_IMPLICIT_VISIBILITY = 52;
const LINT_CALL_TIME_PASS_BY_REF = 53;
private $blacklistedFunctions = array(); private $blacklistedFunctions = array();
private $naminghook; private $naminghook;
@ -116,6 +117,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
self::LINT_DUPLICATE_SWITCH_CASE => 'Duplicate Case Statements', self::LINT_DUPLICATE_SWITCH_CASE => 'Duplicate Case Statements',
self::LINT_BLACKLISTED_FUNCTION => 'Use of Blacklisted Function', self::LINT_BLACKLISTED_FUNCTION => 'Use of Blacklisted Function',
self::LINT_IMPLICIT_VISIBILITY => 'Implicit Method Visibility', self::LINT_IMPLICIT_VISIBILITY => 'Implicit Method Visibility',
self::LINT_CALL_TIME_PASS_BY_REF => 'Call-Time Pass-By-Reference',
); );
} }
@ -214,7 +216,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
public function getVersion() { public function getVersion() {
// The version number should be incremented whenever a new rule is added. // The version number should be incremented whenever a new rule is added.
return '14'; return '15';
} }
protected function resolveFuture($path, Future $future) { protected function resolveFuture($path, Future $future) {
@ -290,6 +292,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
'lintBlacklistedFunction' => self::LINT_BLACKLISTED_FUNCTION, 'lintBlacklistedFunction' => self::LINT_BLACKLISTED_FUNCTION,
'lintMethodModifier' => self::LINT_IMPLICIT_VISIBILITY, 'lintMethodModifier' => self::LINT_IMPLICIT_VISIBILITY,
'lintPropertyModifier' => self::LINT_IMPLICIT_VISIBILITY, 'lintPropertyModifier' => self::LINT_IMPLICIT_VISIBILITY,
'lintCallTimePassByReference' => self::LINT_CALL_TIME_PASS_BY_REF,
); );
foreach ($method_codes as $method => $codes) { foreach ($method_codes as $method => $codes) {
@ -3083,6 +3086,20 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
} }
private function lintCallTimePassByReference(XHPASTNode $root) {
$nodes = $root->selectDescendantsOfType('n_CALL_PARAMETER_LIST');
foreach ($nodes as $node) {
$parameters = $node->selectDescendantsOfType('n_VARIABLE_REFERENCE');
foreach ($parameters as $parameter) {
$this->raiseLintAtNode(
$parameter,
self::LINT_CALL_TIME_PASS_BY_REF,
pht('Call-time pass-by-reference calls are prohibited.'));
}
}
}
public function getSuperGlobalNames() { public function getSuperGlobalNames() {
return array( return array(

View file

@ -0,0 +1,30 @@
<?php
class MyClass {
public function myfunc($var) {
echo $var;
}
}
$myvar = true;
myfunc(&$myvar);
myfunc($myvar);
$this->myfunc(&$myvar);
$this->myfunc($myvar);
MyClass::myfunc(&$myvar);
MyClass::myfunc($myvar);
while (testfunc($var1, &$var2, $var3, &$var4) === false) {}
sprintf('0%o', 0777 & $p);
$foo(&$myvar);
~~~~~~~~~~
error:2:7 XHP19
error:9:8
error:12:15
error:15:17
error:18:24
error:18:39
error:22:6