// 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.

import 'dart:async';
import 'dart:collection';

import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/constants/expressions.dart';
import 'package:compiler/src/dart_types.dart';
import 'package:compiler/src/elements/modelx.dart';
import 'package:compiler/src/resolution/constructors.dart';
import 'package:compiler/src/resolution/members.dart';
import 'package:compiler/src/resolution/registry.dart';
import 'package:compiler/src/resolution/resolution_result.dart';
import 'package:compiler/src/resolution/scope.dart';
import 'package:compiler/src/resolution/tree_elements.dart';

import 'compiler_helper.dart';
import 'link_helper.dart';
import 'parser_helper.dart';

Node buildIdentifier(String name) => new Identifier(scan(name));

Node buildInitialization(String name) =>
  parseBodyCode('$name = 1',
      (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens));

createLocals(List variables) {
  var locals = <Node>[];
  for (final variable in variables) {
    String name = variable[0];
    bool init = variable[1];
    if (init) {
      locals.add(buildInitialization(name));
    } else {
      locals.add(buildIdentifier(name));
    }
  }
  var definitions = new NodeList(null, LinkFromList(locals), null, null);
  return new VariableDefinitions(null, Modifiers.EMPTY, definitions);
}

Future testLocals(List variables) {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    ResolutionResult result = visitor.visit(createLocals(variables));
    // A VariableDefinitions does not have an element.
    Expect.equals(const NoneResult(), result);
    Expect.equals(variables.length, map(visitor).length);

    for (final variable in variables) {
      final name = variable[0];
      Identifier id = buildIdentifier(name);
      ResolutionResult result = visitor.visit(id);
      final VariableElement variableElement = result.element;
      MethodScope scope = visitor.scope;
      Expect.equals(variableElement, scope.elements[name]);
    }
    return compiler;
  });
}

main() {
  asyncTest(() => Future.forEach([
    testLocalsOne,
    testLocalsTwo,
    testLocalsThree,
    testLocalsFour,
    testLocalsFive,
    testParametersOne,
    testFor,
    testTypeAnnotation,
    testSuperclass,
    // testVarSuperclass, // The parser crashes with 'class Foo extends var'.
    // testOneInterface, // Generates unexpected error message.
    // testTwoInterfaces, // Generates unexpected error message.
    testFunctionExpression,
    testNewExpression,
    testTopLevelFields,
    testClassHierarchy,
    testEnumDeclaration,
    testInitializers,
    testThis,
    testSuperCalls,
    testSwitch,
    testTypeVariables,
    testToString,
    testIndexedOperator,
    testIncrementsAndDecrements,
    testOverrideHashCodeCheck,
    testSupertypeOrder,
    testConstConstructorAndNonFinalFields,
    testCantAssignMethods,
    testCantAssignFinalAndConsts,
    testAwaitHint,
    testConstantExpressions,
  ], (f) => f()));
}

Future testSupertypeOrder() {
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""
class I1 {}
class I2 {}
class J1 extends K1 {}
class J2 implements K2 {}
class K1 {}
class K2 {}
class L1 {}
class A implements I1, I2 {}
class B extends A implements J1, J2 {}
class C extends B implements L1 {}
""");
      compiler.resolveStatement("C c;");
      ClassElement classA = compiler.mainApp.find("A");
      ClassElement classB = compiler.mainApp.find("B");
      ClassElement classC = compiler.mainApp.find("C");
      Expect.equals('[ I2, I1, Object ]', classA.allSupertypes.toString());
      Expect.equals('[ A, J2, J1, I2, I1, K2, K1, Object ]',
                    classB.allSupertypes.toString());
      Expect.equals('[ B, L1, A, J2, J1, I2, I1, K2, K1, Object ]',
                    classC.allSupertypes.toString());
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""
class X<T> {}
class Foo extends X<Foo> {}
class Bar extends Foo implements X<Bar> {}
""");
      compiler.resolveStatement("Bar bar;");
      ClassElement classBar = compiler.mainApp.find("Bar");
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(1, compiler.errors.length);
      Expect.equals(MessageKind.MULTI_INHERITANCE,
                    compiler.errors[0].message.kind);
      Expect.equals(0, compiler.crashes.length);
    }),
  ]);
}

Future testTypeVariables() {
  matchResolvedTypes(visitor, text, name, expectedElements) {
    VariableDefinitions definition = parseStatement(text);
    visitor.visit(definition.type);
    InterfaceType type = visitor.registry.mapping.getType(definition.type);
    Expect.equals(definition.type.typeArguments.slowLength(),
                  type.typeArguments.length);
    int index = 0;
    for (DartType argument in type.typeArguments) {
      Expect.equals(true, index < expectedElements.length);
      Expect.equals(expectedElements[index], argument.element);
      index++;
    }
    Expect.equals(index, expectedElements.length);
  }

  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      ResolverVisitor visitor = compiler.resolverVisitor();
      compiler.parseScript('class Foo<T, U> {}');
      ClassElement foo = compiler.mainApp.find('Foo');
      matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo',
                         [compiler.intClass, compiler.stringClass]);
      matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo',
                         [foo, foo]);
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript('class Foo<T, U> {}');
      compiler.resolveStatement('Foo<notype, int> x;');
      Expect.equals(1, compiler.warnings.length);
      Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
                    compiler.warnings[0].message.kind);
      Expect.equals(0, compiler.errors.length);
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript('class Foo<T, U> {}');
      compiler.resolveStatement('var x = new Foo<notype, int>();');
      Expect.equals(1, compiler.warnings.length);
      Expect.equals(0, compiler.errors.length);
      Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
                    compiler.warnings[0].message.kind);
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript('class Foo<T> {'
                           '  Foo<T> t;'
                           '  foo(Foo<T> f) {}'
                           '  bar() { g(Foo<T> f) {}; g(); }'
                           '}');
      ClassElement foo = compiler.mainApp.find('Foo');
      foo.ensureResolved(compiler);
      foo.lookupLocalMember('t').computeType(compiler);;
      foo.lookupLocalMember('foo').computeType(compiler);;
      compiler.resolver.resolve(foo.lookupLocalMember('bar'));
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(0, compiler.errors.length);
    }),
  ]);
}

Future testSuperCalls() {
  return MockCompiler.create((MockCompiler compiler) {
    String script = """class A { foo() {} }
                       class B extends A { foo() => super.foo(); }""";
    compiler.parseScript(script);
    compiler.resolveStatement("B b;");

    ClassElement classB = compiler.mainApp.find("B");
    FunctionElement fooB = classB.lookupLocalMember("foo");
    ClassElement classA = compiler.mainApp.find("A");
    FunctionElement fooA = classA.lookupLocalMember("foo");

    ResolverVisitor visitor =
        new ResolverVisitor(compiler, fooB,
            new ResolutionRegistry(compiler,
                new CollectingTreeElements(fooB)));
    FunctionExpression node = (fooB as FunctionElementX).parseNode(compiler);
    visitor.visit(node.body);
    Map mapping = map(visitor);

    Send superCall = node.body.asReturn().expression;
    FunctionElement called = mapping[superCall];
    Expect.isNotNull(called);
    Expect.equals(fooA, called);
  });
}

Future testSwitch() {
  return MockCompiler.create((MockCompiler compiler) {
    compiler.parseScript("class Foo { foo() {"
        "switch (null) { case '': break; case 2: break; } } }");
    compiler.resolveStatement("Foo foo;");
    ClassElement fooElement = compiler.mainApp.find("Foo");
    FunctionElement funElement = fooElement.lookupLocalMember("foo");
    compiler.processQueue(compiler.enqueuer.resolution, funElement);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.errors.length);
    Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
                  compiler.errors[0].message.kind);
    Expect.equals(2, compiler.infos.length);
    Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
                  compiler.infos[0].message.kind);
    Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
                  compiler.infos[1].message.kind);
  });
}

Future testThis() {
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo { foo() { return this; } }");
      compiler.resolveStatement("Foo foo;");
      ClassElement fooElement = compiler.mainApp.find("Foo");
      FunctionElement funElement = fooElement.lookupLocalMember("foo");
      ResolverVisitor visitor =
          new ResolverVisitor(compiler, funElement,
              new ResolutionRegistry(compiler,
                  new CollectingTreeElements(funElement)));
      FunctionExpression function =
          (funElement as FunctionElementX).parseNode(compiler);
      visitor.visit(function.body);
      Map mapping = map(visitor);
      List<Element> values = mapping.values.toList();
      Expect.equals(0, mapping.length);
      Expect.equals(0, compiler.warnings.length);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.resolveStatement("main() { return this; }");
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(1, compiler.errors.length);
      Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
                    compiler.errors[0].message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo { static foo() { return this; } }");
      compiler.resolveStatement("Foo foo;");
      ClassElement fooElement = compiler.mainApp.find("Foo");
      FunctionElement funElement = fooElement.lookupLocalMember("foo");
      ResolverVisitor visitor = new ResolverVisitor(compiler, funElement,
          new ResolutionRegistry(compiler,
              new CollectingTreeElements(funElement)));
      FunctionExpression function =
          (funElement as FunctionElementX).parseNode(compiler);
      visitor.visit(function.body);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(1, compiler.errors.length);
      Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
                    compiler.errors[0].message.kind);
    }),
  ]);
}

Future testLocalsOne() {
  return Future.forEach([
      () => testLocals([["foo", false]]),
      () => testLocals([["foo", false], ["bar", false]]),
      () => testLocals([["foo", false], ["bar", false], ["foobar", false]]),

      () => testLocals([["foo", true]]),
      () => testLocals([["foo", false], ["bar", true]]),
      () => testLocals([["foo", true], ["bar", true]]),

      () => testLocals([["foo", false], ["bar", false], ["foobar", true]]),
      () => testLocals([["foo", false], ["bar", true], ["foobar", true]]),
      () => testLocals([["foo", true], ["bar", true], ["foobar", true]]),

      () => testLocals([["foo", false], ["foo", false]])
          .then((MockCompiler compiler) {
      Expect.equals(1, compiler.errors.length);
      Expect.equals(
          new Message(
              MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION],
              {'name': 'foo'}, false),
          compiler.errors[0].message);
    })], (f) => f());
}


Future testLocalsTwo() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    Node tree = parseStatement("if (true) { var a = 1; var b = 2; }");
    ResolutionResult result = visitor.visit(tree);
    Expect.equals(const NoneResult(), result);
    MethodScope scope = visitor.scope;
    Expect.equals(0, scope.elements.length);
    Expect.equals(2, map(visitor).length);

    List<Element> elements = new List<Element>.from(map(visitor).values);
    Expect.notEquals(elements[0], elements[1]);
  });
}

Future testLocalsThree() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    Node tree = parseStatement("{ var a = 1; if (true) { a; } }");
    ResolutionResult result = visitor.visit(tree);
    Expect.equals(const NoneResult(), result);
    MethodScope scope = visitor.scope;
    Expect.equals(0, scope.elements.length);
    Expect.equals(2, map(visitor).length);
    List<Element> elements = map(visitor).values.toList();
    Expect.equals(elements[0], elements[1]);
  });
}

Future testLocalsFour() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }");
    ResolutionResult result = visitor.visit(tree);
    Expect.equals(const NoneResult(), result);
    MethodScope scope = visitor.scope;
    Expect.equals(0, scope.elements.length);
    Expect.equals(2, map(visitor).length);
    List<Element> elements = map(visitor).values.toList();
    Expect.notEquals(elements[0], elements[1]);
  });
}

Future testLocalsFive() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    If tree =
        parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}");
    ResolutionResult result = visitor.visit(tree);
    Expect.equals(const NoneResult(), result);
    MethodScope scope = visitor.scope;
    Expect.equals(0, scope.elements.length);
    Expect.equals(4, map(visitor).length);

    Block thenPart = tree.thenPart;
    List statements1 = thenPart.statements.nodes.toList();
    Node def1 = statements1[0].definitions.nodes.head;
    Node id1 = statements1[1].expression;
    Expect.equals(visitor.registry.mapping[def1],
                  visitor.registry.mapping[id1]);

    Block elsePart = tree.elsePart;
    List statements2 = elsePart.statements.nodes.toList();
    Node def2 = statements2[0].definitions.nodes.head;
    Node id2 = statements2[1].expression;
    Expect.equals(visitor.registry.mapping[def2],
                  visitor.registry.mapping[id2]);

    Expect.notEquals(visitor.registry.mapping[def1],
                     visitor.registry.mapping[def2]);
    Expect.notEquals(visitor.registry.mapping[id1],
                     visitor.registry.mapping[id2]);
  });
}

Future testParametersOne() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    FunctionExpression tree =
        parseFunction("void foo(int a) { return a; }", compiler);
    visitor.visit(tree);

    // Check that an element has been created for the parameter.
    VariableDefinitions vardef = tree.parameters.nodes.head;
    Node param = vardef.definitions.nodes.head;
    Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[param].kind);

    // Check that 'a' in 'return a' is resolved to the parameter.
    Block body = tree.body;
    Return ret = body.statements.nodes.head;
    Send use = ret.expression;
    Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[use].kind);
    Expect.equals(visitor.registry.mapping[param],
                  visitor.registry.mapping[use]);
  });
}

Future testFor() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }");
    visitor.visit(tree);

    MethodScope scope = visitor.scope;
    Expect.equals(0, scope.elements.length);
    Expect.equals(5, map(visitor).length);

    VariableDefinitions initializer = tree.initializer;
    Node iNode = initializer.definitions.nodes.head;
    Element iElement = visitor.registry.mapping[iNode];

    // Check that we have the expected nodes. This test relies on the mapping
    // field to be a linked hash map (preserving insertion order).
    Expect.isTrue(map(visitor) is LinkedHashMap);
    List<Node> nodes = map(visitor).keys.toList();
    List<Element> elements = map(visitor).values.toList();

    // for (int i = 0; i < 10; i = i + 1) { i = 5; };
    //          ^^^^^
    checkSendSet(iElement, nodes[0], elements[0]);

    // for (int i = 0; i < 10; i = i + 1) { i = 5; };
    //                 ^
    checkSend(iElement, nodes[1], elements[1]);

    // for (int i = 0; i < 10; i = i + 1) { i = 5; };
    //                             ^
    checkSend(iElement, nodes[2], elements[2]);

    // for (int i = 0; i < 10; i = i + 1) { i = 5; };
    //                         ^^^^^^^^^
    checkSendSet(iElement, nodes[3], elements[3]);

    // for (int i = 0; i < 10; i = i + 1) { i = 5; };
    //                                      ^^^^^
    checkSendSet(iElement, nodes[4], elements[4]);
  });
}

checkIdentifier(Element expected, Node node, Element actual) {
  Expect.isTrue(node is Identifier, node.toDebugString());
  Expect.equals(expected, actual);
}

checkSend(Element expected, Node node, Element actual) {
  Expect.isTrue(node is Send, node.toDebugString());
  Expect.isTrue(node is !SendSet, node.toDebugString());
  Expect.equals(expected, actual);
}

checkSendSet(Element expected, Node node, Element actual) {
  Expect.isTrue(node is SendSet, node.toDebugString());
  Expect.equals(expected, actual);
}

Future testTypeAnnotation() {
  return MockCompiler.create((MockCompiler compiler) {
    String statement = "Foo bar;";

    // Test that we get a warning when Foo is not defined.
    Map mapping = compiler.resolveStatement(statement).map;

    Expect.equals(1, mapping.length); // Only [bar] has an element.
    Expect.equals(1, compiler.warnings.length);

    Node warningNode = compiler.warnings[0].node;

    Expect.equals(
        new Message(
            MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
            {'typeName': 'Foo'}, false),
        compiler.warnings[0].message);
    VariableDefinitions definition = compiler.parsedTree;
    Expect.equals(warningNode, definition.type);
    compiler.clearMessages();

    // Test that there is no warning after defining Foo.
    compiler.parseScript("class Foo {}");
    mapping = compiler.resolveStatement(statement).map;
    Expect.equals(1, mapping.length);
    Expect.equals(0, compiler.warnings.length);

    // Test that 'var' does not create a warning.
    mapping = compiler.resolveStatement("var foo;").map;
    Expect.equals(1, mapping.length);
    Expect.equals(0, compiler.warnings.length);
  });
}

Future testSuperclass() {
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo extends Bar {}");
      compiler.resolveStatement("Foo bar;");
      Expect.equals(1, compiler.errors.length);
      var cannotResolveBar = new Message(
          MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED],
          {'className': 'Foo', 'malformedType': 'Bar'}, false);
      Expect.equals(cannotResolveBar, compiler.errors[0].message);
      compiler.clearMessages();
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo extends Bar {}");
      compiler.parseScript("class Bar {}");
      Map mapping = compiler.resolveStatement("Foo bar;").map;
      Expect.equals(1, mapping.length);

      ClassElement fooElement = compiler.mainApp.find('Foo');
      ClassElement barElement = compiler.mainApp.find('Bar');
      Expect.equals(barElement.computeType(compiler),
                    fooElement.supertype);
      Expect.isTrue(fooElement.interfaces.isEmpty);
      Expect.isTrue(barElement.interfaces.isEmpty);
    }),
  ]);
}

Future testVarSuperclass() {
  return MockCompiler.create((MockCompiler compiler) {
    compiler.parseScript("class Foo extends var {}");
    compiler.resolveStatement("Foo bar;");
    Expect.equals(1, compiler.errors.length);
    Expect.equals(
        new Message(
            MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
            {'typeName': 'var'}, false),
        compiler.errors[0].message);
    compiler.clearMessages();
  });
}

Future testOneInterface() {
  return MockCompiler.create((MockCompiler compiler) {
    compiler.parseScript("class Foo implements Bar {}");
    compiler.resolveStatement("Foo bar;");
    Expect.equals(1, compiler.errors.length);
    Expect.equals(
        new Message(
            MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
            {'typeName': 'bar'}, false),
        compiler.errors[0].message);
    compiler.clearMessages();

    // Add the abstract class to the world and make sure everything is setup
    // correctly.
    compiler.parseScript("abstract class Bar {}");

    ResolverVisitor visitor =
        new ResolverVisitor(compiler, null,
            new ResolutionRegistry(compiler,
                new CollectingTreeElements(null)));
    compiler.resolveStatement("Foo bar;");

    ClassElement fooElement = compiler.mainApp.find('Foo');
    ClassElement barElement = compiler.mainApp.find('Bar');

    Expect.equals(null, barElement.supertype);
    Expect.isTrue(barElement.interfaces.isEmpty);

    Expect.equals(barElement.computeType(compiler),
                  fooElement.interfaces.head);
    Expect.equals(1, length(fooElement.interfaces));
  });
}

Future testTwoInterfaces() {
  return MockCompiler.create((MockCompiler compiler) {
    compiler.parseScript(
        """abstract class I1 {}
           abstract class I2 {}
           class C implements I1, I2 {}""");
    compiler.resolveStatement("Foo bar;");

    ClassElement c = compiler.mainApp.find('C');
    ClassElement i1 = compiler.mainApp.find('I1');
    ClassElement i2 = compiler.mainApp.find('I2');

    Expect.equals(2, length(c.interfaces));
    Expect.equals(i1.computeType(compiler), at(c.interfaces, 0));
    Expect.equals(i2.computeType(compiler), at(c.interfaces, 1));
  });
}

Future testFunctionExpression() {
  return MockCompiler.create((MockCompiler compiler) {
    ResolverVisitor visitor = compiler.resolverVisitor();
    Map mapping = compiler.resolveStatement("int f() {}").map;
    Expect.equals(2, mapping.length);
    Element element;
    Node node;
    mapping.forEach((Node n, Element e) {
      if (n is FunctionExpression) {
        element = e;
        node = n;
      }
    });
    Expect.equals(ElementKind.FUNCTION, element.kind);
    Expect.equals('f', element.name);
    Expect.equals((element as FunctionElement).node, node);
  });
}

Future testNewExpression() {
  return MockCompiler.create((MockCompiler compiler) {
    compiler.parseScript("class A {} foo() { print(new A()); }");
    ClassElement aElement = compiler.mainApp.find('A');

    FunctionElement fooElement = compiler.mainApp.find('foo');
    compiler.resolver.resolve(fooElement);

    Expect.isNotNull(aElement);
    Expect.isNotNull(fooElement);

    fooElement.node;
    compiler.resolver.resolve(fooElement);

    TreeElements elements = compiler.resolveStatement("new A();");
    NewExpression expression =
        compiler.parsedTree.asExpressionStatement().expression;
    Element element = elements[expression.send];
    Expect.equals(ElementKind.GENERATIVE_CONSTRUCTOR, element.kind);
    Expect.isTrue(element.isSynthesized);
  });
}

Future testTopLevelFields() {
  return MockCompiler.create((MockCompiler compiler) {
    compiler.parseScript("int a;");
    VariableElementX element = compiler.mainApp.find("a");
    Expect.equals(ElementKind.FIELD, element.kind);
    VariableDefinitions node = element.variables.parseNode(element, compiler);
    Identifier typeName = node.type.typeName;
    Expect.equals(typeName.source, 'int');

    compiler.parseScript("var b, c;");
    VariableElementX bElement = compiler.mainApp.find("b");
    VariableElementX cElement = compiler.mainApp.find("c");
    Expect.equals(ElementKind.FIELD, bElement.kind);
    Expect.equals(ElementKind.FIELD, cElement.kind);
    Expect.isTrue(bElement != cElement);

    VariableDefinitions bNode = bElement.variables.parseNode(bElement, compiler);
    VariableDefinitions cNode = cElement.variables.parseNode(cElement, compiler);
    Expect.equals(bNode, cNode);
    Expect.isNull(bNode.type);
    Expect.isTrue(bNode.modifiers.isVar);
  });
}

Future resolveConstructor(
    String script, String statement, String className,
    String constructor, int expectedElementCount,
    {List expectedWarnings: const [],
     List expectedErrors: const [],
     List expectedInfos: const [],
     Map<String, String> corelib}) {
  MockCompiler compiler = new MockCompiler.internal(coreSource: corelib);
  return compiler.init().then((_) {
    compiler.parseScript(script);
    compiler.resolveStatement(statement);
    ClassElement classElement = compiler.mainApp.find(className);
    Element element;
    element = classElement.lookupConstructor(constructor);
    FunctionExpression tree = (element as FunctionElement).node;
    ResolverVisitor visitor =
        new ResolverVisitor(compiler, element,
            new ResolutionRegistry(compiler,
                new CollectingTreeElements(element)));
    new InitializerResolver(visitor, element, tree).resolveInitializers();
    visitor.visit(tree.body);
    Expect.equals(expectedElementCount, map(visitor).length,
        "${map(visitor).values} for '$statement' in context of `$script`");

    compareWarningKinds(script, expectedWarnings, compiler.warnings);
    compareWarningKinds(script, expectedErrors, compiler.errors);
    compareWarningKinds(script, expectedInfos, compiler.infos);
  });
}

Future testClassHierarchy() {
  final MAIN = "main";
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A extends A {}
                              main() { return new A(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(1, compiler.errors.length);
      Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
                    compiler.errors[0].message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A extends B {}
                              class B extends A {}
                              main() { return new A(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(2, compiler.errors.length);
      Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
                    compiler.errors[0].message.kind);
      Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR,
                    compiler.errors[1].message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""abstract class A extends B {}
                              abstract class B extends A {}
                              class C implements A {}
                              main() { return new C(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(1, compiler.errors.length);
      Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
                    compiler.errors[0].message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A extends B {}
                              class B extends C {}
                              class C {}
                              main() { return new A(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(0, compiler.errors.length);
      ClassElement aElement = compiler.mainApp.find("A");
      Link<DartType> supertypes = aElement.allSupertypes;
      Expect.equals(<String>['B', 'C', 'Object'].toString(),
                    asSortedStrings(supertypes).toString());
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A<T> {}
                              class B<Z,W> extends A<int>
                                  implements I<Z,List<W>> {}
                              class I<X,Y> {}
                              class C extends B<bool,String> {}
                              main() { return new C(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(0, compiler.errors.length);
      ClassElement aElement = compiler.mainApp.find("C");
      Link<DartType> supertypes = aElement.allSupertypes;
      // Object is once per inheritance path, that is from both A and I.
      Expect.equals(<String>['A<int>', 'B<bool, String>',
                             'I<bool, List<String>>', 'Object'].toString(),
                    asSortedStrings(supertypes).toString());
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A<T> {}
                              class D extends A<E> {}
                              class E extends D {}
                              main() { return new E(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(0, compiler.errors.length);
      ClassElement aElement = compiler.mainApp.find("E");
      Link<DartType> supertypes = aElement.allSupertypes;
      Expect.equals(<String>['A<E>', 'D', 'Object'].toString(),
                    asSortedStrings(supertypes).toString());
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A<T> {}
                              class D extends A<int> implements A<double> {}
                              main() { return new D(); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(1, compiler.errors.length);
      Expect.equals(MessageKind.MULTI_INHERITANCE,
                    compiler.errors[0].message.kind);
      Expect.equals(0, compiler.crashes.length);
    }),
  ]);
}

Future testEnumDeclaration() {
  final MAIN = "main";
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum {}
                              main() { Enum e; }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length,
                    'Unexpected warnings: ${compiler.warnings}');
      Expect.equals(1, compiler.errors.length,
                    'Unexpected errors: ${compiler.errors}');
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { Enum e = Enum.A; }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length,
                    'Unexpected warnings: ${compiler.warnings}');
      Expect.equals(0, compiler.errors.length,
                    'Unexpected errors: ${compiler.errors}');
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { Enum e = Enum.B; }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(1, compiler.warnings.length,
                    'Unexpected warnings: ${compiler.warnings}');
      Expect.equals(MessageKind.MEMBER_NOT_FOUND,
                    compiler.warnings[0].message.kind);
      Expect.equals(0, compiler.errors.length,
                    'Unexpected errors: ${compiler.errors}');
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { List values = Enum.values; }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length,
                    'Unexpected warnings: ${compiler.warnings}');
      Expect.equals(0, compiler.errors.length,
                    'Unexpected errors: ${compiler.errors}');
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { new Enum(0, ''); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length,
                    'Unexpected warnings: ${compiler.warnings}');
      Expect.equals(1, compiler.errors.length,
                    'Unexpected errors: ${compiler.errors}');
      Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
                    compiler.errors[0].message.kind);
    }),

    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { const Enum(0, ''); }""");
      FunctionElement mainElement = compiler.mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      Expect.equals(0, compiler.warnings.length,
                    'Unexpected warnings: ${compiler.warnings}');
      Expect.equals(1, compiler.errors.length,
                    'Unexpected errors: ${compiler.errors}');
      Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
                    compiler.errors[0].message.kind);
    }),
  ]);
}

Future testInitializers() {
  return Future.forEach([
    () {
      String script =
          """class A {
                    int foo; int bar;
                    A() : this.foo = 1, bar = 2;
                  }""";
      return resolveConstructor(script, "A a = new A();", "A", "", 2);
    },
    () {
      String script =
          """class A {
               int foo; A a;
               A() : a.foo = 1;
             }""";
      return resolveConstructor(script, "A a = new A();", "A", "", 0,
          expectedWarnings: [],
          expectedErrors: [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]);
    },
    () {
      String script =
          """class A {
               int foo;
               A() : this.foo = 1, this.foo = 2;
             }""";
      return resolveConstructor(script, "A a = new A();", "A", "", 2,
          expectedInfos: [MessageKind.ALREADY_INITIALIZED],
          expectedErrors: [MessageKind.DUPLICATE_INITIALIZER]);
    },
    () {
      String script =
          """class A {
               A() : this.foo = 1;
             }""";
      return resolveConstructor(script, "A a = new A();", "A", "", 1,
          expectedWarnings: [],
          expectedErrors: [MessageKind.CANNOT_RESOLVE]);
    },
    () {
      String script =
          """class A {
               int foo;
               int bar;
               A() : this.foo = bar;
             }""";
      return resolveConstructor(script, "A a = new A();", "A", "", 2,
          expectedWarnings: [],
          expectedErrors: [MessageKind.NO_INSTANCE_AVAILABLE]);
    },
    () {
      String script =
          """class A {
               int foo() => 42;
               A() : foo();
             }""";
      return resolveConstructor(script, "A a = new A();", "A", "", 0,
          expectedWarnings: [],
          expectedErrors: [MessageKind.CONSTRUCTOR_CALL_EXPECTED]);
    },
    () {
      String script =
          """class A {
               int i;
               A.a() : this.b(0);
               A.b(int i);
             }""";
      return resolveConstructor(script, "A a = new A.a();", "A", "a", 1);
    },
    () {
      String script =
          """class A {
               int i;
               A.a() : i = 42, this(0);
               A(int i);
             }""";
      return resolveConstructor(script, "A a = new A.a();", "A", "a", 2,
          expectedWarnings: [],
          expectedErrors:
              [MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER]);
    },
    () {
      String script =
          """class A {
               int i;
               A(i);
             }
             class B extends A {
               B() : super(0);
             }""";
      return resolveConstructor(script, "B a = new B();", "B", "", 1);
    },
    () {
      String script =
          """class A {
               int i;
               A(i);
             }
             class B extends A {
               B() : super(0), super(1);
             }""";
      return resolveConstructor(script, "B b = new B();", "B", "", 2,
          expectedWarnings: [],
          expectedErrors: [MessageKind.DUPLICATE_SUPER_INITIALIZER]);
    },
    () {
      String script = "";
      final INVALID_OBJECT =
          const { 'Object': 'class Object { Object() : super(); }' };
      return resolveConstructor(script,
          "Object o = new Object();", "Object", "", 1,
          expectedWarnings: [],
          expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT],
          corelib: INVALID_OBJECT);
    },
  ], (f) => f());
}

Future testConstantExpressions() {
  const Map<String, List<String>> testedConstants = const {
    'null': const ['null'],
    'true': const ['true'],
    '0': const ['0'],
    '0.0': const ['0.0'],
    '"foo"': const ['"foo"'],
    '#a': const ['#a'],
    '0 + 1': const ['0', '1', '0 + 1'],
    '0 * 1': const ['0', '1', '0 * 1'],
    '0 * 1 + 2': const ['0', '1', '0 * 1', '2', '0 * 1 + 2'],
    '0 + 1 * 2': const ['0', '1', '2', '1 * 2', '0 + 1 * 2'],
    '-(1)': const ['1', '-1'],
    '-(1 * 4)': const ['1', '4', '1 * 4', '-(1 * 4)'],
    'true ? 0 : 1': const ['true', '0', '1', 'true ? 0 : 1'],
    '"a" "b"': const ['"a"', '"b"', '"ab"'],
    '"a" "b" "c"': const ['"a"', '"b"', '"c"', '"bc"', r'"a${"bc"}"'],
    r'"a${0}b"': const ['"a"', '0', '"b"', r'"a${0}b"'],
    r'"a${0}b${1}"': const ['"a"', '0', '"b"', '1', '""', r'"a${0}b${1}"'],
    'true || false': const ['true', 'false', 'true || false'],
    'true && false': const ['true', 'false', 'true && false'],
    '!true': const ['true', '!true'],
    'const []': const ['const []'],
    'const <int>[]': const ['const <int>[]'],
    'const [0, 1, 2]': const ['0', '1', '2', 'const [0, 1, 2]'],
    'const <int>[0, 1, 2]': const ['0', '1', '2', 'const <int>[0, 1, 2]'],
    'const {}': const ['const {}'],
    'const <String, int>{}': const ['const <String, int>{}'],
    'const {"a": 0, "b": 1, "c": 2}':
        const ['"a"', '0', '"b"', '1', '"c"', '2',
               'const {"a": 0, "b": 1, "c": 2}'],
    'const <String, int>{"a": 0, "b": 1, "c": 2}':
        const ['"a"', '0', '"b"', '1', '"c"', '2',
               'const <String, int>{"a": 0, "b": 1, "c": 2}'],
  };
  return Future.forEach(testedConstants.keys, (String constant) {
    return MockCompiler.create((MockCompiler compiler) {
      CollectingTreeElements elements =
          compiler.resolveStatement("main() => $constant;");
      List<String> expectedConstants = testedConstants[constant];
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(0, compiler.errors.length);
      List<ConstantExpression> constants = elements.constants;
      String constantsText =
          '[${constants.map((c) => c.getText()).join(', ')}]';
      Expect.equals(expectedConstants.length, constants.length,
          "Expected ${expectedConstants.length} constants for `${constant}` "
          "found $constantsText.");
      for (int index = 0; index < expectedConstants.length; index++) {
        Expect.equals(expectedConstants[index], constants[index].getText(),
            "Expected ${expectedConstants} for `$constant`, "
            "found $constantsText.");
      }
    });
  });
}

map(ResolverVisitor visitor) {
  CollectingTreeElements elements = visitor.registry.mapping;
  return elements.map;
}

at(Link link, int index) => (index == 0) ? link.head : at(link.tail, index - 1);

List<String> asSortedStrings(Link link) {
  List<String> result = <String>[];
  for (; !link.isEmpty; link = link.tail) result.add(link.head.toString());
  result.sort((s1, s2) => s1.compareTo(s2));
  return result;
}

Future compileScript(String source) {
  Uri uri = new Uri(scheme: 'source');
  MockCompiler compiler = compilerFor(source, uri);
  compiler.diagnosticHandler = createHandler(compiler, source);
  return compiler.runCompiler(uri).then((_) {
    return compiler;
  });
}

checkMemberResolved(compiler, className, memberName) {
  ClassElement cls = findElement(compiler, className);
  Element memberElement = cls.lookupLocalMember(memberName);
  Expect.isNotNull(memberElement);
  Expect.isTrue(
      compiler.enqueuer.resolution.hasBeenResolved(memberElement));
}

testToString() {
  final script = r"class C { toString() => 'C'; } main() { '${new C()}'; }";
  asyncTest(() => compileScript(script).then((compiler) {
    checkMemberResolved(compiler, 'C', 'toString');
  }));
}

operatorName(op, isUnary) {
  return Elements.constructOperatorName(op, isUnary);
}

testIndexedOperator() {
  final script = r"""
      class C {
        operator[](ix) => ix;
        operator[]=(ix, v) {}
      }
      main() { var c = new C(); c[0]++; }""";
  asyncTest(() => compileScript(script).then((compiler) {
    checkMemberResolved(compiler, 'C', operatorName('[]', false));
    checkMemberResolved(compiler, 'C', operatorName('[]=', false));
  }));
}

testIncrementsAndDecrements() {
  final script = r"""
      class A { operator+(o)=>null; }
      class B { operator+(o)=>null; }
      class C { operator-(o)=>null; }
      class D { operator-(o)=>null; }
      main() {
        var a = new A();
        a++;
        var b = new B();
        ++b;
        var c = new C();
        c--;
        var d = new D();
        --d;
      }""";
  asyncTest(() => compileScript(script).then((compiler) {
    checkMemberResolved(compiler, 'A', operatorName('+', false));
    checkMemberResolved(compiler, 'B', operatorName('+', false));
    checkMemberResolved(compiler, 'C', operatorName('-', false));
    checkMemberResolved(compiler, 'D', operatorName('-', false));
  }));
}

testOverrideHashCodeCheck() {
  final script = r"""
      class A {
        operator==(other) => true;
      }
      class B {
        operator==(other) => true;
        get hashCode => 0;
      }
      main() {
        new A() == new B();
      }""";
  asyncTest(() => compileScript(script).then((compiler) {
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(0, compiler.infos.length);
    Expect.equals(1, compiler.hints.length);
    Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
                  compiler.hints[0].message.kind);
    Expect.equals(0, compiler.errors.length);
  }));
}

testConstConstructorAndNonFinalFields() {
  void expect(compiler, List errors, List infos) {
    Expect.equals(errors.length, compiler.errors.length);
    for (int i = 0 ; i < errors.length ; i++) {
      Expect.equals(errors[i], compiler.errors[i].message.kind);
    }
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(infos.length, compiler.infos.length);
    for (int i = 0 ; i < infos.length ; i++) {
      Expect.equals(infos[i], compiler.infos[i].message.kind);
    }
  }

  final script1 = r"""
      class A {
        var a;
        const A(this.a);
      }
      main() {
        new A(0);
      }""";
  asyncTest(() => compileScript(script1).then((compiler) {
    expect(compiler,
           [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS],
           [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]);
  }));

  final script2 = r"""
      class A {
        var a;
        var b;
        const A(this.a, this.b);
        const A.named(this.a, this.b);
      }
      main() {
        new A(0, 1);
      }""";
  asyncTest(() => compileScript(script2).then((compiler) {
    expect(compiler,
        [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS],
        [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
         MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
         MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
         MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]);
  }));
}

testCantAssignMethods() {
  // Can't override local functions
  checkWarningOn('''
      main() {
        mname() { mname = 2; };
        mname();
      }
      ''', [MessageKind.ASSIGNING_METHOD]);

  checkWarningOn('''
      main() {
        mname() { };
        mname = 3;
      }
      ''', [MessageKind.ASSIGNING_METHOD]);

  // Can't override top-level functions
  checkWarningOn('''
      m() {}
      main() { m = 4; }
      ''', [MessageKind.ASSIGNING_METHOD,
            // TODO(johnniwinther): Avoid duplicate warnings.
            MessageKind.NOT_ASSIGNABLE]);

  // Can't override instance methods
  checkWarningOn('''
      main() { new B().bar(); }
      class B {
        mname() {}
        bar() {
          mname = () => null;
        }
      }
      ''', [MessageKind.SETTER_NOT_FOUND]);
  checkWarningOn('''
      main() { new B().bar(); }
      class B {
        mname() {}
        bar() {
          this.mname = () => null;
        }
      }
      ''', [MessageKind.SETTER_NOT_FOUND]);

  // Can't override super methods
  checkWarningOn('''
      main() { new B().bar(); }
      class A {
        mname() {}
      }
      class B extends A {
        bar() {
          super.mname = () => 6;
        }
      }
      ''', [MessageKind.ASSIGNING_METHOD_IN_SUPER,
            // TODO(johnniwinther): Avoid duplicate warnings.
            MessageKind.SETTER_NOT_FOUND]);

  // But index operators should be OK
  checkWarningOn('''
      main() { new B().bar(); }
      class B {
        operator[]=(x, y) {}
        bar() {
          this[1] = 3; // This is OK
        }
      }
      ''', []);
  checkWarningOn('''
      main() { new B().bar(); }
      class A {
        operator[]=(x, y) {}
      }
      class B extends A {
        bar() {
          super[1] = 3; // This is OK
        }
      }
      ''', []);
}

testCantAssignFinalAndConsts() {
  // Can't write final or const locals.
  checkWarningOn('''
      main() {
        final x = 1;
        x = 2;
      }
      ''', [MessageKind.CANNOT_RESOLVE_SETTER]);
  checkWarningOn('''
      main() {
        const x = 1;
        x = 2;
      }
      ''', [MessageKind.CANNOT_RESOLVE_SETTER]);
  checkWarningOn('''
      final x = 1;
      main() { x = 3; }
      ''', [MessageKind.CANNOT_RESOLVE_SETTER]);

  checkWarningOn('''
      const x = 1;
      main() { x = 3; }
      ''', [MessageKind.CANNOT_RESOLVE_SETTER]);

  // Detect assignments to final fields:
  checkWarningOn('''
      main() => new B().m();
      class B {
        final x = 1;
        m() { x = 2; }
      }
      ''', [MessageKind.SETTER_NOT_FOUND]);

  // ... even if 'this' is explicit:
  checkWarningOn('''
      main() => new B().m();
      class B {
        final x = 1;
        m() { this.x = 2; }
      }
      ''', [MessageKind.SETTER_NOT_FOUND]);

  // ... and in super class:
  checkWarningOn('''
      main() => new B().m();
      class A {
        final x = 1;
      }
      class B extends A {
        m() { super.x = 2; }
      }
      ''', [MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER,
            // TODO(johnniwinther): Avoid duplicate warnings.
            MessageKind.SETTER_NOT_FOUND]);

  // But non-final fields are OK:
  checkWarningOn('''
      main() => new B().m();
      class A {
        int x = 1;
      }
      class B extends A {
        m() { super.x = 2; }
      }
      ''', []);

  // Check getter without setter.
  checkWarningOn('''
      main() => new B().m();
      class A {
        get x => 1;
      }
      class B extends A {
        m() { super.x = 2; }
      }
      ''', [MessageKind.SETTER_NOT_FOUND_IN_SUPER,
            // TODO(johnniwinther): Avoid duplicate warnings.
            MessageKind.SETTER_NOT_FOUND]);
}

/// Helper to test that [script] produces all the given [warnings].
checkWarningOn(String script, List<MessageKind> warnings) {
  Expect.isTrue(warnings.length >= 0 && warnings.length <= 2);
  asyncTest(() => compileScript(script).then((compiler) {
    Expect.equals(0, compiler.errors.length,
        'Unexpected errors in\n$script\n${compiler.errors}');
    Expect.equals(warnings.length, compiler.warnings.length,
        'Unexpected warnings in\n$script\n'
        'Expected:$warnings\nFound:${compiler.warnings}');
    for (int i = 0; i < warnings.length; i++) {
      Expect.equals(warnings[i], compiler.warnings[i].message.kind);
    }
  }));
}

testAwaitHint() {
  check(String script, {String className, String functionName}) {
    var prefix = className == null
        ? "Cannot resolve 'await'"
        : "No member named 'await' in class '$className'";
    var where = functionName == null
        ? 'the enclosing function' : "'$functionName'";
    asyncTest(() => compileScript(script).then((compiler) {
      Expect.equals(0, compiler.errors.length);
      Expect.equals(1, compiler.warnings.length);
      Expect.equals("$prefix.\n"
          "Did you mean to add the 'async' marker to $where?",
          '${compiler.warnings[0].message}');
    }));
  }
  check('main() { await -3; }', functionName: 'main');
  check('main() { () => await -3; }');
  check('foo() => await -3; main() => foo();', functionName: 'foo');
  check('''
    class A {
      m() => await - 3;
    }
    main() => new A().m();
  ''', className: 'A', functionName: 'm');
  check('''
    class A {
      static m() => await - 3;
    }
    main() => A.m();
  ''', functionName: 'm');
  check('''
    class A {
      m() => () => await - 3;
    }
    main() => new A().m();
  ''', className: 'A');
}
