Page MenuHomePhabricator

D13942.id33938.diff
No OneTemporary

D13942.id33938.diff

diff --git a/.arclint b/.arclint
--- a/.arclint
+++ b/.arclint
@@ -45,15 +45,7 @@
"xhpast": {
"type": "xhpast",
"include": "(\\.php$)",
- "severity": {
- "16": "advice",
- "34": "error"
- },
- "xhpast.blacklisted.function": {
- "eval": "The eval() function should be avoided. It is potentially unsafe and makes debugging more difficult."
- },
- "xhpast.php-version": "5.2.3",
- "xhpast.php-version.windows": "5.3.0"
+ "xhpast.standard": "phutil"
}
}
}
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -187,6 +187,7 @@
'ArcanistPHPEchoTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPEchoTagXHPASTLinterRule.php',
'ArcanistPHPOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPOpenTagXHPASTLinterRule.php',
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
+ 'ArcanistPSR2XHPASTLinterStandard' => 'lint/linter/xhpast/standards/ArcanistPSR2XHPASTLinterStandard.php',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
@@ -199,6 +200,7 @@
'ArcanistPhrequentWorkflow' => 'workflow/ArcanistPhrequentWorkflow.php',
'ArcanistPhutilLibraryLinter' => 'lint/linter/ArcanistPhutilLibraryLinter.php',
'ArcanistPhutilXHPASTLinter' => 'lint/linter/ArcanistPhutilXHPASTLinter.php',
+ 'ArcanistPhutilXHPASTLinterStandard' => 'lint/linter/xhpast/standards/ArcanistPhutilXHPASTLinterStandard.php',
'ArcanistPhutilXHPASTLinterTestCase' => 'lint/linter/__tests__/ArcanistPhutilXHPASTLinterTestCase.php',
'ArcanistPlusOperatorOnStringsXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPlusOperatorOnStringsXHPASTLinterRule.php',
'ArcanistPregQuoteMisuseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPregQuoteMisuseXHPASTLinterRule.php',
@@ -275,6 +277,8 @@
'ArcanistXHPASTLinter' => 'lint/linter/ArcanistXHPASTLinter.php',
'ArcanistXHPASTLinterRule' => 'lint/linter/xhpast/ArcanistXHPASTLinterRule.php',
'ArcanistXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/__tests__/ArcanistXHPASTLinterRuleTestCase.php',
+ 'ArcanistXHPASTLinterStandard' => 'lint/linter/xhpast/ArcanistXHPASTLinterStandard.php',
+ 'ArcanistXHPASTLinterStandardTestCase' => 'lint/linter/xhpast/__tests__/ArcanistXHPASTLinterStandardTestCase.php',
'ArcanistXHPASTLinterTestCase' => 'lint/linter/__tests__/ArcanistXHPASTLinterTestCase.php',
'ArcanistXMLLinter' => 'lint/linter/ArcanistXMLLinter.php',
'ArcanistXMLLinterTestCase' => 'lint/linter/__tests__/ArcanistXMLLinterTestCase.php',
@@ -473,6 +477,7 @@
'ArcanistPHPEchoTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistPSR2XHPASTLinterStandard' => 'ArcanistXHPASTLinterStandard',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
@@ -485,6 +490,7 @@
'ArcanistPhrequentWorkflow' => 'ArcanistWorkflow',
'ArcanistPhutilLibraryLinter' => 'ArcanistLinter',
'ArcanistPhutilXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
+ 'ArcanistPhutilXHPASTLinterStandard' => 'ArcanistXHPASTLinterStandard',
'ArcanistPhutilXHPASTLinterTestCase' => 'ArcanistLinterTestCase',
'ArcanistPlusOperatorOnStringsXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPregQuoteMisuseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
@@ -561,6 +567,8 @@
'ArcanistXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
'ArcanistXHPASTLinterRule' => 'Phobject',
'ArcanistXHPASTLinterRuleTestCase' => 'PhutilTestCase',
+ 'ArcanistXHPASTLinterStandard' => 'Phobject',
+ 'ArcanistXHPASTLinterStandardTestCase' => 'PhutilTestCase',
'ArcanistXHPASTLinterTestCase' => 'ArcanistLinterTestCase',
'ArcanistXMLLinter' => 'ArcanistLinter',
'ArcanistXMLLinterTestCase' => 'ArcanistLinterTestCase',
diff --git a/src/lint/linter/ArcanistLinter.php b/src/lint/linter/ArcanistLinter.php
--- a/src/lint/linter/ArcanistLinter.php
+++ b/src/lint/linter/ArcanistLinter.php
@@ -242,6 +242,11 @@
return $this;
}
+ public function addCustomSeverityMap(array $map) {
+ $this->customSeverityMap = array_merge($this->customSeverityMap, $map);
+ return $this;
+ }
+
final public function setCustomSeverityRules(array $rules) {
$this->customSeverityRules = $rules;
return $this;
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
@@ -62,27 +62,53 @@
}
public function getLinterConfigurationOptions() {
- return parent::getLinterConfigurationOptions() + array_mergev(
- mpull($this->rules, 'getLinterConfigurationOptions'));
+ $options = array(
+ 'xhpast.standard' => array(
+ 'type' => 'optional string | list<string>',
+ 'help' => pht('The coding standard(s) to apply.'),
+ ),
+ );
+
+ return array_merge(
+ $options,
+ parent::getLinterConfigurationOptions(),
+ array_mergev(mpull($this->rules, 'getLinterConfigurationOptions')));
}
public function setLinterConfigurationValue($key, $value) {
- $matched = false;
+ switch ($key) {
+ case 'xhpast.standard':
+ $standards = (array)$value;
- foreach ($this->rules as $rule) {
- foreach ($rule->getLinterConfigurationOptions() as $k => $spec) {
- if ($k == $key) {
- $matched = true;
- $rule->setLinterConfigurationValue($key, $value);
+ foreach ($standards as $standard) {
+ $standard = ArcanistXHPASTLinterStandard::getStandard($value);
+
+ foreach ($standard->getLinterConfiguration() as $k => $v) {
+ $this->setLinterConfigurationValue($k, $v);
+ }
+ $this->addCustomSeverityMap($standard->getLinterSeverityMap());
}
- }
- }
- if ($matched) {
- return;
- }
+ return;
- return parent::setLinterConfigurationValue($key, $value);
+ default:
+ $matched = false;
+
+ foreach ($this->rules as $rule) {
+ foreach ($rule->getLinterConfigurationOptions() as $k => $spec) {
+ if ($k == $key) {
+ $matched = true;
+ $rule->setLinterConfigurationValue($key, $value);
+ }
+ }
+ }
+
+ if ($matched) {
+ return;
+ }
+
+ return parent::setLinterConfigurationValue($key, $value);
+ }
}
public function getVersion() {
diff --git a/src/lint/linter/xhpast/ArcanistXHPASTLinterStandard.php b/src/lint/linter/xhpast/ArcanistXHPASTLinterStandard.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/ArcanistXHPASTLinterStandard.php
@@ -0,0 +1,36 @@
+<?php
+
+abstract class ArcanistXHPASTLinterStandard extends Phobject {
+
+ final public static function getStandard($key) {
+ $standards = self::loadAllStandards();
+
+ if (empty($standards[$key])) {
+ throw new ArcanistUsageException(
+ pht(
+ 'No such XHPAST linter standard. Available standards are: %s.',
+ implode(', ', array_keys($standards))));
+ }
+
+ return $standards[$key];
+ }
+
+ final public static function loadAllStandards() {
+ return id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getKey')
+ ->execute();
+ }
+
+ abstract public function getKey();
+ abstract public function getName();
+ abstract public function getDescription();
+
+ public function getLinterConfiguration() {
+ return array();
+ }
+
+ public function getLinterSeverityMap() {
+ return array();
+ }
+}
diff --git a/src/lint/linter/xhpast/__tests__/ArcanistXHPASTLinterStandardTestCase.php b/src/lint/linter/xhpast/__tests__/ArcanistXHPASTLinterStandardTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/__tests__/ArcanistXHPASTLinterStandardTestCase.php
@@ -0,0 +1,10 @@
+<?php
+
+final class ArcanistXHPASTLinterStandardTestCase extends PhutilTestCase {
+
+ public function testLoadAllStandards() {
+ ArcanistXHPASTLinterStandard::loadAllStandards();
+ $this->assertTrue(true);
+ }
+
+}
diff --git a/src/lint/linter/xhpast/standards/ArcanistPSR2XHPASTLinterStandard.php b/src/lint/linter/xhpast/standards/ArcanistPSR2XHPASTLinterStandard.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/standards/ArcanistPSR2XHPASTLinterStandard.php
@@ -0,0 +1,22 @@
+<?php
+
+final class ArcanistPSR2XHPASTLinterStandard
+ extends ArcanistXHPASTLinterStandard {
+
+ public function getKey() {
+ return 'PSR2';
+ }
+
+ public function getName() {
+ return pht('PSR-2');
+ }
+
+ public function getDescription() {
+ return pht('PSR-2 Coding Standard.');
+ }
+
+ public function getLinterConfiguration() {
+ return array();
+ }
+
+}
diff --git a/src/lint/linter/xhpast/standards/ArcanistPhutilXHPASTLinterStandard.php b/src/lint/linter/xhpast/standards/ArcanistPhutilXHPASTLinterStandard.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/standards/ArcanistPhutilXHPASTLinterStandard.php
@@ -0,0 +1,41 @@
+<?php
+
+final class ArcanistPhutilXHPASTLinterStandard
+ extends ArcanistXHPASTLinterStandard {
+
+ public function getKey() {
+ return 'phutil';
+ }
+
+ public function getName() {
+ return pht('Phutil');
+ }
+
+ public function getDescription() {
+ return pht('PHP Coding Standards for Phutil libraries.');
+ }
+
+ public function getLinterConfiguration() {
+ return array(
+ 'xhpast.blacklisted.function' => array(
+ 'eval' => pht(
+ 'The %s function should be avoided. It is potentially unsafe '.
+ 'and makes debugging more difficult.',
+ 'eval()'),
+ 'xhpast.php-version' => '5.2.3',
+ 'xhpast.php-version.windows' => '5.3.0',
+ ),
+ );
+ }
+
+ public function getLinterSeverityMap() {
+ $advice = ArcanistLintSeverity::SEVERITY_ADVICE;
+ $error = ArcanistLintSeverity::SEVERITY_ERROR;
+
+ return array(
+ ArcanistTodoCommentXHPASTLinterRule::ID => $advice,
+ ArcanistCommentSpacingXHPASTLinterRule::ID => $error,
+ );
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Wed, May 22, 1:28 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6298634
Default Alt Text
D13942.id33938.diff (10 KB)

Event Timeline