// 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/elements/modelx.dart';
import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/types.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 'package:compiler/src/universe/use.dart';
import 'package:compiler/src/universe/world_impact.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<MockCompiler> 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;");
      LibraryElement mainApp = compiler.mainApp;
      ClassElement classA = mainApp.find("A");
      ClassElement classB = mainApp.find("B");
      ClassElement classC = 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;");
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(1, collector.errors.length);
      Expect.equals(
          MessageKind.MULTI_INHERITANCE, collector.errors.first.message.kind);
      Expect.equals(0, collector.crashes.length);
    }),
  ]);
}

Future testTypeVariables() {
  matchResolvedTypes(visitor, text, name, expectedElements) {
    VariableDefinitions definition = parseStatement(text);
    visitor.visit(definition.type);
    ResolutionInterfaceType type =
        visitor.registry.mapping.getType(definition.type);
    NominalTypeAnnotation annotation = definition.type;
    Expect.equals(
        annotation.typeArguments.slowLength(), type.typeArguments.length);
    int index = 0;
    for (ResolutionDartType 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> {}');
      LibraryElement mainApp = compiler.mainApp;
      ClassElement foo = mainApp.find('Foo');
      matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', [
        compiler.resolution.commonElements.intClass,
        compiler.resolution.commonElements.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;');
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(1, collector.warnings.length);
      Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
          collector.warnings.first.message.kind);
      Expect.equals(0, collector.errors.length);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript('class Foo<T, U> {}');
      compiler.resolveStatement('var x = new Foo<notype, int>();');
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(1, collector.warnings.length);
      Expect.equals(0, collector.errors.length);
      Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
          collector.warnings.first.message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript('class Foo<T> {'
          '  Foo<T> t;'
          '  foo(Foo<T> f) {}'
          '  bar() { g(Foo<T> f) {}; g(); }'
          '}');
      LibraryElement mainApp = compiler.mainApp;
      ClassElement foo = mainApp.find('Foo');
      foo.ensureResolved(compiler.resolution);
      MemberElement tMember = foo.lookupLocalMember('t');
      tMember.computeType(compiler.resolution);
      MemberElement fooMember = foo.lookupLocalMember('foo');
      fooMember.computeType(compiler.resolution);
      compiler.resolver.resolve(foo.lookupLocalMember('bar'));
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(0, collector.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;");

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

    ResolverVisitor visitor = new ResolverVisitor(
        compiler.resolution,
        fooB,
        new ResolutionRegistry(
            compiler.backend.target, new CollectingTreeElements(fooB)),
        scope: new MockTypeVariablesScope(classB.buildScope()));
    FunctionExpression node =
        (fooB as FunctionElementX).parseNode(compiler.parsingContext);
    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;");
    LibraryElement mainApp = compiler.mainApp;
    ClassElement fooElement = mainApp.find("Foo");
    MethodElement funElement = fooElement.lookupLocalMember("foo");
    compiler.enqueuer.resolution.applyImpact(new WorldImpactBuilderImpl()
      ..registerStaticUse(new StaticUse.implicitInvoke(funElement)));
    compiler.processQueue(compiler.frontendStrategy.elementEnvironment,
        compiler.enqueuer.resolution, null, compiler.libraryLoader.libraries);
    DiagnosticCollector collector = compiler.diagnosticCollector;
    Expect.equals(0, collector.warnings.length);
    Expect.equals(1, collector.errors.length);
    Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
        collector.errors.first.message.kind);
    Expect.equals(2, collector.infos.length);
    Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
        collector.infos.first.message.kind);
    Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
        collector.infos.elementAt(1).message.kind);
  });
}

Future testThis() {
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo { foo() { return this; } }");
      compiler.resolveStatement("Foo foo;");
      LibraryElement mainApp = compiler.mainApp;
      ClassElement fooElement = mainApp.find("Foo");
      FunctionElement funElement = fooElement.lookupLocalMember("foo");
      ResolverVisitor visitor = new ResolverVisitor(
          compiler.resolution,
          funElement,
          new ResolutionRegistry(
              compiler.backend.target, new CollectingTreeElements(funElement)),
          scope: new MockTypeVariablesScope(fooElement.buildScope()));
      FunctionExpression function =
          (funElement as FunctionElementX).parseNode(compiler.parsingContext);
      visitor.visit(function.body);
      Map mapping = map(visitor);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, mapping.length);
      Expect.equals(0, collector.warnings.length);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.resolveStatement("main() { return this; }");
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(1, collector.errors.length);
      Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
          collector.errors.first.message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo { static foo() { return this; } }");
      compiler.resolveStatement("Foo foo;");
      LibraryElement mainApp = compiler.mainApp;
      ClassElement fooElement = mainApp.find("Foo");
      FunctionElement funElement = fooElement.lookupLocalMember("foo");
      ResolverVisitor visitor = new ResolverVisitor(
          compiler.resolution,
          funElement,
          new ResolutionRegistry(
              compiler.backend.target, new CollectingTreeElements(funElement)),
          scope: new MockTypeVariablesScope(fooElement.buildScope()));
      FunctionExpression function =
          (funElement as FunctionElementX).parseNode(compiler.parsingContext);
      visitor.visit(function.body);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(1, collector.errors.length);
      Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
          collector.errors.first.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) {
          DiagnosticCollector collector = compiler.diagnosticCollector;
          Expect.equals(1, collector.errors.length);
          Expect.equals(
              new Message(
                  MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION],
                  {'name': 'foo'},
                  false),
              collector.errors.first.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.
    DiagnosticCollector collector = compiler.diagnosticCollector;
    Expect.equals(1, collector.warnings.length);

    Expect.equals(
        new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
            {'typeName': 'Foo'}, false),
        collector.warnings.first.message);
    collector.clear();

    // 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, collector.warnings.length);

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

Future testSuperclass() {
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("class Foo extends Bar {}");
      compiler.resolveStatement("Foo bar;");
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(1, collector.errors.length);
      var cannotResolveBar = new Message(
          MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED],
          {'className': 'Foo', 'malformedType': 'Bar'},
          false);
      Expect.equals(cannotResolveBar, collector.errors.first.message);
      collector.clear();
    }),
    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);

      LibraryElement mainApp = compiler.mainApp;
      ClassElement fooElement = mainApp.find('Foo');
      ClassElement barElement = 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;");
    DiagnosticCollector collector = compiler.diagnosticCollector;
    Expect.equals(1, collector.errors.length);
    Expect.equals(
        new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE],
            {'typeName': 'var'}, false),
        collector.errors.first.message);
    collector.clear();
  });
}

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

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

    compiler.resolveStatement("Foo bar;");

    LibraryElement mainApp = compiler.mainApp;
    ClassElement fooElement = mainApp.find('Foo');
    ClassElement barElement = 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;");

    LibraryElement mainApp = compiler.mainApp;
    ClassElement c = mainApp.find('C');
    ClassElement i1 = mainApp.find('I1');
    ClassElement i2 = 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) {
    var 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()); }");
    LibraryElement mainApp = compiler.mainApp;
    ClassElement aElement = mainApp.find('A');

    FunctionElement fooElement = 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;");
    LibraryElement mainApp = compiler.mainApp;
    VariableElementX element = mainApp.find("a");
    Expect.equals(ElementKind.FIELD, element.kind);
    VariableDefinitions node =
        element.variables.parseNode(element, compiler.parsingContext);
    NominalTypeAnnotation annotation = node.type;
    Identifier typeName = annotation.typeName;
    Expect.equals(typeName.source, 'int');

    compiler.parseScript("var b, c;");
    VariableElementX bElement = mainApp.find("b");
    VariableElementX cElement = 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.parsingContext);
    VariableDefinitions cNode =
        cElement.variables.parseNode(cElement, compiler.parsingContext);
    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);
    LibraryElement mainApp = compiler.mainApp;
    ClassElement classElement = mainApp.find(className);
    Element element;
    element = classElement.lookupConstructor(constructor);
    FunctionExpression tree = (element as FunctionElement).node;
    ResolverVisitor visitor = new ResolverVisitor(
        compiler.resolution,
        element,
        new ResolutionRegistry(
            compiler.backend.target, new CollectingTreeElements(element)),
        scope: classElement.buildScope());
    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`");

    DiagnosticCollector collector = compiler.diagnosticCollector;
    compareWarningKinds(script, expectedWarnings, collector.warnings);
    compareWarningKinds(script, expectedErrors, collector.errors);
    compareWarningKinds(script, expectedInfos, collector.infos);
  });
}

Future testClassHierarchy() {
  final MAIN = "main";
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A extends A {}
                              main() { return new A(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(1, collector.errors.length);
      Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
          collector.errors.first.message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A extends B {}
                              class B extends A {}
                              main() { return new A(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(2, collector.errors.length);
      Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
          collector.errors.first.message.kind);
      Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
          collector.errors.elementAt(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(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(1, collector.errors.length);
      Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
          collector.errors.first.message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""class A extends B {}
                              class B extends C {}
                              class C {}
                              main() { return new A(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(0, collector.errors.length);
      ClassElement aElement = mainApp.find("A");
      Link<InterfaceType> 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(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(0, collector.errors.length);
      ClassElement aElement = mainApp.find("C");
      Link<InterfaceType> 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(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(0, collector.errors.length);
      ClassElement aElement = mainApp.find("E");
      Link<InterfaceType> 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(); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(1, collector.errors.length);
      Expect.equals(
          MessageKind.MULTI_INHERITANCE, collector.errors.first.message.kind);
      Expect.equals(0, collector.crashes.length);
    }),
  ]);
}

Future testEnumDeclaration() {
  final MAIN = "main";
  return Future.wait([
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum {}
                              main() { Enum e; }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length,
          'Unexpected warnings: ${collector.warnings}');
      Expect.equals(
          1, collector.errors.length, 'Unexpected errors: ${collector.errors}');
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { Enum e = Enum.A; }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length,
          'Unexpected warnings: ${collector.warnings}');
      Expect.equals(
          0, collector.errors.length, 'Unexpected errors: ${collector.errors}');
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { Enum e = Enum.B; }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(1, collector.warnings.length,
          'Unexpected warnings: ${collector.warnings}');
      Expect.equals(
          MessageKind.UNDEFINED_GETTER, collector.warnings.first.message.kind);
      Expect.equals(
          0, collector.errors.length, 'Unexpected errors: ${collector.errors}');
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { List values = Enum.values; }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length,
          'Unexpected warnings: ${collector.warnings}');
      Expect.equals(
          0, collector.errors.length, 'Unexpected errors: ${collector.errors}');
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { new Enum(0, ''); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length,
          'Unexpected warnings: ${collector.warnings}');
      Expect.equals(
          1, collector.errors.length, 'Unexpected errors: ${collector.errors}');
      Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
          collector.errors.first.message.kind);
    }),
    MockCompiler.create((MockCompiler compiler) {
      compiler.parseScript("""enum Enum { A }
                              main() { const Enum(0, ''); }""");
      LibraryElement mainApp = compiler.mainApp;
      FunctionElement mainElement = mainApp.find(MAIN);
      compiler.resolver.resolve(mainElement);
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length,
          'Unexpected warnings: ${collector.warnings}');
      Expect.equals(
          1, collector.errors.length, 'Unexpected errors: ${collector.errors}');
      Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM,
          collector.errors.first.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];
      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.equals(0, collector.warnings.length);
      Expect.equals(0, collector.errors.length);
      List<ConstantExpression> constants = elements.constants;
      String constantsText =
          '[${constants.map((c) => c.toDartText()).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].toDartText(),
            "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.run(uri).then((_) {
    return compiler;
  });
}

checkMemberResolved(compiler, className, memberName) {
  ClassElement cls = findElement(compiler, className);
  MemberElement memberElement = cls.lookupLocalMember(memberName);
  Expect.isNotNull(memberElement);
  Expect.isTrue(compiler.resolutionWorldBuilder.isMemberUsed(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) {
        DiagnosticCollector collector = compiler.diagnosticCollector;
        Expect.equals(0, collector.warnings.length);
        Expect.equals(0, collector.infos.length);
        Expect.equals(1, collector.hints.length);
        Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
            collector.hints.first.message.kind);
        Expect.equals(0, collector.errors.length);
      }));
}

testConstConstructorAndNonFinalFields() {
  void expect(compiler, List errors, List infos) {
    DiagnosticCollector collector = compiler.diagnosticCollector;
    Expect.equals(errors.length, collector.errors.length);
    for (int i = 0; i < errors.length; i++) {
      Expect.equals(errors[i], collector.errors.elementAt(i).message.kind);
    }
    Expect.equals(0, collector.warnings.length);
    Expect.equals(infos.length, collector.infos.length);
    for (int i = 0; i < infos.length; i++) {
      Expect.equals(infos[i], collector.infos.elementAt(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.UNDEFINED_SETTER]);
  checkWarningOn('''
      main() { new B().bar(); }
      class B {
        mname() {}
        bar() {
          this.mname = () => null;
        }
      }
      ''', [MessageKind.UNDEFINED_SETTER]);

  // 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.UNDEFINED_SETTER
  ]);

  // 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.UNDEFINED_STATIC_SETTER_BUT_GETTER]);
  checkWarningOn('''
      main() {
        const x = 1;
        x = 2;
      }
      ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]);
  checkWarningOn('''
      final x = 1;
      main() { x = 3; }
      ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]);

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

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

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

  // ... 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.UNDEFINED_SETTER
  ]);

  // 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.UNDEFINED_SUPER_SETTER,
    // TODO(johnniwinther): Avoid duplicate warnings.
    MessageKind.UNDEFINED_SETTER
  ]);
}

/// 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) {
        DiagnosticCollector collector = compiler.diagnosticCollector;
        Expect.equals(0, collector.errors.length,
            'Unexpected errors in\n$script\n${collector.errors}');
        Expect.equals(
            warnings.length,
            collector.warnings.length,
            'Unexpected warnings in\n$script\n'
            'Expected:$warnings\nFound:${collector.warnings}');
        for (int i = 0; i < warnings.length; i++) {
          Expect.equals(
              warnings[i], collector.warnings.elementAt(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) {
          DiagnosticCollector collector = compiler.diagnosticCollector;
          Expect.equals(0, collector.errors.length);
          Expect.equals(1, collector.warnings.length);
          Expect.equals(
              "$prefix.\n"
              "Did you mean to add the 'async' marker to $where?",
              '${collector.warnings.first.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');
}
