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 @@ -48,6 +48,7 @@ const LINT_LANGUAGE_CONSTRUCT_PAREN = 46; const LINT_EMPTY_STATEMENT = 47; const LINT_ARRAY_SEPARATOR = 48; + const LINT_ONE_STATEMENT_PER_LINE = 49; private $naminghook; private $switchhook; @@ -107,6 +108,7 @@ self::LINT_LANGUAGE_CONSTRUCT_PAREN => 'Language Construct Parentheses', self::LINT_EMPTY_STATEMENT => 'Empty Block Statement', self::LINT_ARRAY_SEPARATOR => 'Array Separator', + self::LINT_ONE_STATEMENT_PER_LINE => 'One Statement Per Line', ); } @@ -147,6 +149,7 @@ self::LINT_LANGUAGE_CONSTRUCT_PAREN => $warning, self::LINT_EMPTY_STATEMENT => $advice, self::LINT_ARRAY_SEPARATOR => $advice, + self::LINT_ONE_STATEMENT_PER_LINE => $advice, ); } @@ -196,7 +199,7 @@ public function getVersion() { // The version number should be incremented whenever a new rule is added. - return '9'; + return '10'; } protected function resolveFuture($path, Future $future) { @@ -267,6 +270,7 @@ 'lintLanguageConstructParentheses' => self::LINT_LANGUAGE_CONSTRUCT_PAREN, 'lintEmptyBlockStatements' => self::LINT_EMPTY_STATEMENT, 'lintArraySeparator' => self::LINT_ARRAY_SEPARATOR, + 'lintStatements' => self::LINT_ONE_STATEMENT_PER_LINE, ); foreach ($method_codes as $method => $codes) { @@ -2760,6 +2764,31 @@ } } + protected function lintStatements(XHPASTNode $root) { + $statements = $root->selectDescendantsOfType('n_STATEMENT'); + + $line = null; + $indent = null; + + foreach ($statements as $statement) { + if ($line == $statement->getLineNumber()) { + $this->raiseLintAtNode( + $statement, + self::LINT_ONE_STATEMENT_PER_LINE, + pht('Multiple statements on a single line.'), + "\n".$indent.$statement->getConcreteString()); + } + + $line = $statement->getLineNumber(); + list($before, $after) = $statement->getSurroundingNonsemanticTokens(); + + $indent = ''; + foreach ($before as $token) { + $indent .= preg_replace("/^\s*\n/", '', $token->getValue()); + } + } + } + public function getSuperGlobalNames() { return array( '$GLOBALS', diff --git a/src/lint/linter/__tests__/xhpast/one-statement-per-line.lint-test b/src/lint/linter/__tests__/xhpast/one-statement-per-line.lint-test new file mode 100644 --- /dev/null +++ b/src/lint/linter/__tests__/xhpast/one-statement-per-line.lint-test @@ -0,0 +1,20 @@ +<?php +foo(); bar(); baz(); +function x() { + foo(); bar(); baz(); +} +~~~~~~~~~~ +advice:2:8 +advice:2:15 +advice:4:10 +advice:4:17 +~~~~~~~~~~ +<?php +foo(); +bar(); +baz(); +function x() { + foo(); + bar(); + baz(); +}