// 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:uri');

#import("../../../lib/compiler/implementation/leg.dart");
#import("../../../lib/compiler/implementation/elements/elements.dart");
#import("../../../lib/compiler/implementation/tree/tree.dart");
#import("../../../lib/compiler/implementation/scanner/scannerlib.dart");
#import("../../../lib/compiler/implementation/universe/universe.dart");
#import("../../../lib/compiler/implementation/util/util.dart");
#import("compiler_helper.dart");
#import("mock_compiler.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 = [];
  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, new Link.fromList(locals), null, null);
  return new VariableDefinitions(null, Modifiers.EMPTY, definitions, null);
}

testLocals(List variables) {
  MockCompiler compiler = new MockCompiler();
  ResolverVisitor visitor = compiler.resolverVisitor();
  Element element = visitor.visit(createLocals(variables));
  // A VariableDefinitions does not have an element.
  Expect.equals(null, element);
  Expect.equals(variables.length, map(visitor).length);

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

main() {
  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();
  testInitializers();
  testThis();
  testSuperCalls();
  testTypeVariables();
  testToString();
  testIndexedOperator();
  testIncrementsAndDecrements();
}

testTypeVariables() {
  matchResolvedTypes(visitor, text, name, expectedElements) {
    VariableDefinitions definition = parseStatement(text);
    visitor.visit(definition.type);
    InterfaceType type = visitor.mapping.getType(definition.type);
    Expect.equals(definition.type.typeArguments.length(),
                  length(type.arguments));
    int index = 0;
    Link<DartType> arguments = type.arguments;
    while (!arguments.isEmpty()) {
      Expect.equals(true, index < expectedElements.length);
      Expect.equals(expectedElements[index], arguments.head.element);
      index++;
      arguments = arguments.tail;
    }
    Expect.equals(index, expectedElements.length);
  }

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

  compiler = new MockCompiler();
  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);

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

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

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

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

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

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

testThis() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript("class Foo { foo() { return this; } }");
  compiler.resolveStatement("Foo foo;");
  ClassElement fooElement = compiler.mainApp.find(buildSourceString("Foo"));
  FunctionElement funElement =
      fooElement.lookupLocalMember(buildSourceString("foo"));
  ResolverVisitor visitor = new ResolverVisitor(compiler, funElement);
  FunctionExpression function = funElement.parseNode(compiler);
  visitor.visit(function.body);
  Map mapping = map(visitor);
  List<Element> values = mapping.getValues();
  Expect.equals(0, mapping.length);
  Expect.equals(0, compiler.warnings.length);

  compiler = new MockCompiler();
  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);

  compiler = new MockCompiler();
  compiler.parseScript("class Foo { static foo() { return this; } }");
  compiler.resolveStatement("Foo foo;");
  fooElement = compiler.mainApp.find(buildSourceString("Foo"));
  funElement =
      fooElement.lookupLocalMember(buildSourceString("foo"));
  visitor = new ResolverVisitor(compiler, funElement);
  function = funElement.parseNode(compiler);
  visitor.visit(function.body);
  Expect.equals(0, compiler.warnings.length);
  Expect.equals(1, compiler.errors.length);
  Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE,
                compiler.errors[0].message.kind);
}

testLocalsOne() {
  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]]);

  MockCompiler compiler = testLocals([["foo", false], ["foo", false]]);
  Expect.equals(1, compiler.errors.length);
  Expect.equals(
      new Message(MessageKind.DUPLICATE_DEFINITION, ['foo']),
      compiler.errors[0].message);
}


testLocalsTwo() {
  MockCompiler compiler = new MockCompiler();
  ResolverVisitor visitor = compiler.resolverVisitor();
  Node tree = parseStatement("if (true) { var a = 1; var b = 2; }");
  Element element = visitor.visit(tree);
  Expect.equals(null, element);
  MethodScope scope = visitor.scope;
  Expect.equals(0, scope.elements.length);
  Expect.equals(2, map(visitor).length);

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

testLocalsThree() {
  MockCompiler compiler = new MockCompiler();
  ResolverVisitor visitor = compiler.resolverVisitor();
  Node tree = parseStatement("{ var a = 1; if (true) { a; } }");
  Element element = visitor.visit(tree);
  Expect.equals(null, element);
  MethodScope scope = visitor.scope;
  Expect.equals(0, scope.elements.length);
  Expect.equals(3, map(visitor).length);
  List<Element> elements = map(visitor).getValues();
  Expect.equals(elements[0], elements[1]);
}

testLocalsFour() {
  MockCompiler compiler = new MockCompiler();
  ResolverVisitor visitor = compiler.resolverVisitor();
  Node tree = parseStatement("{ var a = 1; if (true) { var a = 1; } }");
  Element element = visitor.visit(tree);
  Expect.equals(null, element);
  MethodScope scope = visitor.scope;
  Expect.equals(0, scope.elements.length);
  Expect.equals(2, map(visitor).length);
  List<Element> elements = map(visitor).getValues();
  Expect.notEquals(elements[0], elements[1]);
}

testLocalsFive() {
  MockCompiler compiler = new MockCompiler();
  ResolverVisitor visitor = compiler.resolverVisitor();
  If tree = parseStatement("if (true) { var a = 1; a; } else { var a = 2; a;}");
  Element element = visitor.visit(tree);
  Expect.equals(null, element);
  MethodScope scope = visitor.scope;
  Expect.equals(0, scope.elements.length);
  Expect.equals(6, 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.mapping[def1], visitor.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.mapping[def2], visitor.mapping[id2]);

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

testParametersOne() {
  MockCompiler compiler = new MockCompiler();
  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.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.mapping[use].kind);
  Expect.equals(visitor.mapping[param], visitor.mapping[use]);
}

testFor() {
  MockCompiler compiler = new MockCompiler();
  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(10, map(visitor).length);

  VariableDefinitions initializer = tree.initializer;
  Node iNode = initializer.definitions.nodes.head;
  Element iElement = visitor.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).getKeys();
  List<Element> elements = map(visitor).getValues();


  // for (int i = 0; i < 10; i = i + 1) { i = 5; };
  //      ^^^
  Expect.isTrue(nodes[0] is TypeAnnotation);

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

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

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

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

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

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

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

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

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

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);
}

testTypeAnnotation() {
  MockCompiler compiler = new MockCompiler();
  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); // bar has an element.
  Expect.equals(1, compiler.warnings.length);

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

  Expect.equals(
      new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Foo']),
      compiler.warnings[0].message);
  VariableDefinitions definition = compiler.parsedTree;
  Expect.equals(warningNode, definition.type);
  compiler.clearWarnings();

  // Test that there is no warning after defining Foo.
  compiler.parseScript("class Foo {}");
  mapping = compiler.resolveStatement(statement).map;
  Expect.equals(2, 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);
}

testSuperclass() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript("class Foo extends Bar {}");
  compiler.resolveStatement("Foo bar;");
  // TODO(ahe): We get the same error twice: once from
  // ClassResolverVisitor, and once from ClassSupertypeResolver. We
  // should only the get the error once.
  Expect.equals(2, compiler.errors.length);
  var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Bar']);
  Expect.equals(cannotResolveBar, compiler.errors[0].message);
  Expect.equals(cannotResolveBar, compiler.errors[1].message);
  compiler.clearErrors();

  compiler = new MockCompiler();
  compiler.parseScript("class Foo extends Bar {}");
  compiler.parseScript("class Bar {}");
  Map mapping = compiler.resolveStatement("Foo bar;").map;
  Expect.equals(2, mapping.length);

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

testVarSuperclass() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript("class Foo extends var {}");
  compiler.resolveStatement("Foo bar;");
  Expect.equals(1, compiler.errors.length);
  Expect.equals(
      new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['var']),
      compiler.errors[0].message);
  compiler.clearErrors();
}

testOneInterface() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript("class Foo implements Bar {}");
  compiler.resolveStatement("Foo bar;");
  Expect.equals(1, compiler.errors.length);
  Expect.equals(
      new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['bar']),
      compiler.errors[0].message);
  compiler.clearErrors();

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

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

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

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

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

testTwoInterfaces() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript(
      "interface I1 {} interface I2 {} class C implements I1, I2 {}");
  compiler.resolveStatement("Foo bar;");

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

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

testFunctionExpression() {
  MockCompiler compiler = new MockCompiler();
  ResolverVisitor visitor = compiler.resolverVisitor();
  Map mapping = compiler.resolveStatement("int f() {}").map;
  Expect.equals(3, 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(buildSourceString('f'), element.name);
  Expect.equals(element.parseNode(compiler), node);
}

testNewExpression() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript("class A {} foo() { print(new A()); }");
  ClassElement aElement = compiler.mainApp.find(buildSourceString('A'));
  FunctionElement fooElement = compiler.mainApp.find(buildSourceString('foo'));
  Expect.isTrue(aElement !== null);
  Expect.isTrue(fooElement !== null);

  fooElement.parseNode(compiler);
  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 is SynthesizedConstructorElement);
}

testTopLevelFields() {
  MockCompiler compiler = new MockCompiler();
  compiler.parseScript("int a;");
  VariableElement element = compiler.mainApp.find(buildSourceString("a"));
  Expect.equals(ElementKind.FIELD, element.kind);
  VariableDefinitions node = element.variables.parseNode(compiler);
  Identifier typeName = node.type.typeName;
  Expect.equals(typeName.source.slowToString(), 'int');

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

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

resolveConstructor(String script, String statement, String className,
                   String constructor, int expectedElementCount,
                   [List expectedWarnings = const [],
                    List expectedErrors = const [],
                    String corelib = DEFAULT_CORELIB]) {
  MockCompiler compiler = new MockCompiler(corelib);
  compiler.parseScript(script);
  compiler.resolveStatement(statement);
  ClassElement classElement =
      compiler.mainApp.find(buildSourceString(className));
  Element element =
      classElement.lookupConstructor(
          new Selector.callConstructor(buildSourceString(constructor),
                                       classElement.getLibrary()));
  FunctionExpression tree = element.parseNode(compiler);
  ResolverVisitor visitor = new ResolverVisitor(compiler, element);
  new InitializerResolver(visitor).resolveInitializers(element, tree);
  visitor.visit(tree.body);
  Expect.equals(expectedElementCount, map(visitor).length);

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

testClassHierarchy() {
  final MAIN = buildSourceString("main");
  MockCompiler compiler = new MockCompiler();
  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(1, compiler.errors.length);
  Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
                compiler.errors[0].message.kind);

  compiler = new MockCompiler();
  compiler.parseScript("""interface A extends B {}
                          interface B extends A {}
                          class C implements A {}
                          main() { return new C(); }""");
  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);

  compiler = new MockCompiler();
  compiler.parseScript("""class A extends B {}
                          class B extends C {}
                          class C {}
                          main() { return new A(); }""");
  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(buildSourceString("A"));
  Link<DartType> supertypes = aElement.allSupertypes;
  Expect.equals(<String>['B', 'C', 'Object'].toString(),
                asSortedStrings(supertypes).toString());
}

testInitializers() {
  String script;
  script = """class A {
                int foo; int bar;
                A() : this.foo = 1, bar = 2;
              }""";
  resolveConstructor(script, "A a = new A();", "A", "A", 2);

  script = """class A {
                int foo; A a;
                A() : a.foo = 1;
                }""";
  resolveConstructor(script, "A a = new A();", "A", "A", 0,
                     [], [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]);

  script = """class A {
                int foo;
                A() : this.foo = 1, this.foo = 2;
              }""";
  resolveConstructor(script, "A a = new A();", "A", "A", 2,
                     [MessageKind.ALREADY_INITIALIZED],
                     [MessageKind.DUPLICATE_INITIALIZER]);

  script = """class A {
                A() : this.foo = 1;
              }""";
  resolveConstructor(script, "A a = new A();", "A", "A", 0,
                     [], [MessageKind.CANNOT_RESOLVE]);

  script = """class A {
                int foo;
                int bar;
                A() : this.foo = bar;
              }""";
  resolveConstructor(script, "A a = new A();", "A", "A", 3,
                     [], [MessageKind.NO_INSTANCE_AVAILABLE]);

  script = """class A {
                int foo() => 42;
                A() : foo();
              }""";
  resolveConstructor(script, "A a = new A();", "A", "A", 0,
                     [], [MessageKind.CONSTRUCTOR_CALL_EXPECTED]);

  script = """class A {
                int i;
                A.a() : this.b(0);
                A.b(int i);
              }""";
  resolveConstructor(script, "A a = new A.a();", "A", "a", 1,
                     [], []);

  script = """class A {
                int i;
                A.a() : i = 42, this(0);
                A(int i);
              }""";
  resolveConstructor(script, "A a = new A.a();", "A", "a", 2,
                     [], [MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER]);

  script = """class A {
                int i;
                A(i);
              }
              class B extends A {
                B() : super(0);
              }""";
  resolveConstructor(script, "B a = new B();", "B", "B", 1,
                     [], []);

  script = """class A {
                int i;
                A(i);
              }
              class B extends A {
                B() : super(0), super(1);
              }""";
  resolveConstructor(script, "B b = new B();", "B", "B", 2,
                     [], [MessageKind.DUPLICATE_SUPER_INITIALIZER]);

  script = "";
  final String CORELIB_WITH_INVALID_OBJECT =
      '''print(var obj) {}
         class int {}
         class double {}
         class bool {}
         class String {}
         class num {}
         class Function {}
         class List {}
         class Closure {}
         class Null {}
         class Dynamic_ {}
         class Object { Object() : super(); }''';
  resolveConstructor(script, "Object o = new Object();", "Object", "Object", 1,
                     [], [MessageKind.SUPER_INITIALIZER_IN_OBJECT],
                     corelib: CORELIB_WITH_INVALID_OBJECT);
}

map(ResolverVisitor visitor) {
  TreeElementMapping elements = visitor.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;
}

compileScript(String source) {
  Uri uri = new Uri.fromComponents(scheme: 'source');
  MockCompiler compiler = compilerFor(source, uri);
  compiler.runCompiler(uri);
  return compiler;
}

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

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

  checkMemberResolved(compiler, 'C', buildSourceString('toString'));
}

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

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

  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;
      }""";
  final compiler = compileScript(script);

  checkMemberResolved(compiler, 'A', operatorName('+', false));
  checkMemberResolved(compiler, 'B', operatorName('+', false));
  checkMemberResolved(compiler, 'C', operatorName('-', false));
  checkMemberResolved(compiler, 'D', operatorName('-', false));
}
