Changeset View
Changeset View
Standalone View
Standalone View
src/lint/linter/ArcanistPhutilXHPASTLinter.php
<?php | <?php | ||||
/** | |||||
* @group linter | |||||
*/ | |||||
final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter { | final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter { | ||||
const LINT_ARRAY_COMBINE = 2; | const LINT_ARRAY_COMBINE = 2; | ||||
const LINT_DEPRECATED_FUNCTION = 3; | const LINT_DEPRECATED_FUNCTION = 3; | ||||
const LINT_UNSAFE_DYNAMIC_STRING = 4; | const LINT_UNSAFE_DYNAMIC_STRING = 4; | ||||
private $xhpastLinter; | |||||
private $deprecatedFunctions = array(); | private $deprecatedFunctions = array(); | ||||
private $dynamicStringFunctions = array(); | private $dynamicStringFunctions = array(); | ||||
private $dynamicStringClasses = array(); | private $dynamicStringClasses = array(); | ||||
public function setXHPASTLinter(ArcanistXHPASTLinter $linter) { | public function getLinterPriority() { | ||||
$this->xhpastLinter = $linter; | // Make sure this runs after XHPASTLinter so we can reuse the parse tree | ||||
return $this; | // if it's available. | ||||
return 2.0; | |||||
} | } | ||||
joshuaspence: It would almost be nice if this method was static, in which case we could do `2 *… | |||||
epriestleyAuthorUnsubmitted Not Done Inline ActionsWe can't make this static until late static binding, introduced in PHP 5.3.0. epriestley: We can't make this static until late static binding, introduced in PHP 5.3.0. | |||||
public function setDeprecatedFunctions($map) { | public function setDeprecatedFunctions($map) { | ||||
$this->deprecatedFunctions = $map; | $this->deprecatedFunctions = $map; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function setDynamicStringFunctions($map) { | public function setDynamicStringFunctions($map) { | ||||
$this->dynamicStringFunctions = $map; | $this->dynamicStringFunctions = $map; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function setDynamicStringClasses($map) { | public function setDynamicStringClasses($map) { | ||||
$this->dynamicStringClasses = $map; | $this->dynamicStringClasses = $map; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function setEngine(ArcanistLintEngine $engine) { | |||||
if (!$this->xhpastLinter) { | |||||
throw new Exception( | |||||
'Call setXHPASTLinter() before using ArcanistPhutilXHPASTLinter.'); | |||||
} | |||||
$this->xhpastLinter->setEngine($engine); | |||||
return parent::setEngine($engine); | |||||
} | |||||
public function getLintNameMap() { | public function getLintNameMap() { | ||||
return array( | return array( | ||||
self::LINT_ARRAY_COMBINE => 'array_combine() Unreliable', | self::LINT_ARRAY_COMBINE => 'array_combine() Unreliable', | ||||
self::LINT_DEPRECATED_FUNCTION => 'Use of Deprecated Function', | self::LINT_DEPRECATED_FUNCTION => 'Use of Deprecated Function', | ||||
self::LINT_UNSAFE_DYNAMIC_STRING => 'Unsafe Usage of Dynamic String', | self::LINT_UNSAFE_DYNAMIC_STRING => 'Unsafe Usage of Dynamic String', | ||||
); | ); | ||||
} | } | ||||
Show All 14 Lines | public function getCacheVersion() { | ||||
$version = '2'; | $version = '2'; | ||||
$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; | ||||
} | } | ||||
private function getXHPASTLinter() { | |||||
// If possible, reuse the parse tree generated by an existing vanilla | |||||
// XHPASTLinter. Otherwise, provide one as a shared resource. | |||||
$engine = $this->getEngine(); | |||||
$linter = $engine->getLinterResource('xhpast.linter'); | |||||
joshuaspenceUnsubmitted Not Done Inline ActionsMaybe check that $linter is an instance of ArcanistXHPASTLinter? Just in case... joshuaspence: Maybe check that `$linter` is an instance of `ArcanistXHPASTLinter`? Just in case... | |||||
if (!$linter) { | |||||
$linter = new ArcanistXHPASTLinter(); | |||||
$linter->setEngine($engine); | |||||
$engine->setLinterResource('xhpast.linter', $linter); | |||||
} | |||||
return $linter; | |||||
} | |||||
protected function buildFutures(array $paths) { | protected function buildFutures(array $paths) { | ||||
return $this->xhpastLinter->buildFutures($paths); | return $this->getXHPASTLinter()->buildFutures($paths); | ||||
} | } | ||||
public function willLintPath($path) { | public function willLintPath($path) { | ||||
$this->xhpastLinter->willLintPath($path); | $this->getXHPASTLinter()->willLintPath($path); | ||||
return parent::willLintPath($path); | return parent::willLintPath($path); | ||||
} | } | ||||
protected function resolveFuture($path, Future $future) { | protected function resolveFuture($path, Future $future) { | ||||
$tree = $this->xhpastLinter->getXHPASTTreeForPath($path); | $tree = $this->getXHPASTLinter()->getXHPASTTreeForPath($path); | ||||
if (!$tree) { | if (!$tree) { | ||||
return; | return; | ||||
} | } | ||||
$root = $tree->getRootNode(); | $root = $tree->getRootNode(); | ||||
$method_codes = array( | $method_codes = array( | ||||
'lintArrayCombine' => self::LINT_ARRAY_COMBINE, | 'lintArrayCombine' => self::LINT_ARRAY_COMBINE, | ||||
▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines |
It would almost be nice if this method was static, in which case we could do 2 * ArcanistXHPASTLinter::getLinterPriority().
Maybe (just in case) we should add a unit test which checks that ArcanistPhutilXHPASTLinter has a larger (numerically) priority than ArcanistXHPASTLinter.