1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 14:52:40 +01:00

Minor tidying of ArcanistConduitLinter

Summary: Self-explanatory.

Test Plan: Eyeball it.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin, epriestley

Differential Revision: https://secure.phabricator.com/D11344
This commit is contained in:
Joshua Spence 2015-01-13 06:36:19 +11:00
parent 3152db6cce
commit 25f4563fc8

View file

@ -2,34 +2,31 @@
/** /**
* Implements linting via Conduit RPC call. * Implements linting via Conduit RPC call.
* Slow by definition, but allows sophisticated linting that relies on
* stuff like big indexes of a codebase.
* Recommended usage is to gate these to the advice lint level.
* *
* The conduit endpoint should implement a method named the same as * This linter is slow by definition, but allows sophisticated linting that
* the value of ArcanistConduitLinter::CONDUIT_METHOD. * relies on stuff like big indexes of a codebase. Recommended usage is to gate
* these to the advice lint level.
* *
* It takes an array with a key 'file_contents' which is an array mapping * The conduit endpoint should implement a method named the same as the value
* file paths to their complete contents. * of `ArcanistConduitLinter::CONDUIT_METHOD`. It takes an array with a key
* `file_contents` which is an array mapping file paths to their complete
* contents. It should return an array mapping those same paths to arrays
* describing the lint for each path.
* *
* It should return an array mapping those same paths to arrays describing the * The lint for a path is described as a list of structured dictionaries. The
* lint for each path. * dictionary structure is effectively defined by
* * `ArcanistLintMessage::newFromDictionary`.
* The lint for a path is described as a list of structured dictionaries.
*
* The dictionary structure is effectively defined by
* ArcanistLintMessage::newFromDictionary.
* *
* Effective keys are: * Effective keys are:
* 'path' => must match passed in path. * - `path`: must match passed in path.
* 'line' * - `line`
* 'char' * - `char`
* 'code' * - `code`
* 'severity' => Must match a constant in ArcanistLintSeverity. * - `severity`: must match a constant in @{class:ArcanistLintSeverity}.
* 'name' * - `name`
* 'description' * - `description`
* 'original' & 'replacement' => optional patch information * - `original` & `replacement`: optional patch information.
* 'locations' => other locations of the same error (in the same format) * - `locations`: other locations of the same error (in the same format).
* *
* This class is intended for customization via instantiation, not via * This class is intended for customization via instantiation, not via
* subclassing. * subclassing.
@ -39,63 +36,63 @@ final class ArcanistConduitLinter extends ArcanistLinter {
private $conduitURI; private $conduitURI;
private $linterName; private $linterName;
private $lintByPath; // array(/pa/th/ => <lint>), valid after willLintPaths(). private $results;
public function __construct($conduit_uri = null, $linter_name = null) { public function __construct($conduit_uri = null, $linter_name = null) {
// TODO: Facebook uses this (probably?) but we need to be able to // TODO: Facebook uses this (probably?) but we need to be able to
// construct it without arguments for ".arclint". // construct it without arguments for ".arclint".
$this->conduitURI = $conduit_uri; $this->conduitURI = $conduit_uri;
$this->linterName = $linter_name; $this->linterName = $linter_name;
} }
public function willLintPaths(array $paths) {
// Load all file path data into $this->data.
array_map(array($this, 'getData'), $paths);
$conduit = new ConduitClient($this->conduitURI);
$this->lintByPath = $conduit->callMethodSynchronous(
self::CONDUIT_METHOD,
array(
'file_contents' => $this->data,
));
}
public function lintPath($path) {
$lint_for_path = idx($this->lintByPath, $path);
if (!$lint_for_path) {
return;
}
foreach ($lint_for_path as $lint) {
$this->addLintMessage(ArcanistLintMessage::newFromDictionary($lint));
}
}
public function getLinterName() { public function getLinterName() {
return $this->linterName; return $this->linterName;
} }
public function getLintNameMap() {
// See @{method:getLintSeverityMap} for rationale.
throw new ArcanistUsageException(
pht('%s does not support a name map.', __CLASS__));
}
public function getLintSeverityMap() { public function getLintSeverityMap() {
// The rationale here is that this class will only be used for custom // The rationale here is that this class will only be used for custom
// linting in installations. No two server endpoints will be the same across // linting in installations. No two server endpoints will be the same across
// different instantiations. Therefore, the server can handle all severity // different instantiations. Therefore, the server can handle all severity
// customization directly. // customization directly.
throw new ArcanistUsageException( throw new ArcanistUsageException(
'ArcanistConduitLinter does not support client-side severity '. pht(
'customization.'); '%s does not support client-side severity customization.',
} __CLASS__));
public function getLintNameMap() {
// See getLintSeverityMap for rationale.
throw new ArcanistUsageException(
'ArcanistConduitLinter does not support a name map.');
} }
protected function canCustomizeLintSeverities() { protected function canCustomizeLintSeverities() {
return false; return false;
} }
public function willLintPaths(array $paths) {
// Load all file path data into $this->data.
array_map(array($this, 'getData'), $paths);
$conduit = new ConduitClient($this->conduitURI);
$this->results = $conduit->callMethodSynchronous(
self::CONDUIT_METHOD,
array(
'file_contents' => $this->data,
));
}
public function lintPath($path) {
$lints = idx($this->results, $path);
if (!$lints) {
return;
}
foreach ($lints as $lint) {
$this->addLintMessage(ArcanistLintMessage::newFromDictionary($lint));
}
}
} }