Issue 2862. Report warning when 'default' of switch has fall-through.
http://code.google.com/p/dart/issues/detail?id=2862

R=brianwilkerson@google.com
BUG=

Review URL: https://codereview.chromium.org//11555015

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@16052 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index a58472e..89ed7f1 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -19,7 +19,6 @@
 import com.google.dart.compiler.ast.DartBlock;
 import com.google.dart.compiler.ast.DartBooleanLiteral;
 import com.google.dart.compiler.ast.DartBreakStatement;
-import com.google.dart.compiler.ast.DartCase;
 import com.google.dart.compiler.ast.DartCatchBlock;
 import com.google.dart.compiler.ast.DartClass;
 import com.google.dart.compiler.ast.DartComment;
@@ -1132,21 +1131,6 @@
       return null;
     }
 
-    @Override
-    public Element visitCase(DartCase node) {
-      super.visitCase(node);
-      List<DartStatement> statements = node.getStatements();
-      // the last statement should be: break, continue, return, throw
-      if (!statements.isEmpty()) {
-        DartStatement lastStatement = statements.get(statements.size() - 1);
-        if (!isValidLastSwitchCaseStatement(lastStatement)) {
-          onError(lastStatement, ResolverErrorCode.SWITCH_CASE_FALL_THROUGH);
-        }
-      }
-      // done
-      return null;
-    }
-
     private boolean isValidLastSwitchCaseStatement(DartStatement statement) {
       if (statement instanceof DartExprStmt) {
         DartExprStmt exprStmt = (DartExprStmt) statement;
@@ -1160,9 +1144,23 @@
 
     @Override
     public Element visitSwitchMember(DartSwitchMember x) {
-      getContext().pushScope("<switch member>");
-      x.visitChildren(this);
-      getContext().popScope();
+      // visit children
+      {
+        getContext().pushScope("<switch member>");
+        x.visitChildren(this);
+        getContext().popScope();
+      }
+      // check fall-through
+      {
+        List<DartStatement> statements = x.getStatements();
+        // the last statement should be: break, continue, return, throw
+        if (!statements.isEmpty()) {
+          DartStatement lastStatement = statements.get(statements.size() - 1);
+          if (!isValidLastSwitchCaseStatement(lastStatement)) {
+            onError(lastStatement, ResolverErrorCode.SWITCH_CASE_FALL_THROUGH);
+          }
+        }
+      }
       return null;
     }
 
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index f72b906..9f8cd3c 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -470,6 +470,8 @@
         "        throw new Exception();",
         "      case 4:",
         "        bar();",
+        "      default:",
+        "        bar();",
         "    }",
         "  }",
         "}",
@@ -477,7 +479,8 @@
         "");
     assertErrors(
         libraryResult.getErrors(),
-        errEx(ResolverErrorCode.SWITCH_CASE_FALL_THROUGH, 14, 9, 6));
+        errEx(ResolverErrorCode.SWITCH_CASE_FALL_THROUGH, 14, 9, 6),
+        errEx(ResolverErrorCode.SWITCH_CASE_FALL_THROUGH, 16, 9, 6));
   }
 
   /**
@@ -3363,6 +3366,7 @@
         "  switch (true) {",
         "    default:",
         "      int v = foo;",
+        "      break;",
         "  }",
         "}",
         "");