// 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/constants/values.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.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);

  Iterable<ConstantValue> filterMetadata(Iterable<ConstantValue> constants) {
    const skippedMetadata = const [
      // Annotations on patches are not included in the patched sdk.
      'ConstructedConstant(_Patch())',
      'ConstructedConstant(NoInline())',

      // Inserted by TargetImplementation. Should only be in the VM target.
      'ConstructedConstant(ExternalName(name=StringConstant("")))',
    ];

    return constants
        .where((c) => !skippedMetadata.contains(c.toStructuredText()));
  }

  Iterable<LibraryEntity> filterLibraries(Iterable<LibraryEntity> libraries) {
    List<Uri> skippedLibraries = [
      Uri.parse('dart:mirrors'),
      Uri.parse('dart:_js_mirrors'),
      Uri.parse('dart:js'),
      Uri.parse('dart:js_util'),
      Uri.parse('dart:_chrome'),
    ];
    return libraries.where((l) => !skippedLibraries.contains(l.canonicalUri));
  }

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

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

    if (member1 is FunctionEntity && member2 is FunctionEntity) {
      if (member1 is ConstructorElement &&
          member1.definingConstructor != null) {
        // TODO(johnniwinther): Test these. Currently these are sometimes
        // correctly typed, sometimes using dynamic instead of parameter and
        // return types.
        return;
      }
      check(member1, member2, 'getFunctionType', env1.getFunctionType(member1),
          env2.getFunctionType(member2), strategy.typeEquivalence);
    }
  }

  checkSetEquivalence(env1, env2, 'libraries', filterLibraries(env1.libraries),
      filterLibraries(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,
    List<String> skipClassUsageTesting: const <String>[]}) {
  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);

  checkMaps(
      worldBuilder1.classUsageForTesting,
      worldBuilder2.classUsageForTesting,
      'classUsageForTesting',
      elementEquivalence,
      areAbstractUsagesEquivalent,
      keyFilter: (c) => !skipClassUsageTesting.contains(c.name),
      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.name.key == b.name.key,
      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;
    }
  }
}
