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', | ||||
| ); | ); | ||||
| } | } | ||||
| } | } | ||||