1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-12-23 05:50:54 +01:00

Add version check whitelists for constants to the version compatibility lint rule

Summary: Ref T13249. We currently allow `if (function_exists('X')) { X(); }` but not `if (defined('X')) { X; }`. Allow the latter.

Test Plan: See D20145, which linted clean with this patch in place.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13249

Differential Revision: https://secure.phabricator.com/D20146
This commit is contained in:
epriestley 2019-02-11 14:21:31 -08:00
parent 25c2381959
commit 7e61e43f65
2 changed files with 29 additions and 12 deletions

View file

@ -9,4 +9,4 @@ function f() {
~~~~~~~~~~ ~~~~~~~~~~
warning:3:8 warning:3:8
error:7:1 error:7:1
error:9: error:9:1

View file

@ -26,6 +26,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$whitelist = array( $whitelist = array(
'class' => array(), 'class' => array(),
'function' => array(), 'function' => array(),
'constant' => array(),
); );
$conditionals = $root->selectDescendantsOfType('n_IF'); $conditionals = $root->selectDescendantsOfType('n_IF');
@ -51,6 +52,7 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
case 'class_exists': case 'class_exists':
case 'function_exists': case 'function_exists':
case 'interface_exists': case 'interface_exists':
case 'defined':
$type = null; $type = null;
switch ($function_name) { switch ($function_name) {
case 'class_exists': case 'class_exists':
@ -64,6 +66,10 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
case 'interface_exists': case 'interface_exists':
$type = 'interface'; $type = 'interface';
break; break;
case 'defined':
$type = 'constant';
break;
} }
$params = $function->getChildOfType(1, 'n_CALL_PARAMETER_LIST'); $params = $function->getChildOfType(1, 'n_CALL_PARAMETER_LIST');
@ -98,7 +104,6 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$min = idx($version, 'php.min'); $min = idx($version, 'php.min');
$max = idx($version, 'php.max'); $max = idx($version, 'php.max');
// Check if whitelisted.
$whitelisted = false; $whitelisted = false;
foreach (idx($whitelist['function'], $name, array()) as $range) { foreach (idx($whitelist['function'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) { if (array_intersect($range, array_keys($node->getTokens()))) {
@ -178,18 +183,18 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$version = idx($compat_info['classes'], $name, $version); $version = idx($compat_info['classes'], $name, $version);
$min = idx($version, 'php.min'); $min = idx($version, 'php.min');
$max = idx($version, 'php.max'); $max = idx($version, 'php.max');
// Check if whitelisted.
$whitelisted = false;
foreach (idx($whitelist['class'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) {
$whitelisted = true;
break;
}
}
if ($whitelisted) { $whitelisted = false;
continue; foreach (idx($whitelist['class'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) {
$whitelisted = true;
break;
} }
}
if ($whitelisted) {
continue;
}
if ($min && version_compare($min, $this->version, '>')) { if ($min && version_compare($min, $this->version, '>')) {
$this->raiseLintAtNode( $this->raiseLintAtNode(
@ -225,6 +230,18 @@ final class ArcanistPHPCompatibilityXHPASTLinterRule
$min = idx($version, 'php.min'); $min = idx($version, 'php.min');
$max = idx($version, 'php.max'); $max = idx($version, 'php.max');
$whitelisted = false;
foreach (idx($whitelist['constant'], $name, array()) as $range) {
if (array_intersect($range, array_keys($node->getTokens()))) {
$whitelisted = true;
break;
}
}
if ($whitelisted) {
continue;
}
if ($min && version_compare($min, $this->version, '>')) { if ($min && version_compare($min, $this->version, '>')) {
$this->raiseLintAtNode( $this->raiseLintAtNode(
$node, $node,