Changeset View
Changeset View
Standalone View
Standalone View
src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
Show First 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | abstract class ArcanistXHPASTLinterRule extends Phobject { | ||||
abstract public function process(XHPASTNode $root); | abstract public function process(XHPASTNode $root); | ||||
final public function setLinter(ArcanistXHPASTLinter $linter) { | final public function setLinter(ArcanistXHPASTLinter $linter) { | ||||
$this->linter = $linter; | $this->linter = $linter; | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | |||||
* Statically evaluate a boolean value from an XHP tree. | |||||
* | |||||
* TODO: Improve this and move it to XHPAST proper? | |||||
* | |||||
* @param string The "semantic string" of a single value. | |||||
* @return mixed `true` or `false` if the value could be evaluated | |||||
* statically; `null` if static evaluation was not possible. | |||||
*/ | |||||
protected function evaluateStaticBoolean($string) { | |||||
switch (strtolower($string)) { | |||||
case '0': | |||||
case 'null': | |||||
case 'false': | |||||
return false; | |||||
case '1': | |||||
case 'true': | |||||
return true; | |||||
} | |||||
return null; | |||||
} | |||||
protected function getConcreteVariableString(XHPASTNode $var) { | /* -( Proxied Methods )---------------------------------------------------- */ | ||||
$concrete = $var->getConcreteString(); | |||||
// Strip off curly braces as in `$obj->{$property}`. | |||||
$concrete = trim($concrete, '{}'); | |||||
return $concrete; | |||||
} | |||||
// These methods are proxied to the @{class:ArcanistLinter}. | |||||
final public function getActivePath() { | final public function getActivePath() { | ||||
return $this->linter->getActivePath(); | return $this->linter->getActivePath(); | ||||
} | } | ||||
final public function getOtherLocation($offset, $path = null) { | final public function getOtherLocation($offset, $path = null) { | ||||
return $this->linter->getOtherLocation($offset, $path); | return $this->linter->getOtherLocation($offset, $path); | ||||
} | } | ||||
final protected function raiseLintAtNode( | final protected function raiseLintAtPath($desc) { | ||||
XHPASTNode $node, | return $this->linter->raiseLintAtPath($this->getLintID(), $desc); | ||||
$desc, | |||||
$replace = null) { | |||||
return $this->linter->raiseLintAtNode( | |||||
$node, | |||||
$this->getLintID(), | |||||
$desc, | |||||
$replace); | |||||
} | } | ||||
final public function raiseLintAtOffset( | final public function raiseLintAtOffset( | ||||
$offset, | $offset, | ||||
$desc, | $description, | ||||
$text = null, | $original = null, | ||||
$replace = null) { | $replacement = null) { | ||||
return $this->linter->raiseLintAtOffset( | $this->linter->raiseLintAtOffset( | ||||
$offset, | $offset, | ||||
$this->getLintID(), | $this->getLintID(), | ||||
$desc, | $description, | ||||
$text, | $original, | ||||
$replace); | $replacement); | ||||
} | |||||
final protected function raiseLintAtPath($desc) { | |||||
return $this->linter->raiseLintAtPath($this->getLintID(), $desc); | |||||
} | } | ||||
final protected function raiseLintAtToken( | final protected function raiseLintAtToken( | ||||
XHPASTToken $token, | XHPASTToken $token, | ||||
$desc, | $description, | ||||
$replace = null) { | $replace = null) { | ||||
return $this->linter->raiseLintAtToken( | return $this->linter->raiseLintAtToken( | ||||
$token, | $token, | ||||
$this->getLintID(), | $this->getLintID(), | ||||
$desc, | $description, | ||||
$replace); | |||||
} | |||||
final protected function raiseLintAtNode( | |||||
XHPASTNode $node, | |||||
$description, | |||||
$replace = null) { | |||||
return $this->linter->raiseLintAtNode( | |||||
$node, | |||||
$this->getLintID(), | |||||
$description, | |||||
$replace); | $replace); | ||||
} | } | ||||
/* -( Utility )------------------------------------------------------------ */ | /* -( Utility )------------------------------------------------------------ */ | ||||
/** | |||||
* Statically evaluate a boolean value from an XHP tree. | |||||
* | |||||
* TODO: Improve this and move it to XHPAST proper? | |||||
* | |||||
* @param string The "semantic string" of a single value. | |||||
* @return mixed `true` or `false` if the value could be evaluated | |||||
* statically; `null` if static evaluation was not possible. | |||||
*/ | |||||
protected function evaluateStaticBoolean($string) { | |||||
switch (strtolower($string)) { | |||||
case '0': | |||||
case 'null': | |||||
case 'false': | |||||
return false; | |||||
case '1': | |||||
case 'true': | |||||
return true; | |||||
default: | |||||
return null; | |||||
} | |||||
} | |||||
/** | /** | ||||
* Retrieve all anonymous closure(s). | * Retrieve all anonymous closure(s). | ||||
* | * | ||||
* Returns all descendant nodes which represent an anonymous function | * Returns all descendant nodes which represent an anonymous function | ||||
* declaration. | * declaration. | ||||
* | * | ||||
* @param XHPASTNode Root node. | * @param XHPASTNode Root node. | ||||
* @return AASTNodeList | * @return AASTNodeList | ||||
*/ | */ | ||||
protected function getAnonymousClosures(XHPASTNode $root) { | protected function getAnonymousClosures(XHPASTNode $root) { | ||||
$func_decls = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION'); | $func_decls = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION'); | ||||
$nodes = array(); | $nodes = array(); | ||||
foreach ($func_decls as $func_decl) { | foreach ($func_decls as $func_decl) { | ||||
if ($func_decl->getChildByIndex(2)->getTypeName() == 'n_EMPTY') { | if ($func_decl->getChildByIndex(2)->getTypeName() == 'n_EMPTY') { | ||||
$nodes[] = $func_decl; | $nodes[] = $func_decl; | ||||
} | } | ||||
} | } | ||||
return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes); | return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes); | ||||
} | } | ||||
/** | /** | ||||
* TODO | |||||
* | |||||
* @param XHPASTNode | |||||
* @return string | |||||
*/ | |||||
protected function getConcreteVariableString(XHPASTNode $variable) { | |||||
$concrete = $variable->getConcreteString(); | |||||
// Strip off curly braces as in `$obj->{$property}`. | |||||
$concrete = trim($concrete, '{}'); | |||||
return $concrete; | |||||
} | |||||
/** | |||||
* Retrieve all calls to some specified function(s). | * Retrieve all calls to some specified function(s). | ||||
* | * | ||||
* Returns all descendant nodes which represent a function call to one of the | * Returns all descendant nodes which represent a function call to one of the | ||||
* specified functions. | * specified functions. | ||||
* | * | ||||
* @param XHPASTNode Root node. | * @param XHPASTNode Root node. | ||||
* @param list<string> Function names. | * @param list<string> Function names. | ||||
* @return AASTNodeList | * @return AASTNodeList | ||||
Show All 9 Lines | foreach ($calls as $call) { | ||||
if (in_array($name, $function_names)) { | if (in_array($name, $function_names)) { | ||||
$nodes[] = $call; | $nodes[] = $call; | ||||
} | } | ||||
} | } | ||||
return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes); | return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes); | ||||
} | } | ||||
/** | |||||
* Get PHP superglobals. | |||||
* | |||||
* @return list<string> | |||||
*/ | |||||
public function getSuperGlobalNames() { | public function getSuperGlobalNames() { | ||||
return array( | return array( | ||||
'$GLOBALS', | '$GLOBALS', | ||||
'$_SERVER', | '$_SERVER', | ||||
'$_GET', | '$_GET', | ||||
'$_POST', | '$_POST', | ||||
'$_FILES', | '$_FILES', | ||||
'$_COOKIE', | '$_COOKIE', | ||||
'$_SESSION', | '$_SESSION', | ||||
'$_REQUEST', | '$_REQUEST', | ||||
'$_ENV', | '$_ENV', | ||||
); | ); | ||||
} | } | ||||
} | } |