Page MenuHomePhabricator

D11171.diff
No OneTemporary

D11171.diff

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
@@ -49,6 +49,7 @@
const LINT_EMPTY_STATEMENT = 47;
const LINT_ARRAY_SEPARATOR = 48;
const LINT_CONSTRUCTOR_PARENTHESES = 49;
+ const LINT_DUPLICATE_SWITCH_CASE = 50;
private $naminghook;
private $switchhook;
@@ -109,6 +110,7 @@
self::LINT_EMPTY_STATEMENT => 'Empty Block Statement',
self::LINT_ARRAY_SEPARATOR => 'Array Separator',
self::LINT_CONSTRUCTOR_PARENTHESES => 'Constructor Parentheses',
+ self::LINT_DUPLICATE_SWITCH_CASE => 'Duplicate Case Statements',
);
}
@@ -199,7 +201,7 @@
public function getVersion() {
// The version number should be incremented whenever a new rule is added.
- return '10';
+ return '11';
}
protected function resolveFuture($path, Future $future) {
@@ -271,6 +273,7 @@
'lintEmptyBlockStatements' => self::LINT_EMPTY_STATEMENT,
'lintArraySeparator' => self::LINT_ARRAY_SEPARATOR,
'lintConstructorParentheses' => self::LINT_CONSTRUCTOR_PARENTHESES,
+ 'lintSwitchStatements' => self::LINT_DUPLICATE_SWITCH_CASE,
);
foreach ($method_codes as $method => $codes) {
@@ -2868,6 +2871,44 @@
}
}
+ private function lintSwitchStatements(XHPASTNode $root) {
+ $switch_statements = $root->selectDescendantsOfType('n_SWITCH');
+
+ foreach ($switch_statements as $switch_statement) {
+ $case_statements = $switch_statement
+ ->getChildOfType(1, 'n_STATEMENT_LIST')
+ ->getChildrenOfType('n_CASE');
+ $nodes_by_case = array();
+
+ foreach ($case_statements as $case_statement) {
+ $case = $case_statement
+ ->getChildByIndex(0)
+ ->getSemanticString();
+ $nodes_by_case[$case][] = $case_statement;
+ }
+
+ foreach ($nodes_by_case as $case => $nodes) {
+ if (count($nodes) <= 1) {
+ continue;
+ }
+
+ $node = array_pop($nodes_by_case[$case]);
+ $message = $this->raiseLintAtNode(
+ $node,
+ self::LINT_DUPLICATE_SWITCH_CASE,
+ pht(
+ 'Duplicate case in switch statement. PHP will ignore all '.
+ 'but the first case.'));
+
+ $locations = array();
+ foreach ($nodes_by_case[$case] as $node) {
+ $locations[] = $this->getOtherLocation($node->getOffset());
+ }
+ $message->setOtherLocations($locations);
+ }
+ }
+ }
+
public function getSuperGlobalNames() {
return array(
'$GLOBALS',
diff --git a/src/lint/linter/__tests__/xhpast/duplicate-switch-case.lint-test b/src/lint/linter/__tests__/xhpast/duplicate-switch-case.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/duplicate-switch-case.lint-test
@@ -0,0 +1,28 @@
+<?php
+$x = null;
+$y = null;
+switch ($x) {}
+switch ($x) {
+ case 1: break;
+ case '1': break;
+ case true: break;
+ case null: break;
+ default: break;
+}
+switch ($x) {
+ case 'foo': break;
+ case 'bar': break;
+ case 'foo': break;
+
+ default:
+ switch ($y) {
+ case 'foo': break;
+ case 'bar': break;
+ case 'baz': break;
+ case 'baz': break;
+ }
+ break;
+}
+~~~~~~~~~~
+error:15:3
+error:22:7

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 7, 8:51 PM (2 d, 4 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7706153
Default Alt Text
D11171.diff (3 KB)

Event Timeline