Page MenuHomePhorge

ArcanistXHPASTLinterRule.php
No OneTemporary

ArcanistXHPASTLinterRule.php

<?php
abstract class ArcanistXHPASTLinterRule extends Phobject {
private $linter = null;
private $lintID = null;
protected $version;
protected $windowsVersion;
final public static function loadAllRules() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getLintID')
->execute();
}
final public function getLintID() {
if ($this->lintID === null) {
$class = new ReflectionClass($this);
$const = $class->getConstant('ID');
if ($const === false) {
throw new Exception(
pht(
'`%s` class `%s` must define an ID constant.',
__CLASS__,
get_class($this)));
}
if (!is_int($const)) {
throw new Exception(
pht(
'`%s` class `%s` has an invalid ID constant. '.
'ID must be an integer.',
__CLASS__,
get_class($this)));
}
$this->lintID = $const;
}
return $this->lintID;
}
abstract public function getLintName();
public function getLintSeverity() {
return ArcanistLintSeverity::SEVERITY_ERROR;
}
public function getLinterConfigurationOptions() {
return array(
'xhpast.php-version' => array(
'type' => 'optional string',
'help' => pht('PHP version to target.'),
),
'xhpast.php-version.windows' => array(
'type' => 'optional string',
'help' => pht('PHP version to target on Windows.'),
),
);
}
public function setLinterConfigurationValue($key, $value) {
switch ($key) {
case 'xhpast.php-version':
$this->version = $value;
return;
case 'xhpast.php-version.windows':
$this->windowsVersion = $value;
return;
}
}
abstract public function process(XHPASTNode $root);
final public function setLinter(ArcanistXHPASTLinter $linter) {
$this->linter = $linter;
return $this;
}
/* -( Proxied Methods )---------------------------------------------------- */
final public function getActivePath() {
return $this->linter->getActivePath();
}
final public function getOtherLocation($offset, $path = null) {
return $this->linter->getOtherLocation($offset, $path);
}
final protected function raiseLintAtPath($desc) {
return $this->linter->raiseLintAtPath($this->getLintID(), $desc);
}
final public function raiseLintAtOffset(
$offset,
$description,
$original = null,
$replacement = null) {
$this->linter->raiseLintAtOffset(
$offset,
$this->getLintID(),
$description,
$original,
$replacement);
}
final protected function raiseLintAtToken(
XHPASTToken $token,
$description,
$replace = null) {
return $this->linter->raiseLintAtToken(
$token,
$this->getLintID(),
$description,
$replace);
}
final protected function raiseLintAtNode(
XHPASTNode $node,
$description,
$replace = null) {
return $this->linter->raiseLintAtNode(
$node,
$this->getLintID(),
$description,
$replace);
}
/* -( 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).
*
* Returns all descendant nodes which represent an anonymous function
* declaration.
*
* @param XHPASTNode Root node.
* @return AASTNodeList
*/
protected function getAnonymousClosures(XHPASTNode $root) {
$func_decls = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION');
$nodes = array();
foreach ($func_decls as $func_decl) {
if ($func_decl->getChildByIndex(2)->getTypeName() == 'n_EMPTY') {
$nodes[] = $func_decl;
}
}
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).
*
* 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);
}
/**
* Get class/method modifiers.
*
* @param XHPASTNode A node of type `n_CLASS_DECLARATION` or
* `n_METHOD_DECLARATION`.
* @return map<string, bool> Class/method modifiers.
*/
final protected function getModifiers(XHPASTNode $node) {
$modifier_list = $node->getChildByIndex(0);
switch ($modifier_list->getTypeName()) {
case 'n_CLASS_ATTRIBUTES':
case 'n_CLASS_MEMBER_MODIFIER_LIST':
case 'n_METHOD_MODIFIER_LIST':
break;
default:
return array();
}
$modifiers = array();
foreach ($modifier_list->selectDescendantsOfType('n_STRING') as $modifier) {
$modifiers[strtolower($modifier->getConcreteString())] = true;
}
return $modifiers;
}
/**
* Get PHP superglobals.
*
* @return list<string>
*/
public function getSuperGlobalNames() {
return array(
'$GLOBALS',
'$_SERVER',
'$_GET',
'$_POST',
'$_FILES',
'$_COOKIE',
'$_SESSION',
'$_REQUEST',
'$_ENV',
);
}
}

File Metadata

Mime Type
text/x-php
Expires
Sun, Jan 19, 12:30 (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1116067
Default Alt Text
ArcanistXHPASTLinterRule.php (6 KB)

Event Timeline