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

import 'dart:io';

import 'ast_model.dart';
import 'visitor_generator.dart';

Uri computeEquivalenceUri(Uri repoDir) {
  return repoDir.resolve('pkg/kernel/lib/src/equivalence.dart');
}

Future<void> main(List<String> args) async {
  Uri output = args.isEmpty
      ? computeEquivalenceUri(Uri.base)
      : new File(args[0]).absolute.uri;
  String result = await generateAstEquivalence(Uri.base);
  new File.fromUri(output).writeAsStringSync(result);
}

Future<String> generateAstEquivalence(Uri repoDir, [AstModel? astModel]) async {
  astModel ??= await deriveAstModel(repoDir);
  return generateVisitor(astModel, new EquivalenceVisitorStrategy());
}

class EquivalenceVisitorStrategy extends Visitor1Strategy {
  Map<AstClass, String> _classStrategyMembers = {};
  Map<AstField, String> _fieldStrategyMembers = {};

  EquivalenceVisitorStrategy();

  @override
  String get generatorCommand =>
      'dart pkg/front_end/tool/generate_ast_equivalence.dart';

  @override
  String get argumentType => 'Node';

  @override
  String get argumentName => 'other';

  @override
  String get returnType => 'bool';

  @override
  String get visitorName => 'EquivalenceVisitor';

  String get strategyName => 'EquivalenceStrategy';

  String get internalCheckValues => '_checkValues';

  String get checkValues => 'checkValues';

  String get matchValues => 'matchValues';

  String get internalCheckNodes => '_checkNodes';

  String get checkNodes => 'checkNodes';

  String get shallowMatchNodes => 'shallowMatchNodes';

  String get internalCheckReferences => '_checkReferences';

  String get checkReferences => 'checkReferences';

  String get matchReferences => 'matchReferences';

  String get matchNamedNodes => 'matchNamedNodes';

  String get assumeReferences => 'assumeReferences';

  String get checkAssumedReferences => 'checkAssumedReferences';

  String get checkDeclarations => 'checkDeclarations';

  String get internalCheckDeclarations => '_checkDeclarations';

  String get shallowMatchDeclarations => 'matchDeclarations';

  String get assumeDeclarations => 'assumeDeclarations';

  String get checkAssumedDeclarations => 'checkAssumedDeclarations';

  String get checkLists => 'checkLists';

  String get matchLists => 'matchLists';

  String get checkSets => 'checkSets';

  String get checkMaps => 'checkMaps';

  String get checkingState => '_checkingState';

  String get resultOnInequivalence => 'resultOnInequivalence';

  String get registerInequivalence => 'registerInequivalence';

  String classCheckName(AstClass astClass) => 'check${astClass.name}';

  String fieldCheckName(AstField field) =>
      'check${field.astClass.name}_${field.name}';

  /// Compute the expression code for shallow matching two values of type
  /// [fieldType].
  ///
  /// Shallow matching is used to pair value when checking sets and maps. The
  /// checking doesn't traverse the AST deeply and inequivalences are not
  /// registered.
  ///
  /// [prefix] is used as the receiver of the invocation.
  String computeMatchingHelper(FieldType fieldType, [String prefix = '']) {
    String thisName = 'a';
    String otherName = 'b';
    switch (fieldType.kind) {
      case AstFieldKind.value:
        return '$prefix$matchValues';
      case AstFieldKind.node:
        return '$prefix$shallowMatchNodes';
      case AstFieldKind.reference:
        return '$prefix$matchReferences';
      case AstFieldKind.use:
        return '$prefix$shallowMatchDeclarations';
      case AstFieldKind.list:
        ListFieldType listFieldType = fieldType as ListFieldType;
        String elementEquivalence =
            computeMatchingHelper(listFieldType.elementType);
        return '($thisName, $otherName) => $prefix$matchLists('
            '$thisName, $otherName, $elementEquivalence)';
      case AstFieldKind.set:
        SetFieldType setFieldType = fieldType as SetFieldType;
        String elementMatching =
            computeMatchingHelper(setFieldType.elementType);
        String elementEquivalence =
            computeEquivalenceHelper(setFieldType.elementType);
        return '($thisName, $otherName) => $prefix$checkSets('
            '$thisName, $otherName, $elementMatching, $elementEquivalence)';
      case AstFieldKind.map:
        MapFieldType mapFieldType = fieldType as MapFieldType;
        String keyMatching = computeMatchingHelper(mapFieldType.keyType);
        String keyEquivalence = computeEquivalenceHelper(mapFieldType.keyType);
        String valueEquivalence =
            computeEquivalenceHelper(mapFieldType.valueType);
        return '($thisName,  $otherName) => $prefix$checkMaps('
            '$thisName, $otherName, $keyMatching, '
            '$keyEquivalence, $valueEquivalence)';
      case AstFieldKind.utility:
        StringBuffer sb = new StringBuffer();
        UtilityFieldType utilityFieldType = fieldType as UtilityFieldType;
        registerAstClassEquivalence(utilityFieldType.astClass);
        sb.writeln('''($thisName, $otherName, _) {
    if (identical($thisName, $otherName)) return true;
    return ${classCheckName(utilityFieldType.astClass)}(
        visitor,
        $thisName,
        $otherName);
  }''');
        return sb.toString();
    }
  }

  /// Computes the expression code for checking the equivalence of two fields
  /// of type [fieldType].
  ///
  /// Checking is used to check the AST for equivalence and inequivalences are
  /// registered.
  ///
  /// [prefix] is used as the receiver of the invocation.
  String computeEquivalenceHelper(FieldType fieldType, [String prefix = '']) {
    String thisName = 'a';
    String otherName = 'b';
    switch (fieldType.kind) {
      case AstFieldKind.value:
        return '$prefix$checkValues';
      case AstFieldKind.node:
        return '$prefix$checkNodes';
      case AstFieldKind.reference:
        return '$prefix$checkReferences';
      case AstFieldKind.use:
        return '$prefix$checkDeclarations';
      case AstFieldKind.list:
        ListFieldType listFieldType = fieldType as ListFieldType;
        String elementEquivalence =
            computeEquivalenceHelper(listFieldType.elementType);
        return '($thisName, $otherName) => $prefix$checkLists('
            '$thisName, $otherName, $elementEquivalence)';
      case AstFieldKind.set:
        SetFieldType setFieldType = fieldType as SetFieldType;
        String elementMatching =
            computeMatchingHelper(setFieldType.elementType);
        String elementEquivalence =
            computeEquivalenceHelper(setFieldType.elementType);
        return '($thisName, $otherName) => $prefix$checkSets('
            '$thisName, $otherName, $elementMatching, $elementEquivalence)';
      case AstFieldKind.map:
        MapFieldType mapFieldType = fieldType as MapFieldType;
        String keyMatching = computeMatchingHelper(mapFieldType.keyType);
        String keyEquivalence = computeEquivalenceHelper(mapFieldType.keyType);
        String valueEquivalence =
            computeEquivalenceHelper(mapFieldType.valueType);
        return '($thisName, $otherName) => $prefix$checkMaps('
            '$thisName, $otherName, $keyMatching, '
            '$keyEquivalence, $valueEquivalence)';
      case AstFieldKind.utility:
        StringBuffer sb = new StringBuffer();
        UtilityFieldType utilityFieldType = fieldType as UtilityFieldType;
        registerAstClassEquivalence(utilityFieldType.astClass);
        sb.writeln('''($thisName, $otherName, _) {
    if (identical($thisName, $otherName)) return true;
    return ${classCheckName(utilityFieldType.astClass)}(
        visitor,
        $thisName,
        $otherName);
  }''');
        return sb.toString();
    }
  }

  /// Registers that a strategy method is needed for checking [astClass].
  ///
  /// If the method has not already been generated, it is generated and stored
  /// in [_classStrategyMembers].
  void registerAstClassEquivalence(AstClass astClass) {
    if (_classStrategyMembers.containsKey(astClass)) return;

    String thisName = 'node';
    String otherName = 'other';
    StringBuffer classStrategy = new StringBuffer();
    classStrategy.writeln('''
  bool ${classCheckName(astClass)}(
      $visitorName visitor,
      ${astClass.name}? $thisName,
      Object? $otherName) {''');

    classStrategy.writeln('''
    if (identical($thisName, $otherName)) return true;
    if ($thisName is! ${astClass.name}) return false;
    if ($otherName is! ${astClass.name}) return false;''');
    if (astClass.kind == AstClassKind.named) {
      classStrategy.writeln('''
    if (!visitor.$matchNamedNodes($thisName, $otherName)) {
      return false;
    }''');
    } else if (astClass.kind == AstClassKind.declarative) {
      classStrategy.writeln('''
    if (!visitor.$checkDeclarations($thisName, $otherName, '')) {
      return false;
    }''');
    }

    if (astClass.kind != AstClassKind.utilityAsStructure) {
      classStrategy.writeln('''
    visitor.pushNodeState($thisName, $otherName);''');
    }
    classStrategy.writeln('''
    bool result = true;''');
    for (AstField field in astClass.fields.values) {
      registerAstFieldEquivalence(field);
      classStrategy.writeln('''
    if (!${fieldCheckName(field)}(visitor, $thisName, $otherName)) {
      result = visitor.$resultOnInequivalence;
    }''');
    }

    if (astClass.kind != AstClassKind.utilityAsStructure) {
      classStrategy.writeln('''
    visitor.popState();''');
    }

    classStrategy.writeln('''
    return result;
  }''');

    _classStrategyMembers[astClass] = classStrategy.toString();
  }

  /// Registers that a strategy method is needed for checking [field] in
  /// [astClass].
  ///
  /// If the method has not already been generated, it is generated and stored
  /// in [_fieldStrategyMembers].
  void registerAstFieldEquivalence(AstField field) {
    if (_fieldStrategyMembers.containsKey(field)) return;

    AstClass astClass = field.astClass;
    String thisName = 'node';
    String otherName = 'other';
    StringBuffer fieldStrategy = new StringBuffer();
    fieldStrategy.writeln('''
  bool ${fieldCheckName(field)}(
      $visitorName visitor,
      ${astClass.name} $thisName,
      ${astClass.name} $otherName) {''');
    if (field.parentField != null) {
      registerAstFieldEquivalence(field.parentField!);
      fieldStrategy.writeln('''
    return ${fieldCheckName(field.parentField!)}(
        visitor, $thisName, $otherName);''');
    } else {
      switch (field.type.kind) {
        case AstFieldKind.value:
          fieldStrategy.writeln('''
    return visitor.$checkValues(
        $thisName.${field.name},
        $otherName.${field.name},
        '${field.name}');''');
          break;
        case AstFieldKind.node:
          fieldStrategy.writeln('''
    return visitor.$checkNodes(
        $thisName.${field.name},
        $otherName.${field.name},
        '${field.name}');''');
          break;
        case AstFieldKind.reference:
          fieldStrategy.writeln('''
    return visitor.$checkReferences(
        $thisName.${field.name},
        $otherName.${field.name},
        '${field.name}');''');
          break;
        case AstFieldKind.use:
          fieldStrategy.writeln('''
    return visitor.$checkDeclarations(
        $thisName.${field.name},
        $otherName.${field.name},
        '${field.name}');''');
          break;
        case AstFieldKind.list:
          ListFieldType listFieldType = field.type as ListFieldType;
          fieldStrategy.writeln('''
    return visitor.$checkLists(
        $thisName.${field.name},
        $otherName.${field.name},
        ${computeEquivalenceHelper(listFieldType.elementType, 'visitor.')},
        '${field.name}');''');
          break;
        case AstFieldKind.set:
          SetFieldType setFieldType = field.type as SetFieldType;
          fieldStrategy.writeln('''
    return visitor.$checkSets(
        $thisName.${field.name},
        $otherName.${field.name},
        ${computeMatchingHelper(setFieldType.elementType, 'visitor.')},
        ${computeEquivalenceHelper(setFieldType.elementType, 'visitor.')},
        '${field.name}');''');
          break;
        case AstFieldKind.map:
          MapFieldType mapFieldType = field.type as MapFieldType;
          fieldStrategy.writeln('''
    return visitor.$checkMaps(
        $thisName.${field.name},
        $otherName.${field.name},
        ${computeMatchingHelper(mapFieldType.keyType, 'visitor.')},
        ${computeEquivalenceHelper(mapFieldType.keyType, 'visitor.')},
        ${computeEquivalenceHelper(mapFieldType.valueType, 'visitor.')},
        '${field.name}');''');
          break;
        case AstFieldKind.utility:
          UtilityFieldType utilityFieldType = field.type as UtilityFieldType;
          registerAstClassEquivalence(utilityFieldType.astClass);
          fieldStrategy.writeln('''
    '${field.name}';
    return ${classCheckName(utilityFieldType.astClass)}(
        visitor,
        $thisName.${field.name},
        $otherName.${field.name});''');
          break;
      }
    }
    fieldStrategy.writeln('''
  }''');
    _fieldStrategyMembers[field] = fieldStrategy.toString();
  }

  @override
  void handleVisit(AstModel astModel, AstClass astClass, StringBuffer sb) {
    registerAstClassEquivalence(astClass);
    sb.writeln('''
    return strategy.${classCheckName(astClass)}(
        this, node, $argumentName);''');
  }

  @override
  void handleVisitReference(
      AstModel astModel, AstClass astClass, StringBuffer sb) {
    sb.writeln('''
    return false;''');
  }

  @override
  void generateHeader(AstModel astModel, StringBuffer sb) {
    sb.writeln('''
$preamble

import 'package:kernel/ast.dart';
import 'package:kernel/src/printer.dart';
import 'union_find.dart';

part 'equivalence_helpers.dart';

/// Visitor that uses a $strategyName to compute AST node equivalence.
///
/// The visitor hold a current state that collects found inequivalences and
/// current assumptions. The current state has two modes. In the asserting mode,
/// the default, inequivalences are registered when found. In the non-asserting
/// mode, inequivalences are _not_ registered. The latter is used to compute
/// equivalences in sandboxed state, for instance to determine which elements
/// to pair when checking equivalence of two sets.
class $visitorName$visitorTypeParameters
    implements Visitor1<$returnType, $argumentType> {
  final $strategyName strategy;

  $visitorName({
      this.strategy = const $strategyName()});
''');
  }

  @override
  void generateFooter(AstModel astModel, StringBuffer sb) {
    sb.writeln('''
  /// Returns `true` if [a] and [b] are identical or equal.
  bool $internalCheckValues<T>(T? a, T? b) {
    return identical(a, b) || a == b;
  }

  /// Returns `true` if [a] and [b] are identical or equal and registers the
  /// inequivalence otherwise.
  bool $checkValues<T>(T? a, T? b, String propertyName) {
    bool result = $internalCheckValues(a, b);
    if (!result) {
      registerInequivalence(
          propertyName, 'Values \${a} and \${b} are not equivalent');
    }
    return result;
  }

  /// Returns `true` if [a] and [b] are identical or equal. Inequivalence is
  /// _not_ registered.
  bool $matchValues<T>(T? a, T? b) {
    return $internalCheckValues(a, b);
  }

  /// Cache of Constants compares and the results.
  /// This avoids potential exponential blowup when comparing ASTs
  /// that contain Constants.
  Map<Constant, Map<dynamic, bool>>? _constantCache;

  /// Returns `true` if [a] and [b] are equivalent.
  bool $internalCheckNodes<T extends Node>(T? a, T? b) {
    if (identical(a, b)) return true;
    if (a == null || b == null) {
      return false;
    } else {
      if (a is Constant) {
        Map<Constant, Map<dynamic, bool>> cacheFrom = _constantCache ??= {};
        Map<dynamic, bool> cacheTo = cacheFrom[a] ??= {};
        bool? previousResult = cacheTo[b];
        if (previousResult != null) return previousResult;
        bool result = a.accept1(this, b);
        cacheTo[b] = result;
        return result;
      }
      return a.accept1(this, b);
    }
  }

  /// Returns `true` if [a] and [b] are equivalent, as defined by the current
  /// strategy, and registers the inequivalence otherwise.
  bool $checkNodes<T extends Node>(T? a, T? b,
      [String propertyName = '']) {
    $checkingState.pushPropertyState(propertyName);
    bool result = $internalCheckNodes(a, b);
    $checkingState.popState();
    if (!result) {
      $registerInequivalence(
          propertyName, 'Inequivalent nodes\\n1: \${a}\\n2: \${b}');
    }
    return result;
  }

  /// Returns `true` if [a] and [b] are equivalent, either by existing
  /// assumption or as defined by their corresponding canonical names.
  /// Inequivalence is _not_ registered.
  bool $matchNamedNodes(NamedNode? a, NamedNode? b) {
    return identical(a, b) ||
        a == null ||
        b == null ||
        checkAssumedReferences(a.reference, b.reference) ||
        new ReferenceName.fromNamedNode(a) ==
            new ReferenceName.fromNamedNode(b);
  }

  /// Returns `true` if [a] and [b] are currently assumed to be equivalent.
  bool $checkAssumedReferences(Reference? a, Reference? b) {
    return $checkingState.$checkAssumedReferences(a, b);
  }

  /// Assume that [a] and [b] are equivalent, if possible.
  ///
  /// Returns `true` if [a] and [b] could be assumed to be equivalent. This
  /// would not be the case if [a] xor [b] is `null`.
  bool $assumeReferences(Reference? a, Reference? b) {
    return $checkingState.$assumeReferences(a, b);
  }

  /// Returns `true` if [a] and [b] are equivalent, either by existing
  /// assumption or as defined by their corresponding canonical names.
  /// Inequivalence is _not_ registered.
  bool $matchReferences(Reference? a, Reference? b) {
    return identical(a, b) ||
        checkAssumedReferences(a, b) ||
        ReferenceName.fromReference(a) ==
            ReferenceName.fromReference(b);
  }

  /// Returns `true` if [a] and [b] are equivalent, either by their
  /// corresponding canonical names or by assumption. Inequivalence is _not_
  /// registered.
  bool $internalCheckReferences(Reference? a, Reference? b) {
    if (identical(a, b)) {
      return true;
    } else if (a == null || b == null) {
      return false;
    } else if ($matchReferences(a, b)) {
      return true;
    } else if ($checkAssumedReferences(a, b)) {
      return true;
    } else {
      return false;
    }
  }

  /// Returns `true` if [a] and [b] are equivalent, either by their
  /// corresponding canonical names or by assumption, and registers the
  /// inequivalence otherwise.
  bool $checkReferences(
      Reference? a,
      Reference? b,
      [String propertyName = '']) {
    bool result = $internalCheckReferences(a, b);
    if (!result) {
      $registerInequivalence(
          propertyName, 'Inequivalent references:\\n1: \${a}\\n2: \${b}');
    }
    return result;
  }

  /// Returns `true` if declarations [a] and [b] are currently assumed to be
  /// equivalent.
  bool $checkAssumedDeclarations(dynamic a, dynamic b) {
    return $checkingState.$checkAssumedDeclarations(a, b);
  }

  /// Assume that [a] and [b] are equivalent, if possible.
  ///
  /// Returns `true` if [a] and [b] could be assumed to be equivalent. This
  /// would not be the case if [a] is already assumed to be equivalent to
  /// another declaration.
  bool $assumeDeclarations(dynamic a, dynamic b) {
    return $checkingState.$assumeDeclarations(a, b);
  }

  bool $shallowMatchDeclarations(dynamic a, dynamic b) {''');

    for (AstClass cls in astModel.declarativeClasses) {
      if (cls.declarativeName != null) {
        sb.write('''
    if (a is ${cls.name}) {
      return b is ${cls.name} &&
          a.${cls.declarativeName} == b.${cls.declarativeName};
    }
''');
      } else {
        sb.write('''
    if (a is ${cls.name}) {
      return b is ${cls.name};
    }
''');
      }
    }
    try {
      try {
        try {
          sb.writeln('''
          return false;
  }

  bool $internalCheckDeclarations(dynamic a, dynamic b) {
          if (identical(a, b)) {
            return true;
          } else if (a == null || b == null) {
            return false;
          } else if ($checkAssumedDeclarations(a, b)) {
            return true;
          } else if ($shallowMatchDeclarations(a, b)) {
            return $assumeDeclarations(a, b);
          } else {
            return false;
          }
  }

  bool $checkDeclarations(dynamic a, dynamic b,
            [String propertyName = '']) {
          bool result = $internalCheckDeclarations(a, b);
          if (!result) {
            result = $assumeDeclarations(a, b);
          }
          if (!result) {
            $registerInequivalence(
                propertyName, 'Declarations \${a} and \${b} are not equivalent');
          }
          return result;
  }

  /// Returns `true` if lists [a] and [b] are equivalent, using
  /// [equivalentValues] to determine element-wise equivalence.
  ///
  /// If run in a checking state, the [propertyName] is used for registering
  /// inequivalences.
  bool $checkLists<E>(
            List<E>? a,
            List<E>? b,
            bool Function(E, E, String) equivalentValues,
            [String propertyName = '']) {
          if (identical(a, b)) return true;
          if (a == null || b == null) return false;
          if (a.length != b.length) {
            $registerInequivalence(
              '\${propertyName}.length', 'Lists \${a} and \${b} are not equivalent');
            return false;
          }
          for (int i = 0; i < a.length; i++) {
            if (!equivalentValues(a[i], b[i], '\${propertyName}[\${i}]')) {
              return false;
            }
          }
          return true;
  }

  /// Returns `true` if sets [a] and [b] are equivalent, using
  /// [matchingValues] to determine which elements that should be checked for
  /// element-wise equivalence using [equivalentValues].
  ///
  /// If run in a checking state, the [propertyName] is used for registering
  /// inequivalences.
  bool $checkSets<E>(
            Set<E>? a,
            Set<E>? b,
            bool Function(E, E) matchingValues,
            bool Function(E, E, String) equivalentValues,
            [String propertyName = '']) {
          if (identical(a, b)) return true;
          if (a == null || b == null) return false;
          if (a.length != b.length) {
            $registerInequivalence(
                '\${propertyName}.length', 'Sets \${a} and \${b} are not equivalent');
            return false;
          }
          b = b.toSet();
          for (E aValue in a) {
            bool hasFoundValue = false;
            E? foundValue;
            for (E bValue in b) {
              if (matchingValues(aValue, bValue)) {
                foundValue = bValue;
                hasFoundValue = true;
                if (!equivalentValues(aValue, bValue,
                    '\${propertyName}[\${aValue}]')) {
                  $registerInequivalence(
                      '\${propertyName}[\${aValue}]',
                      'Elements \${aValue} and \${bValue} are not equivalent');
                  return false;
                }
                break;
              }
            }
            if (hasFoundValue) {
              b.remove(foundValue);
            } else {
              $registerInequivalence(
                  '\${propertyName}[\${aValue}]',
                  'Sets \${a} and \${b} are not equivalent, no equivalent value '
                  'found for \$aValue');
              return false;
            }
          }
          return true;
  }

  /// Returns `true` if maps [a] and [b] are equivalent, using
  /// [matchingKeys] to determine which entries that should be checked for
  /// entry-wise equivalence using [equivalentKeys] and [equivalentValues] to
  /// determine key and value equivalences, respectively.
  ///
  /// If run in a checking state, the [propertyName] is used for registering
  /// inequivalences.
  bool $checkMaps<K, V>(
            Map<K, V>? a,
            Map<K, V>? b,
            bool Function(K, K) matchingKeys,
            bool Function(K, K, String) equivalentKeys,
            bool Function(V, V, String) equivalentValues,
            [String propertyName = '']) {
          if (identical(a, b)) return true;
          if (a == null || b == null) return false;
          if (a.length != b.length) {
            $registerInequivalence(
              '\${propertyName}.length',
              'Maps \${a} and \${b} are not equivalent');
            return false;
          }
          Set<K> bKeys = b.keys.toSet();
          for (K aKey in a.keys) {
            bool hasFoundKey = false;
            K? foundKey;
            for (K bKey in bKeys) {
              if (matchingKeys(aKey, bKey)) {
                foundKey = bKey;
                hasFoundKey = true;
                if (!equivalentKeys(aKey, bKey, '\${propertyName}[\${aKey}]')) {
                  $registerInequivalence(
                      '\${propertyName}[\${aKey}]',
                      'Keys \${aKey} and \${bKey} are not equivalent');
                  return false;
                }
                break;
              }
            }
            if (hasFoundKey) {
              bKeys.remove(foundKey);
              if (!equivalentValues(a[aKey]!, b[foundKey]!,
                  '\${propertyName}[\${aKey}]')) {
                return false;
              }
            } else {
              $registerInequivalence(
                '\${propertyName}[\${aKey}]',
                'Maps \${a} and \${b} are not equivalent, no equivalent key '
                    'found for \$aKey');
              return false;
            }
          }
          return true;
  }

  /// The current state of the visitor.
  ///
  /// This holds the current assumptions, found inequivalences, and whether
  /// inequivalences are currently registered.
  CheckingState $checkingState = new CheckingState();

  /// Registers that the visitor enters nodes [a] and [b].
  void pushNodeState(Node a, Node b) {
    $checkingState.pushNodeState(a, b);
  }

  /// Register that the visitor leave the current node or property.
  void popState() {
    $checkingState.popState();
  }

  /// Returns the value used as the result for property inequivalences.
  ///
  /// When inequivalences are currently registered, this is `true`, so that the
  /// visitor will continue find inequivalences that are not directly related.
  ///
  /// An example is finding several child inequivalences on otherwise equivalent
  /// nodes, like finding inequivalences deeply in the members of the second
  /// library of a component even when inequivalences deeply in the members of
  /// the first library. Had the return value been `false`, signaling that the
  /// first libraries were inequivalent, which they technically are, given that
  /// the contain inequivalent subnodes, the visitor would have stopped short in
  /// checking the list of libraries, and the inequivalences in the second
  /// library would not have been found.
  ///
  /// When inequivalences are _not_ currently registered, i.e. we are only
  /// interested in the true/false value of the equivalence test, `false` is
  /// used as the result value to stop the equivalence checking short.
  bool get $resultOnInequivalence =>
            $checkingState.$resultOnInequivalence;

  /// Registers an equivalence on the [propertyName] with a detailed description
  /// in [message].
  void $registerInequivalence(String propertyName, String message) {
          $checkingState.registerInequivalence(propertyName, message);
  }

  /// Returns the inequivalences found by the visitor.
  EquivalenceResult toResult() => $checkingState.toResult();

  ''');
        } catch (e, s) {
          print(s);
        }
      } catch (e, s) {
        print(s);
      }
    } catch (e, s) {
      print(s);
    }
    super.generateFooter(astModel, sb);
    sb.writeln('''
/// Checks [a] and [b] be for equivalence using [strategy].
///
/// Returns an [EquivalenceResult] containing the found inequivalences.
EquivalenceResult checkEquivalence(
    Node a,
    Node b,
    {$strategyName strategy = const $strategyName()}) {
  EquivalenceVisitor visitor = new EquivalenceVisitor(
      strategy: strategy);
  visitor.$checkNodes(a, b, 'root');
  return visitor.toResult();
}
''');

    sb.writeln('''
/// Strategy used for determining equivalence of AST nodes.
///
/// The strategy has a method for determining the equivalence of each AST node
/// class, and a method for determining the equivalence of each property on each
/// AST node class.
///
/// The base implementation enforces a full structural equivalence.
///
/// Custom strategies can be made by extending this strategy and override
/// methods where exceptions to the structural equivalence are needed.
class $strategyName {
  const $strategyName();
''');
    _classStrategyMembers.forEach((key, value) {
      sb.write(value);
    });
    _fieldStrategyMembers.forEach((key, value) {
      sb.write(value);
    });
    sb.writeln(r'''
}
''');
  }
}
