Page MenuHomePhabricator

D14540.diff
No OneTemporary

D14540.diff

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
@@ -181,6 +181,7 @@
'ArcanistModifierOrderingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistModifierOrderingXHPASTLinterRule.php',
'ArcanistNamingConventionsXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistNamingConventionsXHPASTLinterRule.php',
'ArcanistNewlineAfterOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistNewlineAfterOpenTagXHPASTLinterRule.php',
+ 'ArcanistNewlineAfterUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistNewlineAfterUseXHPASTLinterRule.php',
'ArcanistNoEffectException' => 'exception/usage/ArcanistNoEffectException.php',
'ArcanistNoEngineException' => 'exception/usage/ArcanistNoEngineException.php',
'ArcanistNoLintLinter' => 'lint/linter/ArcanistNoLintLinter.php',
@@ -476,6 +477,7 @@
'ArcanistModifierOrderingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistNamingConventionsXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistNewlineAfterOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistNewlineAfterUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistNoEffectException' => 'ArcanistUsageException',
'ArcanistNoEngineException' => 'ArcanistUsageException',
'ArcanistNoLintLinter' => 'ArcanistLinter',
diff --git a/src/lint/linter/__tests__/xhpast/newline-after-use.lint-test b/src/lint/linter/__tests__/xhpast/newline-after-use.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/newline-after-use.lint-test
@@ -0,0 +1,30 @@
+<?php
+
+namespace foo;
+
+use A\Thing;
+
+use bar;
+function my_function() {
+ return 'hello';
+}
+
+use foo;
+use bar;
+use baz;
+/**
+ * There should be a space before this comment.
+ */
+
+namespace foo\bar;
+
+use meme;
+use other\thing;
+
+function my_other_function() {
+ return 'hello';
+}
+~~~~~~~~~~
+warning:7:1
+warning:14:1
+~~~~~~~~~~
diff --git a/src/lint/linter/__tests__/xhpast/php53-features.lint-test b/src/lint/linter/__tests__/xhpast/php53-features.lint-test
--- a/src/lint/linter/__tests__/xhpast/php53-features.lint-test
+++ b/src/lint/linter/__tests__/xhpast/php53-features.lint-test
@@ -12,7 +12,8 @@
echo __DIR__;
~~~~~~~~~~
error:3:1
-error:4:5
+warning:4:1
+error:4:1
error:5:3
error:6:3
error:7:1
diff --git a/src/lint/linter/xhpast/rules/ArcanistNewlineAfterUseXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistNewlineAfterUseXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistNewlineAfterUseXHPASTLinterRule.php
@@ -0,0 +1,64 @@
+<?php
+
+final class ArcanistNewlineAfterUseXHPASTLinterRule
+ extends ArcanistXHPASTLinterRule {
+
+ const ID = 90;
+
+ public function getLintName() {
+ return pht('Newline After Use Tag');
+ }
+
+ public function getLintSeverity() {
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ }
+
+ public function process(XHPASTNode $root) {
+ $uses = $root->selectDescendantsOfType('n_USE_LIST');
+
+ if (count($uses) > 0) {
+ $uses->rewind();
+ for ($use = $uses->current(); $uses->valid(); $use = $uses->current()) {
+ // Get 'n_STATEMENT' above current 'use' and its surrounding whitespace.
+ $statement = $use->getParentNode();
+ list($before, $after) = $statement->getSurroundingNonSemanticTokens();
+ // Progress '$uses' List to next element before next loop.
+ $uses->next();
+
+ // Check if current 'use' has a blank newline after it.
+ if (preg_match('/^\n\s*\n/', head($after)->getValue())) {
+ // Continue if there are more 'use's, otherwise break.
+ if ($uses->valid()) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ // If there are more 'use' statements,
+ // see if next 'use' is on the next line.
+ if ($uses->valid()) {
+ $next = $uses->current();
+ if (($use->getLineNumber() + 1) == $next->getLineNumber()) {
+ continue;
+ }
+ } else {
+ // If no more 'use's left raise lint on last one.
+ $this->raiseListAtStatement($statement);
+ break;
+ }
+
+ $this->raiseListAtStatement($statement);
+ }
+ }
+ }
+
+ public function raiseListAtStatement($statement) {
+ $this->raiseLintAtNode(
+ $statement,
+ pht(
+ 'Use lists should be separated from code by an empty line.'),
+ $statement->getConcreteString()."\n");
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Jul 31 2025, 4:26 PM (4 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
8761187
Default Alt Text
D14540.diff (4 KB)

Event Timeline