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

Move the getFunctionCalls method to ArcanistBaseXHPASTLinter

Summary: Move the `getFunctionCalls` method to the `ArcanistBaseXHPASTLinter` so that it can be used by subclasses.

Test Plan: `arc unit`

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Differential Revision: https://secure.phabricator.com/D12472
This commit is contained in:
Joshua Spence 2015-05-20 07:00:29 +10:00
parent ddfdfce3f5
commit 9862d7c0cb
3 changed files with 90 additions and 78 deletions

View file

@ -196,6 +196,35 @@ abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
return idx($this->exceptions, $path); return idx($this->exceptions, $path);
} }
/* -( Utility )------------------------------------------------------------ */
/**
* Retrieve all calls to some specified function(s).
*
* Returns all descendant nodes which represent a function call to one of the
* specified functions.
*
* @param XHPASTNode Root node.
* @param list<string> Function names.
* @return AASTNodeList
*/
protected function getFunctionCalls(XHPASTNode $root, array $function_names) {
$calls = $root->selectDescendantsOfType('n_FUNCTION_CALL');
$nodes = array();
foreach ($calls as $call) {
$node = $call->getChildByIndex(0);
$name = strtolower($node->getConcreteString());
if (in_array($name, $function_names)) {
$nodes[] = $call;
}
}
return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes);
}
public function getSuperGlobalNames() { public function getSuperGlobalNames() {
return array( return array(
'$GLOBALS', '$GLOBALS',

View file

@ -21,21 +21,6 @@ final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
'linter is intended for use in Phabricator libraries and extensions.'); 'linter is intended for use in Phabricator libraries and extensions.');
} }
public function setDeprecatedFunctions(array $map) {
$this->deprecatedFunctions = $map;
return $this;
}
public function setDynamicStringFunctions(array $map) {
$this->dynamicStringFunctions = $map;
return $this;
}
public function setDynamicStringClasses(array $map) {
$this->dynamicStringClasses = $map;
return $this;
}
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
self::LINT_ARRAY_COMBINE => pht( self::LINT_ARRAY_COMBINE => pht(
@ -49,16 +34,6 @@ final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
); );
} }
public function getLintSeverityMap() {
$warning = ArcanistLintSeverity::SEVERITY_WARNING;
return array(
self::LINT_ARRAY_COMBINE => $warning,
self::LINT_DEPRECATED_FUNCTION => $warning,
self::LINT_UNSAFE_DYNAMIC_STRING => $warning,
self::LINT_RAGGED_CLASSTREE_EDGE => $warning,
);
}
public function getLinterName() { public function getLinterName() {
return 'PHLXHP'; return 'PHLXHP';
} }
@ -67,9 +42,15 @@ final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
return 'phutil-xhpast'; return 'phutil-xhpast';
} }
public function getVersion() { public function getLintSeverityMap() {
// The version number should be incremented whenever a new rule is added. $warning = ArcanistLintSeverity::SEVERITY_WARNING;
return '3';
return array(
self::LINT_ARRAY_COMBINE => $warning,
self::LINT_DEPRECATED_FUNCTION => $warning,
self::LINT_UNSAFE_DYNAMIC_STRING => $warning,
self::LINT_RAGGED_CLASSTREE_EDGE => $warning,
);
} }
public function getLinterConfigurationOptions() { public function getLinterConfigurationOptions() {
@ -107,9 +88,15 @@ final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
case 'phutil-xhpast.dynamic-string.classes': case 'phutil-xhpast.dynamic-string.classes':
$this->setDynamicStringClasses($value); $this->setDynamicStringClasses($value);
return; return;
default:
parent::setLinterConfigurationValue($key, $value);
return;
} }
}
return parent::setLinterConfigurationValue($key, $value); public function getVersion() {
// The version number should be incremented whenever a new rule is added.
return '3';
} }
protected function resolveFuture($path, Future $future) { protected function resolveFuture($path, Future $future) {
@ -137,6 +124,27 @@ final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
} }
/* -( Setters )------------------------------------------------------------ */
public function setDeprecatedFunctions(array $map) {
$this->deprecatedFunctions = $map;
return $this;
}
public function setDynamicStringClasses(array $map) {
$this->dynamicStringClasses = $map;
return $this;
}
public function setDynamicStringFunctions(array $map) {
$this->dynamicStringFunctions = $map;
return $this;
}
/* -( Linter Rules )------------------------------------------------------- */
private function lintUnsafeDynamicString(XHPASTNode $root) { private function lintUnsafeDynamicString(XHPASTNode $root) {
$safe = $this->dynamicStringFunctions + array( $safe = $this->dynamicStringFunctions + array(
'pht' => 0, 'pht' => 0,
@ -206,40 +214,42 @@ final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
private function lintArrayCombine(XHPASTNode $root) { private function lintArrayCombine(XHPASTNode $root) {
$function_calls = $root->selectDescendantsOfType('n_FUNCTION_CALL'); $function_calls = $this->getFunctionCalls($root, array('array_combine'));
foreach ($function_calls as $call) { foreach ($function_calls as $call) {
$name = $call->getChildByIndex(0)->getConcreteString(); $name = $call->getChildByIndex(0)->getConcreteString();
if (strcasecmp($name, 'array_combine') == 0) { $parameter_list = $call->getChildOfType(1, 'n_CALL_PARAMETER_LIST');
$parameter_list = $call->getChildOfType(1, 'n_CALL_PARAMETER_LIST');
if (count($parameter_list->getChildren()) !== 2) {
// Wrong number of parameters, but raise that elsewhere if we want.
continue;
}
$first = $parameter_list->getChildByIndex(0); if (count($parameter_list->getChildren()) !== 2) {
$second = $parameter_list->getChildByIndex(1); // Wrong number of parameters, but raise that elsewhere if we want.
continue;
}
if ($first->getConcreteString() == $second->getConcreteString()) { $first = $parameter_list->getChildByIndex(0);
$this->raiseLintAtNode( $second = $parameter_list->getChildByIndex(1);
$call,
self::LINT_ARRAY_COMBINE, if ($first->getConcreteString() == $second->getConcreteString()) {
pht( $this->raiseLintAtNode(
'Prior to PHP 5.4, `%s` fails when given empty arrays. '. $call,
'Prefer to write `%s` as `%s`.', self::LINT_ARRAY_COMBINE,
'array_combine()', pht(
'array_combine(x, x)', 'Prior to PHP 5.4, `%s` fails when given empty arrays. '.
'array_fuse(x)')); 'Prefer to write `%s` as `%s`.',
} 'array_combine()',
'array_combine(x, x)',
'array_fuse(x)'));
} }
} }
} }
private function lintDeprecatedFunctions(XHPASTNode $root) { private function lintDeprecatedFunctions(XHPASTNode $root) {
$map = $this->deprecatedFunctions; $map = $this->deprecatedFunctions;
$function_calls = $this->getFunctionCalls($root, array_keys($map));
$function_calls = $root->selectDescendantsOfType('n_FUNCTION_CALL');
foreach ($function_calls as $call) { foreach ($function_calls as $call) {
$name = $call->getChildByIndex(0)->getConcreteString(); $name = $call
->getChildByIndex(0)
->getConcreteString();
$name = strtolower($name); $name = strtolower($name);
if (empty($map[$name])) { if (empty($map[$name])) {

View file

@ -4298,31 +4298,4 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
} }
/**
* Retrieve all calls to some specified function(s).
*
* Returns all descendant nodes which represent a function call to one of the
* specified functions.
*
* @param XHPASTNode Root node.
* @param list<string> Function names.
* @return AASTNodeList
*/
protected function getFunctionCalls(XHPASTNode $root, array $function_names) {
$calls = $root->selectDescendantsOfType('n_FUNCTION_CALL');
$nodes = array();
foreach ($calls as $call) {
$node = $call->getChildByIndex(0);
$name = strtolower($node->getConcreteString());
if (in_array($name, $function_names)) {
$nodes[] = $call;
}
}
return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes);
}
} }