Changeset View
Changeset View
Standalone View
Standalone View
src/lint/linter/ArcanistXHPASTLinter.php
<?php | <?php | ||||
/** | /** | ||||
* Uses XHPAST to apply lint rules to PHP. | * Uses XHPAST to apply lint rules to PHP. | ||||
* | |||||
* @group linter | |||||
*/ | */ | ||||
final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { | final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { | ||||
private $futures = array(); | |||||
private $trees = array(); | |||||
const LINT_PHP_SYNTAX_ERROR = 1; | const LINT_PHP_SYNTAX_ERROR = 1; | ||||
const LINT_UNABLE_TO_PARSE = 2; | const LINT_UNABLE_TO_PARSE = 2; | ||||
const LINT_VARIABLE_VARIABLE = 3; | const LINT_VARIABLE_VARIABLE = 3; | ||||
const LINT_EXTRACT_USE = 4; | const LINT_EXTRACT_USE = 4; | ||||
const LINT_UNDECLARED_VARIABLE = 5; | const LINT_UNDECLARED_VARIABLE = 5; | ||||
const LINT_PHP_SHORT_TAG = 6; | const LINT_PHP_SHORT_TAG = 6; | ||||
const LINT_PHP_ECHO_TAG = 7; | const LINT_PHP_ECHO_TAG = 7; | ||||
const LINT_PHP_CLOSE_TAG = 8; | const LINT_PHP_CLOSE_TAG = 8; | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | return array( | ||||
// This is disabled by default because projects don't necessarily target | // This is disabled by default because projects don't necessarily target | ||||
// a specific minimum version. | // a specific minimum version. | ||||
self::LINT_PHP_53_FEATURES => $disabled, | self::LINT_PHP_53_FEATURES => $disabled, | ||||
self::LINT_PHP_54_FEATURES => $disabled, | self::LINT_PHP_54_FEATURES => $disabled, | ||||
); | ); | ||||
} | } | ||||
protected function buildFutures(array $paths) { | |||||
foreach ($paths as $path) { | |||||
if (!isset($this->futures[$path])) { | |||||
$this->futures[$path] = xhpast_get_parser_future($this->getData($path)); | |||||
} | |||||
} | |||||
return array_select_keys($this->futures, $paths); | |||||
} | |||||
public function getXHPASTTreeForPath($path) { | |||||
if (!array_key_exists($path, $this->trees)) { | |||||
$this->trees[$path] = null; | |||||
try { | |||||
$this->trees[$path] = XHPASTTree::newFromDataAndResolvedExecFuture( | |||||
$this->getData($path), | |||||
$this->futures[$path]->resolve()); | |||||
$root = $this->trees[$path]->getRootNode(); | |||||
$root->buildSelectCache(); | |||||
$root->buildTokenCache(); | |||||
} catch (XHPASTSyntaxErrorException $ex) { | |||||
$this->raiseLintAtLine( | |||||
$ex->getErrorLine(), | |||||
1, | |||||
self::LINT_PHP_SYNTAX_ERROR, | |||||
'This file contains a syntax error: '.$ex->getMessage()); | |||||
} catch (Exception $ex) { | |||||
$this->raiseLintAtPath(self::LINT_UNABLE_TO_PARSE, $ex->getMessage()); | |||||
} | |||||
} | |||||
return $this->trees[$path]; | |||||
} | |||||
public function getCacheVersion() { | public function getCacheVersion() { | ||||
$version = '4'; | $version = '4'; | ||||
$path = xhpast_get_binary_path(); | $path = xhpast_get_binary_path(); | ||||
if (Filesystem::pathExists($path)) { | if (Filesystem::pathExists($path)) { | ||||
$version .= '-'.md5_file($path); | $version .= '-'.md5_file($path); | ||||
} | } | ||||
return $version; | return $version; | ||||
} | } | ||||
protected function resolveFuture($path, Future $future) { | protected function resolveFuture($path, Future $future) { | ||||
$tree = $this->getXHPASTTreeForPath($path); | $tree = $this->getXHPASTTreeForPath($path); | ||||
if (!$tree) { | if (!$tree) { | ||||
$ex = $this->getXHPASTExceptionForPath($path); | |||||
if ($ex instanceof XHPASTSyntaxErrorException) { | |||||
$this->raiseLintAtLine( | |||||
$ex->getErrorLine(), | |||||
1, | |||||
self::LINT_PHP_SYNTAX_ERROR, | |||||
'This file contains a syntax error: '.$ex->getMessage()); | |||||
} else if ($ex instanceof Exception) { | |||||
$this->raiseLintAtPath(self::LINT_UNABLE_TO_PARSE, $ex->getMessage()); | |||||
} | |||||
return; | return; | ||||
} | } | ||||
$root = $tree->getRootNode(); | $root = $tree->getRootNode(); | ||||
$method_codes = array( | $method_codes = array( | ||||
'lintStrstrUsedForCheck' => self::LINT_SLOWNESS, | 'lintStrstrUsedForCheck' => self::LINT_SLOWNESS, | ||||
'lintStrposUsedForStart' => self::LINT_SLOWNESS, | 'lintStrposUsedForStart' => self::LINT_SLOWNESS, | ||||
▲ Show 20 Lines • Show All 2,163 Lines • Show Last 20 Lines |