Page MenuHomePhabricator

D13881.diff
No OneTemporary

D13881.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
@@ -90,6 +90,7 @@
'ArcanistDuplicateSwitchCaseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistDuplicateSwitchCaseXHPASTLinterRule.php',
'ArcanistDynamicDefineXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistDynamicDefineXHPASTLinterRule.php',
'ArcanistElseIfUsageXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistElseIfUsageXHPASTLinterRule.php',
+ 'ArcanistEmptyFileXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistEmptyFileXHPASTLinterRule.php',
'ArcanistEmptyStatementXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistEmptyStatementXHPASTLinterRule.php',
'ArcanistEventType' => 'events/constant/ArcanistEventType.php',
'ArcanistExitExpressionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistExitExpressionXHPASTLinterRule.php',
@@ -375,6 +376,7 @@
'ArcanistDuplicateSwitchCaseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistDynamicDefineXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistElseIfUsageXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistEmptyFileXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistEmptyStatementXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistEventType' => 'PhutilEventType',
'ArcanistExitExpressionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
diff --git a/src/lint/linter/ArcanistTextLinter.php b/src/lint/linter/ArcanistTextLinter.php
--- a/src/lint/linter/ArcanistTextLinter.php
+++ b/src/lint/linter/ArcanistTextLinter.php
@@ -13,6 +13,7 @@
const LINT_TRAILING_WHITESPACE = 6;
const LINT_BOF_WHITESPACE = 8;
const LINT_EOF_WHITESPACE = 9;
+ const LINT_EMPTY_FILE = 10;
private $maxLineLength = 80;
@@ -85,16 +86,23 @@
self::LINT_TRAILING_WHITESPACE => pht('Trailing Whitespace'),
self::LINT_BOF_WHITESPACE => pht('Leading Whitespace at BOF'),
self::LINT_EOF_WHITESPACE => pht('Trailing Whitespace at EOF'),
+ self::LINT_EMPTY_FILE => pht('Empty File'),
);
}
public function lintPath($path) {
+ $this->lintEmptyFile($path);
+
if (!strlen($this->getData($path))) {
// If the file is empty, don't bother; particularly, don't require
// the user to add a newline.
return;
}
+ if ($this->didStopAllLinters()) {
+ return;
+ }
+
$this->lintNewlines($path);
$this->lintTabs($path);
@@ -116,6 +124,29 @@
$this->lintEOFWhitespace($path);
}
+ protected function lintEmptyFile($path) {
+ $data = $this->getData($path);
+
+ // It is reasonable for certain file types to be completely empty,
+ // so they are excluded here.
+ switch ($filename = basename($this->getActivePath())) {
+ case '__init__.py':
+ return;
+
+ default:
+ if (strlen($filename) && $filename[0] == '.') {
+ return;
+ }
+ }
+
+ if (preg_match('/^\s*$/', $data)) {
+ $this->raiseLintAtPath(
+ self::LINT_EMPTY_FILE,
+ pht("Empty files usually don't serve any useful purpose."));
+ $this->stopAllLinters();
+ }
+ }
+
protected function lintNewlines($path) {
$data = $this->getData($path);
$pos = strpos($this->getData($path), "\r");
diff --git a/src/lint/linter/__tests__/text/empty-file.lint-test b/src/lint/linter/__tests__/text/empty.lint-test
rename from src/lint/linter/__tests__/text/empty-file.lint-test
rename to src/lint/linter/__tests__/text/empty.lint-test
--- a/src/lint/linter/__tests__/text/empty-file.lint-test
+++ b/src/lint/linter/__tests__/text/empty.lint-test
@@ -1 +1,4 @@
+
+
~~~~~~~~~~
+error::
diff --git a/src/lint/linter/__tests__/xhpast/empty.lint-test b/src/lint/linter/__tests__/xhpast/empty.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/empty.lint-test
@@ -0,0 +1,3 @@
+<?php ?>
+~~~~~~~~~~
+warning::
diff --git a/src/lint/linter/__tests__/xhpast/not-empty.lint-test b/src/lint/linter/__tests__/xhpast/not-empty.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/not-empty.lint-test
@@ -0,0 +1,4 @@
+<?php
+
+// This file is not empty.
+~~~~~~~~~~
diff --git a/src/lint/linter/__tests__/xhpast/php-tags-short.lint-test b/src/lint/linter/__tests__/xhpast/php-tags-short.lint-test
--- a/src/lint/linter/__tests__/xhpast/php-tags-short.lint-test
+++ b/src/lint/linter/__tests__/xhpast/php-tags-short.lint-test
@@ -1,6 +1,7 @@
<?
~~~~~~~~~~
+warning::
error:1:1
~~~~~~~~~~
<?php
diff --git a/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php b/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
@@ -146,6 +146,10 @@
$replace);
}
+ final protected function raiseLintAtPath($desc) {
+ return $this->linter->raiseLintAtPath($this->getLintID(), $desc);
+ }
+
final protected function raiseLintAtToken(
XHPASTToken $token,
$desc,
diff --git a/src/lint/linter/xhpast/rules/ArcanistEmptyFileXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistEmptyFileXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistEmptyFileXHPASTLinterRule.php
@@ -0,0 +1,35 @@
+<?php
+
+final class ArcanistEmptyFileXHPASTLinterRule
+ extends ArcanistXHPASTLinterRule {
+
+ const ID = 82;
+
+ public function getLintName() {
+ return pht('Empty File');
+ }
+
+ public function getLintSeverity() {
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ }
+
+ public function process(XHPASTNode $root) {
+ $tokens = $root->getTokens();
+
+ foreach ($tokens as $token) {
+ switch ($token->getTypeName()) {
+ case 'T_OPEN_TAG':
+ case 'T_CLOSE_TAG':
+ case 'T_WHITESPACE':
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ $this->raiseLintAtPath(
+ pht("Empty files usually don't serve any useful purpose."));
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 12:55 AM (3 d, 8 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7712261
Default Alt Text
D13881.diff (5 KB)

Event Timeline