// 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) {",
        "  }",
        "}",
        ""));
  }
}
