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

// @dart = 2.9

import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart';
import 'package:front_end/src/api_prototype/front_end.dart';
import 'package:front_end/src/api_prototype/kernel_generator.dart';
import 'package:front_end/src/api_prototype/terminal_color_support.dart';
import 'package:front_end/src/api_unstable/ddc.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart';
import 'package:front_end/src/fasta/kernel/kernel_api.dart';
import 'package:front_end/src/kernel_generator_impl.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/src/printer.dart';
import 'package:kernel/type_environment.dart';

final Uri astLibraryUri = Uri.parse('package:kernel/ast.dart');
final Uri canonicalNameLibraryUri =
    Uri.parse('package:kernel/canonical_name.dart');
Uri computePackageConfig(Uri repoDir) =>
    repoDir.resolve('.dart_tool/package_config.json');

/// Map from names of node classes that declares nominal entities that are _not_
/// referenced through a [Reference] to their identifying name, if any.
///
/// For these classes, [_fieldRuleMap] must defined whether fields of these
/// types should be consider declarations or references to the declarations.
///
/// If the identifying name is non-null, this is used to determine the
/// nominality. For instance the name of a variable declaration is taking as
/// defining its identity.
const Map<String, String> _declarativeClassesNames = const {
  'VariableDeclaration': 'name',
  'TypeParameter': 'name',
  'LabeledStatement': null,
  'SwitchCase': null,
};

/// Names of non-node, non-enum classes that should be treated as atomic
/// values.
const Set<String> _utilityClassesAsValues = const {
  'Version',
};

/// Names of subclasses of [Node] that do _not_ have `visitX` or `defaultX`
/// methods.
const Set<String> _classesWithoutVisitMethods = const {
  'InvocationExpression',
  'InstanceInvocationExpression',
  'NamedNode',
  'PrimitiveConstant',
};

/// Names of subclasses of [NamedNode] that do _not_ have `visitXReference` or
/// `defaultXReference` methods.
const Set<String> _classesWithoutVisitReference = const {
  'NamedNode',
  'Library',
  'PrimitiveConstant',
};

/// Map of [FieldRule]s. These consist of a map for each class name, with
/// `null` used for "any class". For each class, a map from field names to
/// [FieldRule] define exceptions to how a field should be treated.
///
/// If a field name maps to `null`, the field is not included in the [AstModel].
const Map<String /*?*/, Map<String, FieldRule /*?*/ >> _fieldRuleMap = {
  null: {
    'hashCode': null,
    'parent': null,
  },
  'Component': {
    'root': null,
    '_mainMethodName': FieldRule(name: 'mainMethodName'),
    '_mode': FieldRule(name: 'mode'),
  },
  'Library': {
    '_languageVersion': FieldRule(name: 'languageVersion'),
    '_libraryId': null,
    '_classes': FieldRule(name: 'classes'),
    '_typedefs': FieldRule(name: 'typedefs'),
    '_extensions': FieldRule(name: 'extensions'),
    '_fields': FieldRule(name: 'fields'),
    '_procedures': FieldRule(name: 'procedures'),
  },
  'Class': {
    'typeParameters': FieldRule(isDeclaration: true),
    '_constructorsView': null,
    '_constructorsInternal': FieldRule(name: 'constructors'),
    '_fieldsView': null,
    '_fieldsInternal': FieldRule(name: 'fields'),
    '_proceduresView': null,
    '_proceduresInternal': FieldRule(name: 'procedures'),
    '_redirectingFactoriesView': null,
    '_redirectingFactoriesInternal':
        FieldRule(name: 'redirectingFactories'),
    'lazyBuilder': null,
    'dirty': null,
  },
  'Extension': {
    'typeParameters': FieldRule(isDeclaration: true),
  },
  'Field': {
    'reference': FieldRule(name: 'getterReference'),
  },
  'TypeParameter': {
    '_variance': FieldRule(name: 'variance'),
  },
  'FunctionNode': {
    '_body': FieldRule(name: 'body'),
    'typeParameters': FieldRule(isDeclaration: true),
    'positionalParameters': FieldRule(isDeclaration: true),
    'namedParameters': FieldRule(isDeclaration: true),
  },
  'Typedef': {
    'typeParameters': FieldRule(isDeclaration: true),
    'typeParametersOfFunctionType': FieldRule(isDeclaration: false),
    'positionalParameters': FieldRule(isDeclaration: false),
    'namedParameters': FieldRule(isDeclaration: false),
  },
  'TypedefTearOff': {
    'typeParameters': FieldRule(isDeclaration: true),
  },
  'TypedefTearOffConstant': {
    'parameters': FieldRule(isDeclaration: true),
  },
  'LocalInitializer': {
    'variable': FieldRule(isDeclaration: true),
  },
  'Let': {
    'variable': FieldRule(isDeclaration: true),
  },
  'VariableGet': {
    'variable': FieldRule(isDeclaration: false),
  },
  'VariableSet': {
    'variable': FieldRule(isDeclaration: false),
  },
  'LocalFunctionInvocation': {
    'variable': FieldRule(isDeclaration: false),
  },
  'BreakStatement': {
    'target': FieldRule(isDeclaration: false),
  },
  'ForStatement': {
    'variables': FieldRule(isDeclaration: true),
  },
  'ForInStatement': {
    'variable': FieldRule(isDeclaration: true),
  },
  'SwitchStatement': {
    'cases': FieldRule(isDeclaration: true),
  },
  'ContinueSwitchStatement': {
    'target': FieldRule(isDeclaration: false),
  },
  'Catch': {
    'exception': FieldRule(isDeclaration: true),
    'stackTrace': FieldRule(isDeclaration: true),
  },
  'FunctionDeclaration': {
    'variable': FieldRule(isDeclaration: true),
  },
  'FunctionType': {
    'typeParameters': FieldRule(isDeclaration: true),
  },
  'TypeParameterType': {
    'parameter': FieldRule(isDeclaration: false),
  },
};

/// Data that determines exceptions to how fields are used.
class FieldRule {
  /// If non-null, the field should be accessed by this name.
  ///
  /// This is for instance used for private fields accessed through a public
  /// getter.
  final String name;

  /// For fields contain ast class of kind `AstClassKind.declarative`, this
  /// value defines whether the field should be treated as a declaration or
  /// a reference to the declaration.
  final bool isDeclaration;

  const FieldRule({this.name, this.isDeclaration});
}

/// Return the [FieldRule] to use for the [field] in [AstClass].
FieldRule getFieldRule(AstClass astClass, Field field) {
  String name = field.name.text;
  Map<String, FieldRule> leafClassMap = _fieldRuleMap[astClass.name];
  if (leafClassMap != null && leafClassMap.containsKey(name)) {
    return leafClassMap[name];
  }
  Map<String, FieldRule> enclosingClassMap =
      _fieldRuleMap[field.enclosingClass.name];
  if (enclosingClassMap != null && enclosingClassMap.containsKey(name)) {
    return enclosingClassMap[name];
  }
  Map<String, FieldRule> defaultClassMap = _fieldRuleMap[null];
  if (defaultClassMap != null && defaultClassMap.containsKey(name)) {
    return defaultClassMap[name];
  }
  return new FieldRule(name: name);
}

/// Categorization of classes declared in 'package:kernel/ast.dart'.
enum AstClassKind {
  /// The root [Node] class.
  root,

  /// An abstract node class that is a superclass of a public class. Most of
  /// these have a corresponding `defaultX` visitor method.
  ///
  /// For instance [Statement] and [Expression].
  inner,

  /// A concrete node class. These are the classes for which we have `visitX`
  /// methods.
  ///
  /// For instance [Procedure] and [VariableGet].
  public,

  /// A concrete node class that serves only as an implementation of public
  /// node class.
  ///
  /// For instance [PrivateName] and [PublicName] that implements the public
  /// node [Name].
  implementation,

  /// A node class that serves as an interface.
  ///
  /// For instance `FileUriNode`.
  interface,

  /// A named node class that declares a nominal entity that is used with a
  /// reference.
  named,

  /// A node class that declares a nominal entity but used without reference.
  ///
  /// For instance [VariableDeclaration] which introduces a new entity when it
  /// occurs in a [Block] but is used as a reference when it occurs in a
  /// [VariableGet].
  declarative,

  /// A none-node class that should be treated as a composite structure.
  ///
  /// For instance [ConstantMapEntry] which is a tuple of a [Constant] key and
  /// a [Constant] value.
  utilityAsStructure,

  /// A none-node class that should be treated as an atomic value.
  ///
  /// For instance enum classes.
  utilityAsValue,
}

class AstClass {
  final Class node;
  AstClassKind _kind;
  final String declarativeName;

  AstClass superclass;
  List<AstClass> interfaces = [];
  List<AstClass> subclasses = [];
  List<AstClass> subtypes = [];

  List<AstField> fields = [];

  AstClass(this.node,
      {this.superclass, AstClassKind kind, this.declarativeName})
      : _kind = kind {
    if (superclass != null) {
      superclass.subclasses.add(this);
    }
  }

  String get name => node.name;

  AstClassKind get kind {
    if (_kind == null) {
      if (node.isAbstract) {
        if (subclasses.isNotEmpty) {
          if (subclasses.every(
              (element) => element.kind == AstClassKind.implementation)) {
            _kind = AstClassKind.public;
          } else {
            _kind = AstClassKind.inner;
          }
        } else {
          _kind = AstClassKind.interface;
        }
      } else {
        if (node.name.startsWith('_')) {
          _kind = AstClassKind.implementation;
        } else {
          _kind = AstClassKind.public;
        }
      }
    }
    return _kind;
  }

  /// Returns `true` if this class has a `visitX` or `defaultX` method.
  ///
  /// This is only valid for subclass of [Node].
  bool get hasVisitMethod {
    switch (kind) {
      case AstClassKind.root:
      case AstClassKind.inner:
      case AstClassKind.public:
      case AstClassKind.named:
      case AstClassKind.declarative:
        return !_classesWithoutVisitMethods.contains(name);
      case AstClassKind.implementation:
      case AstClassKind.interface:
      case AstClassKind.utilityAsStructure:
      case AstClassKind.utilityAsValue:
        return false;
    }
    throw new UnsupportedError("Unexpected $kind");
  }

  /// Returns `true` if this class has a `visitXReference` or
  /// `defaultXReference` method.
  ///
  /// This is only valid for subclass of [NamedNode] or [Constant].
  bool get hasVisitReferenceMethod {
    switch (kind) {
      case AstClassKind.root:
      case AstClassKind.inner:
      case AstClassKind.public:
      case AstClassKind.named:
      case AstClassKind.declarative:
        return !_classesWithoutVisitReference.contains(name);
      case AstClassKind.implementation:
      case AstClassKind.interface:
      case AstClassKind.utilityAsStructure:
      case AstClassKind.utilityAsValue:
        return false;
    }
    throw new UnsupportedError("Unexpected $kind");
  }

  String dump([String indent = ""]) {
    StringBuffer sb = new StringBuffer();
    sb.writeln('${indent}${node.name} ($kind)');
    for (AstField field in fields) {
      sb.write(field.dump('${indent}    '));
    }
    for (AstClass subclass in subclasses) {
      sb.write(subclass.dump('${indent}  '));
    }
    return sb.toString();
  }

  String toString() => '${runtimeType}(${name})';
}

/// Categorization of field types.
enum AstFieldKind {
  /// An atomic non-node value.
  ///
  /// For instance an [int] value.
  value,

  /// A [Node] value that is part of the tree.
  ///
  /// For instance an [Expression] value.
  node,

  /// A [Reference] value.
  reference,

  /// A reference to a declarative [Node].
  ///
  /// For instance the reference to [VariableDeclaration] in [VariableGet].
  use,

  /// A list of values.
  list,

  /// A set of values.
  set,

  /// A map of values.
  map,

  /// A non-node composite value.
  ///
  /// For instance a [ConstantMapEntry] that must be treat as a tuple of
  /// a [Constant] key and a [Constant] value.
  utility,
}

/// Structural description of a field type.
class FieldType {
  final DartType type;
  final AstFieldKind kind;

  FieldType(this.type, this.kind);

  String toString() => 'FieldType($type,$kind)';
}

class ListFieldType extends FieldType {
  final FieldType elementType;

  ListFieldType(DartType type, this.elementType)
      : super(type, AstFieldKind.list);

  String toString() => 'ListFieldType($type,$elementType)';
}

class SetFieldType extends FieldType {
  final FieldType elementType;

  SetFieldType(DartType type, this.elementType) : super(type, AstFieldKind.set);

  String toString() => 'SetFieldType($type,$elementType)';
}

class MapFieldType extends FieldType {
  final FieldType keyType;
  final FieldType valueType;

  MapFieldType(DartType type, this.keyType, this.valueType)
      : super(type, AstFieldKind.map);

  String toString() => 'MapFieldType($type,$keyType,$valueType)';
}

class UtilityFieldType extends FieldType {
  final AstClass astClass;

  UtilityFieldType(DartType type, this.astClass)
      : super(type, AstFieldKind.utility);

  String toString() => 'UtilityFieldType($type,$astClass)';
}

class AstField {
  final Field node;
  final String name;
  final FieldType type;

  AstField(this.node, this.name, this.type);

  String dump([String indent = ""]) {
    StringBuffer sb = new StringBuffer();
    sb.writeln('$indent$name $type');
    return sb.toString();
  }

  String toString() => '${runtimeType}(${name})';
}

class AstModel {
  final AstClass nodeClass;
  final AstClass namedNodeClass;
  final AstClass constantClass;

  AstModel(this.nodeClass, this.namedNodeClass, this.constantClass);

  /// Returns an [Iterable] for all declarative [Node] classes in the AST model.
  Iterable<AstClass> get declarativeClasses {
    return classes.where((cls) => cls.kind == AstClassKind.declarative);
  }

  /// Returns an [Iterable] for all [Node] (sub)classes in the AST model.
  Iterable<AstClass> get classes sync* {
    Iterable<AstClass> visitClass(AstClass cls) sync* {
      yield cls;
      for (AstClass subclass in cls.subclasses) {
        yield* visitClass(subclass);
      }
    }

    yield* visitClass(nodeClass);
  }
}

/// Computes the [AstModel] from 'package:kernel/ast' using [repoDir] to locate
/// the package config file.
///
/// If [printDump] is `true`, a dump of the model printed to stdout.
Future<AstModel> deriveAstModel(Uri repoDir, {bool printDump: false}) async {
  CompilerOptions options = new CompilerOptions();
  options.sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
  options.packagesFileUri = computePackageConfig(repoDir);
  options.onDiagnostic = (DiagnosticMessage message) {
    printDiagnosticMessage(message, print);
  };

  InternalCompilerResult compilerResult = await kernelForProgramInternal(
      astLibraryUri, options,
      retainDataForTesting: true, requireMain: false);
  ClassHierarchy classHierarchy = compilerResult.classHierarchy;
  CoreTypes coreTypes = compilerResult.coreTypes;
  TypeEnvironment typeEnvironment =
      new TypeEnvironment(coreTypes, classHierarchy);

  Library astLibrary = compilerResult.component.libraries
      .singleWhere((library) => library.importUri == astLibraryUri);

  bool errorsFound = false;
  void reportError(String message) {
    print(message);
    errorsFound = true;
  }

  Map<String, String> declarativeClassesNames = {..._declarativeClassesNames};
  Set<String> classesWithoutVisitMethods = _classesWithoutVisitMethods.toSet();
  Set<String> classesWithoutVisitReference =
      _classesWithoutVisitReference.toSet();
  Map<String, Map<String, FieldRule>> fieldRuleMap = {..._fieldRuleMap};
  Map<String, FieldRule> nullFieldRules = {...?fieldRuleMap.remove(null)};
  for (Class cls in astLibrary.classes) {
    declarativeClassesNames.remove(cls.name);
    classesWithoutVisitMethods.remove(cls.name);
    classesWithoutVisitReference.remove(cls.name);
    Map<String, FieldRule> fieldRules = {...?fieldRuleMap.remove(cls.name)};
    Set<String> renames = {};
    Class parent = cls;
    while (parent != null && parent.enclosingLibrary == astLibrary) {
      for (Field field in parent.fields) {
        bool hasFieldRule = fieldRules.containsKey(field.name.text);
        FieldRule fieldRule = fieldRules.remove(field.name.text);
        if (fieldRule != null) {
          if (fieldRule.name != null) {
            renames.add(fieldRule.name);
          }
        }
        if (!hasFieldRule) {
          if (!cls.isEnum && !field.isStatic && field.name.isPrivate) {
            reportError(
                'Private field `${field.name.text}` in ${parent.name} must '
                'have a field rule.');
          }
        }
        if (nullFieldRules.containsKey(field.name.text)) {
          FieldRule nullFieldRule = nullFieldRules.remove(field.name.text);
          if (nullFieldRule != null) {
            reportError('Only `null` is allowed for class `null`.');
          }
        }
      }
      parent = parent.superclass;
    }
    for (Procedure procedure in cls.procedures) {
      renames.remove(procedure.name.text);
    }
    if (renames.isNotEmpty) {
      reportError('Unknown procedure(s) for field redirections in '
          '${cls.name}: ${renames}');
    }
    if (fieldRules.isNotEmpty) {
      reportError(
          'Unknown field(s) for rules in ${cls.name}: ${fieldRules.keys}');
    }
  }
  if (declarativeClassesNames.isNotEmpty) {
    reportError('Unknown declarative classes: ${declarativeClassesNames}');
  }
  if (classesWithoutVisitMethods.isNotEmpty) {
    reportError('Unknown classes without visit methods: '
        '${classesWithoutVisitMethods}');
  }
  if (classesWithoutVisitReference.isNotEmpty) {
    reportError('Unknown classes without visit reference methods: '
        '${classesWithoutVisitReference}');
  }
  if (fieldRuleMap.isNotEmpty) {
    reportError('Unknown classes with field rules: ${fieldRuleMap.keys}');
  }

  Class classNode = astLibrary.classes.singleWhere((cls) => cls.name == 'Node');
  DartType nullableNodeType =
      classNode.getThisType(coreTypes, Nullability.nullable);

  Class classNamedNode =
      astLibrary.classes.singleWhere((cls) => cls.name == 'NamedNode');

  Class classConstant =
      astLibrary.classes.singleWhere((cls) => cls.name == 'Constant');

  Library canonicalNameLibrary = compilerResult.component.libraries
      .singleWhere((library) => library.importUri == canonicalNameLibraryUri);

  Class referenceClass = canonicalNameLibrary.classes
      .singleWhere((cls) => cls.name == 'Reference');
  DartType nullableReferenceType =
      referenceClass.getThisType(coreTypes, Nullability.nullable);

  Set<Class> declarativeClasses = {};
  Set<DartType> declarativeTypes = {};
  for (String name in _declarativeClassesNames.keys) {
    Class cls = astLibrary.classes.singleWhere((cls) => cls.name == name);
    declarativeClasses.add(cls);
    declarativeTypes.add(cls.getThisType(coreTypes, Nullability.nullable));
  }

  Map<Class, AstClass> classMap = {};

  /// Computes the [AstClass] corresponding to [node] if [node] is declared in
  /// 'package:kernel/ast.dart'.
  AstClass computeAstClass(Class node) {
    if (node == null) return null;
    if (node.enclosingLibrary != astLibrary) return null;

    AstClass astClass = classMap[node];
    if (astClass == null) {
      if (node == classNode) {
        astClass = new AstClass(node, kind: AstClassKind.root);
      } else if (classHierarchy.isSubtypeOf(node, classNode)) {
        AstClass superclass = computeAstClass(node.superclass);
        AstClassKind kind;
        String declarativeName;
        if (!node.isAbstract &&
            classHierarchy.isSubtypeOf(node, classNamedNode)) {
          kind = AstClassKind.named;
        } else if (declarativeClasses.contains(node)) {
          kind = AstClassKind.declarative;
          declarativeName = _declarativeClassesNames[node.name];
        }
        astClass = new AstClass(node,
            superclass: superclass,
            kind: kind,
            declarativeName: declarativeName);
        for (Supertype supertype in node.implementedTypes) {
          AstClass astSupertype = computeAstClass(supertype.classNode);
          if (astSupertype != null) {
            astClass.interfaces.add(astSupertype);
            astSupertype.subtypes.add(astClass);
          }
        }
      } else if (node.isEnum || _utilityClassesAsValues.contains(node.name)) {
        astClass = new AstClass(node, kind: AstClassKind.utilityAsValue);
      } else {
        AstClass superclass = computeAstClass(node.superclass);
        astClass = new AstClass(node,
            superclass: superclass, kind: AstClassKind.utilityAsStructure);
      }
      if (astClass != null) {
        classMap[node] = astClass;
      }
    }
    return astClass;
  }

  for (Class cls in astLibrary.classes) {
    computeAstClass(cls);
  }

  for (AstClass astClass in classMap.values) {
    void computeAstField(Field field, Substitution substitution) {
      if (field.isStatic) {
        return;
      }
      FieldRule rule = getFieldRule(astClass, field);
      if (rule == null) {
        return;
      }
      DartType type = substitution.substituteType(field.type);

      FieldType computeFieldType(DartType type) {
        bool isDeclarativeType = false;
        for (InterfaceType declarativeType in declarativeTypes) {
          if (type is InterfaceType &&
              typeEnvironment.isSubtypeOf(
                  type, declarativeType, SubtypeCheckMode.withNullabilities)) {
            isDeclarativeType = true;
            break;
          }
        }
        if (isDeclarativeType) {
          if (rule.isDeclaration == null) {
            reportError(
                "No field rule for '${field.name}' in ${astClass.name}.\n"
                "The field type contains the declarative type "
                "'${type.toText(defaultAstTextStrategy)}' "
                "and a rule must therefore specify "
                "whether this constitutes declarative or referential use.");
          }
          if (!rule.isDeclaration) {
            return new FieldType(type, AstFieldKind.use);
          }
        }
        if (type is InterfaceType &&
            typeEnvironment.isSubtypeOf(type, coreTypes.listNullableRawType,
                SubtypeCheckMode.withNullabilities)) {
          DartType elementType = typeEnvironment
              .getTypeArgumentsAsInstanceOf(type, coreTypes.listClass)
              .single;
          return new ListFieldType(type, computeFieldType(elementType));
        } else if (type is InterfaceType &&
            typeEnvironment.isSubtypeOf(type, coreTypes.setNullableRawType,
                SubtypeCheckMode.withNullabilities)) {
          DartType elementType = typeEnvironment
              .getTypeArgumentsAsInstanceOf(type, coreTypes.setClass)
              .single;
          return new SetFieldType(type, computeFieldType(elementType));
        } else if (type is InterfaceType &&
            typeEnvironment.isSubtypeOf(type, coreTypes.mapNullableRawType,
                SubtypeCheckMode.withNullabilities)) {
          List<DartType> typeArguments = typeEnvironment
              .getTypeArgumentsAsInstanceOf(type, coreTypes.mapClass);
          return new MapFieldType(type, computeFieldType(typeArguments[0]),
              computeFieldType(typeArguments[1]));
        } else if (type is InterfaceType &&
            typeEnvironment.isSubtypeOf(
                type, nullableNodeType, SubtypeCheckMode.withNullabilities)) {
          return new FieldType(type, AstFieldKind.node);
        } else if (type is InterfaceType &&
            typeEnvironment.isSubtypeOf(type, nullableReferenceType,
                SubtypeCheckMode.withNullabilities)) {
          return new FieldType(type, AstFieldKind.reference);
        } else {
          if (type is InterfaceType) {
            AstClass astClass = classMap[type.classNode];
            if (astClass != null &&
                astClass.kind == AstClassKind.utilityAsStructure) {
              return new UtilityFieldType(type, astClass);
            }
          }
          return new FieldType(type, AstFieldKind.value);
        }
      }

      FieldType fieldType;
      fieldType ??= computeFieldType(type);
      astClass.fields
          .add(new AstField(field, rule.name ?? field.name.text, fieldType));
    }

    AstClass parent = astClass;
    Substitution substitution = Substitution.empty;
    while (parent != null) {
      for (Field field in parent.node.fields) {
        computeAstField(field, substitution);
      }
      parent = parent.superclass;
      if (parent != null) {
        substitution = Substitution.fromSupertype(
            classHierarchy.getClassAsInstanceOf(astClass.node, parent.node));
      }
    }
  }

  AstClass astClassNode = classMap[classNode];
  AstClass astClassNamedNode = classMap[classNamedNode];
  AstClass astClassConstant = classMap[classConstant];

  if (printDump) {
    print(classMap[classNode].dump());
    for (AstClass astClass in classMap.values) {
      if (astClass != astClassNode && astClass.superclass == null) {
        print(astClass.dump());
      }
    }
  }
  if (errorsFound) {
    throw 'Errors found';
  }
  return new AstModel(astClassNode, astClassNamedNode, astClassConstant);
}
