// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:io';

import 'package:compiler/src/colors.dart' as colors;
import 'package:compiler/src/common.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/source_file_provider.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import 'package:sourcemap_testing/src/annotated_code_helper.dart';

import '../memory_compiler.dart';
import '../equivalence/id_equivalence.dart';
import '../kernel/test_helpers.dart';

/// `true` if ANSI colors are supported by stdout.
bool useColors = stdout.supportsAnsiEscapes;

/// Colorize a matching annotation [text], if ANSI colors are supported.
String colorizeMatch(String text) {
  if (useColors) {
    return '${colors.blue(text)}';
  } else {
    return text;
  }
}

/// Colorize a single annotation [text], if ANSI colors are supported.
String colorizeSingle(String text) {
  if (useColors) {
    return '${colors.green(text)}';
  } else {
    return text;
  }
}

/// Colorize diffs [left] and [right] and [delimiter], if ANSI colors are
/// supported.
String colorizeDiff(String left, String delimiter, String right) {
  if (useColors) {
    return '${colors.green(left)}'
        '${colors.yellow(delimiter)}${colors.red(right)}';
  } else {
    return '$left$delimiter$right';
  }
}

/// Colorize annotation delimiters [start] and [end] surrounding [text], if
/// ANSI colors are supported.
String colorizeAnnotation(String start, String text, String end) {
  if (useColors) {
    return '${colors.yellow(start)}$text${colors.yellow(end)}';
  } else {
    return '$start$text$end';
  }
}

/// Function that computes a data mapping for [member].
///
/// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
/// for the data origin.
typedef void ComputeMemberDataFunction(
    Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
    {bool verbose});

/// Function that computes a data mapping for [cls].
///
/// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
/// for the data origin.
typedef void ComputeClassDataFunction(
    Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
    {bool verbose});

const String stopAfterTypeInference = 'stopAfterTypeInference';

/// Compute actual data for all members defined in the program with the
/// [entryPoint] and [memorySourceFiles].
///
/// Actual data is computed using [computeMemberData].
Future<CompiledData> computeData(
    Uri entryPoint,
    Map<String, String> memorySourceFiles,
    ComputeMemberDataFunction computeMemberData,
    {List<String> options: const <String>[],
    bool verbose: false,
    bool forUserLibrariesOnly: true,
    bool skipUnprocessedMembers: false,
    bool skipFailedCompilations: false,
    ComputeClassDataFunction computeClassData,
    Iterable<Id> globalIds: const <Id>[]}) async {
  CompilationResult result = await runCompiler(
      entryPoint: entryPoint,
      memorySourceFiles: memorySourceFiles,
      options: options,
      beforeRun: (compiler) {
        compiler.stopAfterTypeInference =
            options.contains(stopAfterTypeInference);
      });
  if (!result.isSuccess) {
    if (skipFailedCompilations) return null;
    Expect.isTrue(result.isSuccess, "Unexpected compilation error.");
  }
  Compiler compiler = result.compiler;
  ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
  CommonElements commonElements = closedWorld.commonElements;

  Map<Uri, Map<Id, ActualData>> actualMaps = <Uri, Map<Id, ActualData>>{};
  Map<Id, ActualData> globalData = <Id, ActualData>{};

  Map<Id, ActualData> actualMapFor(Entity entity) {
    if (entity is Element) {
      // TODO(johnniwinther): Remove this when patched members from kernel are
      // no longer ascribed to the patch file.
      Element element = entity;
      entity = element.implementation;
    }
    SourceSpan span =
        compiler.backendStrategy.spanFromSpannable(entity, entity);
    Uri uri = resolveFastaUri(span.uri);
    return actualMaps.putIfAbsent(uri, () => <Id, ActualData>{});
  }

  void processMember(MemberEntity member, Map<Id, ActualData> actualMap) {
    if (member.isAbstract) {
      return;
    }
    if (member is ConstructorElement && member.isRedirectingFactory) {
      return;
    }
    if (skipUnprocessedMembers &&
        !closedWorld.processedMembers.contains(member)) {
      return;
    }
    if (member.enclosingClass != null) {
      if (elementEnvironment.isEnumClass(member.enclosingClass)) {
        if (member.isConstructor ||
            member.isInstanceMember ||
            member.name == 'values') {
          return;
        }
      }
      if (member.isConstructor &&
          elementEnvironment.isMixinApplication(member.enclosingClass)) {
        return;
      }
    }
    computeMemberData(compiler, member, actualMap, verbose: verbose);
  }

  void processClass(ClassEntity cls, Map<Id, ActualData> actualMap) {
    if (skipUnprocessedMembers && !closedWorld.isImplemented(cls)) {
      return;
    }
    computeClassData(compiler, cls, actualMap, verbose: verbose);
  }

  bool excludeLibrary(LibraryEntity library) {
    return forUserLibrariesOnly &&
        (library.canonicalUri.scheme == 'dart' ||
            library.canonicalUri.scheme == 'package');
  }

  if (computeClassData != null) {
    for (LibraryEntity library in elementEnvironment.libraries) {
      if (excludeLibrary(library)) continue;
      elementEnvironment.forEachClass(library, (ClassEntity cls) {
        processClass(cls, actualMapFor(cls));
      });
    }
  }
  for (MemberEntity member in closedWorld.processedMembers) {
    if (excludeLibrary(member.library)) continue;
    processMember(member, actualMapFor(member));
  }

  List<LibraryEntity> globalLibraries = <LibraryEntity>[
    commonElements.coreLibrary,
    elementEnvironment.lookupLibrary(Uri.parse('dart:collection')),
    commonElements.interceptorsLibrary,
    commonElements.jsHelperLibrary,
  ];

  ClassEntity getGlobalClass(String className) {
    ClassEntity cls;
    for (LibraryEntity library in globalLibraries) {
      cls ??= elementEnvironment.lookupClass(library, className);
    }
    Expect.isNotNull(
        cls,
        "Global class '$className' not found in the global "
        "libraries: ${globalLibraries.map((l) => l.canonicalUri).join(', ')}");
    return cls;
  }

  MemberEntity getGlobalMember(String memberName) {
    MemberEntity member;
    for (LibraryEntity library in globalLibraries) {
      member ??= elementEnvironment.lookupLibraryMember(library, memberName);
    }
    Expect.isNotNull(
        member,
        "Global member '$member' not found in the global "
        "libraries: ${globalLibraries.map((l) => l.canonicalUri).join(', ')}");
    return member;
  }

  for (Id id in globalIds) {
    if (id is ElementId) {
      MemberEntity member;
      if (id.className != null) {
        ClassEntity cls = getGlobalClass(id.className);
        member = elementEnvironment.lookupClassMember(cls, id.memberName);
        member ??= elementEnvironment.lookupConstructor(cls, id.memberName);
        Expect.isNotNull(
            member, "Global member '$member' not found in class $cls.");
      } else {
        member = getGlobalMember(id.memberName);
      }
      processMember(member, globalData);
    } else if (id is ClassId) {
      if (computeClassData != null) {
        ClassEntity cls = getGlobalClass(id.className);
        processClass(cls, globalData);
      }
    } else {
      throw new UnsupportedError("Unexpected global id: $id");
    }
  }

  return new CompiledData(
      compiler, elementEnvironment, entryPoint, actualMaps, globalData);
}

class CompiledData {
  final Compiler compiler;
  final ElementEnvironment elementEnvironment;
  final Uri mainUri;
  final Map<Uri, Map<Id, ActualData>> actualMaps;
  final Map<Id, ActualData> globalData;

  CompiledData(this.compiler, this.elementEnvironment, this.mainUri,
      this.actualMaps, this.globalData);

  Map<int, List<String>> computeAnnotations(Uri uri) {
    Map<Id, ActualData> thisMap = actualMaps[uri];
    Map<int, List<String>> annotations = <int, List<String>>{};
    thisMap.forEach((Id id, ActualData data1) {
      String value1 = '${data1.value}';
      annotations
          .putIfAbsent(data1.offset, () => [])
          .add(colorizeSingle(value1));
    });
    return annotations;
  }

  Map<int, List<String>> computeDiffAnnotationsAgainst(
      Map<Id, ActualData> thisMap, Map<Id, ActualData> otherMap, Uri uri,
      {bool includeMatches: false}) {
    Map<int, List<String>> annotations = <int, List<String>>{};
    thisMap.forEach((Id id, ActualData data1) {
      ActualData data2 = otherMap[id];
      String value1 = '${data1.value}';
      if (data1.value != data2?.value) {
        String value2 = '${data2?.value ?? '---'}';
        annotations
            .putIfAbsent(data1.offset, () => [])
            .add(colorizeDiff(value1, ' | ', value2));
      } else if (includeMatches) {
        annotations
            .putIfAbsent(data1.offset, () => [])
            .add(colorizeMatch(value1));
      }
    });
    otherMap.forEach((Id id, ActualData data2) {
      if (!thisMap.containsKey(id)) {
        String value1 = '---';
        String value2 = '${data2.value}';
        annotations
            .putIfAbsent(data2.offset, () => [])
            .add(colorizeDiff(value1, ' | ', value2));
      }
    });
    return annotations;
  }
}

String withAnnotations(String sourceCode, Map<int, List<String>> annotations) {
  StringBuffer sb = new StringBuffer();
  int end = 0;
  for (int offset in annotations.keys.toList()..sort()) {
    if (offset >= sourceCode.length) {
      sb.write('...');
      return sb.toString();
    }
    if (offset > end) {
      sb.write(sourceCode.substring(end, offset));
    }
    for (String annotation in annotations[offset]) {
      sb.write(colorizeAnnotation('/*', annotation, '*/'));
    }
    end = offset;
  }
  if (end < sourceCode.length) {
    sb.write(sourceCode.substring(end));
  }
  return sb.toString();
}

/// Data collected by [computeData].
class IdData {
  final Map<Uri, AnnotatedCode> code;
  final MemberAnnotations<IdValue> expectedMaps;
  final CompiledData _compiledData;
  final MemberAnnotations<ActualData> _actualMaps = new MemberAnnotations();

  IdData(this.code, this.expectedMaps, this._compiledData) {
    for (Uri uri in code.keys) {
      _actualMaps[uri] = _compiledData.actualMaps[uri] ?? <Id, ActualData>{};
    }
    _actualMaps.globalData.addAll(_compiledData.globalData);
  }

  Compiler get compiler => _compiledData.compiler;
  ElementEnvironment get elementEnvironment => _compiledData.elementEnvironment;
  Uri get mainUri => _compiledData.mainUri;
  MemberAnnotations<ActualData> get actualMaps => _actualMaps;

  String actualCode(Uri uri) {
    Map<int, List<String>> annotations = <int, List<String>>{};
    actualMaps[uri].forEach((Id id, ActualData data) {
      annotations
          .putIfAbsent(data.sourceSpan.begin, () => [])
          .add('${data.value}');
    });
    return withAnnotations(code[uri].sourceCode, annotations);
  }

  String diffCode(Uri uri) {
    Map<int, List<String>> annotations = <int, List<String>>{};
    actualMaps[uri].forEach((Id id, ActualData data) {
      IdValue value = expectedMaps[uri][id];
      if (data.value != value || value == null && data.value.value != '') {
        String expected = value?.toString() ?? '';
        int offset = getOffsetFromId(id, uri);
        String value1 = '${expected}';
        String value2 = '${data.value}';
        annotations
            .putIfAbsent(offset, () => [])
            .add(colorizeDiff(value1, ' | ', value2));
      }
    });
    expectedMaps[uri].forEach((Id id, IdValue expected) {
      if (!actualMaps[uri].containsKey(id)) {
        int offset = getOffsetFromId(id, uri);
        String value1 = '${expected}';
        String value2 = '---';
        annotations
            .putIfAbsent(offset, () => [])
            .add(colorizeDiff(value1, ' | ', value2));
      }
    });
    return withAnnotations(code[uri].sourceCode, annotations);
  }

  int getOffsetFromId(Id id, Uri uri) {
    return compiler.reporter
        .spanFromSpannable(computeSpannable(elementEnvironment, uri, id))
        .begin;
  }
}

/// Encapsulates the member data computed for each source file of interest.
/// It's a glorified wrapper around a map of maps, but written this way to
/// provide a little more information about what it's doing. [DataType] refers
/// to the type this map is holding -- it is either [IdValue] or [ActualData].
class MemberAnnotations<DataType> {
  /// For each Uri, we create a map associating an element id with its
  /// corresponding annotations.
  final Map<Uri, Map<Id, DataType>> _computedDataForEachFile =
      new Map<Uri, Map<Id, DataType>>();

  /// Member or class annotations that don't refer to any of the user files.
  final Map<Id, DataType> globalData = <Id, DataType>{};

  void operator []=(Uri file, Map<Id, DataType> computedData) {
    _computedDataForEachFile[file] = computedData;
  }

  void forEach(void f(Uri file, Map<Id, DataType> computedData)) {
    _computedDataForEachFile.forEach(f);
  }

  Map<Id, DataType> operator [](Uri file) {
    if (!_computedDataForEachFile.containsKey(file)) {
      _computedDataForEachFile[file] = <Id, DataType>{};
    }
    return _computedDataForEachFile[file];
  }
}

typedef void Callback();

/// Check code for all test files int [data] using [computeFromAst] and
/// [computeFromKernel] from the respective front ends. If [skipForKernel]
/// contains the name of the test file it isn't tested for kernel.
///
/// [libDirectory] contains the directory for any supporting libraries that need
/// to be loaded. We expect supporting libraries to have the same prefix as the
/// original test in [dataDir]. So, for example, if testing `foo.dart` in
/// [dataDir], then this function will consider any files named `foo.*\.dart`,
/// such as `foo2.dart`, `foo_2.dart`, and `foo_blah_blah_blah.dart` in
/// [libDirectory] to be supporting library files for `foo.dart`.
/// [setUpFunction] is called once for every test that is executed.
/// If [forUserSourceFilesOnly] is true, we examine the elements in the main
/// file and any supporting libraries.
Future checkTests(Directory dataDir, ComputeMemberDataFunction computeFromAst,
    ComputeMemberDataFunction computeFromKernel,
    {List<String> skipForAst: const <String>[],
    List<String> skipForKernel: const <String>[],
    bool filterActualData(IdValue idValue, ActualData actualData),
    List<String> options: const <String>[],
    List<String> args: const <String>[],
    Directory libDirectory: null,
    bool forUserLibrariesOnly: true,
    Callback setUpFunction,
    ComputeClassDataFunction computeClassDataFromAst,
    ComputeClassDataFunction computeClassDataFromKernel,
    int shards: 1,
    int shardIndex: 0}) async {
  args = args.toList();
  bool verbose = args.remove('-v');
  bool shouldContinue = args.remove('-c');
  bool testAfterFailures = args.remove('-a');
  bool continued = false;
  bool hasFailures = false;

  var relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
  print('Data dir: ${relativeDir}');
  List<FileSystemEntity> entities = dataDir.listSync();
  if (shards > 1) {
    int start = entities.length * shardIndex ~/ shards;
    int end = entities.length * (shardIndex + 1) ~/ shards;
    entities = entities.sublist(start, end);
  }
  for (FileSystemEntity entity in entities) {
    String name = entity.uri.pathSegments.last;
    if (args.isNotEmpty && !args.contains(name) && !continued) continue;
    if (shouldContinue) continued = true;
    List<String> testOptions = options.toList();
    bool strongModeOnlyTest = false;
    if (name.endsWith('_ea.dart')) {
      testOptions.add(Flags.enableAsserts);
    } else if (name.endsWith('_strong.dart')) {
      strongModeOnlyTest = true;
      testOptions.add(Flags.strongMode);
    } else if (name.endsWith('_checked.dart')) {
      testOptions.add(Flags.enableCheckedMode);
    }

    print('----------------------------------------------------------------');
    print('Test: $name');
    // Pretend this is a dart2js_native test to allow use of 'native' keyword
    // and import of private libraries.
    String commonTestPath = 'sdk/tests/compiler';
    Uri entryPoint =
        Uri.parse('memory:$commonTestPath/dart2js_native/main.dart');
    String annotatedCode = await new File.fromUri(entity.uri).readAsString();
    userFiles.add('main.dart');
    Map<Uri, AnnotatedCode> code = {
      entryPoint:
          new AnnotatedCode.fromText(annotatedCode, commentStart, commentEnd)
    };
    Map<String, MemberAnnotations<IdValue>> expectedMaps = {
      astMarker: new MemberAnnotations<IdValue>(),
      kernelMarker: new MemberAnnotations<IdValue>()
    };
    computeExpectedMap(entryPoint, code[entryPoint], expectedMaps);
    Map<String, String> memorySourceFiles = {
      entryPoint.path: code[entryPoint].sourceCode
    };

    if (libDirectory != null) {
      print('Supporting libraries:');
      String filePrefix = name.substring(0, name.lastIndexOf('.'));
      await for (FileSystemEntity libEntity in libDirectory.list()) {
        String libFileName = libEntity.uri.pathSegments.last;
        if (libFileName.startsWith(filePrefix)) {
          print('    - libs/$libFileName');
          Uri libFileUri =
              Uri.parse('memory:$commonTestPath/libs/$libFileName');
          userFiles.add(libEntity.uri.pathSegments.last);
          String libCode = await new File.fromUri(libEntity.uri).readAsString();
          AnnotatedCode annotatedLibCode =
              new AnnotatedCode.fromText(libCode, commentStart, commentEnd);
          memorySourceFiles[libFileUri.path] = annotatedLibCode.sourceCode;
          code[libFileUri] = annotatedLibCode;
          computeExpectedMap(libFileUri, annotatedLibCode, expectedMaps);
        }
      }
    }

    if (setUpFunction != null) setUpFunction();

    if (skipForAst.contains(name) || strongModeOnlyTest) {
      print('--skipped for ast-----------------------------------------------');
    } else {
      print('--from ast------------------------------------------------------');
      MemberAnnotations<IdValue> annotations = expectedMaps[astMarker];
      CompiledData compiledData1 = await computeData(
          entryPoint, memorySourceFiles, computeFromAst,
          computeClassData: computeClassDataFromAst,
          options: testOptions,
          verbose: verbose,
          forUserLibrariesOnly: forUserLibrariesOnly,
          globalIds: annotations.globalData.keys);
      if (await checkCode(code, annotations, compiledData1,
          fatalErrors: !testAfterFailures)) {
        hasFailures = true;
      }
    }
    if (skipForKernel.contains(name)) {
      print('--skipped for kernel--------------------------------------------');
    } else {
      print('--from kernel---------------------------------------------------');
      MemberAnnotations<IdValue> annotations = expectedMaps[kernelMarker];
      CompiledData compiledData2 = await computeData(
          entryPoint, memorySourceFiles, computeFromKernel,
          computeClassData: computeClassDataFromKernel,
          options: [Flags.useKernel]..addAll(testOptions),
          verbose: verbose,
          forUserLibrariesOnly: forUserLibrariesOnly,
          globalIds: annotations.globalData.keys);
      if (await checkCode(code, annotations, compiledData2,
          filterActualData: filterActualData,
          fatalErrors: !testAfterFailures)) {
        hasFailures = true;
      }
    }
  }
  Expect.isFalse(hasFailures, 'Errors found.');
}

final Set<String> userFiles = new Set<String>();

/// Checks [compiledData] against the expected data in [expectedMap] derived
/// from [code].
Future<bool> checkCode(Map<Uri, AnnotatedCode> code,
    MemberAnnotations<IdValue> expectedMaps, CompiledData compiledData,
    {bool filterActualData(IdValue expected, ActualData actualData),
    bool fatalErrors: true}) async {
  IdData data = new IdData(code, expectedMaps, compiledData);
  bool hasFailure = false;

  void checkActualMap(
      Map<Id, ActualData> actualMap, Map<Id, IdValue> expectedMap,
      [Uri uri]) {
    bool hasLocalFailure = false;
    actualMap.forEach((Id id, ActualData actualData) {
      IdValue actual = actualData.value;
      if (!expectedMap.containsKey(id)) {
        if (actual.value != '') {
          reportHere(
              data.compiler.reporter,
              actualData.sourceSpan,
              'Id $id = ${colors.red('$actual')} for ${actualData.object} '
              '(${actualData.object.runtimeType}) '
              'not expected in ${expectedMap.keys}');
          if (filterActualData == null || filterActualData(null, actualData)) {
            hasLocalFailure = true;
          }
        }
      } else {
        IdValue expected = expectedMap[id];
        if (actual != expected) {
          reportHere(
              data.compiler.reporter,
              actualData.sourceSpan,
              'Object: ${actualData.object} '
              '(${actualData.object.runtimeType})\n '
              'expected: ${colors.green('$expected')}\n '
              'actual: ${colors.red('$actual')}');
          if (filterActualData == null ||
              filterActualData(expected, actualData)) {
            hasLocalFailure = true;
          }
        }
      }
    });
    if (hasLocalFailure) {
      hasFailure = true;
      if (uri != null) {
        print('--annotations diff [${uri.pathSegments.last}]-------------');
        print(data.diffCode(uri));
        print('----------------------------------------------------------');
      }
    }
  }

  data.actualMaps.forEach((Uri uri, Map<Id, ActualData> actualMap) {
    checkActualMap(actualMap, data.expectedMaps[uri], uri);
  });
  checkActualMap(data.actualMaps.globalData, data.expectedMaps.globalData);

  Set<Id> missingIds = new Set<Id>();
  StringBuffer combinedAnnotationsDiff = new StringBuffer();
  void checkMissing(Map<Id, IdValue> expectedMap, Map<Id, ActualData> actualMap,
      [Uri uri]) {
    expectedMap.forEach((Id id, IdValue expected) {
      if (!actualMap.containsKey(id)) {
        missingIds.add(id);
        StringBuffer sb = new StringBuffer();
        for (Id id in actualMap.keys.where((d) => d.kind == id.kind)) {
          sb.write('\n  $id');
        }
        if (uri != null) {
          reportHere(
              data.compiler.reporter,
              computeSpannable(data.elementEnvironment, uri, id),
              'Expected $expected for id $id missing in${sb}');
        } else {
          print('Expected $expected for id $id missing in${sb}');
        }
      }
    });
    if (missingIds.isNotEmpty && uri != null) {
      combinedAnnotationsDiff.write('Missing in $uri:\n');
      combinedAnnotationsDiff.write('${data.diffCode(uri)}\n');
    }
  }

  data.expectedMaps.forEach((Uri uri, Map<Id, IdValue> expectedMap) {
    checkMissing(expectedMap, data.actualMaps[uri], uri);
  });
  checkMissing(data.expectedMaps.globalData, data.actualMaps.globalData);
  if (combinedAnnotationsDiff.isNotEmpty) {
    print('--annotations diff--------------------------------------------');
    print(combinedAnnotationsDiff.toString());
    print('--------------------------------------------------------------');
  }
  if (missingIds.isNotEmpty) {
    print("Ids not found: ${missingIds}.");
    hasFailure = true;
  }
  if (hasFailure && fatalErrors) {
    Expect.fail('Errors found.');
  }
  return hasFailure;
}

/// Compute a [Spannable] from an [id] in the library [mainUri].
Spannable computeSpannable(
    ElementEnvironment elementEnvironment, Uri mainUri, Id id) {
  if (id is NodeId) {
    return new SourceSpan(mainUri, id.value, id.value + 1);
  } else if (id is ElementId) {
    String memberName = id.memberName;
    bool isSetter = false;
    if (memberName != '[]=' && memberName.endsWith('=')) {
      isSetter = true;
      memberName = memberName.substring(0, memberName.length - 1);
    }
    LibraryEntity library = elementEnvironment.lookupLibrary(mainUri);
    if (id.className != null) {
      ClassEntity cls =
          elementEnvironment.lookupClass(library, id.className, required: true);
      if (cls == null) {
        throw new ArgumentError("No class '${id.className}' in $mainUri.");
      }
      MemberEntity member = elementEnvironment
          .lookupClassMember(cls, memberName, setter: isSetter);
      if (member == null) {
        ConstructorEntity constructor =
            elementEnvironment.lookupConstructor(cls, memberName);
        if (constructor == null) {
          throw new ArgumentError("No class member '${memberName}' in $cls.");
        }
        return constructor;
      }
      return member;
    } else {
      MemberEntity member = elementEnvironment
          .lookupLibraryMember(library, memberName, setter: isSetter);
      if (member == null) {
        throw new ArgumentError("No member '${memberName}' in $mainUri.");
      }
      return member;
    }
  } else if (id is ClassId) {
    LibraryEntity library = elementEnvironment.lookupLibrary(mainUri);
    ClassEntity cls =
        elementEnvironment.lookupClass(library, id.className, required: true);
    if (cls == null) {
      throw new ArgumentError("No class '${id.className}' in $mainUri.");
    }
    return cls;
  }
  throw new UnsupportedError('Unsupported id $id.');
}

const String astMarker = 'ast.';
const String kernelMarker = 'kernel.';

/// Compute two [MemberAnnotations] objects from [code] specifying the expected
/// annotations we anticipate encountering; one corresponding to the old
/// implementation, one for the new implementation.
///
/// If an annotation starts with 'ast.' it is only expected for the old
/// implementation and if it starts with 'kernel.' it is only expected for the
/// new implementation. Otherwise it is expected for both implementations.
///
/// Most nodes have the same and expectations should match this by using
/// annotations without prefixes.
void computeExpectedMap(Uri sourceUri, AnnotatedCode code,
    Map<String, MemberAnnotations<IdValue>> maps) {
  List<String> mapKeys = [astMarker, kernelMarker];
  Map<String, AnnotatedCode> split = splitByPrefixes(code, mapKeys);

  split.forEach((String marker, AnnotatedCode code) {
    MemberAnnotations<IdValue> fileAnnotations = maps[marker];
    Map<Id, IdValue> expectedValues = fileAnnotations[sourceUri];
    for (Annotation annotation in code.annotations) {
      String text = annotation.text;
      IdValue idValue = IdValue.decode(annotation.offset, text);
      if (idValue.id.isGlobal) {
        Expect.isFalse(
            fileAnnotations.globalData.containsKey(idValue.id),
            "Duplicate annotations for ${idValue.id}: ${idValue} and "
            "${fileAnnotations.globalData[idValue.id]}.");
        fileAnnotations.globalData[idValue.id] = idValue;
      } else {
        Expect.isFalse(
            expectedValues.containsKey(idValue.id),
            "Duplicate annotations for ${idValue.id}: ${idValue} and "
            "${expectedValues[idValue.id]}.");
        expectedValues[idValue.id] = idValue;
      }
    }
  });
}

Future<bool> compareData(
    Uri entryPoint,
    Map<String, String> memorySourceFiles,
    ComputeMemberDataFunction computeAstData,
    ComputeMemberDataFunction computeIrData,
    {List<String> options: const <String>[],
    bool forUserLibrariesOnly: true,
    bool skipUnprocessedMembers: false,
    bool skipFailedCompilations: false,
    bool verbose: false,
    bool whiteList(Uri uri, Id id)}) async {
  print('--from ast----------------------------------------------------------');
  CompiledData data1 = await computeData(
      entryPoint, memorySourceFiles, computeAstData,
      options: options,
      forUserLibrariesOnly: forUserLibrariesOnly,
      skipUnprocessedMembers: skipUnprocessedMembers,
      skipFailedCompilations: skipFailedCompilations);
  if (data1 == null) return false;
  print('--from kernel-------------------------------------------------------');
  CompiledData data2 = await computeData(
      entryPoint, memorySourceFiles, computeIrData,
      options: [Flags.useKernel]..addAll(options),
      forUserLibrariesOnly: forUserLibrariesOnly,
      skipUnprocessedMembers: skipUnprocessedMembers,
      skipFailedCompilations: skipFailedCompilations);
  if (data2 == null) return false;
  await compareCompiledData(data1, data2,
      whiteList: whiteList,
      skipMissingUris: !forUserLibrariesOnly,
      verbose: verbose);
  return true;
}

Future compareCompiledData(CompiledData data1, CompiledData data2,
    {bool skipMissingUris: false,
    bool verbose: false,
    bool whiteList(Uri uri, Id id)}) async {
  if (whiteList == null) {
    whiteList = (uri, id) => false;
  }
  bool hasErrors = false;
  String libraryRoot1;

  SourceFileProvider provider1 = data1.compiler.provider;
  SourceFileProvider provider2 = data2.compiler.provider;
  for (Uri uri1 in data1.actualMaps.keys) {
    Uri uri2 = uri1;
    bool hasErrorsInUri = false;
    Map<Id, ActualData> actualMap1 = data1.actualMaps[uri1];
    Map<Id, ActualData> actualMap2 = data2.actualMaps[uri2];
    if (actualMap2 == null && skipMissingUris) {
      libraryRoot1 ??= '${data1.compiler.options.libraryRoot}';
      String uriText = '$uri1';
      if (uriText.startsWith(libraryRoot1)) {
        String relativePath = uriText.substring(libraryRoot1.length);
        uri2 =
            resolveFastaUri(Uri.parse('patched_dart2js_sdk/${relativePath}'));
        actualMap2 = data2.actualMaps[uri2];
      }
      if (actualMap2 == null) {
        continue;
      }
    }
    Expect.isNotNull(actualMap2,
        "No data for $uri1 in:\n ${data2.actualMaps.keys.join('\n ')}");
    SourceFile sourceFile1 = await provider1.getUtf8SourceFile(uri1) ??
        await provider1.autoReadFromFile(uri1);
    Expect.isNotNull(sourceFile1, 'No source file for $uri1');
    String sourceCode1 = sourceFile1.slowText();
    if (uri1 != uri2) {
      SourceFile sourceFile2 = await provider2.getUtf8SourceFile(uri2) ??
          await provider2.autoReadFromFile(uri2);
      Expect.isNotNull(sourceFile2, 'No source file for $uri2');
      String sourceCode2 = sourceFile2.slowText();
      if (sourceCode1.length != sourceCode2.length) {
        continue;
      }
    }

    actualMap1.forEach((Id id, ActualData actualData1) {
      IdValue value1 = actualData1.value;
      IdValue value2 = actualMap2[id]?.value;
      if (value1 != value2) {
        reportHere(data1.compiler.reporter, actualData1.sourceSpan,
            '$id: from source:${value1},from dill:${value2}');
        if (!whiteList(uri1, id)) {
          hasErrors = hasErrorsInUri = true;
        }
      }
    });
    actualMap2.forEach((Id id, ActualData actualData2) {
      IdValue value2 = actualData2.value;
      IdValue value1 = actualMap1[id]?.value;
      if (value1 != value2) {
        reportHere(data2.compiler.reporter, actualData2.sourceSpan,
            '$id: from source:${value1},from dill:${value2}');
        if (!whiteList(uri1, id)) {
          hasErrors = hasErrorsInUri = true;
        }
      }
    });
    if (hasErrorsInUri) {
      print('--annotations diff $uri1---------------------------------------');
      print(withAnnotations(
          sourceCode1,
          data1.computeDiffAnnotationsAgainst(actualMap1, actualMap2, uri1,
              includeMatches: verbose)));
      print('----------------------------------------------------------');
    }
  }
  if (hasErrors) {
    Expect.fail('Annotations mismatch');
  }
}

/// Set of features used in annotations.
class Features {
  Map<String, Object> _features = <String, Object>{};

  void add(String key, {var value: ''}) {
    _features[key] = value.toString();
  }

  void addElement(String key, [var value]) {
    List<String> list = _features.putIfAbsent(key, () => <String>[]);
    if (value != null) {
      list.add(value.toString());
    }
  }

  bool containsKey(String key) {
    return _features.containsKey(key);
  }

  void operator []=(String key, String value) {
    _features[key] = value;
  }

  String operator [](String key) => _features[key];

  String remove(String key) => _features.remove(key);

  /// Returns a string containing all features in a comma-separated list sorted
  /// by feature names.
  String getText() {
    StringBuffer sb = new StringBuffer();
    bool needsComma = false;
    for (String name in _features.keys.toList()..sort()) {
      dynamic value = _features[name];
      if (value != null) {
        if (needsComma) {
          sb.write(',');
        }
        sb.write(name);
        if (value is List<String>) {
          value = '[${(value..sort()).join(',')}]';
        }
        if (value != '') {
          sb.write('=');
          sb.write(value);
        }
        needsComma = true;
      }
    }
    return sb.toString();
  }
}
