1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 16:22:42 +01:00

Tidying up of linter code.

Summary: Various tidying up of linting code.

Test Plan: `arc lint` and `arc unit` still pass.

Reviewers: chad, epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: epriestley, Korvin

Differential Revision: https://secure.phabricator.com/D9625
This commit is contained in:
Joshua Spence 2014-06-20 18:26:44 +10:00
parent 212c41fbd0
commit 67b6bed92e
29 changed files with 127 additions and 215 deletions

View file

@ -55,7 +55,6 @@ abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
/* -( Sharing Parse Trees )------------------------------------------------ */ /* -( Sharing Parse Trees )------------------------------------------------ */
/** /**
* Get the linter object which is responsible for building parse trees. * Get the linter object which is responsible for building parse trees.
* *
@ -94,7 +93,6 @@ abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
return $linter; return $linter;
} }
/** /**
* Build futures on this linter, for use and to share with other linters. * Build futures on this linter, for use and to share with other linters.
* *
@ -111,7 +109,6 @@ abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
return array_select_keys($this->futures, $paths); return array_select_keys($this->futures, $paths);
} }
/** /**
* Get a path's tree from the responsible linter. * Get a path's tree from the responsible linter.
* *
@ -144,7 +141,6 @@ abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
return $this->trees[$path]; return $this->trees[$path];
} }
/** /**
* Get a path's parse exception from the responsible linter. * Get a path's parse exception from the responsible linter.
* *
@ -160,5 +156,4 @@ abstract class ArcanistBaseXHPASTLinter extends ArcanistFutureLinter {
return idx($this->exceptions, $path); return idx($this->exceptions, $path);
} }
} }

View file

@ -14,8 +14,7 @@ final class ArcanistCSSLintLinter extends ArcanistExternalLinter {
} }
public function getInfoDescription() { public function getInfoDescription() {
return pht( return pht('Use `csslint` to detect issues with CSS source files.');
'Use `csslint` to detect issues with CSS source files.');
} }
public function getLinterName() { public function getLinterName() {

View file

@ -129,8 +129,7 @@ final class ArcanistCSharpLinter extends ArcanistLinter {
$this->loaded = true; $this->loaded = true;
} }
public function lintPath($path) { public function lintPath($path) {}
}
public function willLintPaths(array $paths) { public function willLintPaths(array $paths) {
$this->loadEnvironment(); $this->loadEnvironment();

View file

@ -14,8 +14,7 @@ final class ArcanistClosureLinter extends ArcanistExternalLinter {
} }
public function getInfoDescription() { public function getInfoDescription() {
return pht( return pht("Uses Google's Closure Linter to check Javascript code.");
'Uses Google\'s Closure Linter to check Javascript code.');
} }
public function getLinterName() { public function getLinterName() {
@ -26,16 +25,13 @@ final class ArcanistClosureLinter extends ArcanistExternalLinter {
return 'gjslint'; return 'gjslint';
} }
protected function getDefaultMessageSeverity($code) {
return ArcanistLintSeverity::SEVERITY_ERROR;
}
public function getDefaultBinary() { public function getDefaultBinary() {
return 'gjslint'; return 'gjslint';
} }
public function getInstallInstructions() { public function getInstallInstructions() {
return pht('Install gJSLint using `sudo easy_install http://closure-linter'. return pht(
'Install gJSLint using `sudo easy_install http://closure-linter'.
'.googlecode.com/files/closure_linter-latest.tar.gz`'); '.googlecode.com/files/closure_linter-latest.tar.gz`');
} }
@ -53,7 +49,7 @@ final class ArcanistClosureLinter extends ArcanistExternalLinter {
$regex = '/^Line (\d+), (E:\d+): (.*)/'; $regex = '/^Line (\d+), (E:\d+): (.*)/';
$severity_code = ArcanistLintSeverity::SEVERITY_ERROR; $severity_code = ArcanistLintSeverity::SEVERITY_ERROR;
$lines = explode("\n", $stdout); $lines = phutil_split_lines($stdout, false);
$messages = array(); $messages = array();
foreach ($lines as $line) { foreach ($lines as $line) {
@ -79,4 +75,5 @@ final class ArcanistClosureLinter extends ArcanistExternalLinter {
return $messages; return $messages;
} }
} }

View file

@ -17,7 +17,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
/* -( Interpreters, Binaries and Flags )----------------------------------- */ /* -( Interpreters, Binaries and Flags )----------------------------------- */
/** /**
* Return the default binary name or binary path where the external linter * Return the default binary name or binary path where the external linter
* lives. This can either be a binary name which is expected to be installed * lives. This can either be a binary name which is expected to be installed
@ -33,7 +32,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
*/ */
abstract public function getDefaultBinary(); abstract public function getDefaultBinary();
/** /**
* Return a human-readable string describing how to install the linter. This * Return a human-readable string describing how to install the linter. This
* is normally something like "Install such-and-such by running `npm install * is normally something like "Install such-and-such by running `npm install
@ -44,7 +42,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
*/ */
abstract public function getInstallInstructions(); abstract public function getInstallInstructions();
/** /**
* Return true to continue when the external linter exits with an error code. * Return true to continue when the external linter exits with an error code.
* By default, linters which exit with an error code are assumed to have * By default, linters which exit with an error code are assumed to have
@ -62,7 +59,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return false; return false;
} }
/** /**
* Return true to indicate that the external linter can read input from * Return true to indicate that the external linter can read input from
* stdin, rather than requiring a file. If this mode is supported, it is * stdin, rather than requiring a file. If this mode is supported, it is
@ -93,7 +89,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return false; return false;
} }
/** /**
* If the linter can read data over stdin, override * If the linter can read data over stdin, override
* @{method:supportsReadDataFromStdin} and then optionally override this * @{method:supportsReadDataFromStdin} and then optionally override this
@ -108,7 +103,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return null; return null;
} }
/** /**
* Provide mandatory, non-overridable flags to the linter. Generally these * Provide mandatory, non-overridable flags to the linter. Generally these
* are format flags, like `--format=xml`, which must always be given for * are format flags, like `--format=xml`, which must always be given for
@ -124,7 +118,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return array(); return array();
} }
/** /**
* Provide default, overridable flags to the linter. Generally these are * Provide default, overridable flags to the linter. Generally these are
* configuration flags which affect behavior but aren't critical. Flags * configuration flags which affect behavior but aren't critical. Flags
@ -140,7 +133,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return array(); return array();
} }
/** /**
* Override default flags with custom flags. If not overridden, flags provided * Override default flags with custom flags. If not overridden, flags provided
* by @{method:getDefaultFlags} are used. * by @{method:getDefaultFlags} are used.
@ -154,7 +146,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return $this; return $this;
} }
/** /**
* Return the binary or script to execute. This method synthesizes defaults * Return the binary or script to execute. This method synthesizes defaults
* and configuration. You can override the binary with @{method:setBinary}. * and configuration. You can override the binary with @{method:setBinary}.
@ -166,7 +157,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return coalesce($this->bin, $this->getDefaultBinary()); return coalesce($this->bin, $this->getDefaultBinary());
} }
/** /**
* Override the default binary with a new one. * Override the default binary with a new one.
* *
@ -179,7 +169,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return $this; return $this;
} }
/** /**
* Return true if this linter should use an interpreter (like "python" or * Return true if this linter should use an interpreter (like "python" or
* "node") in addition to the script. * "node") in addition to the script.
@ -194,7 +183,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return false; return false;
} }
/** /**
* Return the default interpreter, like "python" or "node". This method is * Return the default interpreter, like "python" or "node". This method is
* only invoked if @{method:shouldUseInterpreter} has been overridden to * only invoked if @{method:shouldUseInterpreter} has been overridden to
@ -207,7 +195,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
throw new Exception('Incomplete implementation!'); throw new Exception('Incomplete implementation!');
} }
/** /**
* Get the effective interpreter. This method synthesizes configuration and * Get the effective interpreter. This method synthesizes configuration and
* defaults. * defaults.
@ -219,7 +206,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return coalesce($this->interpreter, $this->getDefaultInterpreter()); return coalesce($this->interpreter, $this->getDefaultInterpreter());
} }
/** /**
* Set the interpreter, overriding any default. * Set the interpreter, overriding any default.
* *
@ -235,7 +221,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
/* -( Parsing Linter Output )---------------------------------------------- */ /* -( Parsing Linter Output )---------------------------------------------- */
/** /**
* Parse the output of the external lint program into objects of class * Parse the output of the external lint program into objects of class
* @{class:ArcanistLintMessage} which `arc` can consume. Generally, this * @{class:ArcanistLintMessage} which `arc` can consume. Generally, this
@ -260,7 +245,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
/* -( Executing the Linter )----------------------------------------------- */ /* -( Executing the Linter )----------------------------------------------- */
/** /**
* Check that the binary and interpreter (if applicable) exist, and throw * Check that the binary and interpreter (if applicable) exist, and throw
* an exception with a message about how to install them if they do not. * an exception with a message about how to install them if they do not.
@ -315,7 +299,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
} }
} }
/** /**
* Get the composed executable command, including the interpreter and binary * Get the composed executable command, including the interpreter and binary
* but without flags or paths. This can be used to execute `--version` * but without flags or paths. This can be used to execute `--version`
@ -343,7 +326,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return $bin; return $bin;
} }
/** /**
* Get the composed flags for the executable, including both mandatory and * Get the composed flags for the executable, including both mandatory and
* configured flags. * configured flags.
@ -381,7 +363,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
} }
} }
/** /**
* Prepare the path to be added to the command string. * Prepare the path to be added to the command string.
* *
@ -533,7 +514,6 @@ abstract class ArcanistExternalLinter extends ArcanistFutureLinter {
return parent::setLinterConfigurationValue($key, $value); return parent::setLinterConfigurationValue($key, $value);
} }
/** /**
* Map a configuration lint code to an `arc` lint code. Primarily, this is * Map a configuration lint code to an `arc` lint code. Primarily, this is
* intended for validation, but can also be used to normalize case or * intended for validation, but can also be used to normalize case or

View file

@ -31,7 +31,7 @@ final class ArcanistFilenameLinter extends ArcanistLinter {
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
self::LINT_BAD_FILENAME => pht('Bad Filename'), self::LINT_BAD_FILENAME => pht('Bad Filename'),
); );
} }

View file

@ -71,7 +71,7 @@ final class ArcanistFlake8Linter extends ArcanistExternalLinter {
} }
protected function parseLinterOutput($path, $err, $stdout, $stderr) { protected function parseLinterOutput($path, $err, $stdout, $stderr) {
$lines = phutil_split_lines($stdout, $retain_endings = false); $lines = phutil_split_lines($stdout, false);
$messages = array(); $messages = array();
foreach ($lines as $line) { foreach ($lines as $line) {

View file

@ -17,8 +17,7 @@ final class ArcanistJSHintLinter extends ArcanistExternalLinter {
} }
public function getInfoDescription() { public function getInfoDescription() {
return pht( return pht('Use `jshint` to detect issues with Javascript source files.');
'Use `jshint` to detect issues with Javascript source files.');
} }
public function getLinterName() { public function getLinterName() {
@ -179,4 +178,5 @@ final class ArcanistJSHintLinter extends ArcanistExternalLinter {
return $code; return $code;
} }
} }

View file

@ -51,8 +51,7 @@ final class ArcanistLesscLinter extends ArcanistExternalLinter {
), ),
'lessc.strict-units' => array( 'lessc.strict-units' => array(
'type' => 'optional bool', 'type' => 'optional bool',
'help' => pht( 'help' => pht('Enable strict handling of units in expressions.'),
'Enable strict handling of units in expressions.'),
), ),
); );
} }
@ -195,4 +194,5 @@ final class ArcanistLesscLinter extends ArcanistExternalLinter {
return $messages; return $messages;
} }
} }

View file

@ -28,7 +28,6 @@ abstract class ArcanistLinter {
/* -( Human Readable Information )---------------------------------------- */ /* -( Human Readable Information )---------------------------------------- */
/** /**
* Return an optional informative URI where humans can learn more about this * Return an optional informative URI where humans can learn more about this
* linter. * linter.
@ -43,7 +42,6 @@ abstract class ArcanistLinter {
return null; return null;
} }
/** /**
* Return a brief human-readable description of the linter. * Return a brief human-readable description of the linter.
* *
@ -56,7 +54,6 @@ abstract class ArcanistLinter {
return null; return null;
} }
/** /**
* Return a human-readable linter name. * Return a human-readable linter name.
* *
@ -73,7 +70,6 @@ abstract class ArcanistLinter {
get_class($this)); get_class($this));
} }
public function getLinterPriority() { public function getLinterPriority() {
return 1.0; return 1.0;
} }
@ -264,10 +260,7 @@ abstract class ArcanistLinter {
return $this->addLintMessage($message); return $this->addLintMessage($message);
} }
final protected function raiseLintAtPath( final protected function raiseLintAtPath($code, $desc) {
$code,
$desc) {
return $this->raiseLintAtLine(null, null, $code, $desc, null, null); return $this->raiseLintAtLine(null, null, $code, $desc, null, null);
} }
@ -464,7 +457,6 @@ abstract class ArcanistLinter {
return $code; return $code;
} }
/** /**
* Retrieve an old lint configuration value from `.arcconfig` or a similar * Retrieve an old lint configuration value from `.arcconfig` or a similar
* source. * source.
@ -477,7 +469,6 @@ abstract class ArcanistLinter {
* @return wild Configured value, or default if no configuration exists. * @return wild Configured value, or default if no configuration exists.
*/ */
final protected function getDeprecatedConfiguration($key, $default = null) { final protected function getDeprecatedConfiguration($key, $default = null) {
// If we're being called in a context without an engine (probably from // If we're being called in a context without an engine (probably from
// `arc linters`), just return the default value. // `arc linters`), just return the default value.
if (!$this->engine) { if (!$this->engine) {

View file

@ -45,12 +45,6 @@ final class ArcanistMergeConflictLinter extends ArcanistLinter {
} }
} }
public function getLintSeverityMap() {
return array(
self::LINT_MERGECONFLICT => ArcanistLintSeverity::SEVERITY_ERROR,
);
}
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
self::LINT_MERGECONFLICT => pht('Unresolved merge conflict'), self::LINT_MERGECONFLICT => pht('Unresolved merge conflict'),

View file

@ -75,7 +75,7 @@ final class ArcanistPEP8Linter extends ArcanistExternalLinter {
} }
protected function parseLinterOutput($path, $err, $stdout, $stderr) { protected function parseLinterOutput($path, $err, $stdout, $stderr) {
$lines = phutil_split_lines($stdout, $retain_endings = false); $lines = phutil_split_lines($stdout, false);
$messages = array(); $messages = array();
foreach ($lines as $line) { foreach ($lines as $line) {

View file

@ -1,15 +1,7 @@
<?php <?php
/** /**
* Uses "PHP_CodeSniffer" to detect checkstyle errors in php code. * Uses "PHP_CodeSniffer" to detect checkstyle errors in PHP code.
* To use this linter, you must install PHP_CodeSniffer.
* http://pear.php.net/package/PHP_CodeSniffer.
*
* Optional configurations in .arcconfig:
*
* lint.phpcs.standard
* lint.phpcs.options
* lint.phpcs.bin
* *
* @group linter * @group linter
*/ */
@ -50,6 +42,7 @@ final class ArcanistPhpcsLinter extends ArcanistExternalLinter {
public function getDefaultFlags() { public function getDefaultFlags() {
$options = $this->getDeprecatedConfiguration('lint.phpcs.options', array()); $options = $this->getDeprecatedConfiguration('lint.phpcs.options', array());
$standard = $this->getDeprecatedConfiguration('lint.phpcs.standard'); $standard = $this->getDeprecatedConfiguration('lint.phpcs.standard');
if (!empty($standard)) { if (!empty($standard)) {
if (is_array($options)) { if (is_array($options)) {
$options[] = '--standard='.$standard; $options[] = '--standard='.$standard;

View file

@ -10,9 +10,9 @@
*/ */
final class ArcanistPhutilLibraryLinter extends ArcanistLinter { final class ArcanistPhutilLibraryLinter extends ArcanistLinter {
const LINT_UNKNOWN_SYMBOL = 1; const LINT_UNKNOWN_SYMBOL = 1;
const LINT_DUPLICATE_SYMBOL = 2; const LINT_DUPLICATE_SYMBOL = 2;
const LINT_ONE_CLASS_PER_FILE = 3; const LINT_ONE_CLASS_PER_FILE = 3;
public function getInfoName() { public function getInfoName() {
return 'Phutil Library Linter'; return 'Phutil Library Linter';
@ -30,9 +30,9 @@ final class ArcanistPhutilLibraryLinter extends ArcanistLinter {
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
self::LINT_UNKNOWN_SYMBOL => 'Unknown Symbol', self::LINT_UNKNOWN_SYMBOL => 'Unknown Symbol',
self::LINT_DUPLICATE_SYMBOL => 'Duplicate Symbol', self::LINT_DUPLICATE_SYMBOL => 'Duplicate Symbol',
self::LINT_ONE_CLASS_PER_FILE => 'One Class Per File', self::LINT_ONE_CLASS_PER_FILE => 'One Class Per File',
); );
} }
@ -58,7 +58,7 @@ final class ArcanistPhutilLibraryLinter extends ArcanistLinter {
// the working copy. // the working copy.
$arc_root = dirname(phutil_get_library_root('arcanist')); $arc_root = dirname(phutil_get_library_root('arcanist'));
$bin = "{$arc_root}/scripts/phutil_rebuild_map.php"; $bin = $arc_root.'/scripts/phutil_rebuild_map.php';
$symbols = array(); $symbols = array();
foreach ($libs as $lib) { foreach ($libs as $lib) {

View file

@ -54,7 +54,6 @@
final class ArcanistPyLintLinter extends ArcanistLinter { final class ArcanistPyLintLinter extends ArcanistLinter {
private function getMessageCodeSeverity($code) { private function getMessageCodeSeverity($code) {
$config = $this->getEngine()->getConfigurationManager(); $config = $this->getEngine()->getConfigurationManager();
$error_regexp = $error_regexp =
@ -148,9 +147,9 @@ final class ArcanistPyLintLinter extends ArcanistLinter {
if ($config_paths !== null) { if ($config_paths !== null) {
foreach ($config_paths as $config_path) { foreach ($config_paths as $config_path) {
if ($config_path !== null) { if ($config_path !== null) {
$python_path[] = $python_path[] = Filesystem::resolvePath(
Filesystem::resolvePath($config_path, $config_path,
$working_copy->getProjectRoot()); $working_copy->getProjectRoot());
} }
} }
} }
@ -181,8 +180,8 @@ final class ArcanistPyLintLinter extends ArcanistLinter {
$rcfile = $config->getConfigFromAnySource('lint.pylint.rcfile'); $rcfile = $config->getConfigFromAnySource('lint.pylint.rcfile');
if ($rcfile !== null) { if ($rcfile !== null) {
$rcfile = Filesystem::resolvePath( $rcfile = Filesystem::resolvePath(
$rcfile, $rcfile,
$working_copy->getProjectRoot()); $working_copy->getProjectRoot());
$options[] = csprintf('--rcfile=%s', $rcfile); $options[] = csprintf('--rcfile=%s', $rcfile);
} }
@ -200,16 +199,12 @@ final class ArcanistPyLintLinter extends ArcanistLinter {
} }
private function getLinterVersion() { private function getLinterVersion() {
$pylint_bin = $this->getPyLintPath(); $pylint_bin = $this->getPyLintPath();
$options = '--version'; $options = '--version';
list($stdout) = execx( list($stdout) = execx('%s %s', $pylint_bin, $options);
'%s %s',
$pylint_bin,
$options);
$lines = explode("\n", $stdout); $lines = phutil_split_lines($stdout, false);
$matches = null; $matches = null;
// If the version command didn't return anything or the regex didn't match // If the version command didn't return anything or the regex didn't match
@ -247,13 +242,12 @@ final class ArcanistPyLintLinter extends ArcanistLinter {
} }
} }
$lines = explode("\n", $stdout); $lines = phutil_split_lines($stdout, false);
$messages = array(); $messages = array();
foreach ($lines as $line) { foreach ($lines as $line) {
$matches = null; $matches = null;
if (!preg_match( $regex = '/([A-Z]\d+): *(\d+)(?:|,\d*): *(.*)$/';
'/([A-Z]\d+): *(\d+)(?:|,\d*): *(.*)$/', if (!preg_match($regex, $line, $matches)) {
$line, $matches)) {
continue; continue;
} }
foreach ($matches as $key => $match) { foreach ($matches as $key => $match) {

View file

@ -64,12 +64,8 @@ final class ArcanistRubyLinter extends ArcanistExternalLinter {
return array('-w', '-c'); return array('-w', '-c');
} }
protected function getDefaultMessageSeverity($code) {
return ArcanistLintSeverity::SEVERITY_ERROR;
}
protected function parseLinterOutput($path, $err, $stdout, $stderr) { protected function parseLinterOutput($path, $err, $stdout, $stderr) {
$lines = phutil_split_lines($stderr, $retain_endings = false); $lines = phutil_split_lines($stderr, false);
$messages = array(); $messages = array();
foreach ($lines as $line) { foreach ($lines as $line) {

View file

@ -159,7 +159,6 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
private $output = array(); private $output = array();
public function getInfoName() { public function getInfoName() {
return pht('Script and Regex'); return pht('Script and Regex');
} }
@ -196,7 +195,6 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
} }
} }
/** /**
* Run the regex on the output of the script. * Run the regex on the output of the script.
* *
@ -247,13 +245,13 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
list($line, $char) = $this->getMatchLineAndChar($match, $path); list($line, $char) = $this->getMatchLineAndChar($match, $path);
$dict = array( $dict = array(
'path' => idx($match, 'file', $path), 'path' => idx($match, 'file', $path),
'line' => $line, 'line' => $line,
'char' => $char, 'char' => $char,
'code' => idx($match, 'code', $this->getLinterName()), 'code' => idx($match, 'code', $this->getLinterName()),
'severity' => $this->getMatchSeverity($match), 'severity' => $this->getMatchSeverity($match),
'name' => idx($match, 'name', 'Lint'), 'name' => idx($match, 'name', 'Lint'),
'description' => idx($match, 'message', 'Undefined Lint Message'), 'description' => idx($match, 'message', 'Undefined Lint Message'),
); );
$original = idx($match, 'original'); $original = idx($match, 'original');
@ -274,7 +272,6 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
/* -( Linter Information )------------------------------------------------- */ /* -( Linter Information )------------------------------------------------- */
/** /**
* Return the short name of the linter. * Return the short name of the linter.
* *
@ -290,8 +287,8 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
return 'script-and-regex'; return 'script-and-regex';
} }
/* -( Parsing Output )----------------------------------------------------- */
/* -( Parsing Output )----------------------------------------------------- */
/** /**
* Get the line and character of the message from the regex match. * Get the line and character of the message from the regex match.
@ -315,7 +312,6 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
return array($line, $char); return array($line, $char);
} }
/** /**
* Map the regex matching groups to a message severity. We look for either * Map the regex matching groups to a message severity. We look for either
* a nonempty severity name group like 'error', or a group called 'severity' * a nonempty severity name group like 'error', or a group called 'severity'
@ -328,11 +324,11 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
*/ */
private function getMatchSeverity(array $match) { private function getMatchSeverity(array $match) {
$map = array( $map = array(
'error' => ArcanistLintSeverity::SEVERITY_ERROR, 'error' => ArcanistLintSeverity::SEVERITY_ERROR,
'warning' => ArcanistLintSeverity::SEVERITY_WARNING, 'warning' => ArcanistLintSeverity::SEVERITY_WARNING,
'autofix' => ArcanistLintSeverity::SEVERITY_AUTOFIX, 'autofix' => ArcanistLintSeverity::SEVERITY_AUTOFIX,
'advice' => ArcanistLintSeverity::SEVERITY_ADVICE, 'advice' => ArcanistLintSeverity::SEVERITY_ADVICE,
'disabled' => ArcanistLintSeverity::SEVERITY_DISABLED, 'disabled' => ArcanistLintSeverity::SEVERITY_DISABLED,
); );
$severity_name = strtolower(idx($match, 'severity')); $severity_name = strtolower(idx($match, 'severity'));
@ -340,8 +336,7 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
foreach ($map as $name => $severity) { foreach ($map as $name => $severity) {
if (!empty($match[$name])) { if (!empty($match[$name])) {
return $severity; return $severity;
} } else if ($severity_name == $name) {
if ($severity_name == $name) {
return $severity; return $severity;
} }
} }
@ -352,7 +347,6 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
/* -( Validating Configuration )------------------------------------------- */ /* -( Validating Configuration )------------------------------------------- */
/** /**
* Load, validate, and return the "script" configuration. * Load, validate, and return the "script" configuration.
* *
@ -379,7 +373,6 @@ final class ArcanistScriptAndRegexLinter extends ArcanistLinter {
return $config; return $config;
} }
/** /**
* Load, validate, and return the "regex" configuration. * Load, validate, and return the "regex" configuration.
* *

View file

@ -56,14 +56,14 @@ final class ArcanistSpellingLinter extends ArcanistLinter {
public function getLintSeverityMap() { public function getLintSeverityMap() {
return array( return array(
self::LINT_SPELLING_PICKY => ArcanistLintSeverity::SEVERITY_WARNING, self::LINT_SPELLING_PICKY => ArcanistLintSeverity::SEVERITY_WARNING,
self::LINT_SPELLING_IMPORTANT => ArcanistLintSeverity::SEVERITY_ERROR, self::LINT_SPELLING_IMPORTANT => ArcanistLintSeverity::SEVERITY_ERROR,
); );
} }
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
self::LINT_SPELLING_PICKY => pht('Possible Spelling Mistake'), self::LINT_SPELLING_PICKY => pht('Possible Spelling Mistake'),
self::LINT_SPELLING_IMPORTANT => pht('Possible Spelling Mistake'), self::LINT_SPELLING_IMPORTANT => pht('Possible Spelling Mistake'),
); );
} }
@ -105,7 +105,7 @@ final class ArcanistSpellingLinter extends ArcanistLinter {
$this->raiseLintAtOffset( $this->raiseLintAtOffset(
$next, $next,
$severity, $severity,
sprintf( pht(
"Possible spelling error. You wrote '%s', but did you mean '%s'?", "Possible spelling error. You wrote '%s', but did you mean '%s'?",
$word, $word,
$correct_word), $correct_word),
@ -132,7 +132,7 @@ final class ArcanistSpellingLinter extends ArcanistLinter {
$this->raiseLintAtOffset( $this->raiseLintAtOffset(
$match[1], $match[1],
$severity, $severity,
sprintf( pht(
"Possible spelling error. You wrote '%s', but did you mean '%s'?", "Possible spelling error. You wrote '%s', but did you mean '%s'?",
$word, $word,
$correct_word), $correct_word),
@ -144,14 +144,13 @@ final class ArcanistSpellingLinter extends ArcanistLinter {
public static function fixLetterCase($string, $case) { public static function fixLetterCase($string, $case) {
if ($case == strtolower($case)) { if ($case == strtolower($case)) {
return strtolower($string); return strtolower($string);
} } else if ($case == strtoupper($case)) {
if ($case == strtoupper($case)) {
return strtoupper($string); return strtoupper($string);
} } else if ($case == ucwords(strtolower($case))) {
if ($case == ucwords(strtolower($case))) {
return ucwords(strtolower($string)); return ucwords(strtolower($string));
} else {
return null;
} }
return null;
} }
} }

View file

@ -5,15 +5,15 @@
*/ */
final class ArcanistTextLinter extends ArcanistLinter { final class ArcanistTextLinter extends ArcanistLinter {
const LINT_DOS_NEWLINE = 1; const LINT_DOS_NEWLINE = 1;
const LINT_TAB_LITERAL = 2; const LINT_TAB_LITERAL = 2;
const LINT_LINE_WRAP = 3; const LINT_LINE_WRAP = 3;
const LINT_EOF_NEWLINE = 4; const LINT_EOF_NEWLINE = 4;
const LINT_BAD_CHARSET = 5; const LINT_BAD_CHARSET = 5;
const LINT_TRAILING_WHITESPACE = 6; const LINT_TRAILING_WHITESPACE = 6;
const LINT_NO_COMMIT = 7; const LINT_NO_COMMIT = 7;
const LINT_BOF_WHITESPACE = 8; const LINT_BOF_WHITESPACE = 8;
const LINT_EOF_WHITESPACE = 9; const LINT_EOF_WHITESPACE = 9;
private $maxLineLength = 80; private $maxLineLength = 80;
@ -69,24 +69,24 @@ final class ArcanistTextLinter extends ArcanistLinter {
public function getLintSeverityMap() { public function getLintSeverityMap() {
return array( return array(
self::LINT_LINE_WRAP => ArcanistLintSeverity::SEVERITY_WARNING, self::LINT_LINE_WRAP => ArcanistLintSeverity::SEVERITY_WARNING,
self::LINT_TRAILING_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX, self::LINT_TRAILING_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX,
self::LINT_BOF_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX, self::LINT_BOF_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX,
self::LINT_EOF_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX, self::LINT_EOF_WHITESPACE => ArcanistLintSeverity::SEVERITY_AUTOFIX,
); );
} }
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
self::LINT_DOS_NEWLINE => pht('DOS Newlines'), self::LINT_DOS_NEWLINE => pht('DOS Newlines'),
self::LINT_TAB_LITERAL => pht('Tab Literal'), self::LINT_TAB_LITERAL => pht('Tab Literal'),
self::LINT_LINE_WRAP => pht('Line Too Long'), self::LINT_LINE_WRAP => pht('Line Too Long'),
self::LINT_EOF_NEWLINE => pht('File Does Not End in Newline'), self::LINT_EOF_NEWLINE => pht('File Does Not End in Newline'),
self::LINT_BAD_CHARSET => pht('Bad Charset'), self::LINT_BAD_CHARSET => pht('Bad Charset'),
self::LINT_TRAILING_WHITESPACE => pht('Trailing Whitespace'), self::LINT_TRAILING_WHITESPACE => pht('Trailing Whitespace'),
self::LINT_NO_COMMIT => pht('Explicit %s', '@no'.'commit'), self::LINT_NO_COMMIT => pht('Explicit %s', '@no'.'commit'),
self::LINT_BOF_WHITESPACE => pht('Leading Whitespace at BOF'), self::LINT_BOF_WHITESPACE => pht('Leading Whitespace at BOF'),
self::LINT_EOF_WHITESPACE => pht('Trailing Whitespace at EOF'), self::LINT_EOF_WHITESPACE => pht('Trailing Whitespace at EOF'),
); );
} }

View file

@ -174,7 +174,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
), ),
'xhpast.php-version.windows' => array( 'xhpast.php-version.windows' => array(
'type' => 'optional string', 'type' => 'optional string',
'help' => pht('PHP version to target on Windows.') 'help' => pht('PHP version to target on Windows.'),
), ),
); );
} }

View file

@ -70,4 +70,5 @@ final class ArcanistXMLLinter extends ArcanistLinter {
$this->addLintMessage($message); $this->addLintMessage($message);
} }
} }
} }

View file

@ -1,7 +1,6 @@
<?php <?php
final class ArcanistLesscLinterTestCase final class ArcanistLesscLinterTestCase extends ArcanistArcanistLinterTestCase {
extends ArcanistArcanistLinterTestCase {
public function testLesscLinter() { public function testLesscLinter() {
$this->executeTestsInDirectory( $this->executeTestsInDirectory(

View file

@ -22,7 +22,7 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
pht('Expected to find some .lint-test tests in directory %s!', $root)); pht('Expected to find some .lint-test tests in directory %s!', $root));
} }
private function lintFile($file, $linter) { private function lintFile($file, ArcanistLinter $linter) {
$linter = clone $linter; $linter = clone $linter;
$contents = Filesystem::readFile($file); $contents = Filesystem::readFile($file);
@ -38,14 +38,10 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
$basename = basename($file); $basename = basename($file);
if ($config) { $config = phutil_json_decode($config);
$config = json_decode($config, true); if (!is_array($config)) {
if (!is_array($config)) { throw new Exception(
throw new Exception( "Invalid configuration in test '{$basename}', not valid JSON.");
"Invalid configuration in test '{$basename}', not valid JSON.");
}
} else {
$config = array();
} }
PhutilTypeSpec::checkMap( PhutilTypeSpec::checkMap(
@ -62,8 +58,8 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
$messages = null; $messages = null;
$exception_message = false; $exception_message = false;
$caught_exception = false; $caught_exception = false;
try {
try {
$tmp = new TempFile($basename); $tmp = new TempFile($basename);
Filesystem::writeFile($tmp, $data); Filesystem::writeFile($tmp, $data);
$full_path = (string)$tmp; $full_path = (string)$tmp;
@ -112,7 +108,6 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
$result = reset($results); $result = reset($results);
$patcher = ArcanistLintPatcher::newFromArcanistLintResult($result); $patcher = ArcanistLintPatcher::newFromArcanistLintResult($result);
$after_lint = $patcher->getModifiedFileContent(); $after_lint = $patcher->getModifiedFileContent();
} catch (ArcanistPhutilTestTerminatedException $ex) { } catch (ArcanistPhutilTestTerminatedException $ex) {
throw $ex; throw $ex;
} catch (Exception $exception) { } catch (Exception $exception) {
@ -133,19 +128,16 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
$exception->getTraceAsString(); $exception->getTraceAsString();
} }
switch ($basename) { $this->assertEqual(false, $caught_exception, $exception_message);
default: $this->compareLint($basename, $expect, $result);
$this->assertEqual(false, $caught_exception, $exception_message); $this->compareTransform($xform, $after_lint);
$this->compareLint($basename, $expect, $result);
$this->compareTransform($xform, $after_lint);
break;
}
} }
private function compareLint($file, $expect, $result) { private function compareLint($file, $expect, ArcanistLintResult $result) {
$seen = array(); $seen = array();
$raised = array(); $raised = array();
$message_map = array(); $message_map = array();
foreach ($result->getMessages() as $message) { foreach ($result->getMessages() as $message) {
$sev = $message->getSeverity(); $sev = $message->getSeverity();
$line = $message->getLine(); $line = $message->getLine();
@ -195,7 +187,7 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
} }
} }
protected function compareTransform($expected, $actual) { private function compareTransform($expected, $actual) {
if (!strlen($expected)) { if (!strlen($expected)) {
return; return;
} }

View file

@ -1,7 +1,6 @@
<?php <?php
final class ArcanistPEP8LinterTestCase final class ArcanistPEP8LinterTestCase extends ArcanistArcanistLinterTestCase {
extends ArcanistArcanistLinterTestCase {
public function testPEP8Linter() { public function testPEP8Linter() {
$this->executeTestsInDirectory( $this->executeTestsInDirectory(

View file

@ -5,9 +5,11 @@
* https://git.gnome.org/browse/libxml2/tree/test. * https://git.gnome.org/browse/libxml2/tree/test.
*/ */
final class ArcanistXMLLinterTestCase extends ArcanistArcanistLinterTestCase { final class ArcanistXMLLinterTestCase extends ArcanistArcanistLinterTestCase {
public function testXMLLint() { public function testXMLLint() {
$this->executeTestsInDirectory( $this->executeTestsInDirectory(
dirname(__FILE__).'/xml/', dirname(__FILE__).'/xml/',
new ArcanistXMLLinter()); new ArcanistXMLLinter());
} }
} }

View file

@ -1,19 +1,19 @@
module.exports = { module.exports = {
reporter: function (results) { reporter: function (results) {
var report = []; var report = [];
results.forEach(function (result) { results.forEach(function (result) {
var error = result.error; var error = result.error;
report.push({ report.push({
'file' : result.file, 'file' : result.file,
'line' : error.line, 'line' : error.line,
'col' : error.character, 'col' : error.character,
'reason' : error.reason, 'reason' : error.reason,
'code' : error.code, 'code' : error.code,
'evidence': error.evidence, 'evidence': error.evidence,
}); });
}); });
process.stdout.write(JSON.stringify(report)); process.stdout.write(JSON.stringify(report));
} }
}; };

View file

@ -1,9 +1,8 @@
<?php <?php
/** /**
* You can extend this class and set ##"lint.xhpast.naminghook"## in your * You can extend this class and set `xhpast.naminghook` in your `.arclint` to
* ##.arcconfig## to have an opportunity to override lint results for symbol * have an opportunity to override lint results for symbol names.
* names.
* *
* @task override Overriding Symbol Name Lint Messages * @task override Overriding Symbol Name Lint Messages
* @task util Name Utilities * @task util Name Utilities
@ -16,7 +15,6 @@ abstract class ArcanistXHPASTLintNamingHook {
/* -( Internals )---------------------------------------------------------- */ /* -( Internals )---------------------------------------------------------- */
/** /**
* The constructor is final because @{class:ArcanistXHPASTLinter} is * The constructor is final because @{class:ArcanistXHPASTLinter} is
* responsible for hook instantiation. * responsible for hook instantiation.
@ -31,7 +29,6 @@ abstract class ArcanistXHPASTLintNamingHook {
/* -( Overriding Symbol Name Lint Messages )------------------------------- */ /* -( Overriding Symbol Name Lint Messages )------------------------------- */
/** /**
* Callback invoked for each symbol, which can override the default * Callback invoked for each symbol, which can override the default
* determination of name validity or accept it by returning $default. The * determination of name validity or accept it by returning $default. The
@ -63,7 +60,6 @@ abstract class ArcanistXHPASTLintNamingHook {
/* -( Name Utilities )----------------------------------------------------- */ /* -( Name Utilities )----------------------------------------------------- */
/** /**
* Returns true if a symbol name is UpperCamelCase. * Returns true if a symbol name is UpperCamelCase.
* *
@ -75,7 +71,6 @@ abstract class ArcanistXHPASTLintNamingHook {
return preg_match('/^[A-Z][A-Za-z0-9]*$/', $symbol); return preg_match('/^[A-Z][A-Za-z0-9]*$/', $symbol);
} }
/** /**
* Returns true if a symbol name is lowerCamelCase. * Returns true if a symbol name is lowerCamelCase.
* *
@ -87,7 +82,6 @@ abstract class ArcanistXHPASTLintNamingHook {
return preg_match('/^[a-z][A-Za-z0-9]*$/', $symbol); return preg_match('/^[a-z][A-Za-z0-9]*$/', $symbol);
} }
/** /**
* Returns true if a symbol name is UPPERCASE_WITH_UNDERSCORES. * Returns true if a symbol name is UPPERCASE_WITH_UNDERSCORES.
* *
@ -99,7 +93,6 @@ abstract class ArcanistXHPASTLintNamingHook {
return preg_match('/^[A-Z0-9_]+$/', $symbol); return preg_match('/^[A-Z0-9_]+$/', $symbol);
} }
/** /**
* Returns true if a symbol name is lowercase_with_underscores. * Returns true if a symbol name is lowercase_with_underscores.
* *
@ -111,7 +104,6 @@ abstract class ArcanistXHPASTLintNamingHook {
return preg_match('/^[a-z0-9_]+$/', $symbol); return preg_match('/^[a-z0-9_]+$/', $symbol);
} }
/** /**
* Strip non-name components from PHP function symbols. Notably, this discards * Strip non-name components from PHP function symbols. Notably, this discards
* the "__" magic-method signifier, to make a symbol appropriate for testing * the "__" magic-method signifier, to make a symbol appropriate for testing
@ -127,7 +119,6 @@ abstract class ArcanistXHPASTLintNamingHook {
return preg_replace('/^__/', '', $symbol); return preg_replace('/^__/', '', $symbol);
} }
/** /**
* Strip non-name components from PHP variable symbols. Notably, this discards * Strip non-name components from PHP variable symbols. Notably, this discards
* the "$", to make a symbol appropriate for testing with methods like * the "$", to make a symbol appropriate for testing with methods like

View file

@ -1,9 +1,8 @@
<?php <?php
/** /**
* You can extend this class and set `lint.xhpast.switchhook` in your * You can extend this class and set `xhpast.switchhook` in your `.arclint`
* `.arcconfig` to have an opportunity to override results for linting `switch` * to have an opportunity to override results for linting `switch` statements.
* statements.
* *
* @group lint * @group lint
*/ */

View file

@ -5,26 +5,25 @@
* *
* @group testcase * @group testcase
*/ */
final class ArcanistXHPASTLintNamingHookTestCase final class ArcanistXHPASTLintNamingHookTestCase extends ArcanistTestCase {
extends ArcanistTestCase {
public function testCaseUtilities() { public function testCaseUtilities() {
$tests = array( $tests = array(
'UpperCamelCase' => array(1, 0, 0, 0), 'UpperCamelCase' => array(1, 0, 0, 0),
'UpperCamelCaseROFL' => array(1, 0, 0, 0), 'UpperCamelCaseROFL' => array(1, 0, 0, 0),
'lowerCamelCase' => array(0, 1, 0, 0), 'lowerCamelCase' => array(0, 1, 0, 0),
'lowerCamelCaseROFL' => array(0, 1, 0, 0), 'lowerCamelCaseROFL' => array(0, 1, 0, 0),
'UPPERCASE_WITH_UNDERSCORES' => array(0, 0, 1, 0), 'UPPERCASE_WITH_UNDERSCORES' => array(0, 0, 1, 0),
'_UPPERCASE_WITH_UNDERSCORES_' => array(0, 0, 1, 0), '_UPPERCASE_WITH_UNDERSCORES_' => array(0, 0, 1, 0),
'__UPPERCASE__WITH__UNDERSCORES__' => array(0, 0, 1, 0), '__UPPERCASE__WITH__UNDERSCORES__' => array(0, 0, 1, 0),
'lowercase_with_underscores' => array(0, 0, 0, 1), 'lowercase_with_underscores' => array(0, 0, 0, 1),
'_lowercase_with_underscores_' => array(0, 0, 0, 1), '_lowercase_with_underscores_' => array(0, 0, 0, 1),
'__lowercase__with__underscores__' => array(0, 0, 0, 1), '__lowercase__with__underscores__' => array(0, 0, 0, 1),
'mixedCASE_NoNsEnSe' => array(0, 0, 0, 0), 'mixedCASE_NoNsEnSe' => array(0, 0, 0, 0),
); );
foreach ($tests as $test => $expect) { foreach ($tests as $test => $expect) {