// 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 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/messages.dart' show MessageKind;
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/modelx.dart';
import 'package:compiler/src/tree/tree.dart';
import 'package:compiler/src/types/types.dart';
import 'package:compiler/src/universe/call_structure.dart' show CallStructure;
import 'package:compiler/src/universe/selector.dart' show Selector;
import 'package:compiler/src/world.dart';

import 'mock_compiler.dart';
import 'mock_libraries.dart';

Future<Compiler> applyPatch(String script, String patch,
    {bool analyzeAll: false,
    bool analyzeOnly: false,
    bool runCompiler: false,
    String main: "",
    String patchVersion}) {
  Map<String, String> core = <String, String>{'script': script};
  MockCompiler compiler = new MockCompiler.internal(
      coreSource: core,
      analyzeAll: analyzeAll,
      analyzeOnly: analyzeOnly,
      patchVersion: patchVersion);
  compiler.diagnosticHandler = createHandler(compiler, '');
  var uri = Uri.parse("patch:core");
  compiler.registerSource(uri, "$DEFAULT_PATCH_CORE_SOURCE\n$patch");
  var future;
  if (runCompiler) {
    future = compiler.run(null, main);
  } else {
    future = compiler.init(main);
  }
  return future.then((_) => compiler);
}

void expectHasBody(compiler, ElementX element) {
  var node = element.parseNode(compiler.parsingContext);
  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, ElementX element) {
  var node = element.parseNode(compiler.parsingContext);
  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,
      'Unexpected: $element.isPatched = ${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;
}

Future testPatchFunction() async {
  var compiler = await applyPatch(
      "external test();", "@patch test() { return 'string'; } ");
  ensure(compiler, "test", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true, checkHasBody: true);
  ensure(compiler, "test", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true, checkHasBody: true);

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

Future testPatchFunctionMetadata() async {
  var compiler = await applyPatch(
      """
      const a = 0;
      @a external test();
      """,
      """
      const _b = 1;
      @patch @_b test() {}
      """);
  Element origin = ensure(
      compiler, "test", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true, checkHasBody: true);
  Element patch = ensure(
      compiler, "test", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true, checkHasBody: true);

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

  Expect.equals(1, origin.metadata.length,
      "Unexpected origin metadata: ${origin.metadata}.");
  Expect.equals(3, patch.metadata.length,
      "Unexpected patch metadata: ${patch.metadata}.");
}

Future testPatchVersioned() async {
  String fullPatch = "test(){return 'string';}";
  String lazyPatch = "test(){return 'new and improved string';}";

  String patchSource = """
      @patch_full $fullPatch
      @patch_lazy $lazyPatch
      """;

  Future test(String patchVersion,
      {String patchText,
      bool expectIsPatched: true,
      String expectedError,
      String defaultPatch: '',
      String expectedInternalError}) async {
    return applyPatch(
        "external test();",
        """
        $defaultPatch
        $patchSource
        """,
        patchVersion: patchVersion).then((compiler) {
      Element origin = ensure(
          compiler, "test", compiler.commonElements.coreLibrary.find,
          expectIsPatched: expectIsPatched, checkHasBody: true);
      if (expectIsPatched) {
        AstElement patch = ensure(
            compiler, "test", compiler.commonElements.coreLibrary.patch.find,
            expectIsPatch: true, checkHasBody: true);
        Expect.equals(origin.patch, patch);
        Expect.equals(patch.origin, origin);
        Expect.equals(patchText, patch.node.toString());
      }

      compiler.resolution.computeWorldImpact(origin);
      compiler.enqueuer.resolution.emptyDeferredQueueForTesting();

      DiagnosticCollector collector = compiler.diagnosticCollector;
      Expect.isTrue(collector.warnings.isEmpty,
          "Unexpected warnings: ${collector.warnings}");
      if (expectedError != null) {
        Expect.equals(expectedError, collector.errors.first.message.toString());
      } else {
        Expect.isTrue(
            collector.errors.isEmpty, "Unexpected errors: ${collector.errors}");
      }
    }).catchError((error) {
      if (expectedInternalError != null) {
        Expect.equals(
            'Internal Error: $expectedInternalError', error.toString());
      } else {
        throw error;
      }
    });
  }

  await test('full', patchText: fullPatch);
  await test('lazy', patchText: lazyPatch);
  await test('unknown',
      expectIsPatched: false,
      expectedError: 'External method without an implementation.');
  await test('full',
      defaultPatch: "@patch test(){}",
      expectedInternalError: "Trying to patch a function more than once.");
}

Future testPatchConstructor() async {
  var compiler = await applyPatch(
      """
      class Class {
        external Class();
      }
      """,
      """
      @patch class Class {
        @patch Class();
      }
      """);
  var classOrigin = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  classOrigin.ensureResolved(compiler.resolution);
  var classPatch = ensure(
      compiler, "Class", compiler.commonElements.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);

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

Future testPatchRedirectingConstructor() async {
  var compiler = await applyPatch(
      """
      class Class {
        Class(x) : this._(x, false);

        external Class._(x, y);
      }
      """,
      r"""
      @patch class Class {
        @patch Class._(x, y) { print('$x,$y'); }
      }
      """);
  var classOrigin = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  classOrigin.ensureResolved(compiler.resolution);

  var classPatch = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true);

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

  var constructorRedirecting =
      ensure(compiler, "", (name) => classOrigin.localLookup(name));
  var constructorOrigin = ensure(
      compiler, "_", (name) => classOrigin.localLookup(name),
      expectIsPatched: true);
  var constructorPatch = ensure(
      compiler, "_", (name) => classPatch.localLookup(name),
      expectIsPatch: true);
  Expect.equals(constructorOrigin, constructorPatch.origin);
  Expect.equals(constructorPatch, constructorOrigin.patch);

  compiler.resolver.resolve(constructorRedirecting);

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

Future testPatchMember() async {
  var compiler = await applyPatch(
      """
      class Class {
        external String toString();
      }
      """,
      """
      @patch class Class {
        @patch String toString() => 'string';
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);
  ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true);

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

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

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

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

Future testRegularMember() async {
  var compiler = await applyPatch(
      """
      class Class {
        void regular() {}
      }
      """,
      """
      @patch class Class {
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);
  ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true);

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

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

Future testInjectedMember() async {
  var compiler = await applyPatch(
      """
      class Class {
      }
      """,
      """
      @patch class Class {
        void _injected() {}
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);
  ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true);

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

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

Future testInjectedPublicMember() async {
  var compiler = await applyPatch(
      """
      class Class {
      }
      """,
      """
      @patch class Class {
        void injected() {}
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);
  ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find,
      expectIsPatch: true);

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

  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isTrue(
      collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
  Expect.equals(
      1, collector.errors.length, "Unexpected errors: ${collector.errors}");
  Expect.isTrue(collector.errors.first.message.kind ==
      MessageKind.INJECTED_PUBLIC_MEMBER);
}

Future testInjectedFunction() async {
  var compiler = await applyPatch("", "int _function() => 5;");
  ensure(compiler, "_function", compiler.commonElements.coreLibrary.find,
      expectIsFound: false);
  ensure(compiler, "_function", compiler.commonElements.coreLibrary.patch.find,
      checkHasBody: true, expectIsRegular: true);

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

Future testInjectedPublicFunction() async {
  var compiler = await applyPatch("", "int function() => 5;");
  ensure(compiler, "function", compiler.commonElements.coreLibrary.find,
      expectIsFound: false);
  ensure(compiler, "function", compiler.commonElements.coreLibrary.patch.find,
      checkHasBody: true, expectIsRegular: true);

  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isTrue(
      collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
  Expect.equals(
      1, collector.errors.length, "Unexpected errors: ${collector.errors}");
  Expect.isTrue(collector.errors.first.message.kind ==
      MessageKind.INJECTED_PUBLIC_MEMBER);
}

Future testPatchSignatureCheck() async {
  var compiler = await 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}) {}
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.ensureResolved(compiler.resolution);
  container.parseNode(compiler.parsingContext);
  DiagnosticCollector collector = compiler.diagnosticCollector;

  void expect(String methodName, List infos, List errors) {
    collector.clear();
    compiler.resolver.resolveMethodElement(ensure(
        compiler, methodName, container.lookupLocalMember,
        expectIsPatched: true, checkHasBody: true));
    Expect.equals(0, collector.warnings.length);
    Expect.equals(infos.length, collector.infos.length,
        "Unexpected infos: ${collector.infos} on $methodName");
    for (int i = 0; i < infos.length; i++) {
      Expect.equals(infos[i], collector.infos.elementAt(i).message.kind);
    }
    Expect.equals(errors.length, collector.errors.length,
        "Unexpected errors: ${collector.errors} on $methodName");
    for (int i = 0; i < errors.length; i++) {
      Expect.equals(errors[i], collector.errors.elementAt(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]);
}

Future testExternalWithoutImplementationTopLevel() async {
  var compiler = await applyPatch(
      """
      external void foo();
      """,
      """
      // @patch void foo() {}
      """);
  var function =
      ensure(compiler, "foo", compiler.commonElements.coreLibrary.find);
  compiler.resolver.resolve(function);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isTrue(
      collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
  print('testExternalWithoutImplementationTopLevel:${collector.errors}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(collector.errors.first.message.kind ==
      MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
  Expect.stringEquals('External method without an implementation.',
      collector.errors.first.message.toString());
}

Future testExternalWithoutImplementationMember() async {
  var compiler = await applyPatch(
      """
      class Class {
        external void foo();
      }
      """,
      """
      @patch class Class {
        // @patch void foo() {}
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  collector.clear();
  compiler.resolver.resolveMethodElement(
      ensure(compiler, "foo", container.lookupLocalMember));
  Expect.isTrue(
      collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
  print('testExternalWithoutImplementationMember:${collector.errors}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(collector.errors.first.message.kind ==
      MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
  Expect.stringEquals('External method without an implementation.',
      collector.errors.first.message.toString());
}

Future testIsSubclass() async {
  var compiler = await applyPatch(
      """
      class A {}
      """,
      """
      @patch class A {}
      """);
  ClassElement cls = ensure(
      compiler, "A", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  ClassElement patch = cls.patch;
  Expect.isTrue(cls != patch);
  Expect.isTrue(cls.isSubclassOf(patch));
  Expect.isTrue(patch.isSubclassOf(cls));
}

Future testPatchNonExistingTopLevel() async {
  var compiler = await applyPatch(
      """
      // class Class {}
      """,
      """
      @patch class Class {}
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  Expect.isTrue(
      collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
  print('testPatchNonExistingTopLevel:${collector.errors}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING);
}

Future testPatchNonExistingMember() async {
  var compiler = await applyPatch(
      """
      class Class {}
      """,
      """
      @patch class Class {
        @patch void foo() {}
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);
  DiagnosticCollector collector = compiler.diagnosticCollector;

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

Future testPatchNonPatchablePatch() async {
  var compiler = await applyPatch(
      """
      external get foo;
      """,
      """
      @patch var foo;
      """);
  ensure(compiler, "foo", compiler.commonElements.coreLibrary.find);

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

Future testPatchNonPatchableOrigin() async {
  var compiler = await applyPatch(
      """
      external var foo;
      """,
      """
      @patch get foo => 0;
      """);
  ensure(compiler, "foo", compiler.commonElements.coreLibrary.find);

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

Future testPatchNonExternalTopLevel() async {
  var compiler = await applyPatch(
      """
      void foo() {}
      """,
      """
      @patch void foo() {}
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonExternalTopLevel.errors:${collector.errors}');
  print('testPatchNonExternalTopLevel.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(collector.infos.first.message.kind ==
      MessageKind.PATCH_POINT_TO_FUNCTION);
}

Future testPatchNonExternalMember() async {
  var compiler = await applyPatch(
      """
      class Class {
        void foo() {}
      }
      """,
      """
      @patch class Class {
        @patch void foo() {}
      }
      """);
  var container = ensure(
      compiler, "Class", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  container.parseNode(compiler.parsingContext);

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

Future testPatchNonClass() async {
  var compiler = await applyPatch(
      """
      external void Class() {}
      """,
      """
      @patch class Class {}
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonClass.errors:${collector.errors}');
  print('testPatchNonClass.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NON_CLASS);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(
      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_CLASS);
}

Future testPatchNonGetter() async {
  var compiler = await applyPatch(
      """
      external void foo() {}
      """,
      """
      @patch get foo => 0;
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonClass.errors:${collector.errors}');
  print('testPatchNonClass.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NON_GETTER);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(
      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_GETTER);
}

Future testPatchNoGetter() async {
  var compiler = await applyPatch(
      """
      external set foo(var value) {}
      """,
      """
      @patch get foo => 0;
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonClass.errors:${collector.errors}');
  print('testPatchNonClass.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NO_GETTER);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(
      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_GETTER);
}

Future testPatchNonSetter() async {
  var compiler = await applyPatch(
      """
      external void foo() {}
      """,
      """
      @patch set foo(var value) {}
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonClass.errors:${collector.errors}');
  print('testPatchNonClass.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NON_SETTER);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(
      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_SETTER);
}

Future testPatchNoSetter() async {
  var compiler = await applyPatch(
      """
      external get foo;
      """,
      """
      @patch set foo(var value) {}
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonClass.errors:${collector.errors}');
  print('testPatchNonClass.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NO_SETTER);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(
      collector.infos.first.message.kind == MessageKind.PATCH_POINT_TO_SETTER);
}

Future testPatchNonFunction() async {
  var compiler = await applyPatch(
      """
      external get foo;
      """,
      """
      @patch void foo() {}
      """);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  print('testPatchNonClass.errors:${collector.errors}');
  print('testPatchNonClass.warnings:${collector.warnings}');
  Expect.equals(1, collector.errors.length);
  Expect.isTrue(
      collector.errors.first.message.kind == MessageKind.PATCH_NON_FUNCTION);
  Expect.equals(0, collector.warnings.length);
  Expect.equals(1, collector.infos.length);
  Expect.isTrue(collector.infos.first.message.kind ==
      MessageKind.PATCH_POINT_TO_FUNCTION);
}

Future testPatchAndSelector() async {
  var compiler = await applyPatch(
      """
      class A {
        external void clear();
      }
      class B extends A {
      }
      """,
      """
      @patch class A {
        int method() => 0;
        @patch void clear() {}
      }
      """,
      main: """
      main () {
        new A(); // ensure A and B are instantiated
        new B();
      }
      """,
      runCompiler: true,
      analyzeOnly: true);
  ClosedWorld world = compiler.openWorld.closeWorld(compiler.reporter);

  ClassElement cls = ensure(
      compiler, "A", compiler.commonElements.coreLibrary.find,
      expectIsPatched: true);
  cls.ensureResolved(compiler.resolution);

  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.
  Selector selector =
      new Selector.call(const PublicName('method'), CallStructure.NO_ARGS);
  TypeMask typeMask = new TypeMask.exact(cls, world);
  FunctionElement method = cls.implementation.lookupLocalMember('method');
  method.computeType(compiler.resolution);
  Expect.isTrue(selector.applies(method));
  Expect.isTrue(typeMask.canHit(method, selector, world));

  // Check that the declaration method in the declaration class is a target
  // for a typed selector.
  selector =
      new Selector.call(const PublicName('clear'), CallStructure.NO_ARGS);
  typeMask = new TypeMask.exact(cls, world);
  method = cls.lookupLocalMember('clear');
  method.computeType(compiler.resolution);
  Expect.isTrue(selector.applies(method));
  Expect.isTrue(typeMask.canHit(method, selector, world));

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

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

    var compiler =
        await applyPatch('', patchText, analyzeAll: true, analyzeOnly: true);
    compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
    await compiler.run(null);
    DiagnosticCollector collector = compiler.diagnosticCollector;
    compareWarningKinds(patchText, expectedWarnings, collector.warnings);
  }

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

Future testEffectiveTarget() async {
  String origin = """
    class A {
      A() : super();
      factory A.forward() = B.patchTarget;
      factory A.forwardOne() = B.patchFactory;
      factory A.forwardTwo() = B.reflectBack;
      factory A.forwardThree() = B.patchInjected;
    }
    class B extends A {
      B() : super();
      external B.patchTarget();
      external factory B.patchFactory();
      external factory B.reflectBack();
      B.originTarget() : super();
      external factory B.patchInjected();
    }
    """;
  String patch = """
    @patch class B {
      @patch
      B.patchTarget() : super();
      @patch
      factory B.patchFactory() => new B.patchTarget();
      @patch
      factory B.reflectBack() = B.originTarget;
      @patch
      factory B.patchInjected() = _C.injected;
    }
    class _C extends B {
      _C.injected() : super.patchTarget();
    }
    """;

  var compiler = await applyPatch(origin, patch,
      analyzeAll: true, analyzeOnly: true, runCompiler: true);
  ClassElement clsA = compiler.commonElements.coreLibrary.find("A");
  ClassElement clsB = compiler.commonElements.coreLibrary.find("B");

  ConstructorElement forward = clsA.lookupConstructor("forward");
  ConstructorElement target = forward.effectiveTarget;
  Expect.isTrue(target.isPatched, "Unexpected target $target for $forward");
  Expect.isFalse(target.isPatch, "Unexpected target $target for $forward");
  Expect.equals("patchTarget", target.name);

  ConstructorElement forwardOne = clsA.lookupConstructor("forwardOne");
  target = forwardOne.effectiveTarget;
  Expect.isFalse(forwardOne.isMalformed);
  Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardOne");
  Expect.equals("patchFactory", target.name);

  ConstructorElement forwardTwo = clsA.lookupConstructor("forwardTwo");
  target = forwardTwo.effectiveTarget;
  Expect.isFalse(forwardTwo.isMalformed);
  Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardTwo");
  Expect.equals("originTarget", target.name);

  ConstructorElement forwardThree = clsA.lookupConstructor("forwardThree");
  target = forwardThree.effectiveTarget;
  Expect.isFalse(forwardThree.isMalformed);
  Expect.isTrue(
      target.isInjected, "Unexpected target $target for $forwardThree");
  Expect.equals("injected", target.name);
}

Future testTypecheckPatchedMembers() async {
  String originText = "external void method();";
  String patchText = """
                     @patch void method() {
                       String s = 0;
                     }
                     """;
  var compiler = await applyPatch(originText, patchText,
      analyzeAll: true, analyzeOnly: true);
  compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
  await compiler.run(null);
  DiagnosticCollector collector = compiler.diagnosticCollector;
  compareWarningKinds(
      patchText, [MessageKind.NOT_ASSIGNABLE], collector.warnings);
}

main() {
  asyncTest(() async {
    await testPatchConstructor();
    await testPatchRedirectingConstructor();
    await testPatchFunction();
    await testPatchFunctionMetadata();
    await testPatchMember();
    await testPatchGetter();
    await testRegularMember();
    await testInjectedMember();
    await testInjectedPublicMember();
    await testInjectedFunction();
    await testInjectedPublicFunction();
    await testPatchSignatureCheck();

    await testPatchVersioned();

    await testExternalWithoutImplementationTopLevel();
    await testExternalWithoutImplementationMember();

    await testIsSubclass();

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

    await testPatchAndSelector();

    await testEffectiveTarget();

    await testAnalyzeAllInjectedMembers();
    await testTypecheckPatchedMembers();
  });
}
