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

import 'package:kernel/ast.dart' as ir;
import 'package:kernel/class_hierarchy.dart' as ir;
import 'package:kernel/type_environment.dart' as ir;

import '../common.dart';
import '../ir/scope.dart';
import '../serialization/serialization.dart';
import '../util/enumset.dart';
import 'constants.dart';
import 'impact.dart';
import 'runtime_type_analysis.dart';
import 'static_type.dart';
import 'util.dart';

/// Visitor that builds an [ImpactData] object for the world impact.
class ImpactBuilder extends StaticTypeVisitor implements ImpactRegistry {
  final ImpactData _data = ImpactData();

  @override
  final VariableScopeModel variableScopeModel;

  @override
  final ir.StaticTypeContext staticTypeContext;

  @override
  final bool useAsserts;

  @override
  final inferEffectivelyFinalVariableTypes;

  ImpactBuilder(this.staticTypeContext, StaticTypeCacheImpl staticTypeCache,
      ir.ClassHierarchy classHierarchy, this.variableScopeModel,
      {this.useAsserts = false, this.inferEffectivelyFinalVariableTypes = true})
      : super(
            staticTypeContext.typeEnvironment, classHierarchy, staticTypeCache);

  /// Return the named arguments names as a list of strings.
  List<String> _getNamedArguments(ir.Arguments arguments) =>
      arguments.named.map((n) => n.name).toList();

  ImpactBuilderData computeImpact(ir.Member node) {
    if (retainDataForTesting) {
      typeMapsForTesting = {};
    }
    node.accept(this);
    return ImpactBuilderData(
        node, impactData, typeMapsForTesting, getStaticTypeCache());
  }

  ImpactData get impactData => _data;

  @override
  void handleIntLiteral(ir.IntLiteral node) {
    registerIntLiteral(node.value);
  }

  @override
  void handleDoubleLiteral(ir.DoubleLiteral node) {
    registerDoubleLiteral(node.value);
  }

  @override
  void handleBoolLiteral(ir.BoolLiteral node) {
    registerBoolLiteral(node.value);
  }

  @override
  void handleStringLiteral(ir.StringLiteral node) {
    registerStringLiteral(node.value);
  }

  @override
  void handleSymbolLiteral(ir.SymbolLiteral node) {
    registerSymbolLiteral(node.value);
  }

  @override
  void handleNullLiteral(ir.NullLiteral node) {
    registerNullLiteral();
  }

  @override
  void handleListLiteral(ir.ListLiteral node) {
    registerListLiteral(node.typeArgument,
        isConst: node.isConst, isEmpty: node.expressions.isEmpty);
  }

  @override
  void handleSetLiteral(ir.SetLiteral node) {
    registerSetLiteral(node.typeArgument,
        isConst: node.isConst, isEmpty: node.expressions.isEmpty);
  }

  @override
  void handleMapLiteral(ir.MapLiteral node) {
    registerMapLiteral(node.keyType, node.valueType,
        isConst: node.isConst, isEmpty: node.entries.isEmpty);
  }

  @override
  void handleStaticGet(
      ir.Expression node, ir.Member target, ir.DartType resultType) {
    assert(!(target is ir.Procedure && target.kind == ir.ProcedureKind.Method),
        "Static tear off registered as static get: $node");
    registerStaticGet(target, getDeferredImport(node));
  }

  @override
  void handleStaticTearOff(
      ir.Expression node, ir.Member target, ir.DartType resultType) {
    assert(target is ir.Procedure && target.kind == ir.ProcedureKind.Method,
        "Static get registered as static tear off: $node");
    registerStaticTearOff(target, getDeferredImport(node));
  }

  @override
  void handleStaticSet(ir.StaticSet node, ir.DartType valueType) {
    registerStaticSet(node.target, getDeferredImport(node));
  }

  @override
  void handleAssertStatement(ir.AssertStatement node) {
    registerAssert(withMessage: node.message != null);
  }

  @override
  void handleInstantiation(ir.Instantiation node,
      ir.FunctionType expressionType, ir.DartType resultType) {
    registerGenericInstantiation(expressionType, node.typeArguments);
  }

  void handleAsyncMarker(ir.FunctionNode function) {
    ir.AsyncMarker asyncMarker = function.asyncMarker;
    ir.DartType returnType = function.returnType;

    switch (asyncMarker) {
      case ir.AsyncMarker.Sync:
        break;
      case ir.AsyncMarker.SyncStar:
        ir.DartType elementType = const ir.DynamicType();
        if (returnType is ir.InterfaceType) {
          if (returnType.classNode == typeEnvironment.coreTypes.iterableClass) {
            elementType = returnType.typeArguments.first;
          }
        }
        registerSyncStar(elementType);
        break;

      case ir.AsyncMarker.Async:
        ir.DartType elementType = const ir.DynamicType();
        if (returnType is ir.InterfaceType &&
            returnType.classNode == typeEnvironment.coreTypes.futureClass) {
          elementType = returnType.typeArguments.first;
        } else if (returnType is ir.FutureOrType) {
          elementType = returnType.typeArgument;
        }
        registerAsync(elementType);
        break;

      case ir.AsyncMarker.AsyncStar:
        ir.DartType elementType = const ir.DynamicType();
        if (returnType is ir.InterfaceType) {
          if (returnType.classNode == typeEnvironment.coreTypes.streamClass) {
            elementType = returnType.typeArguments.first;
          }
        }
        registerAsyncStar(elementType);
        break;

      case ir.AsyncMarker.SyncYielding:
        failedAt(CURRENT_ELEMENT_SPANNABLE,
            "Unexpected async marker: ${asyncMarker}");
    }
  }

  @override
  void handleStringConcatenation(ir.StringConcatenation node) {
    registerStringConcatenation();
  }

  @override
  Null handleFunctionDeclaration(ir.FunctionDeclaration node) {
    registerLocalFunction(node);
    handleAsyncMarker(node.function);
  }

  @override
  void handleFunctionExpression(ir.FunctionExpression node) {
    registerLocalFunction(node);
    handleAsyncMarker(node.function);
  }

  @override
  void handleVariableDeclaration(ir.VariableDeclaration node) {
    if (node.initializer == null) {
      registerLocalWithoutInitializer();
    }
  }

  @override
  void handleIsExpression(ir.IsExpression node) {
    registerIsCheck(node.type);
  }

  @override
  void handleAsExpression(ir.AsExpression node, ir.DartType operandType) {
    if (typeEnvironment.isSubtypeOf(
        operandType, node.type, ir.SubtypeCheckMode.ignoringNullabilities)) {
      // Skip unneeded casts.
      return;
    }
    if (node.isTypeError) {
      registerImplicitCast(node.type);
    } else {
      registerAsCast(node.type);
    }
  }

  @override
  void handleThrow(ir.Throw node) {
    registerThrow();
  }

  @override
  void handleForInStatement(ir.ForInStatement node, ir.DartType iterableType,
      ir.DartType iteratorType) {
    if (node.isAsync) {
      registerAsyncForIn(iterableType, iteratorType,
          computeClassRelationFromType(iteratorType));
    } else {
      registerSyncForIn(iterableType, iteratorType,
          computeClassRelationFromType(iteratorType));
    }
  }

  @override
  void handleCatch(ir.Catch node) {
    registerCatch();
    if (node.stackTrace != null) {
      registerStackTrace();
    }
    if (node.guard is! ir.DynamicType) {
      registerCatchType(node.guard);
    }
  }

  @override
  void handleTypeLiteral(ir.TypeLiteral node) {
    registerTypeLiteral(node.type, getDeferredImport(node));
  }

  @override
  void handleFieldInitializer(ir.FieldInitializer node) {
    registerFieldInitialization(node.field);
  }

  @override
  void handleLoadLibrary(ir.LoadLibrary node) {
    registerLoadLibrary();
  }

  @override
  void handleRedirectingInitializer(
      ir.RedirectingInitializer node, ArgumentTypes argumentTypes) {
    registerRedirectingInitializer(
        node.target,
        node.arguments.positional.length,
        _getNamedArguments(node.arguments),
        node.arguments.types);
  }

  @override
  void handleParameter(ir.VariableDeclaration parameter) {
    registerParameterCheck(parameter.type);
  }

  @override
  void handleSignature(ir.FunctionNode node) {
    for (ir.TypeParameter parameter in node.typeParameters) {
      registerParameterCheck(parameter.bound);
    }
  }

  @override
  void handleConstructor(ir.Constructor node) {
    registerConstructorNode(node);
  }

  @override
  void handleField(ir.Field field) {
    registerParameterCheck(field.type);
    if (field.initializer != null) {
      if (!field.isInstanceMember &&
          !field.isConst &&
          field.initializer is! ir.NullLiteral) {
        registerLazyField();
      }
    } else {
      registerNullLiteral();
    }
    registerFieldNode(field);
  }

  @override
  void handleProcedure(ir.Procedure procedure) {
    handleAsyncMarker(procedure.function);
    registerProcedureNode(procedure);
  }

  @override
  void handleConstructorInvocation(ir.ConstructorInvocation node,
      ArgumentTypes argumentTypes, ir.DartType resultType) {
    registerNew(
        node.target,
        node.constructedType,
        node.arguments.positional.length,
        _getNamedArguments(node.arguments),
        node.arguments.types,
        getDeferredImport(node),
        isConst: node.isConst);
    if (node.isConst) {
      registerConstConstructorInvocationNode(node);
    }
  }

  @override
  void handleStaticInvocation(ir.StaticInvocation node,
      ArgumentTypes argumentTypes, ir.DartType returnType) {
    int positionArguments = node.arguments.positional.length;
    List<String> namedArguments = _getNamedArguments(node.arguments);
    List<ir.DartType> typeArguments = node.arguments.types;
    if (node.target.kind == ir.ProcedureKind.Factory) {
      // TODO(johnniwinther): We should not mark the type as instantiated but
      // rather follow the type arguments directly.
      //
      // Consider this:
      //
      //    abstract class A<T> {
      //      factory A.regular() => new B<T>();
      //      factory A.redirect() = B<T>;
      //    }
      //
      //    class B<T> implements A<T> {}
      //
      //    main() {
      //      print(new A<int>.regular() is B<int>);
      //      print(new A<String>.redirect() is B<String>);
      //    }
      //
      // To track that B is actually instantiated as B<int> and B<String> we
      // need to follow the type arguments passed to A.regular and A.redirect
      // to B. Currently, we only do this soundly if we register A<int> and
      // A<String> as instantiated. We should instead register that A.T is
      // instantiated as int and String.
      registerNew(
          node.target,
          ir.InterfaceType(node.target.enclosingClass,
              node.target.enclosingLibrary.nonNullable, typeArguments),
          positionArguments,
          namedArguments,
          node.arguments.types,
          getDeferredImport(node),
          isConst: node.isConst);
    } else {
      registerStaticInvocation(node.target, positionArguments, namedArguments,
          typeArguments, getDeferredImport(node));
    }
    registerStaticInvocationNode(node);
  }

  @override
  void handleDynamicInvocation(
      ir.InvocationExpression node,
      ir.DartType receiverType,
      ArgumentTypes argumentTypes,
      ir.DartType returnType) {
    int positionArguments = node.arguments.positional.length;
    List<String> namedArguments = _getNamedArguments(node.arguments);
    List<ir.DartType> typeArguments = node.arguments.types;
    ClassRelation relation = computeClassRelationFromType(receiverType);
    registerDynamicInvocation(receiverType, relation, node.name,
        positionArguments, namedArguments, typeArguments);
  }

  @override
  void handleFunctionInvocation(
      ir.InvocationExpression node,
      ir.DartType receiverType,
      ArgumentTypes argumentTypes,
      ir.DartType returnType) {
    int positionArguments = node.arguments.positional.length;
    List<String> namedArguments = _getNamedArguments(node.arguments);
    List<ir.DartType> typeArguments = node.arguments.types;
    registerFunctionInvocation(
        receiverType, positionArguments, namedArguments, typeArguments);
  }

  @override
  void handleInstanceInvocation(
      ir.InvocationExpression node,
      ir.DartType receiverType,
      ir.Member interfaceTarget,
      ArgumentTypes argumentTypes) {
    int positionArguments = node.arguments.positional.length;
    List<String> namedArguments = _getNamedArguments(node.arguments);
    List<ir.DartType> typeArguments = node.arguments.types;
    ClassRelation relation = computeClassRelationFromType(receiverType);

    if (interfaceTarget is ir.Field ||
        interfaceTarget is ir.Procedure &&
            interfaceTarget.kind == ir.ProcedureKind.Getter) {
      registerInstanceInvocation(receiverType, relation, interfaceTarget,
          positionArguments, namedArguments, typeArguments);
      registerFunctionInvocation(interfaceTarget.getterType, positionArguments,
          namedArguments, typeArguments);
    } else {
      registerInstanceInvocation(receiverType, relation, interfaceTarget,
          positionArguments, namedArguments, typeArguments);
    }
  }

  @override
  void handleLocalFunctionInvocation(
      ir.InvocationExpression node,
      ir.FunctionDeclaration function,
      ArgumentTypes argumentTypes,
      ir.DartType returnType) {
    int positionArguments = node.arguments.positional.length;
    List<String> namedArguments = _getNamedArguments(node.arguments);
    List<ir.DartType> typeArguments = node.arguments.types;
    registerLocalFunctionInvocation(
        function, positionArguments, namedArguments, typeArguments);
  }

  @override
  void handleEqualsCall(ir.Expression left, ir.DartType leftType,
      ir.Expression right, ir.DartType rightType, ir.Member interfaceTarget) {
    ClassRelation relation = computeClassRelationFromType(leftType);
    registerInstanceInvocation(leftType, relation, interfaceTarget, 1,
        const <String>[], const <ir.DartType>[]);
  }

  @override
  void handleEqualsNull(ir.EqualsNull node, ir.DartType expressionType) {
    registerNullLiteral();
  }

  @override
  void handleDynamicGet(ir.Expression node, ir.DartType receiverType,
      ir.Name name, ir.DartType resultType) {
    ClassRelation relation = computeClassRelationFromType(receiverType);
    registerDynamicGet(receiverType, relation, name);
  }

  @override
  void handleInstanceGet(ir.Expression node, ir.DartType receiverType,
      ir.Member interfaceTarget, ir.DartType resultType) {
    ClassRelation relation = computeClassRelationFromType(receiverType);
    registerInstanceGet(receiverType, relation, interfaceTarget);
  }

  @override
  void handleDynamicSet(ir.Expression node, ir.DartType receiverType,
      ir.Name name, ir.DartType valueType) {
    ClassRelation relation = computeClassRelationFromType(receiverType);
    registerDynamicSet(receiverType, relation, name);
  }

  @override
  void handleInstanceSet(ir.Expression node, ir.DartType receiverType,
      ir.Member interfaceTarget, ir.DartType valueType) {
    ClassRelation relation = computeClassRelationFromType(receiverType);
    registerInstanceSet(receiverType, relation, interfaceTarget);
  }

  @override
  void handleSuperMethodInvocation(ir.SuperMethodInvocation node,
      ArgumentTypes argumentTypes, ir.DartType returnType) {
    registerSuperInvocation(
        getEffectiveSuperTarget(node.interfaceTarget),
        node.arguments.positional.length,
        _getNamedArguments(node.arguments),
        node.arguments.types);
  }

  @override
  void handleSuperPropertyGet(
      ir.SuperPropertyGet node, ir.DartType resultType) {
    registerSuperGet(getEffectiveSuperTarget(node.interfaceTarget));
  }

  @override
  void handleSuperPropertySet(ir.SuperPropertySet node, ir.DartType valueType) {
    registerSuperSet(getEffectiveSuperTarget(node.interfaceTarget));
  }

  @override
  void handleSuperInitializer(
      ir.SuperInitializer node, ArgumentTypes argumentTypes) {
    registerSuperInitializer(
        node.parent,
        node.target,
        node.arguments.positional.length,
        _getNamedArguments(node.arguments),
        node.arguments.types);
  }

  @override
  Null visitSwitchStatement(ir.SwitchStatement node) {
    registerSwitchStatementNode(node);
    return super.visitSwitchStatement(node);
  }

  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
  // invocation encoding is no longer used.
  @override
  void handleRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
      ir.DartType receiverType, ir.DartType argumentType) {
    registerRuntimeTypeUse(node, kind, receiverType, argumentType);
  }

  @override
  void handleConstantExpression(ir.ConstantExpression node) {
    ir.LibraryDependency import = getDeferredImport(node);
    ConstantImpactVisitor(this, import, node, staticTypeContext)
        .visitConstant(node.constant);
  }

  void _registerFeature(_Feature feature) {
    _data._features ??= EnumSet<_Feature>();
    _data._features.add(feature);
  }

  void _registerTypeUse(ir.DartType type, _TypeUseKind kind) {
    _data._typeUses ??= [];
    _data._typeUses.add(_TypeUse(type, kind));
  }

  @override
  void registerSuperInitializer(
      ir.Constructor source,
      ir.Constructor target,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    _data._superInitializers ??= [];
    _data._superInitializers.add(_SuperInitializer(source, target,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerSuperSet(ir.Member target) {
    _data._superSets ??= [];
    _data._superSets.add(target);
  }

  @override
  void registerSuperGet(ir.Member target) {
    _data._superGets ??= [];
    _data._superGets.add(target);
  }

  @override
  void registerSuperInvocation(ir.Member target, int positionalArguments,
      List<String> namedArguments, List<ir.DartType> typeArguments) {
    _data._superInvocations ??= [];
    _data._superInvocations.add(_SuperInvocation(target,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerInstanceSet(
      ir.DartType receiverType, ClassRelation relation, ir.Member target) {
    _data._instanceSets ??= [];
    _data._instanceSets.add(_InstanceAccess(receiverType, relation, target));
  }

  @override
  void registerDynamicSet(
      ir.DartType receiverType, ClassRelation relation, ir.Name name) {
    _data._dynamicSets ??= [];
    _data._dynamicSets.add(_DynamicAccess(receiverType, relation, name));
  }

  @override
  void registerInstanceGet(
      ir.DartType receiverType, ClassRelation relation, ir.Member target) {
    _data._instanceGets ??= [];
    _data._instanceGets.add(_InstanceAccess(receiverType, relation, target));
  }

  @override
  void registerDynamicGet(
      ir.DartType receiverType, ClassRelation relation, ir.Name name) {
    _data._dynamicGets ??= [];
    _data._dynamicGets.add(_DynamicAccess(receiverType, relation, name));
  }

  @override
  void registerFunctionInvocation(
      ir.DartType receiverType,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    _data._functionInvocations ??= [];
    _data._functionInvocations.add(_FunctionInvocation(receiverType,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerInstanceInvocation(
      ir.DartType receiverType,
      ClassRelation relation,
      ir.Member target,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    _data._instanceInvocations ??= [];
    _data._instanceInvocations.add(_InstanceInvocation(
        receiverType,
        relation,
        target,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerDynamicInvocation(
      ir.DartType receiverType,
      ClassRelation relation,
      ir.Name name,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    _data._dynamicInvocations ??= [];
    _data._dynamicInvocations.add(_DynamicInvocation(
        receiverType,
        relation,
        name,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerLocalFunctionInvocation(
      ir.FunctionDeclaration localFunction,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    _data._localFunctionInvocations ??= [];
    _data._localFunctionInvocations.add(_LocalFunctionInvocation(localFunction,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerStaticInvocation(
      ir.Procedure target,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments,
      ir.LibraryDependency import) {
    _data._staticInvocations ??= [];
    _data._staticInvocations.add(_StaticInvocation(
        target,
        _CallStructure(positionalArguments, namedArguments, typeArguments),
        import));
  }

  @override
  void registerNew(
      ir.Member constructor,
      ir.InterfaceType type,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments,
      ir.LibraryDependency import,
      {bool isConst}) {
    _data._constructorInvocations ??= [];
    _data._constructorInvocations.add(_ConstructorInvocation(
        constructor,
        type,
        _CallStructure(positionalArguments, namedArguments, typeArguments),
        import,
        isConst: isConst));
  }

  @override
  void registerConstInstantiation(ir.Class cls, List<ir.DartType> typeArguments,
      ir.LibraryDependency import) {
    _data._constInstantiations ??= [];
    _data._constInstantiations
        .add(_ConstInstantiation(cls, typeArguments, import));
  }

  @override
  void registerLazyField() {
    _registerFeature(_Feature.lazyField);
  }

  @override
  void registerParameterCheck(ir.DartType type) {
    _registerTypeUse(type, _TypeUseKind.parameterCheck);
  }

  @override
  void registerRedirectingInitializer(
      ir.Constructor constructor,
      int positionalArguments,
      List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    _data._redirectingInitializers ??= [];
    _data._redirectingInitializers.add(_RedirectingInitializer(constructor,
        _CallStructure(positionalArguments, namedArguments, typeArguments)));
  }

  @override
  void registerLoadLibrary() {
    _registerFeature(_Feature.loadLibrary);
  }

  @override
  void registerFieldInitialization(ir.Field node) {
    _data._fieldInitializers ??= [];
    _data._fieldInitializers.add(node);
  }

  @override
  void registerFieldConstantInitialization(
      ir.Field node, ConstantReference constant) {
    _data._fieldConstantInitializers ??= {};
    _data._fieldConstantInitializers.putIfAbsent(node, () => []).add(constant);
  }

  @override
  void registerTypeLiteral(ir.DartType type, ir.LibraryDependency import) {
    _data._typeLiterals ??= [];
    _data._typeLiterals.add(_TypeLiteral(type, import));
  }

  @override
  void registerCatchType(ir.DartType type) {
    _registerTypeUse(type, _TypeUseKind.catchType);
  }

  @override
  void registerStackTrace() {
    _registerFeature(_Feature.stackTrace);
  }

  @override
  void registerCatch() {
    _registerFeature(_Feature.catchClause);
  }

  @override
  void registerAsyncForIn(ir.DartType iterableType, ir.DartType iteratorType,
      ClassRelation iteratorClassRelation) {
    _data._forInData ??= [];
    _data._forInData.add(_ForInData(
        iterableType, iteratorType, iteratorClassRelation,
        isAsync: true));
  }

  @override
  void registerSyncForIn(ir.DartType iterableType, ir.DartType iteratorType,
      ClassRelation iteratorClassRelation) {
    _data._forInData ??= [];
    _data._forInData.add(_ForInData(
        iterableType, iteratorType, iteratorClassRelation,
        isAsync: false));
  }

  @override
  void registerThrow() {
    _registerFeature(_Feature.throwExpression);
  }

  @override
  void registerAsCast(ir.DartType type) {
    _registerTypeUse(type, _TypeUseKind.asCast);
  }

  @override
  void registerImplicitCast(ir.DartType type) {
    _registerTypeUse(type, _TypeUseKind.implicitCast);
  }

  @override
  void registerIsCheck(ir.DartType type) {
    _registerTypeUse(type, _TypeUseKind.isCheck);
  }

  @override
  void registerLocalWithoutInitializer() {
    _registerFeature(_Feature.localWithoutInitializer);
  }

  @override
  void registerLocalFunction(ir.TreeNode node) {
    _data._localFunctions ??= [];
    _data._localFunctions.add(node);
  }

  @override
  void registerStringConcatenation() {
    _registerFeature(_Feature.stringConcatenation);
  }

  @override
  void registerAsyncStar(ir.DartType elementType) {
    _registerTypeUse(elementType, _TypeUseKind.asyncStarMarker);
  }

  @override
  void registerAsync(ir.DartType elementType) {
    _registerTypeUse(elementType, _TypeUseKind.asyncMarker);
  }

  @override
  void registerSyncStar(ir.DartType elementType) {
    _registerTypeUse(elementType, _TypeUseKind.syncStarMarker);
  }

  @override
  void registerGenericInstantiation(
      ir.FunctionType expressionType, List<ir.DartType> typeArguments) {
    _data._genericInstantiations ??= [];
    _data._genericInstantiations
        .add(_GenericInstantiation(expressionType, typeArguments));
  }

  @override
  void registerAssert({bool withMessage}) {
    _registerFeature(withMessage
        ? _Feature.assertWithMessage
        : _Feature.assertWithoutMessage);
  }

  @override
  void registerStaticSet(ir.Member member, ir.LibraryDependency import) {
    _data._staticSets ??= [];
    _data._staticSets.add(_StaticAccess(member, import));
  }

  @override
  void registerStaticGet(ir.Member member, ir.LibraryDependency import) {
    _data._staticGets ??= [];
    _data._staticGets.add(_StaticAccess(member, import));
  }

  @override
  void registerStaticTearOff(
      ir.Procedure procedure, ir.LibraryDependency import) {
    _data._staticTearOffs ??= [];
    _data._staticTearOffs.add(_StaticAccess(procedure, import));
  }

  @override
  void registerMapLiteral(ir.DartType keyType, ir.DartType valueType,
      {bool isConst, bool isEmpty}) {
    _data._mapLiterals ??= [];
    _data._mapLiterals.add(
        _MapLiteral(keyType, valueType, isConst: isConst, isEmpty: isEmpty));
  }

  @override
  void registerListLiteral(ir.DartType elementType,
      {bool isConst, bool isEmpty}) {
    _data._listLiterals ??= [];
    _data._listLiterals.add(
        _ContainerLiteral(elementType, isConst: isConst, isEmpty: isEmpty));
  }

  @override
  void registerSetLiteral(ir.DartType elementType,
      {bool isConst, bool isEmpty}) {
    _data._setLiterals ??= [];
    _data._setLiterals.add(
        _ContainerLiteral(elementType, isConst: isConst, isEmpty: isEmpty));
  }

  @override
  void registerNullLiteral() {
    _registerFeature(_Feature.nullLiteral);
  }

  @override
  void registerSymbolLiteral(String value) {
    _data._symbolLiterals ??= {};
    _data._symbolLiterals.add(value);
  }

  @override
  void registerStringLiteral(String value) {
    _data._stringLiterals ??= {};
    _data._stringLiterals.add(value);
  }

  @override
  void registerBoolLiteral(bool value) {
    _data._boolLiterals ??= {};
    _data._boolLiterals.add(value);
  }

  @override
  void registerDoubleLiteral(double value) {
    _data._doubleLiterals ??= {};
    _data._doubleLiterals.add(value);
  }

  @override
  void registerIntLiteral(int value) {
    _data._intLiterals ??= {};
    _data._intLiterals.add(value);
  }

  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
  // invocation encoding is no longer used.
  @override
  void registerRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
      ir.DartType receiverType, ir.DartType argumentType) {
    _data._runtimeTypeUses ??= [];
    _data._runtimeTypeUses
        .add(_RuntimeTypeUse(node, kind, receiverType, argumentType));
  }

  @override
  void registerConstructorNode(ir.Constructor node) {
    _data._constructorNodes ??= [];
    _data._constructorNodes.add(node);
  }

  @override
  void registerFieldNode(ir.Field node) {
    _data._fieldNodes ??= [];
    _data._fieldNodes.add(node);
  }

  @override
  void registerProcedureNode(ir.Procedure node) {
    _data._procedureNodes ??= [];
    _data._procedureNodes.add(node);
  }

  @override
  void registerStaticInvocationNode(ir.StaticInvocation node) {
    _data._staticInvocationNodes ??= [];
    _data._staticInvocationNodes.add(node);
  }

  @override
  void registerSwitchStatementNode(ir.SwitchStatement node) {
    _data._switchStatementNodes ??= [];
    _data._switchStatementNodes.add(node);
  }

  @override
  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node) {
    _data._constConstructorInvocationNodes ??= [];
    _data._constConstructorInvocationNodes.add(node);
  }
}

/// Data object that contains the world impact data derived purely from kernel.
class ImpactData {
  static const String tag = 'ImpactData';

  List<_SuperInitializer> _superInitializers;
  List<ir.Member> _superSets;
  List<ir.Member> _superGets;
  List<_SuperInvocation> _superInvocations;
  List<_InstanceAccess> _instanceSets;
  List<_DynamicAccess> _dynamicSets;
  List<_InstanceAccess> _instanceGets;
  List<_DynamicAccess> _dynamicGets;
  List<_FunctionInvocation> _functionInvocations;
  List<_InstanceInvocation> _instanceInvocations;
  List<_DynamicInvocation> _dynamicInvocations;
  List<_LocalFunctionInvocation> _localFunctionInvocations;
  List<_StaticInvocation> _staticInvocations;
  List<_ConstructorInvocation> _constructorInvocations;
  List<_ConstInstantiation> _constInstantiations;
  EnumSet<_Feature> _features;
  List<_TypeUse> _typeUses;
  List<_RedirectingInitializer> _redirectingInitializers;
  List<ir.Field> _fieldInitializers;
  Map<ir.Field, List<ConstantReference>> _fieldConstantInitializers;
  List<_TypeLiteral> _typeLiterals;
  List<ir.TreeNode> _localFunctions;
  List<_GenericInstantiation> _genericInstantiations;
  List<_StaticAccess> _staticSets;
  List<_StaticAccess> _staticGets;
  List<_StaticAccess> _staticTearOffs;
  List<_MapLiteral> _mapLiterals;
  List<_ContainerLiteral> _listLiterals;
  List<_ContainerLiteral> _setLiterals;
  Set<String> _symbolLiterals;
  Set<String> _stringLiterals;
  Set<bool> _boolLiterals;
  Set<double> _doubleLiterals;
  Set<int> _intLiterals;
  List<_RuntimeTypeUse> _runtimeTypeUses;
  List<_ForInData> _forInData;

  // TODO(johnniwinther): Remove these when CFE provides constants.
  List<ir.Constructor> _constructorNodes;
  List<ir.Field> _fieldNodes;
  List<ir.Procedure> _procedureNodes;
  List<ir.SwitchStatement> _switchStatementNodes;
  List<ir.StaticInvocation> _staticInvocationNodes;
  List<ir.ConstructorInvocation> _constConstructorInvocationNodes;

  ImpactData();

  ImpactData.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    _superInitializers = source.readList(
        () => _SuperInitializer.fromDataSource(source),
        emptyAsNull: true);
    _superSets =
        source.readList(() => source.readMemberNode(), emptyAsNull: true);
    _superGets =
        source.readList(() => source.readMemberNode(), emptyAsNull: true);
    _superInvocations = source.readList(
        () => _SuperInvocation.fromDataSource(source),
        emptyAsNull: true);
    _instanceSets = source.readList(
        () => _InstanceAccess.fromDataSource(source),
        emptyAsNull: true);
    _dynamicSets = source.readList(() => _DynamicAccess.fromDataSource(source),
        emptyAsNull: true);
    _instanceGets = source.readList(
        () => _InstanceAccess.fromDataSource(source),
        emptyAsNull: true);
    _dynamicGets = source.readList(() => _DynamicAccess.fromDataSource(source),
        emptyAsNull: true);
    _functionInvocations = source.readList(
        () => _FunctionInvocation.fromDataSource(source),
        emptyAsNull: true);
    _instanceInvocations = source.readList(
        () => _InstanceInvocation.fromDataSource(source),
        emptyAsNull: true);
    _dynamicInvocations = source.readList(
        () => _DynamicInvocation.fromDataSource(source),
        emptyAsNull: true);
    _localFunctionInvocations = source.readList(
        () => _LocalFunctionInvocation.fromDataSource(source),
        emptyAsNull: true);
    _staticInvocations = source.readList(
        () => _StaticInvocation.fromDataSource(source),
        emptyAsNull: true);
    _constructorInvocations = source.readList(
        () => _ConstructorInvocation.fromDataSource(source),
        emptyAsNull: true);
    _features = EnumSet<_Feature>.fromValue(source.readInt());
    _typeUses = source.readList(() => _TypeUse.fromDataSource(source),
        emptyAsNull: true);
    _redirectingInitializers = source.readList(
        () => _RedirectingInitializer.fromDataSource(source),
        emptyAsNull: true);
    _fieldInitializers = source.readMemberNodes<ir.Field>(emptyAsNull: true);
    _fieldConstantInitializers =
        source.readMemberNodeMap(source.readTreeNodes, emptyAsNull: true);
    _typeLiterals = source.readList(() => _TypeLiteral.fromDataSource(source),
        emptyAsNull: true);
    _localFunctions = source.readTreeNodes(emptyAsNull: true);
    _genericInstantiations = source.readList(
        () => _GenericInstantiation.fromDataSource(source),
        emptyAsNull: true);
    _staticSets = source.readList(() => _StaticAccess.fromDataSource(source),
        emptyAsNull: true);
    _staticGets = source.readList(() => _StaticAccess.fromDataSource(source),
        emptyAsNull: true);
    _staticTearOffs = source.readList(
        () => _StaticAccess.fromDataSource(source),
        emptyAsNull: true);
    _mapLiterals = source.readList(() => _MapLiteral.fromDataSource(source),
        emptyAsNull: true);
    _listLiterals = source.readList(
        () => _ContainerLiteral.fromDataSource(source),
        emptyAsNull: true);
    _setLiterals = source.readList(
        () => _ContainerLiteral.fromDataSource(source),
        emptyAsNull: true);
    _symbolLiterals = source.readStrings(emptyAsNull: true)?.toSet();
    _stringLiterals = source.readStrings(emptyAsNull: true)?.toSet();
    _boolLiterals =
        source.readList(() => source.readBool(), emptyAsNull: true)?.toSet();
    _doubleLiterals = source
        .readList(() => source.readDoubleValue(), emptyAsNull: true)
        ?.toSet();
    _intLiterals = source
        .readList(() => source.readIntegerValue(), emptyAsNull: true)
        ?.toSet();
    _runtimeTypeUses = source.readList(
        () => _RuntimeTypeUse.fromDataSource(source),
        emptyAsNull: true);

    // TODO(johnniwinther): Remove these when CFE provides constants.
    _constructorNodes =
        source.readMemberNodes<ir.Constructor>(emptyAsNull: true);
    _fieldNodes = source.readMemberNodes<ir.Field>(emptyAsNull: true);
    _procedureNodes = source.readMemberNodes<ir.Procedure>(emptyAsNull: true);
    _switchStatementNodes =
        source.readTreeNodes<ir.SwitchStatement>(emptyAsNull: true);
    _staticInvocationNodes =
        source.readTreeNodes<ir.StaticInvocation>(emptyAsNull: true);
    _constConstructorInvocationNodes =
        source.readTreeNodes<ir.ConstructorInvocation>(emptyAsNull: true);
    source.end(tag);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);

    sink.writeList(
        _superInitializers, (_SuperInitializer o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_superSets, sink.writeMemberNode, allowNull: true);
    sink.writeList(_superGets, sink.writeMemberNode, allowNull: true);
    sink.writeList(
        _superInvocations, (_SuperInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_instanceSets, (_InstanceAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_dynamicSets, (_DynamicAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_instanceGets, (_InstanceAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_dynamicGets, (_DynamicAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(
        _functionInvocations, (_FunctionInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(
        _instanceInvocations, (_InstanceInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(
        _dynamicInvocations, (_DynamicInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_localFunctionInvocations,
        (_LocalFunctionInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(
        _staticInvocations, (_StaticInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_constructorInvocations,
        (_ConstructorInvocation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeInt(_features?.value ?? 0);
    sink.writeList(_typeUses, (_TypeUse o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_redirectingInitializers,
        (_RedirectingInitializer o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeMemberNodes(_fieldInitializers, allowNull: true);
    sink.writeMemberNodeMap(_fieldConstantInitializers, sink.writeTreeNodes,
        allowNull: true);
    sink.writeList(_typeLiterals, (_TypeLiteral o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeTreeNodes(_localFunctions, allowNull: true);
    sink.writeList(
        _genericInstantiations, (_GenericInstantiation o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_staticSets, (_StaticAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_staticGets, (_StaticAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_staticTearOffs, (_StaticAccess o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_mapLiterals, (_MapLiteral o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_listLiterals, (_ContainerLiteral o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeList(_setLiterals, (_ContainerLiteral o) => o.toDataSink(sink),
        allowNull: true);
    sink.writeStrings(_symbolLiterals, allowNull: true);
    sink.writeStrings(_stringLiterals, allowNull: true);
    sink.writeList(_boolLiterals, sink.writeBool, allowNull: true);
    sink.writeList(_doubleLiterals, sink.writeDoubleValue, allowNull: true);
    sink.writeList(_intLiterals, sink.writeIntegerValue, allowNull: true);
    sink.writeList(_runtimeTypeUses, (_RuntimeTypeUse o) => o.toDataSink(sink),
        allowNull: true);

    // TODO(johnniwinther): Remove these when CFE provides constants.
    sink.writeMemberNodes(_constructorNodes, allowNull: true);
    sink.writeMemberNodes(_fieldNodes, allowNull: true);
    sink.writeMemberNodes(_procedureNodes, allowNull: true);
    sink.writeTreeNodes(_switchStatementNodes, allowNull: true);
    sink.writeTreeNodes(_staticInvocationNodes, allowNull: true);
    sink.writeTreeNodes(_constConstructorInvocationNodes, allowNull: true);

    sink.end(tag);
  }

  /// Registers the impact data with [registry].
  void apply(ImpactRegistry registry) {
    if (_superInitializers != null) {
      for (_SuperInitializer data in _superInitializers) {
        registry.registerSuperInitializer(
            data.source,
            data.target,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_superSets != null) {
      for (ir.Member data in _superSets) {
        registry.registerSuperSet(data);
      }
    }
    if (_superGets != null) {
      for (ir.Member data in _superGets) {
        registry.registerSuperGet(data);
      }
    }
    if (_superInvocations != null) {
      for (_SuperInvocation data in _superInvocations) {
        registry.registerSuperInvocation(
            data.target,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_instanceSets != null) {
      for (_InstanceAccess data in _instanceSets) {
        registry.registerInstanceSet(
            data.receiverType, data.classRelation, data.target);
      }
    }
    if (_dynamicSets != null) {
      for (_DynamicAccess data in _dynamicSets) {
        registry.registerDynamicSet(
            data.receiverType, data.classRelation, data.name);
      }
    }
    if (_instanceGets != null) {
      for (_InstanceAccess data in _instanceGets) {
        registry.registerInstanceGet(
            data.receiverType, data.classRelation, data.target);
      }
    }
    if (_dynamicGets != null) {
      for (_DynamicAccess data in _dynamicGets) {
        registry.registerDynamicGet(
            data.receiverType, data.classRelation, data.name);
      }
    }
    if (_functionInvocations != null) {
      for (_FunctionInvocation data in _functionInvocations) {
        registry.registerFunctionInvocation(
            data.receiverType,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_instanceInvocations != null) {
      for (_InstanceInvocation data in _instanceInvocations) {
        registry.registerInstanceInvocation(
            data.receiverType,
            data.classRelation,
            data.target,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_dynamicInvocations != null) {
      for (_DynamicInvocation data in _dynamicInvocations) {
        registry.registerDynamicInvocation(
            data.receiverType,
            data.classRelation,
            data.name,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_localFunctionInvocations != null) {
      for (_LocalFunctionInvocation data in _localFunctionInvocations) {
        registry.registerLocalFunctionInvocation(
            data.localFunction,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_staticInvocations != null) {
      for (_StaticInvocation data in _staticInvocations) {
        registry.registerStaticInvocation(
            data.target,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments,
            data.import);
        ;
      }
    }
    if (_constructorInvocations != null) {
      for (_ConstructorInvocation data in _constructorInvocations) {
        registry.registerNew(
            data.constructor,
            data.type,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments,
            data.import,
            isConst: data.isConst);
      }
    }
    if (_constInstantiations != null) {
      for (_ConstInstantiation data in _constInstantiations) {
        registry.registerConstInstantiation(
            data.cls, data.typeArguments, data.import);
      }
    }
    if (_features != null) {
      for (_Feature data in _features.iterable(_Feature.values)) {
        switch (data) {
          case _Feature.lazyField:
            registry.registerLazyField();
            break;
          case _Feature.loadLibrary:
            registry.registerLoadLibrary();
            break;
          case _Feature.stackTrace:
            registry.registerStackTrace();
            break;
          case _Feature.catchClause:
            registry.registerCatch();
            break;
          case _Feature.throwExpression:
            registry.registerThrow();
            break;
          case _Feature.localWithoutInitializer:
            registry.registerLocalWithoutInitializer();
            break;
          case _Feature.stringConcatenation:
            registry.registerStringConcatenation();
            break;
          case _Feature.assertWithMessage:
            registry.registerAssert(withMessage: true);
            break;
          case _Feature.assertWithoutMessage:
            registry.registerAssert(withMessage: false);
            break;
          case _Feature.nullLiteral:
            registry.registerNullLiteral();
            break;
        }
      }
    }
    if (_typeUses != null) {
      for (_TypeUse data in _typeUses) {
        switch (data.kind) {
          case _TypeUseKind.parameterCheck:
            registry.registerParameterCheck(data.type);
            break;
          case _TypeUseKind.catchType:
            registry.registerCatchType(data.type);
            break;
          case _TypeUseKind.asCast:
            registry.registerAsCast(data.type);
            break;
          case _TypeUseKind.implicitCast:
            registry.registerImplicitCast(data.type);
            break;
          case _TypeUseKind.isCheck:
            registry.registerIsCheck(data.type);
            break;
          case _TypeUseKind.asyncStarMarker:
            registry.registerAsyncStar(data.type);
            break;
          case _TypeUseKind.asyncMarker:
            registry.registerAsync(data.type);
            break;
          case _TypeUseKind.syncStarMarker:
            registry.registerSyncStar(data.type);
            break;
        }
      }
    }
    if (_redirectingInitializers != null) {
      for (_RedirectingInitializer data in _redirectingInitializers) {
        registry.registerRedirectingInitializer(
            data.constructor,
            data.callStructure.positionalArguments,
            data.callStructure.namedArguments,
            data.callStructure.typeArguments);
      }
    }
    if (_fieldInitializers != null) {
      for (ir.Field data in _fieldInitializers) {
        registry.registerFieldInitialization(data);
      }
    }
    if (_fieldConstantInitializers != null) {
      _fieldConstantInitializers
          .forEach((ir.Field field, List<ConstantReference> constants) {
        for (ConstantReference constant in constants) {
          registry.registerFieldConstantInitialization(field, constant);
        }
      });
    }
    if (_typeLiterals != null) {
      for (_TypeLiteral data in _typeLiterals) {
        registry.registerTypeLiteral(data.type, data.import);
      }
    }
    if (_localFunctions != null) {
      for (ir.TreeNode data in _localFunctions) {
        registry.registerLocalFunction(data);
      }
    }
    if (_genericInstantiations != null) {
      for (_GenericInstantiation data in _genericInstantiations) {
        registry.registerGenericInstantiation(
            data.expressionType, data.typeArguments);
      }
    }
    if (_staticSets != null) {
      for (_StaticAccess data in _staticSets) {
        registry.registerStaticSet(data.target, data.import);
      }
    }
    if (_staticGets != null) {
      for (_StaticAccess data in _staticGets) {
        registry.registerStaticGet(data.target, data.import);
      }
    }
    if (_staticTearOffs != null) {
      for (_StaticAccess data in _staticTearOffs) {
        registry.registerStaticTearOff(data.target, data.import);
      }
    }
    if (_mapLiterals != null) {
      for (_MapLiteral data in _mapLiterals) {
        registry.registerMapLiteral(data.keyType, data.valueType,
            isConst: data.isConst, isEmpty: data.isEmpty);
      }
    }
    if (_listLiterals != null) {
      for (_ContainerLiteral data in _listLiterals) {
        registry.registerListLiteral(data.elementType,
            isConst: data.isConst, isEmpty: data.isEmpty);
      }
    }
    if (_setLiterals != null) {
      for (_ContainerLiteral data in _setLiterals) {
        registry.registerSetLiteral(data.elementType,
            isConst: data.isConst, isEmpty: data.isEmpty);
      }
    }
    if (_symbolLiterals != null) {
      for (String data in _symbolLiterals) {
        registry.registerSymbolLiteral(data);
      }
    }
    if (_stringLiterals != null) {
      for (String data in _stringLiterals) {
        registry.registerStringLiteral(data);
      }
    }
    if (_boolLiterals != null) {
      for (bool data in _boolLiterals) {
        registry.registerBoolLiteral(data);
      }
    }
    if (_doubleLiterals != null) {
      for (double data in _doubleLiterals) {
        registry.registerDoubleLiteral(data);
      }
    }
    if (_intLiterals != null) {
      for (int data in _intLiterals) {
        registry.registerIntLiteral(data);
      }
    }
    if (_runtimeTypeUses != null) {
      for (_RuntimeTypeUse data in _runtimeTypeUses) {
        registry.registerRuntimeTypeUse(
            data.node, data.kind, data.receiverType, data.argumentType);
      }
    }
    if (_forInData != null) {
      for (_ForInData data in _forInData) {
        if (data.isAsync) {
          registry.registerAsyncForIn(
              data.iterableType, data.iteratorType, data.iteratorClassRelation);
        } else {
          registry.registerSyncForIn(
              data.iterableType, data.iteratorType, data.iteratorClassRelation);
        }
      }
    }

    // TODO(johnniwinther): Remove these when CFE provides constants.
    if (_constructorNodes != null) {
      for (ir.Constructor data in _constructorNodes) {
        registry.registerConstructorNode(data);
      }
    }
    if (_fieldNodes != null) {
      for (ir.Field data in _fieldNodes) {
        registry.registerFieldNode(data);
      }
    }
    if (_procedureNodes != null) {
      for (ir.Procedure data in _procedureNodes) {
        registry.registerProcedureNode(data);
      }
    }
    if (_switchStatementNodes != null) {
      for (ir.SwitchStatement data in _switchStatementNodes) {
        registry.registerSwitchStatementNode(data);
      }
    }
    if (_staticInvocationNodes != null) {
      for (ir.StaticInvocation data in _staticInvocationNodes) {
        registry.registerStaticInvocationNode(data);
      }
    }
    if (_constConstructorInvocationNodes != null) {
      for (ir.ConstructorInvocation data in _constConstructorInvocationNodes) {
        registry.registerConstConstructorInvocationNode(data);
      }
    }
  }
}

class _CallStructure {
  static const String tag = '_CallStructure';

  final List<ir.DartType> typeArguments;
  final int positionalArguments;
  final List<String> namedArguments;

  _CallStructure.internal(
      this.typeArguments, this.positionalArguments, this.namedArguments);

  factory _CallStructure(int positionalArguments, List<String> namedArguments,
      List<ir.DartType> typeArguments) {
    return _CallStructure.internal(
        typeArguments, positionalArguments, namedArguments);
  }

  factory _CallStructure.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    List<ir.DartType> typeArguments = source.readDartTypeNodes();
    int positionalArguments = source.readInt();
    List<String> namedArguments = source.readStrings();
    source.end(tag);
    return _CallStructure.internal(
        typeArguments, positionalArguments, namedArguments);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNodes(typeArguments);
    sink.writeInt(positionalArguments);
    sink.writeStrings(namedArguments);
    sink.end(tag);
  }
}

class _SuperInitializer {
  static const String tag = '_SuperInitializer';

  final ir.Constructor source;
  final ir.Constructor target;
  final _CallStructure callStructure;

  _SuperInitializer(this.source, this.target, this.callStructure);

  factory _SuperInitializer.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.Constructor sourceConstructor = source.readMemberNode();
    ir.Constructor targetConstructor = source.readMemberNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _SuperInitializer(
        sourceConstructor, targetConstructor, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberNode(source);
    sink.writeMemberNode(target);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _SuperInvocation {
  static const String tag = '_SuperInvocation';

  final ir.Member target;
  final _CallStructure callStructure;

  _SuperInvocation(this.target, this.callStructure);

  factory _SuperInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.Member member = source.readMemberNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _SuperInvocation(member, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberNode(target);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _InstanceAccess {
  static const String tag = '_InstanceAccess';

  final ir.DartType receiverType;
  final ClassRelation classRelation;
  final ir.Member target;

  _InstanceAccess(this.receiverType, this.classRelation, this.target);

  factory _InstanceAccess.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType receiverType = source.readDartTypeNode();
    ClassRelation classRelation = source.readEnum(ClassRelation.values);
    ir.Member target = source.readMemberNode();
    source.end(tag);
    return _InstanceAccess(receiverType, classRelation, target);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(receiverType);
    sink.writeEnum(classRelation);
    sink.writeMemberNode(target);
    sink.end(tag);
  }
}

class _DynamicAccess {
  static const String tag = '_DynamicAccess';

  final ir.DartType receiverType;
  final ClassRelation classRelation;
  final ir.Name name;

  _DynamicAccess(this.receiverType, this.classRelation, this.name);

  factory _DynamicAccess.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType receiverType = source.readDartTypeNode();
    ClassRelation classRelation = source.readEnum(ClassRelation.values);
    ir.Name name = source.readName();
    source.end(tag);
    return _DynamicAccess(receiverType, classRelation, name);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(receiverType);
    sink.writeEnum(classRelation);
    sink.writeName(name);
    sink.end(tag);
  }
}

class _FunctionInvocation {
  static const String tag = '_FunctionInvocation';

  final ir.DartType receiverType;
  final _CallStructure callStructure;

  _FunctionInvocation(this.receiverType, this.callStructure);

  factory _FunctionInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType receiverType = source.readDartTypeNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _FunctionInvocation(receiverType, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(receiverType);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _InstanceInvocation {
  static const String tag = '_InstanceInvocation';

  final ir.DartType receiverType;
  final ClassRelation classRelation;
  final ir.Member target;
  final _CallStructure callStructure;

  _InstanceInvocation(
      this.receiverType, this.classRelation, this.target, this.callStructure);

  factory _InstanceInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType receiverType = source.readDartTypeNode();
    ClassRelation classRelation = source.readEnum(ClassRelation.values);
    ir.Member target = source.readMemberNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _InstanceInvocation(
        receiverType, classRelation, target, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(receiverType);
    sink.writeEnum(classRelation);
    sink.writeMemberNode(target);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _DynamicInvocation {
  static const String tag = '_DynamicInvocation';

  final ir.DartType receiverType;
  final ClassRelation classRelation;
  final ir.Name name;
  final _CallStructure callStructure;

  _DynamicInvocation(
      this.receiverType, this.classRelation, this.name, this.callStructure);

  factory _DynamicInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType receiverType = source.readDartTypeNode();
    ClassRelation classRelation = source.readEnum(ClassRelation.values);
    ir.Name name = source.readName();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _DynamicInvocation(receiverType, classRelation, name, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(receiverType);
    sink.writeEnum(classRelation);
    sink.writeName(name);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _LocalFunctionInvocation {
  static const String tag = '_LocalFunctionInvocation';

  final ir.FunctionDeclaration localFunction;
  final _CallStructure callStructure;

  _LocalFunctionInvocation(this.localFunction, this.callStructure);

  factory _LocalFunctionInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.FunctionDeclaration localFunction = source.readTreeNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _LocalFunctionInvocation(localFunction, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeTreeNode(localFunction);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _StaticInvocation {
  static const String tag = '_StaticInvocation';

  final ir.Procedure target;
  final _CallStructure callStructure;
  final ir.LibraryDependency import;

  _StaticInvocation(this.target, this.callStructure, this.import);

  factory _StaticInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.Procedure target = source.readMemberNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
    source.end(tag);
    return _StaticInvocation(target, callStructure, import);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberNode(target);
    callStructure.toDataSink(sink);
    sink.writeLibraryDependencyNodeOrNull(import);
    sink.end(tag);
  }
}

class _ConstructorInvocation {
  static const String tag = '_ConstructorInvocation';

  final ir.Member constructor;
  final ir.InterfaceType type;
  final _CallStructure callStructure;
  final ir.LibraryDependency import;
  final bool isConst;

  _ConstructorInvocation(
      this.constructor, this.type, this.callStructure, this.import,
      {this.isConst});

  factory _ConstructorInvocation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.Member constructor = source.readMemberNode();
    ir.InterfaceType type = source.readDartTypeNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
    bool isConst = source.readBool();
    source.end(tag);
    return _ConstructorInvocation(constructor, type, callStructure, import,
        isConst: isConst);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberNode(constructor);
    sink.writeDartTypeNode(type);
    callStructure.toDataSink(sink);
    sink.writeLibraryDependencyNodeOrNull(import);
    sink.writeBool(isConst);
    sink.end(tag);
  }
}

class _ConstInstantiation {
  final ir.Class cls;
  final List<ir.DartType> typeArguments;
  final ir.LibraryDependency import;

  _ConstInstantiation(this.cls, this.typeArguments, this.import);
}

enum _Feature {
  lazyField,
  loadLibrary,
  stackTrace,
  catchClause,
  throwExpression,
  localWithoutInitializer,
  stringConcatenation,
  assertWithMessage,
  assertWithoutMessage,
  nullLiteral,
}

class _TypeUse {
  static const String tag = '_TypeUse';

  final ir.DartType type;
  final _TypeUseKind kind;

  _TypeUse(this.type, this.kind);

  factory _TypeUse.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType type = source.readDartTypeNode();
    _TypeUseKind kind = source.readEnum(_TypeUseKind.values);
    source.end(tag);
    return _TypeUse(type, kind);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(type);
    sink.writeEnum(kind);
    sink.end(tag);
  }
}

enum _TypeUseKind {
  parameterCheck,
  catchType,
  asCast,
  implicitCast,
  isCheck,
  asyncStarMarker,
  asyncMarker,
  syncStarMarker,
}

class _RedirectingInitializer {
  static const String tag = '_RedirectingInitializer';

  final ir.Constructor constructor;
  final _CallStructure callStructure;

  _RedirectingInitializer(this.constructor, this.callStructure);

  factory _RedirectingInitializer.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.Constructor constructor = source.readMemberNode();
    _CallStructure callStructure = _CallStructure.fromDataSource(source);
    source.end(tag);
    return _RedirectingInitializer(constructor, callStructure);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberNode(constructor);
    callStructure.toDataSink(sink);
    sink.end(tag);
  }
}

class _TypeLiteral {
  static const String tag = '_TypeLiteral';

  final ir.DartType type;
  final ir.LibraryDependency import;

  _TypeLiteral(this.type, this.import);

  factory _TypeLiteral.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType type = source.readDartTypeNode();
    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
    source.end(tag);
    return _TypeLiteral(type, import);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(type);
    sink.writeLibraryDependencyNodeOrNull(import);
    sink.end(tag);
  }
}

class _GenericInstantiation {
  static const String tag = '_GenericInstantiation';

  final ir.FunctionType expressionType;
  final List<ir.DartType> typeArguments;

  _GenericInstantiation(this.expressionType, this.typeArguments);

  factory _GenericInstantiation.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.FunctionType expressionType = source.readDartTypeNode();
    List<ir.DartType> typeArguments = source.readDartTypeNodes();
    source.end(tag);
    return _GenericInstantiation(expressionType, typeArguments);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(expressionType);
    sink.writeDartTypeNodes(typeArguments);
    sink.end(tag);
  }
}

class _StaticAccess {
  static const String tag = '_StaticAccess';

  final ir.Member target;
  final ir.LibraryDependency import;

  _StaticAccess(this.target, this.import);

  factory _StaticAccess.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.Member target = source.readMemberNode();
    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
    source.end(tag);
    return _StaticAccess(target, import);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberNode(target);
    sink.writeLibraryDependencyNodeOrNull(import);
    sink.end(tag);
  }
}

class _MapLiteral {
  static const String tag = '_MapLiteral';

  final ir.DartType keyType;
  final ir.DartType valueType;
  final bool isConst;
  final bool isEmpty;

  _MapLiteral(this.keyType, this.valueType, {this.isConst, this.isEmpty});

  factory _MapLiteral.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType keyType = source.readDartTypeNode();
    ir.DartType valueType = source.readDartTypeNode();
    bool isConst = source.readBool();
    bool isEmpty = source.readBool();
    source.end(tag);
    return _MapLiteral(keyType, valueType, isConst: isConst, isEmpty: isEmpty);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(keyType);
    sink.writeDartTypeNode(valueType);
    sink.writeBool(isConst);
    sink.writeBool(isEmpty);
    sink.end(tag);
  }
}

class _ContainerLiteral {
  static const String tag = '_ContainerLiteral';

  final ir.DartType elementType;
  final bool isConst;
  final bool isEmpty;

  _ContainerLiteral(this.elementType, {this.isConst, this.isEmpty});

  factory _ContainerLiteral.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.DartType elementType = source.readDartTypeNode();
    bool isConst = source.readBool();
    bool isEmpty = source.readBool();
    source.end(tag);
    return _ContainerLiteral(elementType, isConst: isConst, isEmpty: isEmpty);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeDartTypeNode(elementType);
    sink.writeBool(isConst);
    sink.writeBool(isEmpty);
    sink.end(tag);
  }
}

class _RuntimeTypeUse {
  static const String tag = '_RuntimeTypeUse';

  // TODO(johnniwinther): Change [node] `InstanceGet` when the old method
  // invocation encoding is no longer used.
  final ir.Expression node;
  final RuntimeTypeUseKind kind;
  final ir.DartType receiverType;
  final ir.DartType argumentType;

  _RuntimeTypeUse(this.node, this.kind, this.receiverType, this.argumentType);

  factory _RuntimeTypeUse.fromDataSource(DataSourceReader source) {
    source.begin(tag);
    ir.TreeNode node = source.readTreeNode();
    RuntimeTypeUseKind kind = source.readEnum(RuntimeTypeUseKind.values);
    ir.DartType receiverType = source.readDartTypeNode();
    ir.DartType argumentType = source.readDartTypeNode(allowNull: true);
    source.end(tag);
    return _RuntimeTypeUse(node, kind, receiverType, argumentType);
  }

  void toDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeTreeNode(node);
    sink.writeEnum(kind);
    sink.writeDartTypeNode(receiverType);
    sink.writeDartTypeNode(argumentType, allowNull: true);
    sink.end(tag);
  }
}

class _ForInData {
  final ir.DartType iterableType;
  final ir.DartType iteratorType;
  final ClassRelation iteratorClassRelation;
  final bool isAsync;

  _ForInData(this.iterableType, this.iteratorType, this.iteratorClassRelation,
      {this.isAsync});
}
