// 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.resolution);
      foo.lookupLocalMember('t').computeType(compiler.resolution);
      foo.lookupLocalMember('foo').computeType(compiler.resolution);
      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.parsing);
    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.parsing);
      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.parsing);
      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.resolution),
                    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.resolution),
                  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.resolution), at(c.interfaces, 0));
    Expect.equals(i2.computeType(compiler.resolution), 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.parsing);
    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.parsing);
    VariableDefinitions cNode =
        cElement.variables.parseNode(cElement, compiler.parsing);
    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.hasBeenProcessed(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');
}
