Page MenuHomePhabricator

D9059.id21509.diff
No OneTemporary

D9059.id21509.diff

diff --git a/src/lint/engine/ArcanistLintEngine.php b/src/lint/engine/ArcanistLintEngine.php
--- a/src/lint/engine/ArcanistLintEngine.php
+++ b/src/lint/engine/ArcanistLintEngine.php
@@ -65,6 +65,8 @@
private $postponedLinters = array();
private $configurationManager;
+ private $linterResources = array();
+
public function __construct() {
}
@@ -548,4 +550,38 @@
}
+ /**
+ * Get a named linter resource shared by another linter.
+ *
+ * This mechanism allows linters to share arbitrary resources, like the
+ * results of computation. If several linters need to perform the same
+ * expensive computation step, they can use a named resource to synchronize
+ * construction of the result so it doesn't need to be built multiple
+ * times.
+ *
+ * @param string Resource identifier.
+ * @param wild Optionally, default value to return if resource does not
+ * exist.
+ * @return wild Resource, or default value if not present.
+ */
+ public function getLinterResource($key, $default = null) {
+ return idx($this->linterResources, $key, $default);
+ }
+
+
+ /**
+ * Set a linter resource that other linters can accesss.
+ *
+ * See @{method:getLinterResource} for a description of this mechanism.
+ *
+ * @param string Resource identifier.
+ * @param wild Resource.
+ * @return this
+ */
+ public function setLinterResource($key, $value) {
+ $this->linterResources[$key] = $value;
+ return $this;
+ }
+
+
}
diff --git a/src/lint/engine/PhutilLintEngine.php b/src/lint/engine/PhutilLintEngine.php
--- a/src/lint/engine/PhutilLintEngine.php
+++ b/src/lint/engine/PhutilLintEngine.php
@@ -58,7 +58,6 @@
$linters[] = $xhpast_linter;
$linters[] = id(new ArcanistPhutilXHPASTLinter())
- ->setXHPASTLinter($xhpast_linter)
->setPaths($php_paths);
$merge_conflict_linter = id(new ArcanistMergeConflictLinter());
diff --git a/src/lint/linter/ArcanistBaseXHPASTLinter.php b/src/lint/linter/ArcanistBaseXHPASTLinter.php
--- a/src/lint/linter/ArcanistBaseXHPASTLinter.php
+++ b/src/lint/linter/ArcanistBaseXHPASTLinter.php
@@ -1,8 +1,5 @@
<?php
-/**
- * @group linter
- */
abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
protected final function raiseLintAtToken(
diff --git a/src/lint/linter/ArcanistPhutilXHPASTLinter.php b/src/lint/linter/ArcanistPhutilXHPASTLinter.php
--- a/src/lint/linter/ArcanistPhutilXHPASTLinter.php
+++ b/src/lint/linter/ArcanistPhutilXHPASTLinter.php
@@ -1,22 +1,19 @@
<?php
-/**
- * @group linter
- */
final class ArcanistPhutilXHPASTLinter extends ArcanistBaseXHPASTLinter {
const LINT_ARRAY_COMBINE = 2;
const LINT_DEPRECATED_FUNCTION = 3;
const LINT_UNSAFE_DYNAMIC_STRING = 4;
- private $xhpastLinter;
private $deprecatedFunctions = array();
private $dynamicStringFunctions = array();
private $dynamicStringClasses = array();
- public function setXHPASTLinter(ArcanistXHPASTLinter $linter) {
- $this->xhpastLinter = $linter;
- return $this;
+ public function getLinterPriority() {
+ // Make sure this runs after XHPASTLinter so we can reuse the parse tree
+ // if it's available.
+ return 2.0;
}
public function setDeprecatedFunctions($map) {
@@ -34,15 +31,6 @@
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() {
return array(
self::LINT_ARRAY_COMBINE => 'array_combine() Unreliable',
@@ -73,17 +61,30 @@
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');
+ if (!$linter) {
+ $linter = new ArcanistXHPASTLinter();
+ $linter->setEngine($engine);
+ $engine->setLinterResource('xhpast.linter', $linter);
+ }
+ return $linter;
+ }
+
protected function buildFutures(array $paths) {
- return $this->xhpastLinter->buildFutures($paths);
+ return $this->getXHPASTLinter()->buildFutures($paths);
}
public function willLintPath($path) {
- $this->xhpastLinter->willLintPath($path);
+ $this->getXHPASTLinter()->willLintPath($path);
return parent::willLintPath($path);
}
protected function resolveFuture($path, Future $future) {
- $tree = $this->xhpastLinter->getXHPASTTreeForPath($path);
+ $tree = $this->getXHPASTLinter()->getXHPASTTreeForPath($path);
if (!$tree) {
return;
}
diff --git a/src/lint/linter/ArcanistXHPASTLinter.php b/src/lint/linter/ArcanistXHPASTLinter.php
--- a/src/lint/linter/ArcanistXHPASTLinter.php
+++ b/src/lint/linter/ArcanistXHPASTLinter.php
@@ -92,6 +92,18 @@
);
}
+ public function willLintPaths(array $paths) {
+ // If nothing has shared an XHPASTLinter yet, provide this linter as a
+ // shared resource. Other linters which rely on the parse tree will be
+ // able to reuse the one this linter generates.
+ $engine = $this->getEngine();
+ if (!$engine->getLinterResource('xhpast.linter')) {
+ $engine->setLinterResource('xhpast.linter', $this);
+ }
+
+ return parent::willLintPaths($paths);
+ }
+
public function getLinterName() {
return 'XHP';
}
diff --git a/src/lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php b/src/lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php
--- a/src/lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php
+++ b/src/lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php
@@ -8,7 +8,6 @@
public function testPhutilXHPASTLint() {
$linter = new ArcanistPhutilXHPASTLinter();
- $linter->setXHPASTLinter(new ArcanistXHPASTLinter());
$linter->setDeprecatedFunctions(array(
'deprecated_function' => 'This function is most likely deprecated.',
));

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 22, 4:22 PM (2 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7717220
Default Alt Text
D9059.id21509.diff (6 KB)

Event Timeline