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 for the instanceof operator

Summary: The `instanceof` operator expects the first argument to be an object instance. See http://www.phpwtf.org/instanceof-smart.

Test Plan: Added test case

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, epriestley

Differential Revision: https://secure.phabricator.com/D12856
This commit is contained in:
Joshua Spence 2015-05-18 18:00:08 +10:00
parent 0c9a037719
commit 4bb2eecdaf
2 changed files with 38 additions and 1 deletions

View file

@ -68,6 +68,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
const LINT_CAST_SPACING = 66; const LINT_CAST_SPACING = 66;
const LINT_TOSTRING_EXCEPTION = 67; const LINT_TOSTRING_EXCEPTION = 67;
const LINT_LAMBDA_FUNC_FUNCTION = 68; const LINT_LAMBDA_FUNC_FUNCTION = 68;
const LINT_INSTANCEOF_OPERATOR = 69;
private $blacklistedFunctions = array(); private $blacklistedFunctions = array();
private $naminghook; private $naminghook;
@ -212,6 +213,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
=> pht('Throwing Exception in %s Method', '__toString'), => pht('Throwing Exception in %s Method', '__toString'),
self::LINT_LAMBDA_FUNC_FUNCTION self::LINT_LAMBDA_FUNC_FUNCTION
=> pht('%s Function', '__lambda_func'), => pht('%s Function', '__lambda_func'),
self::LINT_INSTANCEOF_OPERATOR
=> pht('%s Operator', 'instanceof'),
); );
} }
@ -332,7 +335,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 '30'; return '31';
} }
protected function resolveFuture($path, Future $future) { protected function resolveFuture($path, Future $future) {
@ -427,6 +430,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
'lintCastSpacing' => self::LINT_CAST_SPACING, 'lintCastSpacing' => self::LINT_CAST_SPACING,
'lintThrowExceptionInToStringMethod' => self::LINT_TOSTRING_EXCEPTION, 'lintThrowExceptionInToStringMethod' => self::LINT_TOSTRING_EXCEPTION,
'lintLambdaFuncFunction' => self::LINT_LAMBDA_FUNC_FUNCTION, 'lintLambdaFuncFunction' => self::LINT_LAMBDA_FUNC_FUNCTION,
'lintInstanceOfOperator' => self::LINT_INSTANCEOF_OPERATOR,
); );
foreach ($method_codes as $method => $codes) { foreach ($method_codes as $method => $codes) {
@ -4196,6 +4200,30 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
} }
private function lintInstanceOfOperator(XHPASTNode $root) {
$expressions = $root->selectDescendantsOfType('n_BINARY_EXPRESSION');
foreach ($expressions as $expression) {
$operator = $expression->getChildOfType(1, 'n_OPERATOR');
if (strtolower($operator->getConcreteString()) != 'instanceof') {
continue;
}
$object = $expression->getChildByIndex(0);
if ($object->isStaticScalar() ||
$object->getTypeName() == 'n_SYMBOL_NAME') {
$this->raiseLintAtNode(
$object,
self::LINT_INSTANCEOF_OPERATOR,
pht(
'%s expects an object instance, constant given.',
'instanceof'));
}
}
}
/** /**
* Retrieve all calls to some specified function(s). * Retrieve all calls to some specified function(s).

View file

@ -0,0 +1,9 @@
<?php
var_dump('foobar' instanceof stdClass);
var_dump(123 instanceof stdClass);
var_dump(null instanceof stdClass);
var_dump($x instanceof stdClass);
~~~~~~~~~~
error:2:10
error:3:10
error:4:10