// 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 "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
import "mock_compiler.dart";
import "parser_helper.dart";

Future<Compiler> applyPatch(String script, String patch,
                            {bool analyzeAll: false, bool analyzeOnly: false}) {
  String core = "$DEFAULT_CORELIB\n$script";
  MockCompiler compiler = new MockCompiler(coreSource: core,
                                           analyzeAll: analyzeAll,
                                           analyzeOnly: analyzeOnly);
  var uri = Uri.parse("core.dartp");
  compiler.sourceFiles[uri.toString()] = new MockFile(patch);
  var handler = new LibraryDependencyHandler(compiler);
  return compiler.patchParser.patchLibrary(handler, uri, compiler.coreLibrary)
      .then((_) {
    handler.computeExports();
    return compiler;
  });
}

void expectHasBody(compiler, Element element) {
    var node = element.parseNode(compiler);
    Expect.isNotNull(node, "Element isn't parseable, when a body was expected");
    Expect.isNotNull(node.body);
    // If the element has a body it is either a Block or a Return statement,
    // both with different begin and end tokens.
    Expect.isTrue(node.body is Block || node.body is Return);
    Expect.notEquals(node.body.getBeginToken(), node.body.getEndToken());
}

void expectHasNoBody(compiler, Element element) {
    var node = element.parseNode(compiler);
    Expect.isNotNull(node, "Element isn't parseable, when a body was expected");
    Expect.isFalse(node.hasBody());
}

Element ensure(compiler,
               String name,
               Element lookup(name),
               {bool expectIsPatched: false,
                bool expectIsPatch: false,
                bool checkHasBody: false,
                bool expectIsGetter: false,
                bool expectIsFound: true,
                bool expectIsRegular: false}) {
  var element = lookup(name);
  if (!expectIsFound) {
    Expect.isNull(element);
    return element;
  }
  Expect.isNotNull(element);
  if (expectIsGetter) {
    Expect.isTrue(element is AbstractFieldElement);
    Expect.isNotNull(element.getter);
    element = element.getter;
  }
  Expect.equals(expectIsPatched, element.isPatched);
  if (expectIsPatched) {
    Expect.isNull(element.origin);
    Expect.isNotNull(element.patch);

    Expect.equals(element, element.declaration);
    Expect.equals(element.patch, element.implementation);

    if (checkHasBody) {
      expectHasNoBody(compiler, element);
      expectHasBody(compiler, element.patch);
    }
  } else {
    Expect.isTrue(element.isImplementation);
  }
  Expect.equals(expectIsPatch, element.isPatch);
  if (expectIsPatch) {
    Expect.isNotNull(element.origin);
    Expect.isNull(element.patch);

    Expect.equals(element.origin, element.declaration);
    Expect.equals(element, element.implementation);

    if (checkHasBody) {
      expectHasBody(compiler, element);
      expectHasNoBody(compiler, element.origin);
    }
  } else {
    Expect.isTrue(element.isDeclaration);
  }
  if (expectIsRegular) {
    Expect.isNull(element.origin);
    Expect.isNull(element.patch);

    Expect.equals(element, element.declaration);
    Expect.equals(element, element.implementation);

    if (checkHasBody) {
      expectHasBody(compiler, element);
    }
  }
  Expect.isFalse(element.isPatched && element.isPatch);
  return element;
}

testPatchFunction() {
  asyncTest(() => applyPatch(
      "external test();",
      "patch test() { return 'string'; } ").then((compiler) {
    ensure(compiler, "test", compiler.coreLibrary.find,
           expectIsPatched: true, checkHasBody: true);
    ensure(compiler, "test", compiler.coreLibrary.patch.find,
           expectIsPatch: true, checkHasBody: true);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testPatchConstructor() {
  asyncTest(() => applyPatch(
      """
      class Class {
        external Class();
      }
      """,
      """
      patch class Class {
        patch Class();
      }
      """).then((compiler) {
    var classOrigin = ensure(compiler, "Class", compiler.coreLibrary.find,
                             expectIsPatched: true);
    classOrigin.ensureResolved(compiler);
    var classPatch = ensure(compiler, "Class", compiler.coreLibrary.patch.find,
                            expectIsPatch: true);

    Expect.equals(classPatch, classOrigin.patch);
    Expect.equals(classOrigin, classPatch.origin);

    var constructorOrigin = ensure(compiler, "",
                                   (name) => classOrigin.localLookup(name),
                                   expectIsPatched: true);
    var constructorPatch = ensure(compiler, "",
                                  (name) => classPatch.localLookup(name),
                                  expectIsPatch: true);

    Expect.equals(constructorPatch, constructorOrigin.patch);
    Expect.equals(constructorOrigin, constructorPatch.origin);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testPatchMember() {
  asyncTest(() => applyPatch(
      """
      class Class {
        external String toString();
      }
      """,
      """
      patch class Class {
        patch String toString() => 'string';
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);
    ensure(compiler, "Class", compiler.coreLibrary.patch.find,
           expectIsPatch: true);

    ensure(compiler, "toString", container.lookupLocalMember,
           expectIsPatched: true, checkHasBody: true);
    ensure(compiler, "toString", container.patch.lookupLocalMember,
           expectIsPatch: true, checkHasBody: true);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testPatchGetter() {
  asyncTest(() => applyPatch(
      """
      class Class {
        external int get field;
      }
      """,
      """
      patch class Class {
        patch int get field => 5;
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);
    ensure(compiler,
           "field",
           container.lookupLocalMember,
           expectIsGetter: true,
           expectIsPatched: true,
           checkHasBody: true);
    ensure(compiler,
           "field",
           container.patch.lookupLocalMember,
           expectIsGetter: true,
           expectIsPatch: true,
           checkHasBody: true);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testRegularMember() {
  asyncTest(() => applyPatch(
      """
      class Class {
        void regular() {}
      }
      """,
      """
      patch class Class {
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);
    ensure(compiler, "Class", compiler.coreLibrary.patch.find,
           expectIsPatch: true);

    ensure(compiler, "regular", container.lookupLocalMember,
           checkHasBody: true, expectIsRegular: true);
    ensure(compiler, "regular", container.patch.lookupLocalMember,
           checkHasBody: true, expectIsRegular: true);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testGhostMember() {
  asyncTest(() => applyPatch(
      """
      class Class {
      }
      """,
      """
      patch class Class {
        void ghost() {}
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);
    ensure(compiler, "Class", compiler.coreLibrary.patch.find,
           expectIsPatch: true);

    ensure(compiler, "ghost", container.lookupLocalMember,
           expectIsFound: false);
    ensure(compiler, "ghost", container.patch.lookupLocalMember,
           checkHasBody: true, expectIsRegular: true);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testInjectFunction() {
  asyncTest(() => applyPatch(
      "",
      "int _function() => 5;").then((compiler) {
    ensure(compiler,
           "_function",
           compiler.coreLibrary.find,
           expectIsFound: false);
    ensure(compiler,
           "_function",
           compiler.coreLibrary.patch.find,
           checkHasBody: true, expectIsRegular: true);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    Expect.isTrue(compiler.errors.isEmpty,
                  "Unexpected errors: ${compiler.errors}");
  }));
}

testPatchSignatureCheck() {
  asyncTest(() => applyPatch(
      """
      class Class {
        external String method1();
        external void method2(String str);
        external void method3(String s1);
        external void method4([String str]);
        external void method5({String str});
        external void method6({String str});
        external void method7([String s1]);
        external void method8({String s1});
        external void method9(String str);
        external void method10([String str]);
        external void method11({String str});
      }
      """,
      """
      patch class Class {
        patch int method1() => 0;
        patch void method2() {}
        patch void method3(String s2) {}
        patch void method4([String str, int i]) {}
        patch void method5() {}
        patch void method6([String str]) {}
        patch void method7([String s2]) {}
        patch void method8({String s2}) {}
        patch void method9(int str) {}
        patch void method10([int str]) {}
        patch void method11({int str}) {}
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.ensureResolved(compiler);
    container.parseNode(compiler);

    void expect(String methodName, List infos, List errors) {
      compiler.clearMessages();
      compiler.resolver.resolveMethodElement(
          ensure(compiler, methodName, container.lookupLocalMember,
              expectIsPatched: true, checkHasBody: true));
      Expect.equals(0, compiler.warnings.length);
      Expect.equals(infos.length, compiler.infos.length,
                    "Unexpected infos: ${compiler.infos} on $methodName");
      for (int i = 0 ; i < infos.length ; i++) {
        Expect.equals(infos[i], compiler.infos[i].message.kind);
      }
      Expect.equals(errors.length, compiler.errors.length,
                    "Unexpected errors: ${compiler.errors} on $methodName");
      for (int i = 0 ; i < errors.length ; i++) {
        Expect.equals(errors[i], compiler.errors[i].message.kind);
      }
    }

    expect("method1", [], [MessageKind.PATCH_RETURN_TYPE_MISMATCH]);
    expect("method2", [],
           [MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH]);
    expect("method3", [MessageKind.PATCH_POINT_TO_PARAMETER],
                      [MessageKind.PATCH_PARAMETER_MISMATCH]);
    expect("method4", [],
           [MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH]);
    expect("method5", [],
           [MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH]);
    expect("method6", [],
           [MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH]);
    expect("method7", [MessageKind.PATCH_POINT_TO_PARAMETER],
                      [MessageKind.PATCH_PARAMETER_MISMATCH]);
    expect("method8", [MessageKind.PATCH_POINT_TO_PARAMETER],
                      [MessageKind.PATCH_PARAMETER_MISMATCH]);
    expect("method9", [MessageKind.PATCH_POINT_TO_PARAMETER],
                      [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]);
    expect("method10", [MessageKind.PATCH_POINT_TO_PARAMETER],
                       [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]);
    expect("method11", [MessageKind.PATCH_POINT_TO_PARAMETER],
                       [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]);
  }));
}

testExternalWithoutImplementationTopLevel() {
  asyncTest(() => applyPatch(
      """
      external void foo();
      """,
      """
      // patch void foo() {}
      """).then((compiler) {
    var function = ensure(compiler, "foo", compiler.coreLibrary.find);
    compiler.resolver.resolve(function);
    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    print('testExternalWithoutImplementationTopLevel:${compiler.errors}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind ==
            MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
    Expect.stringEquals('Error: External method without an implementation.',
                        compiler.errors[0].message.toString());
  }));
}

testExternalWithoutImplementationMember() {
  asyncTest(() => applyPatch(
      """
      class Class {
        external void foo();
      }
      """,
      """
      patch class Class {
        // patch void foo() {}
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);

    compiler.warnings.clear();
    compiler.errors.clear();
    compiler.resolver.resolveMethodElement(
        ensure(compiler, "foo", container.lookupLocalMember));
    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    print('testExternalWithoutImplementationMember:${compiler.errors}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind ==
            MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
    Expect.stringEquals('Error: External method without an implementation.',
                        compiler.errors[0].message.toString());
  }));
}

testIsSubclass() {
  asyncTest(() => applyPatch(
      """
      class A {}
      """,
      """
      patch class A {}
      """).then((compiler) {
    ClassElement cls = ensure(compiler, "A", compiler.coreLibrary.find,
                              expectIsPatched: true);
    ClassElement patch = cls.patch;
    Expect.isTrue(cls != patch);
    Expect.isTrue(cls.isSubclassOf(patch));
    Expect.isTrue(patch.isSubclassOf(cls));
  }));
}

testPatchNonExistingTopLevel() {
  asyncTest(() => applyPatch(
      """
      // class Class {}
      """,
      """
      patch class Class {}
      """).then((compiler) {
    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    print('testPatchNonExistingTopLevel:${compiler.errors}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXISTING);
  }));
}

testPatchNonExistingMember() {
  asyncTest(() => applyPatch(
      """
      class Class {}
      """,
      """
      patch class Class {
        patch void foo() {}
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    print('testPatchNonExistingMember:${compiler.errors}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXISTING);
  }));
}

testPatchNonPatchablePatch() {
  asyncTest(() => applyPatch(
      """
      external get foo;
      """,
      """
      patch var foo;
      """).then((compiler) {
    ensure(compiler, "foo", compiler.coreLibrary.find);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    print('testPatchNonPatchablePatch:${compiler.errors}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NONPATCHABLE);
  }));
}

testPatchNonPatchableOrigin() {
  asyncTest(() => applyPatch(
      """
      external var foo;
      """,
      """
      patch get foo => 0;
      """).then((compiler) {
    ensure(compiler, "foo", compiler.coreLibrary.find);

    Expect.isTrue(compiler.warnings.isEmpty,
                  "Unexpected warnings: ${compiler.warnings}");
    print('testPatchNonPatchableOrigin:${compiler.errors}');
    Expect.equals(2, compiler.errors.length);
    Expect.equals(
        MessageKind.EXTRANEOUS_MODIFIER, compiler.errors[0].message.kind);
    Expect.equals(
        // TODO(ahe): Eventually, this error should be removed as it will be
        // handled by the regular parser.
        MessageKind.PATCH_NONPATCHABLE, compiler.errors[1].message.kind);
  }));
}

testPatchNonExternalTopLevel() {
  asyncTest(() => applyPatch(
      """
      void foo() {}
      """,
      """
      patch void foo() {}
      """).then((compiler) {
    print('testPatchNonExternalTopLevel.errors:${compiler.errors}');
    print('testPatchNonExternalTopLevel.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXTERNAL);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(compiler.infos[0].message.kind ==
        MessageKind.PATCH_POINT_TO_FUNCTION);
  }));
}

testPatchNonExternalMember() {
  asyncTest(() => applyPatch(
      """
      class Class {
        void foo() {}
      }
      """,
      """
      patch class Class {
        patch void foo() {}
      }
      """).then((compiler) {
    var container = ensure(compiler, "Class", compiler.coreLibrary.find,
                           expectIsPatched: true);
    container.parseNode(compiler);

    print('testPatchNonExternalMember.errors:${compiler.errors}');
    print('testPatchNonExternalMember.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_EXTERNAL);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(compiler.infos[0].message.kind ==
        MessageKind.PATCH_POINT_TO_FUNCTION);
  }));
}

testPatchNonClass() {
  asyncTest(() => applyPatch(
      """
      external void Class() {}
      """,
      """
      patch class Class {}
      """).then((compiler) {
    print('testPatchNonClass.errors:${compiler.errors}');
    print('testPatchNonClass.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_CLASS);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(
        compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_CLASS);
  }));
}

testPatchNonGetter() {
  asyncTest(() => applyPatch(
      """
      external void foo() {}
      """,
      """
      patch get foo => 0;
      """).then((compiler) {
    print('testPatchNonClass.errors:${compiler.errors}');
    print('testPatchNonClass.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_GETTER);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(
        compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_GETTER);
  }));
}

testPatchNoGetter() {
  asyncTest(() => applyPatch(
      """
      external set foo(var value) {}
      """,
      """
      patch get foo => 0;
      """).then((compiler) {
    print('testPatchNonClass.errors:${compiler.errors}');
    print('testPatchNonClass.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NO_GETTER);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(
        compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_GETTER);
  }));
}

testPatchNonSetter() {
  asyncTest(() => applyPatch(
      """
      external void foo() {}
      """,
      """
      patch set foo(var value) {}
      """).then((compiler) {
    print('testPatchNonClass.errors:${compiler.errors}');
    print('testPatchNonClass.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_SETTER);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(
        compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_SETTER);
  }));
}

testPatchNoSetter() {
  asyncTest(() => applyPatch(
      """
      external get foo;
      """,
      """
      patch set foo(var value) {}
      """).then((compiler) {
    print('testPatchNonClass.errors:${compiler.errors}');
    print('testPatchNonClass.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NO_SETTER);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(
        compiler.infos[0].message.kind == MessageKind.PATCH_POINT_TO_SETTER);
  }));
}

testPatchNonFunction() {
  asyncTest(() => applyPatch(
      """
      external get foo;
      """,
      """
      patch void foo() {}
      """).then((compiler) {
    print('testPatchNonClass.errors:${compiler.errors}');
    print('testPatchNonClass.warnings:${compiler.warnings}');
    Expect.equals(1, compiler.errors.length);
    Expect.isTrue(
        compiler.errors[0].message.kind == MessageKind.PATCH_NON_FUNCTION);
    Expect.equals(0, compiler.warnings.length);
    Expect.equals(1, compiler.infos.length);
    Expect.isTrue(
        compiler.infos[0].message.kind ==
            MessageKind.PATCH_POINT_TO_FUNCTION);
  }));
}

testPatchAndSelector() {
  asyncTest(() => applyPatch(
      """
      class A {
        external void clear();
      }
      class B extends A {
      }
      """,
      """
      patch class A {
        int method() => 0;
        patch void clear() {}
      }
      """).then((compiler) {
    ClassElement cls = ensure(compiler, "A", compiler.coreLibrary.find,
                              expectIsPatched: true);
    cls.ensureResolved(compiler);

    ensure(compiler, "method", cls.patch.lookupLocalMember,
           checkHasBody: true, expectIsRegular: true);

    ensure(compiler, "clear", cls.lookupLocalMember,
           checkHasBody: true, expectIsPatched: true);

    compiler.phase = Compiler.PHASE_DONE_RESOLVING;

    // Check that a method just in the patch class is a target for a
    // typed selector.
    var selector = new Selector.call(
        'method', compiler.coreLibrary, 0);
    var typedSelector = new TypedSelector.exact(cls, selector);
    Element method =
        cls.implementation.lookupLocalMember('method');
    Expect.isTrue(selector.applies(method, compiler));
    Expect.isTrue(typedSelector.applies(method, compiler));

    // Check that the declaration method in the declaration class is a target
    // for a typed selector.
    selector = new Selector.call(
        'clear', compiler.coreLibrary, 0);
    typedSelector = new TypedSelector.exact(cls, selector);
    method = cls.lookupLocalMember('clear');
    Expect.isTrue(selector.applies(method, compiler));
    Expect.isTrue(typedSelector.applies(method, compiler));

    // Check that the declaration method in the declaration class is a target
    // for a typed selector on a subclass.
    cls = ensure(compiler, "B", compiler.coreLibrary.find);
    cls.ensureResolved(compiler);
    typedSelector = new TypedSelector.exact(cls, selector);
    Expect.isTrue(selector.applies(method, compiler));
    Expect.isTrue(typedSelector.applies(method, compiler));
  }));
}

void testAnalyzeAllInjectedMembers() {
  void expect(String patchText, [expectedWarnings]) {
    if (expectedWarnings == null) expectedWarnings = [];
    if (expectedWarnings is! List) {
      expectedWarnings = <MessageKind>[expectedWarnings];
    }

    asyncTest(() => applyPatch('', patchText, analyzeAll: true,
               analyzeOnly: true).then((compiler) {
      compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
      return compiler.runCompiler(null).then((_) {
        compareWarningKinds(patchText, expectedWarnings, compiler.warnings);
      });
    }));
  }

  expect('String s = 0;', MessageKind.NOT_ASSIGNABLE.warning);
  expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE.warning);
  expect('''
         class Class {
           String s = 0;
         }
         ''',
         MessageKind.NOT_ASSIGNABLE.warning);
  expect('''
         class Class {
           void method() {
             String s = 0;
           }
         }
         ''',
         MessageKind.NOT_ASSIGNABLE.warning);
}

void testTypecheckPatchedMembers() {
  String originText = "external void method();";
  String patchText = """
                     patch void method() {
                       String s = 0;
                     }
                     """;
  asyncTest(() => applyPatch(originText, patchText,
             analyzeAll: true, analyzeOnly: true).then((compiler) {
    compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
    return compiler.runCompiler(null).then((_) {
      compareWarningKinds(patchText,
          [MessageKind.NOT_ASSIGNABLE.warning], compiler.warnings);
    });
  }));
}

main() {
  testPatchConstructor();
  testPatchFunction();
  testPatchMember();
  testPatchGetter();
  testRegularMember();
  testGhostMember();
  testInjectFunction();
  testPatchSignatureCheck();

  testExternalWithoutImplementationTopLevel();
  testExternalWithoutImplementationMember();

  testIsSubclass();

  testPatchNonExistingTopLevel();
  testPatchNonExistingMember();
  testPatchNonPatchablePatch();
  testPatchNonPatchableOrigin();
  testPatchNonExternalTopLevel();
  testPatchNonExternalMember();
  testPatchNonClass();
  testPatchNonGetter();
  testPatchNoGetter();
  testPatchNonSetter();
  testPatchNoSetter();
  testPatchNonFunction();

  testPatchAndSelector();

  testAnalyzeAllInjectedMembers();
  testTypecheckPatchedMembers();
}
