// 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.

/// Equivalence test functions for data objects.

library dart2js.equivalence.functions;

import 'package:expect/expect.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/enqueue.dart';
import 'package:compiler/src/js/js_debug.dart' as js;
import 'package:compiler/src/js_backend/backend.dart';
import 'package:compiler/src/js_backend/backend_usage.dart';
import 'package:compiler/src/js_backend/enqueuer.dart';
import 'package:compiler/src/js_backend/native_data.dart';
import 'package:compiler/src/js_backend/interceptor_data.dart';
import 'package:compiler/src/js_emitter/code_emitter_task.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/universe/class_set.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/world.dart';
import 'package:js_ast/js_ast.dart' as js;
import 'check_helpers.dart';

void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
    {TestStrategy strategy: const TestStrategy(),
    bool allowExtra: false,
    bool verbose: false,
    bool allowMissingClosureClasses: false}) {
  if (verbose) {
    print(closedWorld1.dump());
    print(closedWorld2.dump());
  }
  checkClassHierarchyNodes(
      closedWorld1,
      closedWorld2,
      closedWorld1
          .getClassHierarchyNode(closedWorld1.commonElements.objectClass),
      closedWorld2
          .getClassHierarchyNode(closedWorld2.commonElements.objectClass),
      strategy.elementEquivalence,
      verbose: verbose,
      allowMissingClosureClasses: allowMissingClosureClasses);

  checkNativeData(closedWorld1.nativeData, closedWorld2.nativeData,
      strategy: strategy, allowExtra: allowExtra, verbose: verbose);
  checkInterceptorData(closedWorld1.interceptorData,
      closedWorld2.interceptorData, strategy.elementEquivalence,
      verbose: verbose);
}

void checkNativeData(NativeDataImpl data1, NativeDataImpl data2,
    {TestStrategy strategy: const TestStrategy(),
    bool allowExtra: false,
    bool verbose: false}) {
  checkMapEquivalence(data1, data2, 'nativeMemberName', data1.nativeMemberName,
      data2.nativeMemberName, strategy.elementEquivalence, equality,
      allowExtra: allowExtra);

  checkMapEquivalence(
      data1,
      data2,
      'nativeMethodBehavior',
      data1.nativeMethodBehavior,
      data2.nativeMethodBehavior,
      strategy.elementEquivalence,
      (a, b) => testNativeBehavior(a, b, strategy: strategy),
      allowExtra: allowExtra);

  checkMapEquivalence(
      data1,
      data2,
      'nativeFieldLoadBehavior',
      data1.nativeFieldLoadBehavior,
      data2.nativeFieldLoadBehavior,
      strategy.elementEquivalence,
      (a, b) => testNativeBehavior(a, b, strategy: strategy),
      allowExtra: allowExtra);

  checkMapEquivalence(
      data1,
      data2,
      'nativeFieldStoreBehavior',
      data1.nativeFieldStoreBehavior,
      data2.nativeFieldStoreBehavior,
      strategy.elementEquivalence,
      (a, b) => testNativeBehavior(a, b, strategy: strategy),
      allowExtra: allowExtra);

  checkMapEquivalence(
      data1,
      data2,
      'jsInteropLibraryNames',
      data1.jsInteropLibraries,
      data2.jsInteropLibraries,
      strategy.elementEquivalence,
      equality);

  checkSetEquivalence(
      data1,
      data2,
      'anonymousJsInteropClasses',
      data1.anonymousJsInteropClasses,
      data2.anonymousJsInteropClasses,
      strategy.elementEquivalence);

  checkMapEquivalence(
      data1,
      data2,
      'jsInteropClassNames',
      data1.jsInteropClasses,
      data2.jsInteropClasses,
      strategy.elementEquivalence,
      equality);

  checkMapEquivalence(
      data1,
      data2,
      'jsInteropMemberNames',
      data1.jsInteropMembers,
      data2.jsInteropMembers,
      strategy.elementEquivalence,
      equality);
}

void checkInterceptorData(InterceptorDataImpl data1, InterceptorDataImpl data2,
    bool elementEquivalence(Entity a, Entity b),
    {bool verbose: false}) {
  checkMapEquivalence(
      data1,
      data2,
      'interceptedElements',
      data1.interceptedMembers,
      data2.interceptedMembers,
      equality,
      (a, b) => areSetsEquivalent(a, b, elementEquivalence));

  checkSetEquivalence(data1, data2, 'interceptedClasses',
      data1.interceptedClasses, data2.interceptedClasses, elementEquivalence);

  checkSetEquivalence(
      data1,
      data2,
      'classesMixedIntoInterceptedClasses',
      data1.classesMixedIntoInterceptedClasses,
      data2.classesMixedIntoInterceptedClasses,
      elementEquivalence);
}

void checkClassHierarchyNodes(
    ClosedWorld closedWorld1,
    ClosedWorld closedWorld2,
    ClassHierarchyNode node1,
    ClassHierarchyNode node2,
    bool elementEquivalence(Entity a, Entity b),
    {bool verbose: false,
    bool allowMissingClosureClasses: false}) {
  if (verbose) {
    print('Checking $node1 vs $node2');
  }
  ClassEntity cls1 = node1.cls;
  ClassEntity cls2 = node2.cls;
  Expect.isTrue(elementEquivalence(cls1, cls2),
      "Element identity mismatch for ${cls1} vs ${cls2}.");
  Expect.equals(
      node1.isDirectlyInstantiated,
      node2.isDirectlyInstantiated,
      "Value mismatch for 'isDirectlyInstantiated' "
      "for ${cls1} vs ${cls2}.");
  Expect.equals(
      node1.isIndirectlyInstantiated,
      node2.isIndirectlyInstantiated,
      "Value mismatch for 'isIndirectlyInstantiated' "
      "for ${node1.cls} vs ${node2.cls}.");
  // TODO(johnniwinther): Enforce a canonical and stable order on direct
  // subclasses.
  for (ClassHierarchyNode child in node1.directSubclasses) {
    bool found = false;
    for (ClassHierarchyNode other in node2.directSubclasses) {
      ClassEntity child1 = child.cls;
      ClassEntity child2 = other.cls;
      if (elementEquivalence(child1, child2)) {
        checkClassHierarchyNodes(
            closedWorld1, closedWorld2, child, other, elementEquivalence,
            verbose: verbose,
            allowMissingClosureClasses: allowMissingClosureClasses);
        found = true;
        break;
      }
    }
    if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) {
      if (child.isInstantiated) {
        print('Missing subclass ${child.cls} of ${node1.cls} '
            'in ${node2.directSubclasses}');
        print(closedWorld1.dump(
            verbose ? closedWorld1.commonElements.objectClass : node1.cls));
        print(closedWorld2.dump(
            verbose ? closedWorld2.commonElements.objectClass : node2.cls));
      }
      Expect.isFalse(
          child.isInstantiated,
          'Missing subclass ${child.cls} of ${node1.cls} in '
          '${node2.directSubclasses}');
    }
  }
  checkMixinUses(
      closedWorld1, closedWorld2, node1.cls, node2.cls, elementEquivalence,
      verbose: verbose);
  ClassSet classSet1 = closedWorld1.getClassSet(cls1);
  ClassSet classSet2 = closedWorld2.getClassSet(cls2);
  Expect.isNotNull(classSet1, "Missing ClassSet for $cls1");
  Expect.isNotNull(classSet2, "Missing ClassSet for $cls2");
  checkClassSets(
      closedWorld1, closedWorld2, classSet1, classSet2, elementEquivalence,
      verbose: verbose, allowMissingClosureClasses: allowMissingClosureClasses);
}

void checkClassSets(
    ClosedWorld closedWorld1,
    ClosedWorld closedWorld2,
    ClassSet classSet1,
    ClassSet classSet2,
    bool elementEquivalence(Entity a, Entity b),
    {bool verbose: false,
    bool allowMissingClosureClasses: false}) {
  for (ClassHierarchyNode child in classSet1.subtypeNodes) {
    bool found = false;
    for (ClassHierarchyNode other in classSet2.subtypeNodes) {
      ClassEntity child1 = child.cls;
      ClassEntity child2 = other.cls;
      if (elementEquivalence(child1, child2)) {
        found = true;
        break;
      }
    }
    if (!found && (!child.cls.isClosure || !allowMissingClosureClasses)) {
      if (child.isInstantiated) {
        print('Missing subtype ${child.cls} of ${classSet1.cls} '
            'in ${classSet2.subtypeNodes}');
        print(closedWorld1.dump(
            verbose ? closedWorld1.commonElements.objectClass : classSet1.cls));
        print(closedWorld2.dump(
            verbose ? closedWorld2.commonElements.objectClass : classSet2.cls));
      }
      Expect.isFalse(
          child.isInstantiated,
          'Missing subclass ${child.cls} of ${classSet1.cls} in '
          '${classSet2.subtypeNodes}');
    }
  }
}

void checkMixinUses(
    ClosedWorld closedWorld1,
    ClosedWorld closedWorld2,
    ClassEntity class1,
    ClassEntity class2,
    bool elementEquivalence(Entity a, Entity b),
    {bool verbose: false}) {
  checkSets(closedWorld1.mixinUsesOf(class1), closedWorld2.mixinUsesOf(class2),
      "Mixin uses of $class1 vs $class2", elementEquivalence,
      verbose: verbose);
}

/// Check member property equivalence between all members common to [compiler1]
/// and [compiler2].
void checkLoadedLibraryMembers(
    Compiler compiler1,
    Compiler compiler2,
    bool hasProperty(Element member1),
    void checkMemberProperties(Compiler compiler1, Element member1,
        Compiler compiler2, Element member2,
        {bool verbose}),
    {bool verbose: false}) {
  void checkMembers(Element member1, Element member2) {
    if (member1.isClass && member2.isClass) {
      ClassElement class1 = member1;
      ClassElement class2 = member2;
      if (!class1.isResolved) return;

      if (hasProperty(member1)) {
        if (areElementsEquivalent(member1, member2)) {
          checkMemberProperties(compiler1, member1, compiler2, member2,
              verbose: verbose);
        }
      }

      class1.forEachLocalMember((m1) {
        checkMembers(m1, class2.localLookup(m1.name));
      });
      ClassElement superclass1 = class1.superclass;
      ClassElement superclass2 = class2.superclass;
      while (superclass1 != null && superclass1.isUnnamedMixinApplication) {
        for (ConstructorElement c1 in superclass1.constructors) {
          checkMembers(c1, superclass2.lookupConstructor(c1.name));
        }
        superclass1 = superclass1.superclass;
        superclass2 = superclass2.superclass;
      }
      return;
    }

    if (!hasProperty(member1)) {
      return;
    }

    if (member2 == null) {
      throw 'Missing member for ${member1}';
    }

    if (areElementsEquivalent(member1, member2)) {
      checkMemberProperties(compiler1, member1, compiler2, member2,
          verbose: verbose);
    }
  }

  for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
    LibraryElement library2 =
        compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
    if (library2 != null) {
      library1.forEachLocalMember((Element member1) {
        checkMembers(member1, library2.localLookup(member1.name));
      });
    }
  }
}

/// Check equivalence of all resolution impacts.
void checkAllImpacts(Compiler compiler1, Compiler compiler2,
    {bool verbose: false}) {
  checkLoadedLibraryMembers(compiler1, compiler2, (Element member1) {
    return compiler1.resolution.hasResolutionImpact(member1);
  }, checkImpacts, verbose: verbose);
}

/// Check equivalence of resolution impact for [member1] and [member2].
void checkImpacts(
    Compiler compiler1, Element member1, Compiler compiler2, Element member2,
    {bool verbose: false}) {
  ResolutionImpact impact1 = compiler1.resolution.getResolutionImpact(member1);
  ResolutionImpact impact2 = compiler2.resolution.getResolutionImpact(member2);

  if (impact1 == null && impact2 == null) return;

  if (verbose) {
    print('Checking impacts for $member1 vs $member2');
  }

  if (impact1 == null) {
    throw 'Missing impact for $member1. $member2 has $impact2';
  }
  if (impact2 == null) {
    throw 'Missing impact for $member2. $member1 has $impact1';
  }

  testResolutionImpactEquivalence(impact1, impact2,
      strategy: const CheckStrategy());
}

void checkAllResolvedAsts(Compiler compiler1, Compiler compiler2,
    {bool verbose: false}) {
  checkLoadedLibraryMembers(compiler1, compiler2, (Element member1) {
    return member1 is ExecutableElement &&
        compiler1.resolution.hasResolvedAst(member1);
  }, checkResolvedAsts, verbose: verbose);
}

/// Check equivalence of [impact1] and [impact2].
void checkResolvedAsts(
    Compiler compiler1, Element member1, Compiler compiler2, Element member2,
    {bool verbose: false}) {
  if (!compiler2.serialization.isDeserialized(member2)) {
    return;
  }
  ResolvedAst resolvedAst1 = compiler1.resolution.getResolvedAst(member1);
  ResolvedAst resolvedAst2 = compiler2.serialization.getResolvedAst(member2);

  if (resolvedAst1 == null || resolvedAst2 == null) return;

  if (verbose) {
    print('Checking resolved asts for $member1 vs $member2');
  }

  testResolvedAstEquivalence(resolvedAst1, resolvedAst2, const CheckStrategy());
}

void checkNativeClasses(
    Compiler compiler1, Compiler compiler2, TestStrategy strategy) {
  Iterable<ClassEntity> nativeClasses1 = compiler1
      .backend.nativeResolutionEnqueuerForTesting.nativeClassesForTesting;
  Iterable<ClassEntity> nativeClasses2 = compiler2
      .backend.nativeResolutionEnqueuerForTesting.nativeClassesForTesting;

  checkSetEquivalence(compiler1, compiler2, 'nativeClasses', nativeClasses1,
      nativeClasses2, strategy.elementEquivalence);

  Iterable<ClassEntity> liveNativeClasses1 =
      compiler1.backend.nativeResolutionEnqueuerForTesting.liveNativeClasses;
  Iterable<ClassEntity> liveNativeClasses2 =
      compiler2.backend.nativeResolutionEnqueuerForTesting.liveNativeClasses;

  checkSetEquivalence(compiler1, compiler2, 'liveNativeClasses',
      liveNativeClasses1, liveNativeClasses2, strategy.elementEquivalence);
}

void checkNativeBasicData(NativeBasicDataImpl data1, NativeBasicDataImpl data2,
    TestStrategy strategy) {
  checkMapEquivalence(
      data1,
      data2,
      'nativeClassTagInfo',
      data1.nativeClassTagInfo,
      data2.nativeClassTagInfo,
      strategy.elementEquivalence,
      (a, b) => a == b);
  checkSetEquivalence(
      data1,
      data2,
      'jsInteropLibraries',
      data1.jsInteropLibraries.keys,
      data2.jsInteropLibraries.keys,
      strategy.elementEquivalence);
  checkSetEquivalence(
      data1,
      data2,
      'jsInteropClasses',
      data1.jsInteropClasses.keys,
      data2.jsInteropClasses.keys,
      strategy.elementEquivalence);
}

void checkBackendUsage(
    BackendUsageImpl usage1, BackendUsageImpl usage2, TestStrategy strategy) {
  checkSetEquivalence(
      usage1,
      usage2,
      'globalClassDependencies',
      usage1.globalClassDependencies,
      usage2.globalClassDependencies,
      strategy.elementEquivalence);
  checkSetEquivalence(
      usage1,
      usage2,
      'globalFunctionDependencies',
      usage1.globalFunctionDependencies,
      usage2.globalFunctionDependencies,
      strategy.elementEquivalence);
  checkSetEquivalence(
      usage1,
      usage2,
      'helperClassesUsed',
      usage1.helperClassesUsed,
      usage2.helperClassesUsed,
      strategy.elementEquivalence);
  checkSetEquivalence(
      usage1,
      usage2,
      'helperFunctionsUsed',
      usage1.helperFunctionsUsed,
      usage2.helperFunctionsUsed,
      strategy.elementEquivalence);
  check(
      usage1,
      usage2,
      'needToInitializeIsolateAffinityTag',
      usage1.needToInitializeIsolateAffinityTag,
      usage2.needToInitializeIsolateAffinityTag);
  check(
      usage1,
      usage2,
      'needToInitializeDispatchProperty',
      usage1.needToInitializeDispatchProperty,
      usage2.needToInitializeDispatchProperty);
  check(usage1, usage2, 'requiresPreamble', usage1.requiresPreamble,
      usage2.requiresPreamble);
  check(usage1, usage2, 'isInvokeOnUsed', usage1.isInvokeOnUsed,
      usage2.isInvokeOnUsed);
  check(usage1, usage2, 'isRuntimeTypeUsed', usage1.isRuntimeTypeUsed,
      usage2.isRuntimeTypeUsed);
  check(usage1, usage2, 'isIsolateInUse', usage1.isIsolateInUse,
      usage2.isIsolateInUse);
  check(usage1, usage2, 'isFunctionApplyUsed', usage1.isFunctionApplyUsed,
      usage2.isFunctionApplyUsed);
  check(usage1, usage2, 'isNoSuchMethodUsed', usage1.isNoSuchMethodUsed,
      usage2.isNoSuchMethodUsed);
}

checkElementEnvironment(ElementEnvironment env1, ElementEnvironment env2,
    DartTypes types1, DartTypes types2, TestStrategy strategy,
    {bool checkConstructorBodies: false}) {
  strategy.testElements(
      env1, env2, 'mainLibrary', env1.mainLibrary, env2.mainLibrary);
  strategy.testElements(
      env1, env2, 'mainFunction', env1.mainFunction, env2.mainFunction);

  checkMembers(MemberEntity member1, MemberEntity member2) {
    Expect.equals(env1.isDeferredLoadLibraryGetter(member1),
        env2.isDeferredLoadLibraryGetter(member2));

    checkListEquivalence(
        member1,
        member2,
        'metadata',
        env1.getMemberMetadata(member1),
        env2.getMemberMetadata(member2),
        strategy.testConstantValues);

    if (member1 is FunctionEntity && member2 is FunctionEntity) {
      check(member1, member2, 'getFunctionType', env1.getFunctionType(member1),
          env2.getFunctionType(member2), strategy.typeEquivalence);
    }
  }

  checkSetEquivalence(env1, env2, 'libraries', env1.libraries, env2.libraries,
      strategy.elementEquivalence,
      onSameElement: (LibraryEntity lib1, LibraryEntity lib2) {
    Expect.identical(lib1, env1.lookupLibrary(lib1.canonicalUri));
    Expect.identical(lib2, env2.lookupLibrary(lib2.canonicalUri));

    // TODO(johnniwinther): Check libraryName.

    List<ClassEntity> classes2 = <ClassEntity>[];
    env1.forEachClass(lib1, (ClassEntity cls1) {
      Expect.identical(cls1, env1.lookupClass(lib1, cls1.name));

      String className = cls1.name;
      ClassEntity cls2 = env2.lookupClass(lib2, className);
      Expect.isNotNull(cls2, 'Missing class $className in $lib2');
      Expect.identical(cls2, env2.lookupClass(lib2, cls2.name));

      check(lib1, lib2, 'class:${className}', cls1, cls2,
          strategy.elementEquivalence);

      Expect.equals(env1.isGenericClass(cls1), env2.isGenericClass(cls2));

      check(
          cls1,
          cls2,
          'superclass',
          env1.getSuperClass(cls1, skipUnnamedMixinApplications: false),
          env2.getSuperClass(cls2, skipUnnamedMixinApplications: false),
          strategy.elementEquivalence);
      check(
          cls1,
          cls2,
          'superclass',
          env1.getSuperClass(cls1, skipUnnamedMixinApplications: true),
          env2.getSuperClass(cls2, skipUnnamedMixinApplications: true),
          strategy.elementEquivalence);

      InterfaceType thisType1 = env1.getThisType(cls1);
      InterfaceType thisType2 = env2.getThisType(cls2);
      check(cls1, cls2, 'thisType', thisType1, thisType2,
          strategy.typeEquivalence);
      check(cls1, cls2, 'rawType', env1.getRawType(cls1), env2.getRawType(cls2),
          strategy.typeEquivalence);
      check(
          cls1,
          cls2,
          'createInterfaceType',
          env1.createInterfaceType(cls1, thisType1.typeArguments),
          env2.createInterfaceType(cls2, thisType2.typeArguments),
          strategy.typeEquivalence);

      check(cls1, cls2, 'isGenericClass', env1.isGenericClass(cls1),
          env2.isGenericClass(cls2));
      check(cls1, cls2, 'isMixinApplication', env1.isMixinApplication(cls1),
          env2.isMixinApplication(cls2));
      check(
          cls1,
          cls2,
          'isUnnamedMixinApplication',
          env1.isUnnamedMixinApplication(cls1),
          env2.isUnnamedMixinApplication(cls2));
      check(
          cls1,
          cls2,
          'getEffectiveMixinClass',
          env1.getEffectiveMixinClass(cls1),
          env2.getEffectiveMixinClass(cls2),
          strategy.elementEquivalence);

      // TODO(johnniwinther): Check type variable bounds.

      check(cls1, cls2, 'callType', types1.getCallType(thisType1),
          types2.getCallType(thisType2), strategy.typeEquivalence);

      List<InterfaceType> supertypes1 = <InterfaceType>[];
      env1.forEachSupertype(cls1, supertypes1.add);
      List<InterfaceType> supertypes2 = <InterfaceType>[];
      env2.forEachSupertype(cls2, supertypes2.add);
      checkLists(supertypes1, supertypes2, 'supertypes on $cls1, $cls2',
          strategy.typeEquivalence);

      List<ClassEntity> mixins1 = <ClassEntity>[];
      env1.forEachMixin(cls1, mixins1.add);
      List<ClassEntity> mixins2 = <ClassEntity>[];
      env2.forEachMixin(cls2, mixins2.add);
      checkLists(mixins1, mixins2, 'mixins on $cls1, $cls2',
          strategy.elementEquivalence);

      Map<MemberEntity, ClassEntity> members1 = <MemberEntity, ClassEntity>{};
      Map<MemberEntity, ClassEntity> members2 = <MemberEntity, ClassEntity>{};
      env1.forEachClassMember(cls1,
          (ClassEntity declarer1, MemberEntity member1) {
        if (cls1 == declarer1) {
          Expect.identical(
              member1,
              env1.lookupClassMember(cls1, member1.name,
                  setter: member1.isSetter));
        }
        members1[member1] = declarer1;
      });
      env2.forEachClassMember(cls2,
          (ClassEntity declarer2, MemberEntity member2) {
        if (cls2 == declarer2) {
          Expect.identical(
              member2,
              env2.lookupClassMember(cls2, member2.name,
                  setter: member2.isSetter));
        }
        members2[member2] = declarer2;
      });
      checkMapEquivalence(cls1, cls2, 'members', members1, members2, (a, b) {
        bool result = strategy.elementEquivalence(a, b);
        if (result) checkMembers(a, b);
        return result;
      }, strategy.elementEquivalence);

      Set<ConstructorEntity> constructors2 = new Set<ConstructorEntity>();
      env1.forEachConstructor(cls1, (ConstructorEntity constructor1) {
        Expect.identical(
            constructor1, env1.lookupConstructor(cls1, constructor1.name));

        String constructorName = constructor1.name;
        ConstructorEntity constructor2 =
            env2.lookupConstructor(cls2, constructorName);
        Expect.isNotNull(
            constructor2, "Missing constructor for $constructor1 in $cls2 ");
        Expect.identical(
            constructor2, env2.lookupConstructor(cls2, constructor2.name));

        constructors2.add(constructor2);

        check(cls1, cls2, 'constructor:${constructorName}', constructor1,
            constructor2, strategy.elementEquivalence);

        checkMembers(constructor1, constructor2);
      });
      env2.forEachConstructor(cls2, (ConstructorEntity constructor2) {
        Expect.isTrue(constructors2.contains(constructor2),
            "Extra constructor $constructor2 in $cls2");
      });

      if (checkConstructorBodies) {
        Set<ConstructorBodyEntity> constructorBodies1 =
            new Set<ConstructorBodyEntity>();
        Set<ConstructorBodyEntity> constructorBodies2 =
            new Set<ConstructorBodyEntity>();
        env1.forEachConstructorBody(cls1,
            (ConstructorBodyEntity constructorBody1) {
          constructorBodies1.add(constructorBody1);
        });
        env2.forEachConstructorBody(cls2,
            (ConstructorBodyEntity constructorBody2) {
          constructorBodies2.add(constructorBody2);
        });
        checkSetEquivalence(cls1, cls2, 'constructor-bodies',
            constructorBodies1, constructorBodies2, strategy.elementEquivalence,
            onSameElement: (ConstructorBodyEntity constructorBody1,
                ConstructorBodyEntity constructorBody2) {
          check(constructorBody1, constructorBody2, 'name',
              constructorBody1.name, constructorBody2.name);

          checkMembers(constructorBody1, constructorBody2);
        });
      }
      classes2.add(cls2);
    });
    env2.forEachClass(lib2, (ClassEntity cls2) {
      Expect.isTrue(classes2.contains(cls2), "Extra class $cls2 in $lib2");
    });

    Set<MemberEntity> members2 = new Set<MemberEntity>();
    env1.forEachLibraryMember(lib1, (MemberEntity member1) {
      Expect.identical(
          member1,
          env1.lookupLibraryMember(lib1, member1.name,
              setter: member1.isSetter));

      String memberName = member1.name;
      MemberEntity member2 =
          env2.lookupLibraryMember(lib2, memberName, setter: member1.isSetter);
      Expect.isNotNull(member2, 'Missing member for $member1 in $lib2');
      Expect.identical(
          member2,
          env2.lookupLibraryMember(lib2, member2.name,
              setter: member2.isSetter));

      members2.add(member2);

      check(lib1, lib2, 'member:${memberName}', member1, member2,
          strategy.elementEquivalence);

      checkMembers(member1, member2);
    });
    env2.forEachLibraryMember(lib2, (MemberEntity member2) {
      Expect.isTrue(
          members2.contains(member2), "Extra member $member2 in $lib2");
    });
  });
  // TODO(johnniwinther): Check getLocalFunctionType and getUnaliasedType ?
}

bool areInstantiationInfosEquivalent(
    InstantiationInfo info1,
    InstantiationInfo info2,
    bool elementEquivalence(Entity a, Entity b),
    bool typeEquivalence(DartType a, DartType b)) {
  checkMaps(
      info1.instantiationMap,
      info2.instantiationMap,
      'instantiationMap of\n   '
      '${info1.instantiationMap}\nvs ${info2.instantiationMap}',
      elementEquivalence,
      (a, b) => areSetsEquivalent(
          a, b, (a, b) => areInstancesEquivalent(a, b, typeEquivalence)));
  return true;
}

bool areInstancesEquivalent(Instance instance1, Instance instance2,
    bool typeEquivalence(DartType a, DartType b)) {
  InterfaceType type1 = instance1.type;
  InterfaceType type2 = instance2.type;
  return typeEquivalence(type1, type2) &&
      instance1.kind == instance2.kind &&
      instance1.isRedirection == instance2.isRedirection;
}

bool areAbstractUsagesEquivalent(AbstractUsage usage1, AbstractUsage usage2) {
  return usage1.hasSameUsage(usage2);
}

bool _areEntitiesEquivalent(a, b) => areElementsEquivalent(a, b);

void checkResolutionEnqueuers(
    BackendUsage backendUsage1,
    BackendUsage backendUsage2,
    ResolutionEnqueuer enqueuer1,
    ResolutionEnqueuer enqueuer2,
    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
    bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
    bool elementFilter(Entity element),
    bool verbose: false,
    bool skipClassUsageTesting: false}) {
  elementFilter ??= (_) => true;

  ResolutionWorldBuilderBase worldBuilder1 = enqueuer1.worldBuilder;
  ResolutionWorldBuilderBase worldBuilder2 = enqueuer2.worldBuilder;

  checkSets(worldBuilder1.instantiatedTypes, worldBuilder2.instantiatedTypes,
      "Instantiated types mismatch", typeEquivalence,
      verbose: verbose);

  checkSets(
      worldBuilder1.directlyInstantiatedClasses,
      worldBuilder2.directlyInstantiatedClasses,
      "Directly instantiated classes mismatch",
      elementEquivalence,
      verbose: verbose);

  checkMaps(
      worldBuilder1.getInstantiationMap(),
      worldBuilder2.getInstantiationMap(),
      "Instantiated classes mismatch",
      elementEquivalence,
      (a, b) => areInstantiationInfosEquivalent(
          a, b, elementEquivalence, typeEquivalence),
      verbose: verbose);

  checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
      "Processed element mismatch", elementEquivalence,
      elementFilter: elementFilter, verbose: verbose);

  checkSets(worldBuilder1.isChecks, worldBuilder2.isChecks, "Is-check mismatch",
      typeEquivalence,
      verbose: verbose);

  checkSets(worldBuilder1.closurizedMembers, worldBuilder2.closurizedMembers,
      "closurizedMembers", elementEquivalence,
      verbose: verbose);
  checkSets(worldBuilder1.fieldSetters, worldBuilder2.fieldSetters,
      "fieldSetters", elementEquivalence,
      verbose: verbose);
  checkSets(
      worldBuilder1.methodsNeedingSuperGetter,
      worldBuilder2.methodsNeedingSuperGetter,
      "methodsNeedingSuperGetter",
      elementEquivalence,
      verbose: verbose);

  if (!skipClassUsageTesting) {
    checkMaps(
        worldBuilder1.classUsageForTesting,
        worldBuilder2.classUsageForTesting,
        'classUsageForTesting',
        elementEquivalence,
        areAbstractUsagesEquivalent,
        verbose: verbose);
  }
  checkMaps(
      worldBuilder1.staticMemberUsageForTesting,
      worldBuilder2.staticMemberUsageForTesting,
      'staticMemberUsageForTesting',
      elementEquivalence,
      areAbstractUsagesEquivalent,
      keyFilter: elementFilter,
      verbose: verbose);
  checkMaps(
      worldBuilder1.instanceMemberUsageForTesting,
      worldBuilder2.instanceMemberUsageForTesting,
      'instanceMemberUsageForTesting',
      elementEquivalence,
      areAbstractUsagesEquivalent,
      verbose: verbose);

  Expect.equals(backendUsage1.isInvokeOnUsed, backendUsage2.isInvokeOnUsed,
      "JavaScriptBackend.hasInvokeOnSupport mismatch");
  Expect.equals(
      backendUsage1.isFunctionApplyUsed,
      backendUsage1.isFunctionApplyUsed,
      "JavaScriptBackend.hasFunctionApplySupport mismatch");
  Expect.equals(
      backendUsage1.isRuntimeTypeUsed,
      backendUsage2.isRuntimeTypeUsed,
      "JavaScriptBackend.hasRuntimeTypeSupport mismatch");
  Expect.equals(backendUsage1.isIsolateInUse, backendUsage2.isIsolateInUse,
      "JavaScriptBackend.hasIsolateSupport mismatch");
}

void checkCodegenEnqueuers(CodegenEnqueuer enqueuer1, CodegenEnqueuer enqueuer2,
    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
    bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
    bool elementFilter(Element element),
    bool verbose: false}) {
  CodegenWorldBuilderImpl worldBuilder1 = enqueuer1.worldBuilder;
  CodegenWorldBuilderImpl worldBuilder2 = enqueuer2.worldBuilder;

  checkSets(worldBuilder1.instantiatedTypes, worldBuilder2.instantiatedTypes,
      "Instantiated types mismatch", typeEquivalence,
      verbose: verbose);

  checkSets(
      worldBuilder1.directlyInstantiatedClasses,
      worldBuilder2.directlyInstantiatedClasses,
      "Directly instantiated classes mismatch",
      elementEquivalence,
      verbose: verbose);

  checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
      "Processed element mismatch", elementEquivalence, elementFilter: (e) {
    return elementFilter != null ? elementFilter(e) : true;
  }, verbose: verbose);

  checkSets(worldBuilder1.isChecks, worldBuilder2.isChecks, "Is-check mismatch",
      typeEquivalence,
      verbose: verbose);

  checkSets(
      worldBuilder1.allReferencedStaticFields,
      worldBuilder2.allReferencedStaticFields,
      "Directly instantiated classes mismatch",
      elementEquivalence,
      verbose: verbose);
  checkSets(worldBuilder1.closurizedMembers, worldBuilder2.closurizedMembers,
      "closurizedMembers", elementEquivalence,
      verbose: verbose);
  checkSets(worldBuilder1.processedClasses, worldBuilder2.processedClasses,
      "processedClasses", elementEquivalence,
      verbose: verbose);
  checkSets(
      worldBuilder1.methodsNeedingSuperGetter,
      worldBuilder2.methodsNeedingSuperGetter,
      "methodsNeedingSuperGetter",
      elementEquivalence,
      verbose: verbose);
  checkSets(
      worldBuilder1.staticFunctionsNeedingGetter,
      worldBuilder2.staticFunctionsNeedingGetter,
      "staticFunctionsNeedingGetter",
      elementEquivalence,
      verbose: verbose);

  checkMaps(
      worldBuilder1.classUsageForTesting,
      worldBuilder2.classUsageForTesting,
      'classUsageForTesting',
      elementEquivalence,
      areAbstractUsagesEquivalent,
      verbose: verbose);
  checkMaps(
      worldBuilder1.staticMemberUsageForTesting,
      worldBuilder2.staticMemberUsageForTesting,
      'staticMemberUsageForTesting',
      elementEquivalence,
      areAbstractUsagesEquivalent,
      verbose: verbose);
  checkMaps(
      worldBuilder1.instanceMemberUsageForTesting,
      worldBuilder2.instanceMemberUsageForTesting,
      'instanceMemberUsageForTesting',
      elementEquivalence,
      areAbstractUsagesEquivalent,
      verbose: verbose);
}

// TODO(johnniwinther): Check all emitter properties.
void checkEmitters(
    CodeEmitterTask emitter1, CodeEmitterTask emitter2, TestStrategy strategy,
    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent,
    bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
    bool elementFilter(Element element),
    bool verbose: false}) {
  checkEmitterPrograms(emitter1.emitter.programForTesting,
      emitter2.emitter.programForTesting, strategy);

  checkSets(
      emitter1.typeTestRegistry.rtiNeededClasses,
      emitter2.typeTestRegistry.rtiNeededClasses,
      "TypeTestRegistry rti needed classes mismatch",
      strategy.elementEquivalence,
      verbose: verbose);

  checkSets(
      emitter1.typeTestRegistry.checkedFunctionTypes,
      emitter2.typeTestRegistry.checkedFunctionTypes,
      "TypeTestRegistry checked function types mismatch",
      strategy.typeEquivalence,
      verbose: verbose);

  checkSets(
      emitter1.typeTestRegistry.checkedClasses,
      emitter2.typeTestRegistry.checkedClasses,
      "TypeTestRegistry checked classes mismatch",
      strategy.elementEquivalence,
      verbose: verbose);
}

void checkEmitterPrograms(
    Program program1, Program program2, TestStrategy strategy) {
  checkLists(program1.fragments, program2.fragments, 'fragments',
      (a, b) => a.outputFileName == b.outputFileName,
      onSameElement: (a, b) => checkEmitterFragments(a, b, strategy));
  checkLists(
      program1.holders, program2.holders, 'holders', (a, b) => a.name == b.name,
      onSameElement: checkEmitterHolders);
  check(program1, program2, 'outputContainsConstantList',
      program1.outputContainsConstantList, program2.outputContainsConstantList);
  check(program1, program2, 'needsNativeSupport', program1.needsNativeSupport,
      program2.needsNativeSupport);
  check(program1, program2, 'hasIsolateSupport', program1.hasIsolateSupport,
      program2.hasIsolateSupport);
  check(program1, program2, 'hasSoftDeferredClasses',
      program1.hasSoftDeferredClasses, program2.hasSoftDeferredClasses);
  checkMaps(
      program1.loadMap,
      program2.loadMap,
      'loadMap',
      equality,
      (a, b) => areSetsEquivalent(
          a, b, (a, b) => a.outputFileName == b.outputFileName));
  checkMaps(program1.symbolsMap, program2.symbolsMap, 'symbolsMap',
      (a, b) => a.key == b.key, equality);

  check(
      program1,
      program2,
      'typeToInterceptorMap',
      program1.typeToInterceptorMap,
      program2.typeToInterceptorMap,
      areJsNodesEquivalent,
      js.nodeToString);
  check(program1, program2, 'metadata', program1.metadata, program2.metadata,
      areJsNodesEquivalent, js.nodeToString);
}

void checkEmitterFragments(
    Fragment fragment1, Fragment fragment2, TestStrategy strategy) {
  // TODO(johnniwinther): Check outputUnit.
  checkLists(fragment1.libraries, fragment2.libraries, 'libraries',
      (a, b) => a.element.canonicalUri == b.element.canonicalUri,
      onSameElement: (a, b) => checkEmitterLibraries(a, b, strategy));
  checkLists(fragment1.constants, fragment2.constants, 'constants',
      (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterConstants(a, b, strategy));
  checkLists(fragment1.staticNonFinalFields, fragment2.staticNonFinalFields,
      'staticNonFinalFields', (a, b) => a.name.key == b.name.key,
      onSameElement: checkEmitterStaticFields);
  checkLists(
      fragment1.staticLazilyInitializedFields,
      fragment2.staticLazilyInitializedFields,
      'staticLazilyInitializedFields',
      (a, b) => a.name.key == b.name.key,
      onSameElement: checkEmitterStaticFields);
  check(fragment1, fragment2, 'isMainFragment', fragment1.isMainFragment,
      fragment2.isMainFragment);
  if (fragment1 is MainFragment && fragment2 is MainFragment) {
    check(fragment1, fragment2, 'invokeMain', fragment1.invokeMain,
        fragment2.invokeMain, areJsNodesEquivalent, js.nodeToString);
  } else if (fragment1 is DeferredFragment && fragment2 is DeferredFragment) {
    check(fragment1, fragment2, 'name', fragment1.name, fragment2.name);
  }
}

void checkEmitterLibraries(
    Library library1, Library library2, TestStrategy strategy) {
  check(library1, library2, 'uri', library1.uri, library2.uri);
  checkLists(library1.classes, library2.classes, 'classes',
      (a, b) => a.element.name == b.element.name,
      onSameElement: (a, b) => checkEmitterClasses(a, b, strategy));
  checkLists(library1.statics, library2.statics, 'statics',
      (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
  checkLists(
      library1.staticFieldsForReflection,
      library2.staticFieldsForReflection,
      'staticFieldsForReflection on $library1/$library2',
      (a, b) => a.name.key == b.name.key,
      onSameElement: checkEmitterFields);
}

void checkEmitterClasses(Class class1, Class class2, TestStrategy strategy) {
  checkLists(class1.methods, class2.methods, 'methods',
      (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
  checkLists(class1.fields, class2.fields, 'fields',
      (a, b) => a.name.key == b.name.key,
      onSameElement: checkEmitterFields);
  checkLists(class1.isChecks, class2.isChecks, 'isChecks',
      (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
  checkLists(class1.checkedSetters, class2.checkedSetters, 'checkedSetters',
      (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
  checkLists(class1.callStubs, class2.callStubs, 'callStubs',
      (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
  checkLists(class1.noSuchMethodStubs, class2.noSuchMethodStubs,
      'noSuchMethodStubs', (a, b) => a.name.key == b.name.key,
      onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
  checkLists(
      class1.staticFieldsForReflection,
      class2.staticFieldsForReflection,
      'staticFieldsForReflection on $class1/$class2',
      (a, b) => a.name.key == b.name.key,
      onSameElement: checkEmitterFields);

  check(class1, class2, 'superclassName', class1.superclassName?.key,
      class2.superclassName?.key);
  check(class1, class2, 'isMixinApplication', class1.isMixinApplication,
      class2.isMixinApplication);
  check(class1, class2, 'hasRtiField', class1.hasRtiField, class2.hasRtiField);
  check(class1, class2, 'onlyForRti', class1.onlyForRti, class2.onlyForRti);
  check(class1, class2, 'isDirectlyInstantiated', class1.isDirectlyInstantiated,
      class2.isDirectlyInstantiated);
  check(class1, class2, 'isNative', class1.isNative, class2.isNative);
  check(class1, class2, 'isClosureBaseClass', class1.isClosureBaseClass,
      class2.isClosureBaseClass);
  check(class1, class2, 'isSoftDeferred', class1.isSoftDeferred,
      class2.isSoftDeferred);
  check(class1, class2, 'isEager', class1.isEager, class2.isEager);
  checkEmitterHolders(class1.holder, class2.holder);
}

void checkEmitterMethods(
    Method method1, Method method2, TestStrategy strategy) {
  check(method1, method2, 'code', method1.code, method2.code,
      areJsNodesEquivalent, js.nodeToString);
  check(method1, method2, 'is ParameterStubMethod',
      method1 is ParameterStubMethod, method2 is ParameterStubMethod);
  if (method1 is ParameterStubMethod && method2 is ParameterStubMethod) {
    check(method1, method2, 'callName', method1.callName?.key,
        method2.callName?.key);
  }
  check(method1, method2, 'is DartMethod', method1 is DartMethod,
      method2 is DartMethod);
  if (method1 is DartMethod && method2 is DartMethod) {
    check(method1, method2, 'callName', method1.callName?.key,
        method2.callName?.key);
    check(method1, method2, 'needsTearOff', method1.needsTearOff,
        method2.needsTearOff);
    check(method1, method2, 'tearOffName', method1.tearOffName?.key,
        method2.tearOffName?.key);
    checkLists(method1.parameterStubs, method2.parameterStubs, 'parameterStubs',
        (a, b) => a.name.key == b.name.key,
        onSameElement: (a, b) => checkEmitterMethods(a, b, strategy));
    check(method1, method2, 'canBeApplied', method1.canBeApplied,
        method2.canBeApplied);
    check(method1, method2, 'canBeReflected', method1.canBeReflected,
        method2.canBeReflected);
    check(method1, method2, 'functionType', method1.functionType,
        method2.functionType, areJsNodesEquivalent, js.nodeToString);
    check(method1, method2, 'requiredParameterCount',
        method1.requiredParameterCount, method2.requiredParameterCount);
    if (method1.optionalParameterDefaultValues == null &&
        method2.optionalParameterDefaultValues == null) {
      // Nothing to test.
    } else if (method1.optionalParameterDefaultValues is List &&
        method2.optionalParameterDefaultValues is List) {
      checkLists(
          method1.optionalParameterDefaultValues,
          method2.optionalParameterDefaultValues,
          'optionalParameterDefaultValues',
          strategy.constantValueEquivalence);
    } else if (method1.optionalParameterDefaultValues is Map &&
        method2.optionalParameterDefaultValues is Map) {
      checkMaps(
          method1.optionalParameterDefaultValues,
          method2.optionalParameterDefaultValues,
          'optionalParameterDefaultValues',
          equality,
          strategy.constantValueEquivalence);
    } else {
      check(
          method1,
          method2,
          'optionalParameterDefaultValues',
          method1.optionalParameterDefaultValues,
          method2.optionalParameterDefaultValues);
    }
  }
}

void checkEmitterFields(Field field1, Field field2) {
  check(field1, field2, 'accessorName', field1.accessorName?.key,
      field2.accessorName?.key);
  check(field1, field2, 'getterFlags', field1.getterFlags, field2.getterFlags);
  check(field1, field2, 'setterFlags', field1.setterFlags, field2.setterFlags);
  check(field1, field2, 'needsCheckedSetter', field1.needsCheckedSetter,
      field2.needsCheckedSetter);
}

void checkEmitterConstants(
    Constant constant1, Constant constant2, TestStrategy strategy) {
  checkEmitterHolders(constant1.holder, constant2.holder);
  check(constant1, constant2, 'value', constant1.value, constant2.value,
      strategy.constantValueEquivalence);
}

void checkEmitterStaticFields(StaticField field1, StaticField field2) {
  check(field1, field2, 'code', field1.code, field2.code, areJsNodesEquivalent,
      js.nodeToString);
  check(field1, field2, 'isFinal', field1.isFinal, field2.isFinal);
  check(field1, field2, 'isLazy', field1.isLazy, field2.isLazy);
  checkEmitterHolders(field1.holder, field2.holder);
}

void checkEmitterHolders(Holder holder1, Holder holder2) {
  check(holder1, holder2, 'name', holder1.name, holder2.name);
  check(holder1, holder2, 'index', holder1.index, holder2.index);
  check(holder1, holder2, 'isStaticStateHolder', holder1.isStaticStateHolder,
      holder2.isStaticStateHolder);
  check(holder1, holder2, 'isConstantsHolder', holder1.isConstantsHolder,
      holder2.isConstantsHolder);
}

void checkGeneratedCode(JavaScriptBackend backend1, JavaScriptBackend backend2,
    {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent}) {
  checkMaps(backend1.generatedCode, backend2.generatedCode, 'generatedCode',
      elementEquivalence, areJsNodesEquivalent,
      valueToString: js.nodeToString);
}

bool areJsNodesEquivalent(js.Node node1, js.Node node2) {
  return new JsEquivalenceVisitor().testNodes(node1, node2);
}

class JsEquivalenceVisitor extends js.EquivalenceVisitor {
  Map<String, String> labelsMap = <String, String>{};

  @override
  bool failAt(js.Node node1, js.Node node2) {
    print('Node mismatch:');
    print('  ${node1 != null ? js.nodeToString(node1) : '<null>'}');
    print('  ${node2 != null ? js.nodeToString(node2) : '<null>'}');
    return false;
  }

  @override
  bool testValues(js.Node node1, Object value1, js.Node node2, Object value2) {
    if (value1 != value2) {
      print('Value mismatch:');
      print('  ${value1}');
      print('  ${value2}');
      print('at');
      print('  ${node1 != null ? js.nodeToString(node1) : '<null>'}');
      print('  ${node2 != null ? js.nodeToString(node2) : '<null>'}');
      return false;
    }
    return true;
  }

  @override
  bool testLabels(js.Node node1, String label1, js.Node node2, String label2) {
    if (label1 == null && label2 == null) return true;
    if (labelsMap.containsKey(label1)) {
      String expectedValue = labelsMap[label1];
      if (expectedValue != label2) {
        print('Value mismatch:');
        print('  ${label1}');
        print('  found ${label2}, expected ${expectedValue}');
        print('at');
        print('  ${js.nodeToString(node1)}');
        print('  ${js.nodeToString(node2)}');
      }
      return expectedValue == label2;
    } else {
      labelsMap[label1] = label2;
      return true;
    }
  }
}
