Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Unified Diff: compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java

Issue 9959054: More error recovery back to the top level for some cases (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Previous patch had problems when JUnit tests added Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java b/compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d0e9381612e228f96f1f717ff395892441675d7
--- /dev/null
+++ b/compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java
@@ -0,0 +1,255 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.google.dart.compiler.parser;
+
+import com.google.common.base.Joiner;
+import com.google.dart.compiler.ast.DartClass;
+import com.google.dart.compiler.ast.DartFieldDefinition;
+import com.google.dart.compiler.ast.DartIdentifier;
+import com.google.dart.compiler.ast.DartMethodDefinition;
+import com.google.dart.compiler.ast.DartUnit;
+
+public class ParserRecoveryTest extends AbstractParserTest {
+
+ @Override
+ public void testStringsErrors() {
+ // Implemented elsewhere
+ }
+
+ public void testVarOnMethodDefinition() {
+ // This syntax is illegal, and should produce errors, but since it is a common error,
+ // we want to make sure it produce a valid AST for editor users
+ DartUnit unit = parseUnit("phony_var_on_method.dart",
+ Joiner.on("\n").join(
+ "var f1() { return 1;}", // Error, use of var on a method
+ "class A { ",
+ " var f2() { return 1;}", // Error, use of var on a method
+ " f3() { return 2; }",
+ "}"),
+ ParserErrorCode.VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 1, 1,
+ ParserErrorCode.VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 3, 3);
+ DartMethodDefinition f1 = (DartMethodDefinition)unit.getTopLevelNodes().get(0);
+ assertEquals("f1", ((DartIdentifier)(f1.getName())).getName());
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
+ DartMethodDefinition f2 = (DartMethodDefinition)(A.getMembers().get(0));
+ assertEquals("f2", ((DartIdentifier)(f2.getName())).getName());
+ // Make sure that parsing continue
+ DartMethodDefinition f3 = (DartMethodDefinition)(A.getMembers().get(1));
+ assertEquals("f3", ((DartIdentifier)(f3.getName())).getName());
+ }
+
+ public void testFinalOnMethodDefinition() {
+ // This syntax is illegal, and should produce errors, but since it is a common error,
+ // we want to make sure it produce a valid AST for editor users
+ DartUnit unit = parseUnit("phony_final_on_method.dart",
+ Joiner.on("\n").join(
+ "final f1() {return 1;}", // Error, use of final on a method
+ "class A { ",
+ " final f2() {return 1;}", // Error, use of final on a method
+ " f3() { return 2; }",
+ " final String f4() { return 1; }", // Error, use of final on a method
+ "}"),
+ ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 1, 1,
+ ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 3, 3,
+ ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 5, 9);
+ DartMethodDefinition f1 = (DartMethodDefinition)unit.getTopLevelNodes().get(0);
+ assertEquals("f1", ((DartIdentifier)(f1.getName())).getName());
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
+ DartMethodDefinition f2 = (DartMethodDefinition)(A.getMembers().get(0));
+ assertEquals("f2", ((DartIdentifier)(f2.getName())).getName());
+ DartMethodDefinition f3 = (DartMethodDefinition)(A.getMembers().get(1));
+ assertEquals("f3", ((DartIdentifier)(f3.getName())).getName());
+ DartMethodDefinition f4 = (DartMethodDefinition)(A.getMembers().get(2));
+ assertEquals("f4", ((DartIdentifier)(f4.getName())).getName());
+ }
+
+ public void testRecoverToTopLevel1() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel1.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ "", // error - missing right brace
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel2() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel2.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " var incomplete", // error - missing semicolon
+ "", // error - missing closing brace
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel3() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel3.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " var incomplete = ", // error - missing value
+ "", // error - missing closing brace
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel4() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel4.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " incomplete()", // error - missing body
+ "", // error - missing right brace
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel5() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel5.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " incomplete()", // error - missing body
+ "}",
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel6() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel6.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " method() { instance.field", // error - missing semicolon, missing rbrace
+ "}",
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel7() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel7.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " method() { instance.field", // error - missing semicolon, missing rbrace
+ "", // error missing rbrace
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testRecoverToTopLevel8() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel8.dart",
+ Joiner.on("\n").join(
+ "class A {",
+ " var a;",
+ " method() {",
+ " B instance ;",
+ " instance.", // error - missing semicolon, missing rbrace
+ "", // error missing rbrace
+ "class B { ", // error recover should pick up class B
+ " var b;",
+ "}"));
+ // Make sure class B is still around
+ DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("A", A.getName().getName());
+ DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
+ assertEquals("a", A_a.getFields().get(0).getName().getName());
+ DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
+ assertEquals("B", B.getName().getName());
+ DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
+ assertEquals("b", B_b.getFields().get(0).getName().getName());
+ }
+
+ public void testReservedWordClass() {
+ DartUnit unit = parseUnitUnspecifiedErrors("phony_reserved_word_class",
+ Joiner.on("\n").join(
+ "class foo {}",
+ "main() {",
+ " int class = 10;",
+ " print(\"class = $class\");",
+ "}",
+ "class bar {}"));
zundel 2012/04/02 20:02:59 I added another top level class definition to assu
+ DartClass foo = (DartClass)unit.getTopLevelNodes().get(0);
+ assertEquals("foo", foo.getName().getName());
+ DartMethodDefinition mainMethod = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
+ assertEquals("main", ((DartIdentifier)mainMethod.getName()).getName());
+ // The recovery on 'int class' closes the main method, assuming int class = 10 is a
+ // new toplevel so 'print' ends up as a bogus top level node.
+ DartClass bar = (DartClass)unit.getTopLevelNodes().get(3);
+ assertEquals("bar", bar.getName().getName());
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698