// Copyright (c) 2015, 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.

library dart2js.serialization_test;

import 'dart:io';
import 'memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/constants/constructors.dart';
import 'package:compiler/src/constants/expressions.dart';
import 'package:compiler/src/dart_types.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/invariant.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/visitor.dart';
import 'package:compiler/src/ordered_typeset.dart';
import 'package:compiler/src/serialization/element_serialization.dart';
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/serialization/json_serializer.dart';
import 'package:compiler/src/serialization/serialization.dart';

main(List<String> arguments) {
  // Ensure that we can print out constant expressions.
  DEBUG_MODE = true;

  Uri entryPoint;
  String outPath;
  bool prettyPrint = false;
  for (String arg in arguments) {
    if (arg.startsWith('--')) {
      if (arg.startsWith('--out=')) {
        outPath = arg.substring('--out='.length);
      } else if (arg == '--pretty-print') {
        prettyPrint = true;
      } else {
        print("Unknown option $arg");
      }
    } else {
      if (entryPoint != null) {
        print("Multiple entrypoints is not supported.");
      }
      entryPoint = Uri.parse(arg);
    }
  }
  if (entryPoint == null) {
    entryPoint = Uri.parse('dart:core');
  }
  asyncTest(() async {
    CompilationResult result = await runCompiler(
        entryPoint: entryPoint, options: [Flags.analyzeAll]);
    Compiler compiler = result.compiler;
    testSerialization(compiler.libraryLoader.libraries,
                      outPath: outPath,
                      prettyPrint: prettyPrint);
  });
}

void testSerialization(Iterable<LibraryElement> libraries1,
                       {String outPath,
                        bool prettyPrint}) {
  Serializer serializer = new Serializer();
  for (LibraryElement library1 in libraries1) {
    serializer.serialize(library1);
  }
  String text = serializer.toText(const JsonSerializationEncoder());
  String outText = text;
  if (prettyPrint) {
    outText = serializer.prettyPrint();
  }
  if (outPath != null) {
    new File(outPath).writeAsStringSync(outText);
  } else if (prettyPrint) {
    print(outText);
  }

  Deserializer deserializer = new Deserializer.fromText(
      new DeserializationContext(),
      text, const JsonSerializationDecoder());
  List<LibraryElement> libraries2 = <LibraryElement>[];
  for (LibraryElement library1 in libraries1) {
    LibraryElement library2 =
        deserializer.lookupLibrary(library1.canonicalUri);
    if (library2 == null) {
      throw new ArgumentError('No library ${library1.canonicalUri} found.');
    }
    checkLibraryContent('library1', 'library2', 'library', library1, library2);
    libraries2.add(library2);
  }

  Serializer serializer2 = new Serializer();
  for (LibraryElement library2 in libraries2) {
    serializer2.serialize(library2);
  }
  String text2 = serializer2.toText(const JsonSerializationEncoder());

  Deserializer deserializer3 = new Deserializer.fromText(
      new DeserializationContext(),
      text2, const JsonSerializationDecoder());
  for (LibraryElement library1 in libraries1) {
    LibraryElement library2 =
        deserializer.lookupLibrary(library1.canonicalUri);
    if (library2 == null) {
      throw new ArgumentError('No library ${library1.canonicalUri} found.');
    }
    LibraryElement library3 =
        deserializer3.lookupLibrary(library1.canonicalUri);
    if (library3 == null) {
      throw new ArgumentError('No library ${library1.canonicalUri} found.');
    }
    checkLibraryContent('library1', 'library3', 'library', library1, library3);
    checkLibraryContent('library2', 'library3', 'library', library2, library3);
  }
}

/// Check the equivalence of [library1] and [library2] and their content.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
checkLibraryContent(
    Object object1, object2, String property,
    LibraryElement library1, LibraryElement library2) {
  checkElementProperties(object1, object2, property, library1, library2);
}

/// Check the equivalence of [element1] and [element2] and their properties.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
checkElementProperties(
    Object object1, object2, String property,
    Element element1, Element element2) {
  const ElementPropertyEquivalence().visit(element1, element2);
}

/// Check the equivalence of the two lists of elements, [list1] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
checkElementLists(Object object1, Object object2, String property,
                  Iterable<Element> list1, Iterable<Element> list2) {
  checkListEquivalence(object1, object2, property,
                  list1, list2, checkElementProperties);
}

/// Check equivalence of the two lists, [list1] and [list2], using
/// [checkEquivalence] to check the pair-wise equivalence.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkListEquivalence(
    Object object1, Object object2, String property,
    Iterable list1, Iterable list2,
    void checkEquivalence(o1, o2, property, a, b)) {
  for (int i = 0; i < list1.length && i < list2.length; i++) {
    checkEquivalence(
        object1, object2, property,
        list1.elementAt(i), list2.elementAt(i));
  }
  for (int i = list1.length; i < list2.length; i++) {
    throw
        'Missing equivalent for element '
        '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n'
        '`${property}` on $object1:\n ${list1.join('\n ')}\n'
        '`${property}` on $object2:\n ${list2.join('\n ')}';
  }
  for (int i = list2.length; i < list1.length; i++) {
    throw
        'Missing equivalent for element '
        '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n'
        '`${property}` on $object1:\n ${list1.join('\n ')}\n'
        '`${property}` on $object2:\n ${list2.join('\n ')}';
  }
  return true;
}

/// Computes the set difference between [set1] and [set2] using
/// [elementEquivalence] to determine element equivalence.
///
/// Elements both in [set1] and [set2] are added to [common], elements in [set1]
/// but not in [set2] are added to [unfound], and the set of elements in [set2]
/// but not in [set1] are returned.
Set computeSetDifference(
    Iterable set1,
    Iterable set2,
    List common,
    List unfound,
    [bool sameElement(a, b) = equality]) {
  // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas:
  // - convert each set to a list and sort it first, then compare by walking
  // both lists in parallel
  // - map each element to a canonical object, create a map containing those
  // mappings, use the mapped sets to compare (then operations like
  // set.difference would work)
  Set remaining = set2.toSet();
  for (var element1 in set1) {
    bool found = false;
    for (var element2 in remaining) {
      if (sameElement(element1, element2)) {
        found = true;
        remaining.remove(element2);
        break;
      }
    }
    if (found) {
      common.add(element1);
    } else {
      unfound.add(element1);
    }
  }
  return remaining;
}

/// Check equivalence of the two iterables, [set1] and [set1], as sets using
/// [elementEquivalence] to compute the pair-wise equivalence.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkSetEquivalence(
    var object1,
    var object2,
    String property,
    Iterable set1,
    Iterable set2,
    bool sameElement(a, b)) {
  List common = [];
  List unfound = [];
  Set remaining =
      computeSetDifference(set1, set2, common, unfound, sameElement);
  if (unfound.isNotEmpty || remaining.isNotEmpty) {
    String message =
        "Set mismatch for `$property` on $object1 vs $object2: \n"
        "Common:\n ${common.join('\n ')}\n"
        "Unfound:\n ${unfound.join('\n ')}\n"
        "Extra: \n ${remaining.join('\n ')}";
    throw message;
  }
  return true;
}

/// Checks the equivalence of the identity (but not properties) of [element1]
/// and [element2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkElementIdentities(
    Object object1, Object object2, String property,
    Element element1, Element element2) {
  if (identical(element1, element2)) return true;
  if (element1 == null || element2 == null) {
    return check(object1, object2, property, element1, element2);
  } else {
    return const ElementIdentityEquivalence(const CheckStrategy())
        .visit(element1, element2);
  }
}

/// Checks the pair-wise equivalence of the identity (but not properties) of the
/// elements in [list] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkElementListIdentities(
    Object object1, Object object2, String property,
    Iterable<Element> list1, Iterable<Element> list2) {
  return checkListEquivalence(
      object1, object2, property,
      list1, list2, checkElementIdentities);
}

/// Checks the equivalence of [type1] and [type2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkTypes(
    Object object1, Object object2, String property,
    DartType type1, DartType type2) {
  if (identical(type1, type2)) return true;
  if (type1 == null || type2 == null) {
    return check(object1, object2, property, type1, type2);
  } else {
    return const TypeEquivalence(const CheckStrategy()).visit(type1, type2);
  }
}

/// Checks the pair-wise equivalence of the types in [list1] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkTypeLists(
    Object object1, Object object2, String property,
    List<DartType> list1, List<DartType> list2) {
  return checkListEquivalence(
      object1, object2, property, list1, list2, checkTypes);
}

/// Checks the equivalence of [exp1] and [exp2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkConstants(
    Object object1, Object object2, String property,
    ConstantExpression exp1, ConstantExpression exp2) {
  if (identical(exp1, exp2)) return true;
  if (exp1 == null || exp2 == null) {
    return check(object1, object2, property, exp1, exp2);
  } else {
    return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2);
  }
}

/// Checks the pair-wise equivalence of the contants in [list1] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkConstantLists(
    Object object1, Object object2, String property,
    List<ConstantExpression> list1,
    List<ConstantExpression> list2) {
  return checkListEquivalence(
      object1, object2, property,
      list1, list2, checkConstants);
}


/// Strategy for checking equivalence.
///
/// Use this strategy to fail early with contextual information in the event of
/// inequivalence.
class CheckStrategy implements TestStrategy {
  const CheckStrategy();

  @override
  bool test(var object1, var object2, String property, var value1, var value2) {
    return check(object1, object2, property, value1, value2);
  }

  @override
  bool testLists(
      Object object1, Object object2, String property,
      List list1, List list2,
      [bool elementEquivalence(a, b) = equality]) {
    return checkListEquivalence(
        object1, object2, property, list1, list2,
        (o1, o2, p, v1, v2) {
          if (!elementEquivalence(v1, v2)) {
            throw "$o1.$p = '${v1}' <> "
                  "$o2.$p = '${v2}'";
          }
          return true;
        });
  }

  @override
  bool testSets(
      var object1, var object2, String property,
      Iterable set1, Iterable set2,
      [bool elementEquivalence(a, b) = equality]) {
    return checkSetEquivalence(
        object1, object2,property, set1, set2, elementEquivalence);
  }

  @override
  bool testElements(
      Object object1, Object object2, String property,
      Element element1, Element element2) {
    return checkElementIdentities(
        object1, object2, property, element1, element2);
  }

  @override
  bool testTypes(
      Object object1, Object object2, String property,
      DartType type1, DartType type2) {
    return checkTypes(object1, object2, property, type1, type2);
  }

  @override
  bool testConstants(
      Object object1, Object object2, String property,
      ConstantExpression exp1, ConstantExpression exp2) {
    return checkConstants(object1, object2, property, exp1, exp2);
  }

  @override
  bool testTypeLists(
      Object object1, Object object2, String property,
      List<DartType> list1, List<DartType> list2) {
    return checkTypeLists(object1, object2, property, list1, list2);
  }

  @override
  bool testConstantLists(
      Object object1, Object object2, String property,
      List<ConstantExpression> list1,
      List<ConstantExpression> list2) {
    return checkConstantLists(object1, object2, property, list1, list2);
  }
}

/// Checks the equivalence of [constructor1] and [constructor2].
void constantConstructorEquivalence(ConstantConstructor constructor1,
                                    ConstantConstructor constructor2) {
  const ConstantConstructorEquivalence().visit(constructor1, constructor2);
}

/// Visitor that checks the equivalence of [ConstantConstructor]s.
class ConstantConstructorEquivalence
    extends ConstantConstructorVisitor<dynamic, ConstantConstructor> {
  const ConstantConstructorEquivalence();

  @override
  void visit(ConstantConstructor constructor1,
             ConstantConstructor constructor2) {
    if (identical(constructor1, constructor2)) return;
    check(constructor1, constructor2, 'kind',
          constructor1.kind, constructor2.kind);
    constructor1.accept(this, constructor2);
  }

  @override
  visitGenerative(
      GenerativeConstantConstructor constructor1,
      GenerativeConstantConstructor constructor2) {
    checkTypes(
        constructor1, constructor2, 'type',
        constructor1.type, constructor2.type);
    check(constructor1, constructor2, 'defaultValues.length',
          constructor1.defaultValues.length,
          constructor2.defaultValues.length);
    constructor1.defaultValues.forEach((k, v) {
      checkConstants(
          constructor1, constructor2, 'defaultValue[$k]',
          v, constructor2.defaultValues[k]);
    });
    check(constructor1, constructor2, 'fieldMap.length',
          constructor1.fieldMap.length,
          constructor2.fieldMap.length);
    constructor1.fieldMap.forEach((k1, v1) {
      bool matched = false;
      constructor2.fieldMap.forEach((k2, v2) {
        if (k1.name == k2.name &&
            k1.library.canonicalUri == k2.library.canonicalUri) {
          checkElementIdentities(
              constructor1, constructor2, 'fieldMap[${k1.name}].key', k1, k2);
          checkConstants(
              constructor1, constructor2, 'fieldMap[${k1.name}].value', v1, v2);
          matched = true;
        }
      });
      if (!matched) {
        throw 'Unmatched field $k1 = $v1';
      }
    });
    checkConstants(
        constructor1, constructor2, 'superConstructorInvocation',
        constructor1.superConstructorInvocation,
        constructor2.superConstructorInvocation);
  }

  @override
  visitRedirectingFactory(
      RedirectingFactoryConstantConstructor constructor1,
      RedirectingFactoryConstantConstructor constructor2) {
    checkConstants(
        constructor1, constructor2, 'targetConstructorInvocation',
        constructor1.targetConstructorInvocation,
        constructor2.targetConstructorInvocation);
  }

  @override
  visitRedirectingGenerative(
      RedirectingGenerativeConstantConstructor constructor1,
      RedirectingGenerativeConstantConstructor constructor2) {
    check(constructor1, constructor2, 'defaultValues.length',
          constructor1.defaultValues.length,
          constructor2.defaultValues.length);
    constructor1.defaultValues.forEach((k, v) {
      checkConstants(
          constructor1, constructor2, 'defaultValue[$k]',
          v, constructor2.defaultValues[k]);
    });
    checkConstants(
        constructor1, constructor2, 'thisConstructorInvocation',
        constructor1.thisConstructorInvocation,
        constructor2.thisConstructorInvocation);
  }
}

/// Check that the values [property] of [object1] and [object2], [value1] and
/// [value2] respectively, are equal and throw otherwise.
bool check(var object1, var object2, String property, var value1, value2) {
  if (value1 != value2) {
    throw "$object1.$property = '${value1}' <> "
          "$object2.$property = '${value2}'";
  }
  return true;
}

/// Visitor that checks for equivalence of [Element] properties.
class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> {
  const ElementPropertyEquivalence();

  void visit(Element element1, Element element2) {
    if (element1 == null && element2 == null) return;
    element1 = element1.declaration;
    element2 = element2.declaration;
    if (element1 == element2) return;
    check(element1, element2, 'kind', element1.kind, element2.kind);
    element1.accept(this, element2);
  }

  @override
  void visitElement(Element e, Element arg) {
    throw new UnsupportedError("Unsupported element $e");
  }

  @override
  void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'libraryName',
          element1.libraryName, element2.libraryName);
    visitMembers(element1, element2);
    visit(element1.entryCompilationUnit, element2.entryCompilationUnit);

    checkElementLists(
        element1, element2, 'compilationUnits',
        LibrarySerializer.getCompilationUnits(element1),
        LibrarySerializer.getCompilationUnits(element2));

    checkElementListIdentities(
        element1, element2, 'imports',
        LibrarySerializer.getImports(element1),
        LibrarySerializer.getImports(element2));
    checkElementListIdentities(
        element1, element2, 'exports', element1.exports, element2.exports);

    checkElementListIdentities(
        element1, element2, 'importScope',
        LibrarySerializer.getImportedElements(element1),
        LibrarySerializer.getImportedElements(element2));

    checkElementListIdentities(
        element1, element2, 'exportScope',
        LibrarySerializer.getExportedElements(element1),
        LibrarySerializer.getExportedElements(element2));
  }

  @override
  void visitCompilationUnitElement(CompilationUnitElement element1,
                                   CompilationUnitElement element2) {
    check(element1, element2,
          'name',
          element1.name, element2.name);
    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    check(element1, element2,
          'script.resourceUri',
          element1.script.resourceUri, element2.script.resourceUri);
    List<Element> members1 = <Element>[];
    List<Element> members2 = <Element>[];
    element1.forEachLocalMember((Element member) {
      members1.add(member);
    });
    element2.forEachLocalMember((Element member) {
      members2.add(member);
    });
    checkElementListIdentities(
        element1, element2, 'localMembers', members1, members2);
  }

  void visitMembers(ScopeContainerElement element1,
                    ScopeContainerElement element2) {
    Set<String> names = new Set<String>();
    Iterable<Element> members1 = element1.isLibrary
        ? LibrarySerializer.getMembers(element1)
        : ClassSerializer.getMembers(element1);
    Iterable<Element> members2 = element2.isLibrary
        ? LibrarySerializer.getMembers(element2)
        : ClassSerializer.getMembers(element2);
    for (Element member in members1) {
      names.add(member.name);
    }
    for (Element member in members2) {
      names.add(member.name);
    }
    element1 = element1.implementation;
    element2 = element2.implementation;
    for (String name in names) {
      Element member1 = element1.localLookup(name);
      Element member2 = element2.localLookup(name);
      if (member1 == null) {
        String message =
            'Missing member for $member2 in\n ${members1.join('\n ')}';
        if (member2.isAbstractField) {
          // TODO(johnniwinther): Ensure abstract fields are handled correctly.
          //print(message);
          continue;
        } else {
          throw message;
        }
      }
      if (member2 == null) {
        String message =
            'Missing member for $member1 in\n ${members2.join('\n ')}';
        if (member1.isAbstractField) {
          // TODO(johnniwinther): Ensure abstract fields are handled correctly.
          //print(message);
          continue;
        } else {
          throw message;
        }
      }
      //print('Checking member ${member1} against ${member2}');
      visit(member1, member2);
    }
  }

  @override
  void visitClassElement(ClassElement element1, ClassElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name',
          element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    check(element1, element2, 'isObject',
        element1.isObject, element2.isObject);
    checkTypeLists(element1, element2, 'typeVariables',
        element1.typeVariables, element2.typeVariables);
    check(element1, element2, 'isAbstract',
        element1.isAbstract, element2.isAbstract);
    check(element1, element2, 'isUnnamedMixinApplication',
        element1.isUnnamedMixinApplication, element2.isUnnamedMixinApplication);
    check(element1, element2, 'isEnumClass',
        element1.isEnumClass, element2.isEnumClass);
    if (element1.isEnumClass) {
      EnumClassElement enum1 = element1;
      EnumClassElement enum2 = element2;
      checkElementLists(enum1, enum2, 'enumValues',
                        enum1.enumValues, enum2.enumValues);
    }
    if (!element1.isObject) {
      checkTypes(element1, element2, 'supertype',
          element1.supertype, element2.supertype);
    }
    check(element1, element2, 'hierarchyDepth',
          element1.hierarchyDepth, element2.hierarchyDepth);
    checkTypeLists(
        element1, element2, 'allSupertypes',
        element1.allSupertypes.toList(),
        element2.allSupertypes.toList());
    OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf;
    OrderedTypeSet typeSet2 = element1.allSupertypesAndSelf;
    checkListEquivalence(
        element1, element2, 'allSupertypes',
        typeSet1.levelOffsets,
        typeSet2.levelOffsets,
        check);
    check(element1, element2, 'allSupertypesAndSelf.levels',
          typeSet1.levels, typeSet2.levels);
    checkTypeLists(
        element1, element2, 'supertypes',
        typeSet1.supertypes.toList(),
        typeSet2.supertypes.toList());
    checkTypeLists(
        element1, element2, 'types',
        typeSet1.types.toList(),
        typeSet2.types.toList());

    checkTypeLists(
        element1, element2, 'interfaces',
        element1.interfaces.toList(),
        element2.interfaces.toList());

    List<ConstructorElement> getConstructors(ClassElement cls) {
      return cls.implementation.constructors.map((c) => c.declaration).toList();
    }

    checkElementLists(
        element1, element2, 'constructors',
        getConstructors(element1),
        getConstructors(element2));

    visitMembers(element1, element2);
  }

  @override
  void visitFieldElement(FieldElement element1, FieldElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name',
          element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    check(element1, element2, 'isConst',
          element1.isConst, element2.isConst);
    check(element1, element2, 'isFinal',
          element1.isFinal, element2.isFinal);
    if (element1.isConst) {
      checkConstants(
          element1, element2, 'constant',
          element1.constant, element2.constant);
    }
    check(element1, element2, 'isTopLevel',
          element1.isTopLevel, element2.isTopLevel);
    check(element1, element2, 'isStatic',
          element1.isStatic, element2.isStatic);
    check(element1, element2, 'isInstanceMember',
          element1.isInstanceMember, element2.isInstanceMember);

    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    checkElementIdentities(
        element1, element2, 'enclosingClass',
        element1.enclosingClass, element2.enclosingClass);
  }

  @override
  void visitFunctionElement(FunctionElement element1,
                            FunctionElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name',
          element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    checkListEquivalence(
        element1, element2, 'parameters',
        element1.parameters, element2.parameters,
        checkElementProperties);
    check(element1, element2, 'isOperator',
          element1.isOperator, element2.isOperator);

    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    checkElementIdentities(
        element1, element2, 'enclosingClass',
        element1.enclosingClass, element2.enclosingClass);
  }

  @override
  void visitConstructorElement(ConstructorElement element1,
                               ConstructorElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    checkElementIdentities(
        element1, element2, 'enclosingClass',
        element1.enclosingClass, element2.enclosingClass);
    check(
        element1, element2, 'name',
        element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkListEquivalence(
        element1, element2, 'parameters',
        element1.parameters, element2.parameters,
        checkElementProperties);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    check(element1, element2, 'isConst',
          element1.isConst, element2.isConst);
    check(element1, element2, 'isExternal',
          element1.isExternal, element2.isExternal);
    if (element1.isConst && !element1.isExternal) {
      constantConstructorEquivalence(
          element1.constantConstructor,
          element2.constantConstructor);
    }
  }

  @override
  void visitAbstractFieldElement(AbstractFieldElement element1,
                                 AbstractFieldElement element2) {
    visit(element1.getter, element2.getter);
    visit(element1.setter, element2.setter);
  }

  @override
  void visitTypeVariableElement(TypeVariableElement element1,
                                TypeVariableElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    check(element1, element2, 'index', element1.index, element2.index);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    checkTypes(
        element1, element2, 'bound',
        element1.bound, element2.bound);
  }

  @override
  void visitTypedefElement(TypedefElement element1,
                           TypedefElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'alias',
        element1.alias, element2.alias);
    checkTypeLists(
        element1, element2, 'typeVariables',
        element1.typeVariables, element2.typeVariables);
    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    // TODO(johnniwinther): Check the equivalence of typedef parameters.
  }

  @override
  void visitParameterElement(ParameterElement element1,
                             ParameterElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    checkElementIdentities(
        element1, element2, 'functionDeclaration',
        element1.functionDeclaration, element2.functionDeclaration);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    check(
        element1, element2, 'isOptional',
        element1.isOptional, element2.isOptional);
    check(
        element1, element2, 'isNamed',
        element1.isNamed, element2.isNamed);
    check(element1, element2, 'name', element1.name, element2.name);
    if (element1.isOptional) {
      checkConstants(
          element1, element2, 'constant',
          element1.constant, element2.constant);
    }
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
  }

  @override
  void visitFieldParameterElement(InitializingFormalElement element1,
                                  InitializingFormalElement element2) {
    visitParameterElement(element1, element2);
    checkElementIdentities(
        element1, element2, 'fieldElement',
        element1.fieldElement, element2.fieldElement);
  }

  @override
  void visitImportElement(ImportElement element1, ImportElement element2) {
    check(element1, element2, 'uri', element1.uri, element2.uri);
    check(
        element1, element2, 'isDeferred',
        element1.isDeferred, element2.isDeferred);
    checkElementProperties(
        element1, element2, 'prefix',
        element1.prefix, element2.prefix);
    checkElementIdentities(
        element1, element2, 'importedLibrary',
        element1.importedLibrary, element2.importedLibrary);
  }

  @override
  void visitExportElement(ExportElement element1, ExportElement element2) {
    check(element1, element2, 'uri', element1.uri, element2.uri);
    checkElementIdentities(
        element1, element2, 'importedLibrary',
        element1.exportedLibrary, element2.exportedLibrary);
  }

  @override
  void visitPrefixElement(PrefixElement element1, PrefixElement element2) {
    check(
        element1, element2, 'isDeferred',
        element1.isDeferred, element2.isDeferred);
    checkElementIdentities(
        element1, element2, 'importedLibrary',
        element1.deferredImport, element2.deferredImport);
    // TODO(johnniwinther): Check members.
  }
}
