blob: e1c94ca4e033a9e1a218effc8d3ee9ad840f2102 [file] [log] [blame]
// 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.CompilerTestCase;
import com.google.dart.compiler.ast.DartClass;
import com.google.dart.compiler.ast.DartIdentifier;
import com.google.dart.compiler.ast.DartMethodDefinition;
import com.google.dart.compiler.ast.DartNode;
import com.google.dart.compiler.ast.DartUnit;
import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
import static com.google.dart.compiler.common.ErrorExpectation.errEx;
import java.util.List;
import java.util.Set;
/**
* Negative Parser/Syntax tests.
*/
public class NegativeParserTest extends CompilerTestCase {
public void test_deprecatedGetterSyntax() {
parseExpectErrors("get foo() {}", errEx(ParserErrorCode.DEPRECATED_GETTER, 1, 5, 3));
}
public void test_deprecatedStrictEQ() {
parseExpectErrors(makeCode(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" 1 === 2;",
"}",
""), errEx(ParserErrorCode.DEPRECATED_STRICT_EQ, 3, 5, 3));
}
public void test_deprecatedStrictNE() {
parseExpectErrors(makeCode(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" 1 !== 2;",
"}",
""), errEx(ParserErrorCode.DEPRECATED_STRICT_NE, 3, 5, 3));
}
public void test_deprecatedAbstract() {
parseExpectWarnings(makeCode(
"// filler filler filler filler filler filler filler filler filler filler",
"abstract class A {",
" abstract m();",
"}",
""), errEx(ParserErrorCode.DEPRECATED_ABSTRACT_METHOD, 3, 3, 8));
}
public void testFieldInitializerInRedirectionConstructor1() {
parseExpectErrors(
"class A { A(x) { } A.foo() : this(5), y = 5; var y; }",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 39, 5),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 30, 7));
}
public void test_deprecatedFunctionLiteral() {
parseExpectWarnings(
makeCode(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" var x = f() => 42;",
" var y = int g() => 87;",
"}",
""),
errEx(ParserErrorCode.DEPRECATED_FUNCTION_LITERAL, 3, 11, 1),
errEx(ParserErrorCode.DEPRECATED_FUNCTION_LITERAL, 4, 11, 3));
}
public void testFieldInitializerInRedirectionConstructor2() {
parseExpectErrors(
"class A { A(x) { } A.foo() : y = 5, this(5); var y; }",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 5),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 37, 7));
}
public void testFieldInitializerInRedirectionConstructor3() {
parseExpectErrors(
"class A { A.foo(x) { } A() : y = 5, this.foo(5); var y; }",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 5),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 37, 11));
}
public void testFieldInitializerInRedirectionConstructor4() {
parseExpectErrors(
"class A { A(x) { } A.foo(this.y, this.z) : this(5); var y; var z;}",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 26, 6),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 34, 6),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 44, 7));
}
public void testFieldInitializerInRedirectionConstructor5() {
parseExpectErrors(
"class A { A(x) { } A.foo(this.y) : this(5), z = 7; var y; var z;}",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 26, 6),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 45, 5),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 36, 7));
}
public void testSuperInRedirectionConstructor1() {
parseExpectErrors(
"class A { A(x) { } A.foo() : this(5), super(); var y; }",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 39, 7),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 30, 7));
}
public void testSuperInRedirectionConstructor2() {
parseExpectErrors(
"class A { A(x) { } A.foo() : super(), this(5); var y; }",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 7),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 39, 7));
}
public void testMultipleRedirectionConstructors() {
parseExpectErrors(
"class A { A(x) { } A.foo() : this(1), this(2); }",
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE, 1, 30, 7),
errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE, 1, 39, 7));
}
/**
* May be parsing errors, but not exceptions.
* <p>
* http://code.google.com/p/dart/issues/detail?id=4040
*/
public void test_incompleteArguments() {
parseSource(makeCode(
"// filler filler filler filler filler filler filler filler filler filler",
"main() {",
" f(a: 0,",
"}",
""));
}
public void testSuperMultipleInvocationsTest() {
String source =
makeCode(
"class A {",
" int a;",
" A(this.a);",
" A.foo(int x, int y);",
"}",
"",
"class B extends A {",
" int b1;",
" int b2;",
" B(int x) : this.b1 = x, super(x), this.b2 = x, super.foo(x, x);",
"}");
parseExpectErrors(
source,
errEx(ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE, 10, 29, 8),
errEx(ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE, 10, 52, 15));
}
public void testIncompleteClassDeclaration_noLBrace() {
String sourceCode =
makeCode(
"class Baz",
"class Foo<T> implements Bar<T> {",
" Foo(T head, Bar<T> tail);",
"}");
DartUnit unit =
parseSourceUnitErrors(
sourceCode,
ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE.getMessage(),
2,
1);
// check structure of AST, top level Baz and Foo expected
assertEquals(2, unit.getTopLevelNodes().size());
assertEquals(
makeCode(
"// unit Test.dart",
"class Baz {",
"}",
"",
"class Foo<T> implements Bar<T> {",
"",
" Foo(T head, Bar<T> tail) ;",
"}",
""),
unit.toSource());
}
/**
* Language specification requires that factory should be declared in class. However declaring
* factory on top level should not cause exceptions in compiler. To ensure this we parse top level
* factory into normal {@link DartMethodDefinition}.
* <p>
* http://code.google.com/p/dart/issues/detail?id=345
*/
public void test_badTopLevelFactory() {
DartUnit unit =
parseSourceUnitErrors(
"factory foo() {}",
ParserErrorCode.FACTORY_CANNOT_BE_TOP_LEVEL.getMessage(),
1,
1);
DartMethodDefinition factory = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
assertNotNull(factory);
// this factory has name, which is allowed for normal method
assertEquals(true, factory.getName() instanceof DartIdentifier);
assertEquals("foo", ((DartIdentifier) factory.getName()).getName());
}
public void test_defaultParameterValue_inClosureTypedef() {
parseExpectErrors(
"typedef void f(int a, [int b = 12345, inc c]);",
errEx(ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_TYPEDEF, 1, 32, 5));
}
public void test_defaultParameterValue_inClosure() {
parseExpectErrors(
"class A {void f(void cb(int a, [int b = 12345, int c])) {}}",
errEx(ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_CLOSURE, 1, 41, 5));
}
public void test_optionalPositionalParameterValue_inSetter() {
parseExpectErrors(
"class A { set f([int b]); }",
errEx(ParserErrorCode.OPTIONAL_POSITIONAL_PARAMETER_NOT_ALLOWED, 1, 18, 5));
}
public void test_namedParameterValue_inSetter() {
parseExpectErrors(
"class A { set f({int b}); }",
errEx(ParserErrorCode.NAMED_PARAMETER_NOT_ALLOWED, 1, 18, 5));
}
public void test_missingEndOfOptionalParameters() {
parseExpectErrors(
"class A {void m(var p1, [var p2 = const []) {} }",
errEx(ParserErrorCode.MISSING_OPTIONAL_PARAMETER_END, 1, 43, 1));
}
public void test_optionalPositionalParameterValue_inOperator() {
parseExpectErrors(
"class A { operator []=(int a, [int b]); }",
errEx(ParserErrorCode.OPTIONAL_POSITIONAL_PARAMETER_NOT_ALLOWED, 1, 32, 5));
}
public void test_namedParameterValue_inOperator() {
parseExpectErrors(
"class A { operator []=(int a, {int b}); }",
errEx(ParserErrorCode.NAMED_PARAMETER_NOT_ALLOWED, 1, 32, 5));
}
/**
* If keyword "extends" is mistyped in type parameters declaration, we should report about this
* and then recover correctly.
* <p>
* http://code.google.com/p/dart/issues/detail?id=341
*/
public void test_parseTypeParameter_expectedExtends_mistypedExtends() throws Exception {
DartParserRunner parserRunner =
parseSource(Joiner.on("\n").join(
"class A {",
"}",
"class B<X ex> {",
"}",
"class C<X extneds A> {",
"}",
"class D<X extneds A, Y extends A> {",
"}"));
// check expected errors
assertErrors(
parserRunner.getErrors(),
errEx(ParserErrorCode.EXPECTED_EXTENDS, 3, 11, 2),
errEx(ParserErrorCode.EXPECTED_EXTENDS, 5, 11, 7),
errEx(ParserErrorCode.EXPECTED_EXTENDS, 7, 11, 7));
// check structure of AST
DartUnit dartUnit = parserRunner.getDartUnit();
String expected =
Joiner.on("\n").join(
"// unit " + getName(),
"class A {",
"}",
"",
"class B<X> {",
"}",
"",
"class C<X extends A> {",
"}",
"",
"class D<X extends A, Y extends A> {",
"}");
String actual = dartUnit.toSource().trim();
if (!expected.equals(actual)) {
System.err.println("Expected:\n" + expected);
System.err.println("\nActual:\n" + actual);
}
assertEquals(expected, actual);
}
/**
* Type parameters declaration is not finished.
* <p>
* http://code.google.com/p/dart/issues/detail?id=341
*/
public void test_parseTypeParameter_unfinishedTypeParameters() throws Exception {
DartParserRunner parserRunner =
parseSource(Joiner.on("\n").join(
"class ClassWithLongEnoughName {",
"}",
"class B<X {",
"}",
"class C {",
"}"));
// check expected errors
assertErrors(
parserRunner.getErrors(),
errEx(ParserErrorCode.EXPECTED_EXTENDS, 3, 11, 1),
errEx(ParserErrorCode.EXPECTED_TOKEN, 4, 1, 1),
errEx(ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE, 5, 1, 5));
// check structure of AST
DartUnit dartUnit = parserRunner.getDartUnit();
assertEquals(
Joiner.on("\n").join(
"// unit " + getName(),
"class ClassWithLongEnoughName {",
"}",
"",
"class B<X> {",
"}",
"",
"class C {",
"}"),
dartUnit.toSource().trim());
}
/**
* Type parameters declaration is not finished, next top level element beginning encountered. May
* be use just types new class declaration before existing one.
* <p>
* http://code.google.com/p/dart/issues/detail?id=341
*/
public void test_parseTypeParameter_nextTopLevelInTheMiddle() throws Exception {
DartParserRunner parserRunner =
parseSource(Joiner.on("\n").join(
"class ClassWithLongEnoughName {",
"}",
"class B<X",
"class C {",
"}"));
// check expected errors
assertErrors(parserRunner.getErrors(),
errEx(ParserErrorCode.EXPECTED_TOKEN, 4, 1, 5));
// check structure of AST
DartUnit dartUnit = parserRunner.getDartUnit();
assertEquals(
Joiner.on("\n").join(
"// unit " + getName(),
"class ClassWithLongEnoughName {",
"}",
"",
"class B<X> {",
"}",
"",
"class C {",
"}"),
dartUnit.toSource().trim());
}
/**
* Function signatures require the name to be an identifier; especially true at the top level.
* <p>
* http://code.google.com/p/dart/issues/detail?id=839
*/
public void testTopLevelFunctionNotIdentifier() {
parseExpectErrors(
"foo.baz() {}",
errEx(ParserErrorCode.FUNCTION_NAME_EXPECTED_IDENTIFIER, 1, 1, 7));
}
public void testInvalidStringInterpolation() {
parseExpectErrors(
Joiner.on("\n").join(
"void main() {",
" print(\"1 ${42} 2 ${} 3\");",
" print(\"1 ${42} 2 ${10;} 3\");",
" print(\"1 ${42} 2 ${10,20} 3\");",
" print(\"1 ${42} 2 ${10 20} 3\");",
" print(\"$\");",
" print(\"$",
"}"),
errEx(ParserErrorCode.UNEXPECTED_TOKEN, 2, 22, 1),
errEx(ParserErrorCode.EXPECTED_TOKEN, 2, 23, 3),
errEx(ParserErrorCode.EXPECTED_TOKEN, 3, 24, 1),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 3, 25, 1),
errEx(ParserErrorCode.EXPECTED_TOKEN, 4, 24, 1),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 4, 25, 2),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 4, 27, 1),
errEx(ParserErrorCode.EXPECTED_TOKEN, 5, 25, 2),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 5, 27, 1),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 6, 11, 0),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 7, 11, 0),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 7, 11, 1),
errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 8, 1, 1),
errEx(ParserErrorCode.INCOMPLETE_STRING_LITERAL, 8, 1, 1),
errEx(ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_PAREN, 8, 2, 0));
}
public void testDeprecatedFactoryInInterface() {
parseExpectWarnings(
"interface foo factory bar {}",
errEx(ParserErrorCode.DEPRECATED_INTERFACE, 1, 1, 9),
errEx(ParserErrorCode.DEPRECATED_USE_OF_FACTORY_KEYWORD, 1, 15, 7));
}
public void test_deprecatedRawString() {
parseExpectWarnings(
"String s() { return @'s'; }",
errEx(ParserErrorCode.DEPRECATED_RAW_STRING, 1, 21, 1));
}
public void test_useExtendsInTypedef() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"typedef ParameterizedFun1<T, U extends bool, V>(T t, U u);",
""));
}
public void test_abstractTopLevel_class() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"abstract class A {",
"}"));
}
public void test_abstractTopLevel_interface() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"abstract interface A {",
"}"),
errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 10, 9),
errEx(ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT, 2, 1, 8));
}
public void test_deprecatedInterface() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"interface A {",
"}"),
errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 1, 9));
}
public void test_abstractTopLevel_typedef() {
parseExpectErrors(
"abstract typedef void f();",
errEx(ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT, 1, 1, 8));
}
public void test_abstractTopLevel_method() {
parseExpectErrors(
"abstract void foo() {}",
errEx(ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT, 1, 1, 8));
}
public void test_incompleteExpressionInInterpolation() {
parseExpectErrors(
"var s = 'fib(3) = ${fib(3}';",
errEx(ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_PAREN, 1, 26, 1));
}
public void test_interfaceMethodWithBody() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"interface A {",
" foo() {",
" }",
"}"),
errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 1, 9),
errEx(ParserErrorCode.INTERFACE_METHOD_WITH_BODY, 3, 3, 3));
}
/**
* The Language Specification in the section 6.1 states: "It is a compile-time error to preface a
* function declaration with the built-in identifier static."
*/
public void test_staticFunction_topLevel() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"static foo() {",
"}"),
errEx(ParserErrorCode.TOP_LEVEL_CANNOT_BE_STATIC, 2, 1, 6));
}
/**
* The Language Specification in the section 6.1 states: "It is a compile-time error to preface a
* function declaration with the built-in identifier static."
*/
public void test_staticFunction_local() {
DartParserRunner parserRunner =
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"topLevelMethodWithLongEnoughNameToForceWrapping() {",
" static int localFunction() {",
" }",
"}"),
errEx(ParserErrorCode.LOCAL_CANNOT_BE_STATIC, 3, 3, 6));
// Check that "static" was ignored and "int" parsed as return type.
assertEquals(
makeCode(
"// unit " + getName(),
"",
"topLevelMethodWithLongEnoughNameToForceWrapping() {",
" int localFunction() {",
" };",
"}"),
parserRunner.getDartUnit().toSource());
}
public void test_positionalArgument_afterNamed() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"f(r1, [n1, n2]) {}",
"foo() {",
" f(-1, n1: 1, 2);",
"}"),
errEx(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, 4, 16, 1));
}
public void test_unaryPlus() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"var a = 1;",
"var b = -1;",
"var c = +1;",
"var d = -a;",
"var e = +a;",
"var f = + 1;",
""),
errEx(ParserErrorCode.NO_UNARY_PLUS_OPERATOR, 6, 9, 1),
errEx(ParserErrorCode.NO_SPACE_AFTER_PLUS, 7, 9, 1));
}
public void test_formalParameters_const() throws Exception {
parseExpectErrors(
Joiner.on("\n").join(
"func_const(const x) {}",
"func_constTyped(const int $) {}"),
errEx(ParserErrorCode.FORMAL_PARAMETER_IS_CONST, 1, 12, 5),
errEx(ParserErrorCode.FORMAL_PARAMETER_IS_CONST, 2, 17, 5));
}
/**
* Test with variants of function declarations and function literal invocations.
*/
public void test_functionDeclaration_functionLiteral() {
DartParserRunner parserRunner =
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"foo() {",
" f0(p){}", // declaration of function as statement
" int f1(p){}", // declaration of function as statement, has type
" var res = (p){}(1);", // invocation of function literal in assignment
" (p){}(2);", // invocation of function literal in statement, no name
" f3(p) => 4;", // function with => arrow ends with ';'
" (5);", // this is separate statement, not invocation of previous function
" join(promises, (p) => 6);", // function with => arrow as argument
" join(promises, (p) {return 7;});", // function with block as argument
"}",
""));
assertEquals(
makeCode(
"// unit " + getName(),
"",
"foo() {",
" f0(p) {",
" };",
" int f1(p) {",
" };",
" var res = (p) {",
" }(1);",
" (p) {",
" }(2);",
" f3(p) {",
" return 4;",
" };",
" (5);",
" join(promises, (p) {",
" return 6;",
" });",
" join(promises, (p) {",
" return 7;",
" });",
"}"),
parserRunner.getDartUnit().toSource());
}
/**
* Test for {@link DartUnit#getTopDeclarationNames()}.
*/
public void test_getTopDeclarationNames() throws Exception {
DartParserRunner parserRunner =
parseSource(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class MyClass {}",
"class MyInterface {}",
"topLevelMethod() {}",
"int get topLevelGetter {return 0;}",
"void set topLevelSetter(int v) {}",
"typedef void MyTypeDef();",
""));
DartUnit unit = parserRunner.getDartUnit();
// Check top level declarations.
Set<String> names = unit.getTopDeclarationNames();
assertEquals(6, names.size());
assertTrue(names.contains("MyClass"));
assertTrue(names.contains("MyInterface"));
assertTrue(names.contains("topLevelMethod"));
assertTrue(names.contains("topLevelGetter"));
assertTrue(names.contains("topLevelSetter"));
assertTrue(names.contains("MyTypeDef"));
}
/**
* Test for {@link DartUnit#getTopDeclarationNames()} and qualified top-level method name.
* <p>
* http://code.google.com/p/dart/issues/detail?id=1738
*/
public void test_getTopDeclarationNames_badName() throws Exception {
DartParserRunner parserRunner =
parseSource(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"void my.method() {}",
""));
DartUnit unit = parserRunner.getDartUnit();
// We have top-level node...
List<DartNode> topLevelNodes = unit.getTopLevelNodes();
assertEquals(1, topLevelNodes.size());
// ...but it has wrong name, so ignored.
Set<String> names = unit.getTopDeclarationNames();
assertEquals(0, names.size());
}
/**
* Test for {@link DartUnit#getDeclarationNames()}.
*/
public void test_getDeclarationNames() throws Exception {
DartParserRunner parserRunner =
parseSource(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class MyClass<TypeVar> {",
" myMethod(int pA, int pB) {",
" int varA;",
" try {",
" } catch(var ex) {",
" }",
" }",
"}",
"topLevelMethod() {}",
"int get topLevelGetter {return 0;}",
"void set topLevelSetter(int setterParam) {}",
"typedef void MyTypeDef();",
""));
DartUnit unit = parserRunner.getDartUnit();
// Check all declarations.
Set<String> names = unit.getDeclarationNames();
assertEquals(12, names.size());
assertTrue(names.contains("MyClass"));
assertTrue(names.contains("TypeVar"));
assertTrue(names.contains("myMethod"));
assertTrue(names.contains("pA"));
assertTrue(names.contains("pB"));
assertTrue(names.contains("varA"));
assertTrue(names.contains("ex"));
assertTrue(names.contains("topLevelMethod"));
assertTrue(names.contains("topLevelGetter"));
assertTrue(names.contains("topLevelSetter"));
assertTrue(names.contains("setterParam"));
assertTrue(names.contains("MyTypeDef"));
}
/**
* There was bug in diet parser, it did not understand new "arrow" syntax of function definition.
*/
public void test_dietParser_functionArrow() {
DartParserRunner parserRunner =
DartParserRunner.parse(
getName(),
Joiner.on("\n").join(
"class ClassWithVeryLongNameEnoughToForceLineWrapping {",
" foo() => return 0;",
"}",
""),
true);
assertErrors(parserRunner.getErrors());
assertEquals(
Joiner.on("\n").join(
"// unit " + getName(),
"class ClassWithVeryLongNameEnoughToForceLineWrapping {",
"",
" foo() {",
" }",
"}"),
parserRunner.getDartUnit().toSource().trim());
}
/**
* "get" is valid name for method, it can cause warning, but not parsing failure.
*/
public void test_methodNamed_get() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" void get() {}",
"}",
""));
}
/**
* "set" is valid name for method, it can cause warning, but not parsing failure.
*/
public void test_methodNamed_set() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" void set() {}",
"}",
""));
}
/**
* "operator" is valid name for method, it can cause warning, but not parsing failure.
*/
public void test_methodNamed_operator() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" void operator() {}",
"}",
""));
}
/**
* We can parse operator "call" declaration.
*/
public void test_operator_call() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" operator call() {}",
"}",
""));
}
/**
* We can parse operator "equals" declaration.
*/
public void test_operator_equals() {
DartParserRunner runner = parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" operator ==(other) => false;",
"}",
""));
DartClass clazz = (DartClass) runner.getDartUnit().getTopLevelNodes().get(0);
DartMethodDefinition method = (DartMethodDefinition) clazz.getMembers().get(0);
assertTrue(method.getModifiers().isOperator());
}
/**
* "native" can be specified only for classes.
*/
public void test_native_inInterace() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"interface A native 'N' {",
"}",
""),
errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 1, 9),
errEx(ParserErrorCode.NATIVE_ONLY_CLASS, 2, 13, 6));
}
/**
* "native" can be specified only for classes without "extends".
*/
public void test_native_classWithExtends() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
"}",
"class B extends A native 'N' {",
"}",
""),
errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 4, 19, 6));
}
/**
* "native" can be specified only in "corelib".
*/
public void test_native_onlyCoreLib() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A native 'N' {",
"}",
""),
errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 2, 9, 6));
}
/**
* "native" can be specified only in "corelib".
*/
public void test_native_onlyCoreLib_factory() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" factory A() native;",
"}",
""),
errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 3, 15, 6));
}
/**
* "native" can be specified only in "corelib".
*/
public void test_native_onlyCoreLib_method() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" factory A() native;",
"}",
""),
errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 3, 15, 6));
}
/**
* The spec in the section 10.28 says:
* <p>
* It is a compile-time error if a built-in identifier is used as the declared name of a class,
* interface, type variable or type alias.
* <p>
* http://code.google.com/p/dart/issues/detail?id=3477
*/
public void test_builtInIdentifier_asClassName() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class abstract {}",
"class as {}",
"class dynamic {}",
"class export {}",
"class external {}",
"class factory {}",
"class get {}",
"class implements {}",
"class import {}",
"class library {}",
"class operator {}",
"class part {}",
"class set {}",
"class static {}",
"class typedef {}",
""),
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 2, 7, 8), // abstract
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 3, 7, 2), // as
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 4, 7, 7), // dynamic
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 5, 7, 6), // export
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 7, 8), // external
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 7, 7, 7), // factory
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 8, 7, 3), // get
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 9, 7, 10), // implements
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 10, 7, 6), // import
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 11, 7, 7), // library
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 12, 7, 8), // operator
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 13, 7, 4), // part
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 14, 7, 3), // set
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 15, 7, 6), // static
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 16, 7, 7)); // typedef
}
/**
* The spec in the section 10.28 says:
* <p>
* It is a compile-time error if a built-in identifier is used as the declared name of a class,
* interface, type variable or type alias.
* <p>
* http://code.google.com/p/dart/issues/detail?id=3477
*/
public void test_builtInIdentifier_asTypevariableName() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class C01<abstract> {}",
"class C02<as> {}",
"class C03<dynamic> {}",
"class C04<export> {}",
"class C05<external> {}",
"class C06<factory> {}",
"class C07<get> {}",
"class C08<implements> {}",
"class C09<import> {}",
"class C10<library> {}",
"class C11<operator> {}",
"class C12<part> {}",
"class C13<set> {}",
"class C14<static> {}",
"class C15<typedef> {}",
""),
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 2, 11, 8), // abstract
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 3, 11, 2), // as
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 4, 11, 7), // dynamic
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 5, 11, 6), // export
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 6, 11, 8), // external
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 7, 11, 7), // factory
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 8, 11, 3), // get
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 9, 11, 10), // implements
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 10, 11, 6), // import
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 11, 11, 7), // library
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 12, 11, 8), // operator
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 13, 11, 4), // part
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 14, 11, 3), // set
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 15, 11, 6), // static
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 16, 11, 7)); // typedef
}
/**
* The spec in the section 10.28 says:
* <p>
* It is a compile-time error if a built-in identifier is used as the declared name of a class,
* interface, type variable or type alias.
* <p>
* http://code.google.com/p/dart/issues/detail?id=3477
*/
public void test_builtInIdentifier_asTypedefName() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"typedef abstract();",
"typedef as();",
"typedef dynamic();",
"typedef export();",
"typedef external();",
"typedef factory();",
"typedef get();",
"typedef implements();",
"typedef import();",
"typedef library();",
"typedef operator();",
"typedef part();",
"typedef set();",
"typedef static();",
"typedef typedef();",
""),
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 2, 9, 8), // abstract
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 3, 9, 2), // as
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 4, 9, 7), // dynamic
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 5, 9, 6), // export
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 6, 9, 8), // external
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 7, 9, 7), // factory
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 8, 9, 3), // get
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 9, 9, 10), // implements
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 10, 9, 6), // import
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 11, 9, 7), // library
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 12, 9, 8), // operator
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 13, 9, 4), // part
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 14, 9, 3), // set
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 15, 9, 6), // static
errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 16, 9, 7)); // typedef
}
/**
* There is ambiguity in parsing function expression inside of initializer.
* <p>
* But we should be able to parse when function expression is inside of "new expression".
* <p>
* http://code.google.com/p/dart/issues/detail?id=2339
*/
public void test_functionExpression_inInitializer_newExpression() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" A(var p) {}",
"}",
"class B {",
" var f;",
" B() : f = new A(() => 42) {",
" }",
"}",
""));
}
/**
* There is ambiguity in parsing function expression inside of initializer.
* <p>
* But we should be able to parse when function expression is inside of "const expression".
* <p>
* http://code.google.com/p/dart/issues/detail?id=2339
*/
public void test_functionExpression_inInitializer_constExpression() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"class A {",
" const A(var p) {}",
"}",
"class B {",
" var f;",
" B() : f = const A(() => 42) {",
" }",
"}",
""));
}
/**
* There is ambiguity in parsing function expression inside of initializer.
* <p>
* But we should be able to parse when function expression is inside of "method invocation".
* <p>
* http://code.google.com/p/dart/issues/detail?id=2339
*/
public void test_functionExpression_inInitializer_methodInvocation() {
parseExpectErrors(
Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"foo(var p) {}",
"class B {",
" var f;",
" B() : f = foo(() => 42) {",
" }",
"}",
""));
}
public void test_qualifiedType_inForIn() {
parseExpectErrors(Joiner.on("\n").join(
"// filler filler filler filler filler filler filler filler filler filler",
"foo() {",
" for (pref.A a in elements) {",
" }",
"}",
""));
}
}