From 5218ec357c5cf8ecb9390a5efd4a90fdeddfb429 Mon Sep 17 00:00:00 2001 From: Joshua Spence Date: Wed, 2 Dec 2015 06:25:22 +1100 Subject: [PATCH] Add a table showing all XHPAST linter rules to the output of `arc linters xhpast` Summary: Now that we have 91 subclasses of `ArcanistXHPASTLinterRule`, it is becoming difficult to manage the IDs. This diff adds a table to `arc linters xhpast` workflow to facilitate this. Test Plan: ``` > arc xhpast-linter-rules +=====+=======================================================+===================================================================+ | ID | Class | Name | +=====+=======================================================+===================================================================+ | 1 | ArcanistSyntaxErrorXHPASTLinterRule | PHP Syntax Error! | | 2 | ArcanistUnableToParseXHPASTLinterRule | Unable to Parse | | 3 | ArcanistVariableVariableXHPASTLinterRule | Use of Variable Variable | | 4 | ArcanistExtractUseXHPASTLinterRule | Use of `extract` | | 5 | ArcanistUndeclaredVariableXHPASTLinterRule | Use of Undeclared Variable | | 6 | ArcanistPHPShortTagXHPASTLinterRule | Use of Short Tag `` | | 9 | ArcanistNamingConventionsXHPASTLinterRule | Naming Conventions | | 10 | ArcanistImplicitConstructorXHPASTLinterRule | Implicit Constructor | | 12 | ArcanistDynamicDefineXHPASTLinterRule | Dynamic `define` | | 13 | ArcanistStaticThisXHPASTLinterRule | Use of `$this` in Static Context | | 14 | ArcanistPregQuoteMisuseXHPASTLinterRule | Misuse of `preg_quote` | | 15 | ArcanistPHPOpenTagXHPASTLinterRule | Expected Open Tag | | 16 | ArcanistTodoCommentXHPASTLinterRule | TODO Comment | | 17 | ArcanistExitExpressionXHPASTLinterRule | `exit` Used as Expression | | 18 | ArcanistCommentStyleXHPASTLinterRule | Comment Style | | 19 | ArcanistClassFilenameMismatchXHPASTLinterRule | Class-Filename Mismatch | | 20 | ArcanistTautologicalExpressionXHPASTLinterRule | Tautological Expression | | 21 | ArcanistPlusOperatorOnStringsXHPASTLinterRule | Not String Concatenation | | 22 | ArcanistDuplicateKeysInArrayXHPASTLinterRule | Duplicate Keys in Array | | 23 | ArcanistReusedIteratorXHPASTLinterRule | Reuse of Iterator Variable | | 24 | ArcanistBraceFormattingXHPASTLinterRule | Brace Placement | | 25 | ArcanistParenthesesSpacingXHPASTLinterRule | Spaces Inside Parentheses | | 26 | ArcanistControlStatementSpacingXHPASTLinterRule | Space After Control Statement | | 27 | ArcanistBinaryExpressionSpacingXHPASTLinterRule | Space Around Binary Operator | | 28 | ArcanistArrayIndexSpacingXHPASTLinterRule | Spacing Before Array Index | | 30 | ArcanistImplicitFallthroughXHPASTLinterRule | Implicit Fallthrough | | 32 | ArcanistReusedAsIteratorXHPASTLinterRule | Variable Reused As Iterator | | 34 | ArcanistCommentSpacingXHPASTLinterRule | Comment Spaces | | 36 | ArcanistSlownessXHPASTLinterRule | Slow Construct | | 37 | ArcanistCallParenthesesXHPASTLinterRule | Call Formatting | | 38 | ArcanistDeclarationParenthesesXHPASTLinterRule | Declaration Formatting | | 39 | ArcanistReusedIteratorReferenceXHPASTLinterRule | Reuse of Iterator References | | 40 | ArcanistKeywordCasingXHPASTLinterRule | Keyword Conventions | | 41 | ArcanistDoubleQuoteXHPASTLinterRule | Unnecessary Double Quotes | | 42 | ArcanistElseIfUsageXHPASTLinterRule | `elseif` Usage | | 43 | ArcanistSemicolonSpacingXHPASTLinterRule | Semicolon Spacing | | 44 | ArcanistConcatenationOperatorXHPASTLinterRule | Concatenation Spacing | | 45 | ArcanistPHPCompatibilityXHPASTLinterRule | PHP Compatibility | | 46 | ArcanistLanguageConstructParenthesesXHPASTLinterRule | Language Construct Parentheses | | 47 | ArcanistEmptyStatementXHPASTLinterRule | Empty Block Statement | | 48 | ArcanistArraySeparatorXHPASTLinterRule | Array Separator | | 49 | ArcanistConstructorParenthesesXHPASTLinterRule | Constructor Parentheses | | 50 | ArcanistDuplicateSwitchCaseXHPASTLinterRule | Duplicate Case Statements | | 51 | ArcanistBlacklistedFunctionXHPASTLinterRule | Use of Blacklisted Function | | 52 | ArcanistImplicitVisibilityXHPASTLinterRule | Implicit Method Visibility | | 53 | ArcanistCallTimePassByReferenceXHPASTLinterRule | Call-Time Pass-By-Reference | | 54 | ArcanistFormattedStringXHPASTLinterRule | Formatted String | | 55 | ArcanistUnnecessaryFinalModifierXHPASTLinterRule | Unnecessary Final Modifier | | 56 | ArcanistUnnecessarySemicolonXHPASTLinterRule | Unnecessary Semicolon | | 57 | ArcanistSelfMemberReferenceXHPASTLinterRule | Self Member Reference | | 58 | ArcanistLogicalOperatorsXHPASTLinterRule | Logical Operators | | 59 | ArcanistInnerFunctionXHPASTLinterRule | Inner Functions | | 60 | ArcanistDefaultParametersXHPASTLinterRule | Default Parameters | | 61 | ArcanistLowercaseFunctionsXHPASTLinterRule | Lowercase Functions | | 62 | ArcanistClassNameLiteralXHPASTLinterRule | Class Name Literal | | 63 | ArcanistUselessOverridingMethodXHPASTLinterRule | Useless Overriding Method | | 64 | ArcanistNoParentScopeXHPASTLinterRule | No Parent Scope | | 65 | ArcanistAliasFunctionXHPASTLinterRule | Alias Functions | | 66 | ArcanistCastSpacingXHPASTLinterRule | Cast Spacing | | 67 | ArcanistToStringExceptionXHPASTLinterRule | Throwing Exception in `__toString` Method | | 68 | ArcanistLambdaFuncFunctionXHPASTLinterRule | `__lambda_func` Function | | 69 | ArcanistInstanceOfOperatorXHPASTLinterRule | `instanceof` Operator | | 70 | ArcanistInvalidDefaultParameterXHPASTLinterRule | Invalid Default Parameter | | 71 | ArcanistModifierOrderingXHPASTLinterRule | Modifier Ordering | | 72 | ArcanistInvalidModifiersXHPASTLinterRule | Invalid Modifiers | | 73 | ArcanistUnaryPrefixExpressionSpacingXHPASTLinterRule | Space After Unary Prefix Operator | | 74 | ArcanistObjectOperatorSpacingXHPASTLinterRule | Object Operator Spacing | | 75 | ArcanistUnaryPostfixExpressionSpacingXHPASTLinterRule | Space Before Unary Postfix Operator | | 76 | ArcanistArrayValueXHPASTLinterRule | Array Element | | 77 | ArcanistListAssignmentXHPASTLinterRule | List Assignment | | 78 | ArcanistInlineHTMLXHPASTLinterRule | Inline HTML | | 79 | ArcanistGlobalVariableXHPASTLinterRule | Global Variables | | 80 | ArcanistParseStrUseXHPASTLinterRule | Questionable Use of `parse_str` | | 81 | ArcanistNewlineAfterOpenTagXHPASTLinterRule | Newline After PHP Open Tag | | 82 | ArcanistEmptyFileXHPASTLinterRule | Empty File | | 83 | ArcanistParentMemberReferenceXHPASTLinterRule | Parent Member Reference | | 84 | ArcanistArrayCombineXHPASTLinterRule | `array_combine()` Unreliable | | 85 | ArcanistDeprecationXHPASTLinterRule | Use of Deprecated Function | | 86 | ArcanistUnsafeDynamicStringXHPASTLinterRule | Unsafe Usage of Dynamic String | | 87 | ArcanistRaggedClassTreeEdgeXHPASTLinterRule | Class Not `abstract` Or `final` | | 88 | ArcanistClassExtendsObjectXHPASTLinterRule | Class Not Extending `Phobject` | | 90 | ArcanistNestedNamespacesXHPASTLinterRule | Nested `namespace` Statements | | 91 | ArcanistThisReassignmentXHPASTLinterRule | `$this` Reassignment | | 92 | ArcanistUnexpectedReturnValueXHPASTLinterRule | Unexpected `return` Value | | 97 | ArcanistUseStatementNamespacePrefixXHPASTLinterRule | `use` Statement Namespace Prefix | | 99 | ArcanistUnnecessarySymbolAliasXHPASTLinterRule | Unnecessary Symbol Alias | | 107 | ArcanistAbstractPrivateMethodXHPASTLinterRule | `abstract` Method Cannot Be Declared `private` | | 108 | ArcanistAbstractMethodBodyXHPASTLinterRule | `abstract` Method Cannot Contain Body | | 113 | ArcanistClassMustBeDeclaredAbstractXHPASTLinterRule | `class` Containing `abstract` Methods Must Be Declared `abstract` | +=====+=======================================================+===================================================================+ ``` Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D14563 --- src/lint/linter/ArcanistLinter.php | 14 ++++++++++++++ src/lint/linter/ArcanistXHPASTLinter.php | 23 +++++++++++++++++++++++ src/workflow/ArcanistLintersWorkflow.php | 14 ++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/lint/linter/ArcanistLinter.php b/src/lint/linter/ArcanistLinter.php index 292d4438..d2695148 100644 --- a/src/lint/linter/ArcanistLinter.php +++ b/src/lint/linter/ArcanistLinter.php @@ -57,6 +57,20 @@ abstract class ArcanistLinter extends Phobject { return null; } + /** + * Return arbitrary additional information. + * + * Linters can use this method to provide arbitrary additional information to + * be included in the output of `arc linters`. + * + * @return map A mapping of header to body content for the + * additional information sections. + * @task info + */ + public function getAdditionalInformation() { + return array(); + } + /** * Return a human-readable linter name. * diff --git a/src/lint/linter/ArcanistXHPASTLinter.php b/src/lint/linter/ArcanistXHPASTLinter.php index aa3a472b..636d8569 100644 --- a/src/lint/linter/ArcanistXHPASTLinter.php +++ b/src/lint/linter/ArcanistXHPASTLinter.php @@ -46,6 +46,29 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter { return pht('Use XHPAST to enforce coding conventions on PHP source files.'); } + public function getAdditionalInformation() { + $table = id(new PhutilConsoleTable()) + ->setBorders(true) + ->addColumn('id', array('title' => pht('ID'))) + ->addColumn('class', array('title' => pht('Class'))) + ->addColumn('name', array('title' => pht('Name'))); + + $rules = $this->rules; + ksort($rules); + + foreach ($rules as $id => $rule) { + $table->addRow(array( + 'id' => $id, + 'class' => get_class($rule), + 'name' => $rule->getLintName(), + )); + } + + return array( + pht('Linter Rules') => $table->drawConsoleString(), + ); + } + public function getLinterName() { return 'XHP'; } diff --git a/src/workflow/ArcanistLintersWorkflow.php b/src/workflow/ArcanistLintersWorkflow.php index 3c7d5606..9932f3b9 100644 --- a/src/workflow/ArcanistLintersWorkflow.php +++ b/src/workflow/ArcanistLintersWorkflow.php @@ -78,6 +78,7 @@ EOTEXT if ($exact) { $linter_info = $this->findExactNames($linter_info, $exact); + if (!$linter_info) { $console->writeOut( "%s\n", @@ -170,6 +171,18 @@ EOTEXT $print_tail = true; } + $additional = $linter['additional']; + foreach ($additional as $title => $body) { + $console->writeOut( + "\n%s**%s**\n\n", + $pad, + $title); + + // TODO: This should maybe use `tsprintf`. + // See some discussion in D14563. + echo $body; + } + if ($print_tail) { $console->writeOut("\n"); } @@ -250,6 +263,7 @@ EOTEXT 'description' => $linter->getInfoDescription(), 'exception' => $exception, 'options' => $linter->getLinterConfigurationOptions(), + 'additional' => $linter->getAdditionalInformation(), ); }