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

library js_backend.backend.annotations;

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

import '../common.dart';
import '../elements/entities.dart';
import '../ir/annotations.dart';
import '../ir/util.dart';
import '../kernel/dart2js_target.dart';
import '../options.dart';
import '../serialization/serialization.dart';
import '../util/enumset.dart';

/// `@pragma('dart2js:...')` annotations understood by dart2js.
///
/// Some of these annotations are (documented
/// elsewhere)[pkg/compiler/doc/pragmas.md].
enum PragmaAnnotation {
  /// Tells the optimizing compiler to not inline the annotated method.
  noInline('noInline', forFunctionsOnly: true),

  /// Tells the optimizing compiler to always inline the annotated method, if
  /// possible.
  tryInline('tryInline', forFunctionsOnly: true),

  /// Annotation on a member that tells the optimizing compiler to disable
  /// inlining at call sites within the member.
  disableInlining('disable-inlining'),

  disableFinal('disableFinal', forFunctionsOnly: true, internalOnly: true),
  noElision('noElision'),

  /// Tells the optimizing compiler that the annotated method cannot throw.
  /// Requires @pragma('dart2js:noInline') to function correctly.
  noThrows('noThrows', forFunctionsOnly: true, internalOnly: true),

  /// Tells the optimizing compiler that the annotated method has no
  /// side-effects. Allocations don't count as side-effects, since they can be
  /// dropped without changing the semantics of the program.
  ///
  /// Requires @pragma('dart2js:noInline') to function correctly.
  noSideEffects('noSideEffects', forFunctionsOnly: true, internalOnly: true),

  /// Use this as metadata on method declarations to disable closed world
  /// assumptions on parameters, effectively assuming that the runtime arguments
  /// could be any value. Note that the constraints due to static types still
  /// apply.
  assumeDynamic('assumeDynamic', forFunctionsOnly: true, internalOnly: true),

  asTrust('as:trust', forFunctionsOnly: false, internalOnly: false),
  asCheck('as:check', forFunctionsOnly: false, internalOnly: false),
  typesTrust('types:trust', forFunctionsOnly: false, internalOnly: false),
  typesCheck('types:check', forFunctionsOnly: false, internalOnly: false),
  parameterTrust('parameter:trust',
      forFunctionsOnly: false, internalOnly: false),
  parameterCheck('parameter:check',
      forFunctionsOnly: false, internalOnly: false),
  downcastTrust('downcast:trust', forFunctionsOnly: false, internalOnly: false),
  downcastCheck('downcast:check', forFunctionsOnly: false, internalOnly: false),
  indexBoundsTrust('index-bounds:trust',
      forFunctionsOnly: false, internalOnly: false),
  indexBoundsCheck('index-bounds:check',
      forFunctionsOnly: false, internalOnly: false),

  /// Annotation for a `late` field to omit the checks on the late field. The
  /// annotation is not restricted to a field since it is copied from the field
  /// to the getter and setter.
  // TODO(45682): Make this annotation apply to local and static late variables.
  lateTrust('late:trust'),

  /// Annotation for a `late` field to perform the checks on the late field. The
  /// annotation is not restricted to a field since it is copied from the field
  /// to the getter and setter.
  // TODO(45682): Make this annotation apply to local and static late variables.
  lateCheck('late:check'),

  loadLibraryPriority('load-priority', hasOption: true),
  resourceIdentifier('resource-identifier'),
  ;

  final String name;
  final bool forFunctionsOnly;
  final bool internalOnly;
  final bool hasOption;

  // TODO(sra): Review [forFunctionsOnly]. Fields have implied getters and
  // setters, so some annotations meant only for functions could reasonable be
  // placed on a field to apply to the getter and setter.

  const PragmaAnnotation(this.name,
      {this.forFunctionsOnly = false,
      this.internalOnly = false,
      this.hasOption = true});

  static const Map<PragmaAnnotation, Set<PragmaAnnotation>> implies = {
    typesTrust: {parameterTrust, downcastTrust},
    typesCheck: {parameterCheck, downcastCheck},
  };
  static const Map<PragmaAnnotation, Set<PragmaAnnotation>> excludes = {
    noInline: {tryInline},
    tryInline: {noInline, resourceIdentifier},
    typesTrust: {typesCheck, parameterCheck, downcastCheck},
    typesCheck: {typesTrust, parameterTrust, downcastTrust},
    parameterTrust: {parameterCheck},
    parameterCheck: {parameterTrust},
    downcastTrust: {downcastCheck},
    downcastCheck: {downcastTrust},
    asTrust: {asCheck},
    asCheck: {asTrust},
    lateTrust: {lateCheck},
    lateCheck: {lateTrust},
    resourceIdentifier: {tryInline},
  };
  static const Map<PragmaAnnotation, Set<PragmaAnnotation>> requires = {
    noThrows: {noInline},
    noSideEffects: {noInline},
  };

  static final Map<String, PragmaAnnotation> lookupMap = {
    for (final annotation in values) annotation.name: annotation,
    // Aliases
    'never-inline': noInline,
    'prefer-inline': tryInline,
  };
}

ir.Library _enclosingLibrary(ir.TreeNode node) {
  while (true) {
    if (node is ir.Library) return node;
    if (node is ir.Member) return node.enclosingLibrary;
    node = node.parent!;
  }
}

EnumSet<PragmaAnnotation> processMemberAnnotations(
    CompilerOptions options,
    DiagnosticReporter reporter,
    ir.Annotatable node,
    List<PragmaAnnotationData> pragmaAnnotationData) {
  EnumSet<PragmaAnnotation> annotations = EnumSet<PragmaAnnotation>.empty();

  ir.Library library = _enclosingLibrary(node);
  Uri uri = library.importUri;
  bool platformAnnotationsAllowed =
      options.testMode || uri.isScheme('dart') || maybeEnableNative(uri);

  for (PragmaAnnotationData data in pragmaAnnotationData) {
    String name = data.name;
    String suffix = data.suffix;
    final annotation = PragmaAnnotation.lookupMap[suffix];
    if (annotation != null) {
      annotations += annotation;

      if (data.options != null && !annotation.hasOption) {
        reporter.reportErrorMessage(
            computeSourceSpanFromTreeNode(node),
            MessageKind.GENERIC,
            {'text': "@pragma('$name') annotation does not take options"});
      }
      if (annotation.forFunctionsOnly) {
        if (node is! ir.Procedure && node is! ir.Constructor) {
          reporter.reportErrorMessage(
              computeSourceSpanFromTreeNode(node), MessageKind.GENERIC, {
            'text': "@pragma('$name') annotation is only supported "
                "for methods and constructors."
          });
        }
      }
      if (annotation.internalOnly && !platformAnnotationsAllowed) {
        reporter.reportErrorMessage(
            computeSourceSpanFromTreeNode(node),
            MessageKind.GENERIC,
            {'text': "Unrecognized dart2js pragma @pragma('$name')"});
      }
    } else {
      reporter.reportErrorMessage(
          computeSourceSpanFromTreeNode(node),
          MessageKind.GENERIC,
          {'text': "Unknown dart2js pragma @pragma('$name')"});
    }
  }

  Map<PragmaAnnotation, EnumSet<PragmaAnnotation>> reportedExclusions = {};
  for (PragmaAnnotation annotation
      in annotations.iterable(PragmaAnnotation.values)) {
    Set<PragmaAnnotation>? implies = PragmaAnnotation.implies[annotation];
    if (implies != null) {
      for (PragmaAnnotation other in implies) {
        if (annotations.contains(other)) {
          reporter.reportHintMessage(
              computeSourceSpanFromTreeNode(node), MessageKind.GENERIC, {
            'text': "@pragma('dart2js:${annotation.name}') implies "
                "@pragma('dart2js:${other.name}')."
          });
        }
      }
    }
    Set<PragmaAnnotation>? excludes = PragmaAnnotation.excludes[annotation];
    if (excludes != null) {
      for (PragmaAnnotation other in excludes) {
        if (annotations.contains(other) &&
            !(reportedExclusions[other]?.contains(annotation) ?? false)) {
          reporter.reportErrorMessage(
              computeSourceSpanFromTreeNode(node), MessageKind.GENERIC, {
            'text': "@pragma('dart2js:${annotation.name}') must not be used "
                "with @pragma('dart2js:${other.name}')."
          });
          reportedExclusions.update(
              annotation, (exclusions) => exclusions + other,
              ifAbsent: () => EnumSet.fromValue(other));
        }
      }
    }
    Set<PragmaAnnotation>? requires = PragmaAnnotation.requires[annotation];
    if (requires != null) {
      for (PragmaAnnotation other in requires) {
        if (!annotations.contains(other)) {
          reporter.reportErrorMessage(
              computeSourceSpanFromTreeNode(node), MessageKind.GENERIC, {
            'text': "@pragma('dart2js:${annotation.name}') should always be "
                "combined with @pragma('dart2js:${other.name}')."
          });
        }
      }
    }
  }
  return annotations;
}

abstract class AnnotationsData {
  /// Deserializes an [AnnotationsData] object from [source].
  factory AnnotationsData.readFromDataSource(
      CompilerOptions options,
      DiagnosticReporter reporter,
      DataSourceReader source) = AnnotationsDataImpl.readFromDataSource;

  /// Serializes this [AnnotationsData] to [sink].
  void writeToDataSink(DataSinkWriter sink);

  /// Returns `true` if [member] has an `@pragma('dart2js:assumeDynamic')`
  /// annotation.
  bool hasAssumeDynamic(MemberEntity member);

  /// Returns `true` if [member] has a `@pragma('dart2js:noInline')` annotation.
  bool hasNoInline(MemberEntity member);

  /// Returns `true` if [member] has a `@pragma('dart2js:tryInline')`
  /// annotation.
  bool hasTryInline(MemberEntity member);

  /// Returns `true` if inlining is disabled at call sites inside [member].
  // TODO(49475): This should be a property of call site, but ssa/builder.dart
  // does not currently always pass the call site ir.TreeNode.
  bool hasDisableInlining(MemberEntity member);

  /// Returns `true` if [member] has a `@pragma('dart2js:disableFinal')`
  /// annotation.
  bool hasDisableFinal(MemberEntity member);

  /// Returns `true` if [member] has a `@pragma('dart2js:noElision')`
  /// annotation.
  bool hasNoElision(MemberEntity member);

  /// Returns `true` if [member] has a `@pragma('dart2js:noThrows')` annotation.
  bool hasNoThrows(MemberEntity member);

  /// Returns `true` if [member] has a `@pragma('dart2js:noSideEffects')`
  /// annotation.
  bool hasNoSideEffects(MemberEntity member);

  /// What the compiler should do with parameter type assertions in [member].
  ///
  /// If [member] is `null`, the default policy is returned.
  // TODO(49475): Need this be nullable?
  CheckPolicy getParameterCheckPolicy(MemberEntity? member);

  /// What the compiler should do with implicit downcasts in [member].
  ///
  /// If [member] is `null`, the default policy is returned.
  // TODO(49475): Need this be nullable?
  CheckPolicy getImplicitDowncastCheckPolicy(MemberEntity? member);

  /// What the compiler should do with a boolean value in a condition context
  /// in [member] when the language specification says it is a runtime error for
  /// it to be null.
  ///
  /// If [member] is `null`, the default policy is returned.
  // TODO(49475): Need this be nullable?
  CheckPolicy getConditionCheckPolicy(MemberEntity? member);

  /// What the compiler should do with explicit casts in [member].
  ///
  /// If [member] is `null`, the default policy is returned.
  // TODO(49475): Need this be nullable?
  CheckPolicy getExplicitCastCheckPolicy(MemberEntity? member);

  /// What the compiler should do with index bounds checks `[]`, `[]=` and
  /// `removeLast()` operations in the body of [member].
  ///
  /// If [member] is `null`, the default policy is returned.
  // TODO(49475): Need this be nullable?
  CheckPolicy getIndexBoundsCheckPolicy(MemberEntity? member);

  /// What the compiler should do with late field checks at a position in the
  /// body of a method. The method is usually the getter or setter for a late
  /// field.
  // If we change our late field lowering to happen later, [node] could be the
  // [ir.Field].
  CheckPolicy getLateVariableCheckPolicyAt(ir.TreeNode node);

  /// The priority to load the specified library with.
  ///
  /// This can be an arbitrary string to be interpreted by the custom deferred
  /// loader.
  String getLoadLibraryPriority(ir.LoadLibrary node);

  /// Determines whether [member] is annotated as a resource identifier.
  bool methodIsResourceIdentifier(FunctionEntity member);
}

class AnnotationsDataImpl implements AnnotationsData {
  /// Tag used for identifying serialized [AnnotationsData] objects in a
  /// debugging data stream.
  static const String tag = 'annotations-data';

  final CompilerOptions _options;
  final DiagnosticReporter _reporter;

  final CheckPolicy _defaultParameterCheckPolicy;
  final CheckPolicy _defaultImplicitDowncastCheckPolicy;
  final CheckPolicy _defaultConditionCheckPolicy;
  final CheckPolicy _defaultExplicitCastCheckPolicy;
  final CheckPolicy _defaultIndexBoundsCheckPolicy;
  final CheckPolicy _defaultLateVariableCheckPolicy;
  final bool _defaultDisableInlining;

  /// Pragma annotations for members. These are captured for the K-entities and
  /// translated to J-entities.
  // TODO(49475): Change the queries that use [pragmaAnnotation] to use the
  // DirectivesContext so that we can avoid the need for persisting annotations.
  final Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations;

  /// Pragma annotation environments for annotatable places in the Kernel
  /// AST. These annotations generated on demand and not precomputed or
  /// persisted.  This map is a cache of the pragma annotation environment and
  /// its enclosing environments.
  // TODO(49475): Periodically clear this map to release references to tree
  // nodes.
  final Map<ir.Annotatable, DirectivesContext> _nodeToContextMap = {};

  /// Root annotation environment that allows similar
  final DirectivesContext _root = DirectivesContext.root();

  AnnotationsDataImpl(
      CompilerOptions options, this._reporter, this.pragmaAnnotations)
      : this._options = options,
        this._defaultParameterCheckPolicy = options.defaultParameterCheckPolicy,
        this._defaultImplicitDowncastCheckPolicy =
            options.defaultImplicitDowncastCheckPolicy,
        this._defaultConditionCheckPolicy = options.defaultConditionCheckPolicy,
        this._defaultExplicitCastCheckPolicy =
            options.defaultExplicitCastCheckPolicy,
        this._defaultIndexBoundsCheckPolicy =
            options.defaultIndexBoundsCheckPolicy,
        this._defaultLateVariableCheckPolicy = CheckPolicy.checked,
        this._defaultDisableInlining = options.disableInlining;

  factory AnnotationsDataImpl.readFromDataSource(CompilerOptions options,
      DiagnosticReporter reporter, DataSourceReader source) {
    source.begin(tag);
    Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations = source
        .readMemberMap((MemberEntity member) => EnumSet(source.readInt()));
    source.end(tag);
    return AnnotationsDataImpl(options, reporter, pragmaAnnotations);
  }

  @override
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMemberMap(pragmaAnnotations,
        (MemberEntity member, EnumSet<PragmaAnnotation> set) {
      sink.writeInt(set.mask);
    });
    sink.end(tag);
  }

  bool _hasPragma(MemberEntity member, PragmaAnnotation annotation) {
    EnumSet<PragmaAnnotation>? set = pragmaAnnotations[member];
    return set != null && set.contains(annotation);
  }

  @override
  bool hasAssumeDynamic(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.assumeDynamic);

  @override
  bool hasNoInline(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.noInline);

  @override
  bool hasTryInline(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.tryInline);

  @override
  bool hasDisableInlining(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.disableInlining) ||
      _defaultDisableInlining;

  @override
  bool hasDisableFinal(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.disableFinal);

  @override
  bool hasNoElision(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.noElision);

  @override
  bool hasNoThrows(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.noThrows);

  @override
  bool hasNoSideEffects(MemberEntity member) =>
      _hasPragma(member, PragmaAnnotation.noSideEffects);

  @override
  CheckPolicy getParameterCheckPolicy(MemberEntity? member) {
    if (member != null) {
      EnumSet<PragmaAnnotation>? annotations = pragmaAnnotations[member];
      if (annotations != null) {
        if (annotations.contains(PragmaAnnotation.typesTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.typesCheck)) {
          return CheckPolicy.checked;
        } else if (annotations.contains(PragmaAnnotation.parameterTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.parameterCheck)) {
          return CheckPolicy.checked;
        }
      }
    }
    return _defaultParameterCheckPolicy;
  }

  @override
  CheckPolicy getImplicitDowncastCheckPolicy(MemberEntity? member) {
    if (member != null) {
      EnumSet<PragmaAnnotation>? annotations = pragmaAnnotations[member];
      if (annotations != null) {
        if (annotations.contains(PragmaAnnotation.typesTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.typesCheck)) {
          return CheckPolicy.checked;
        } else if (annotations.contains(PragmaAnnotation.downcastTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.downcastCheck)) {
          return CheckPolicy.checked;
        }
      }
    }
    return _defaultImplicitDowncastCheckPolicy;
  }

  @override
  CheckPolicy getConditionCheckPolicy(MemberEntity? member) {
    if (member != null) {
      EnumSet<PragmaAnnotation>? annotations = pragmaAnnotations[member];
      if (annotations != null) {
        if (annotations.contains(PragmaAnnotation.typesTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.typesCheck)) {
          return CheckPolicy.checked;
        } else if (annotations.contains(PragmaAnnotation.downcastTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.downcastCheck)) {
          return CheckPolicy.checked;
        }
      }
    }
    return _defaultConditionCheckPolicy;
  }

  @override
  CheckPolicy getExplicitCastCheckPolicy(MemberEntity? member) {
    if (member != null) {
      EnumSet<PragmaAnnotation>? annotations = pragmaAnnotations[member];
      if (annotations != null) {
        if (annotations.contains(PragmaAnnotation.asTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.asCheck)) {
          return CheckPolicy.checked;
        }
      }
    }
    return _defaultExplicitCastCheckPolicy;
  }

  @override
  CheckPolicy getIndexBoundsCheckPolicy(MemberEntity? member) {
    if (member != null) {
      EnumSet<PragmaAnnotation>? annotations = pragmaAnnotations[member];
      if (annotations != null) {
        if (annotations.contains(PragmaAnnotation.indexBoundsTrust)) {
          return CheckPolicy.trusted;
        } else if (annotations.contains(PragmaAnnotation.indexBoundsCheck)) {
          return CheckPolicy.checked;
        }
      }
    }
    return _defaultIndexBoundsCheckPolicy;
  }

  @override
  CheckPolicy getLateVariableCheckPolicyAt(ir.TreeNode node) {
    return _getLateVariableCheckPolicyAt(_findContext(node));
  }

  CheckPolicy _getLateVariableCheckPolicyAt(DirectivesContext? context) {
    while (context != null) {
      EnumSet<PragmaAnnotation> annotations = context.annotations;
      if (annotations.contains(PragmaAnnotation.lateTrust)) {
        return CheckPolicy.trusted;
      } else if (annotations.contains(PragmaAnnotation.lateCheck)) {
        return CheckPolicy.checked;
      }
      context = context.parent;
    }
    return _defaultLateVariableCheckPolicy;
  }

  DirectivesContext _findContext(ir.TreeNode startNode) {
    final node = _getContextNode(startNode);
    if (node == null) return _root;
    return _nodeToContextMap[node] ??= _getContext(node);
  }

  ir.Annotatable? _getContextNode(ir.TreeNode startNode) {
    ir.TreeNode? node = startNode;
    while (node is! ir.Annotatable) {
      if (node == null) return null;
      node = node.parent;
    }
    return node;
  }

  DirectivesContext _getContext(ir.Annotatable node) {
    return _nodeToContextMap[node] ??= _findContext(node.parent!).extend(
        processMemberAnnotations(_options, _reporter, node,
            computePragmaAnnotationDataFromIr(node)));
  }

  @override
  String getLoadLibraryPriority(ir.LoadLibrary node) {
    String? _getPragmaOptionForNode(ir.TreeNode node) {
      ir.Annotatable? contextNode = _getContextNode(node);
      if (contextNode == null) return null;
      if (!_hasLoadLibraryPriority(_getContext(contextNode))) return null;
      final pragmaData = computePragmaAnnotationDataFromIr(contextNode);
      final annotationData = pragmaData.firstWhere((d) =>
          PragmaAnnotation.lookupMap[d.suffix] ==
          PragmaAnnotation.loadLibraryPriority);
      final option = annotationData.options;
      if (option is! ir.StringConstant) return null;
      return option.value;
    }

    // Annotation may be on enclosing declaration or on the import.
    return _getPragmaOptionForNode(node) ??
        _getPragmaOptionForNode(node.import) ??
        '';
  }

  bool _hasLoadLibraryPriority(DirectivesContext? context) {
    while (context != null) {
      EnumSet<PragmaAnnotation> annotations = context.annotations;
      if (annotations.contains(PragmaAnnotation.loadLibraryPriority)) {
        return true;
      }
      context = context.parent;
    }
    return false;
  }

  @override
  bool methodIsResourceIdentifier(MemberEntity member) {
    EnumSet<PragmaAnnotation>? annotations = pragmaAnnotations[member];
    if (annotations != null) {
      if (annotations.contains(PragmaAnnotation.resourceIdentifier)) {
        return true;
      }
    }
    return false;
  }
}

class AnnotationsDataBuilder {
  Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations = {};

  void registerPragmaAnnotations(
      MemberEntity member, EnumSet<PragmaAnnotation> annotations) {
    if (annotations.isNotEmpty) {
      pragmaAnnotations[member] = annotations;
    }
  }

  AnnotationsData close(CompilerOptions options, DiagnosticReporter reporter) {
    return AnnotationsDataImpl(options, reporter, pragmaAnnotations);
  }
}

/// A [DirectivesContext] is a chain of enclosing parent annotatable
/// scopes.
///
/// The context chain for a location always starts with a node that reflects the
/// annotations at the location so that it is possible to determine if an
/// annotation is 'on' the element. Chains for different locations that have the
/// same structure are shared. `method1` and `method2` have the same annotations
/// in scope, with no annotations on the method itself but inheriting
/// `late:trust` from the class scope. This is represented by DirectivesContext
/// [D].
///
/// Links in the context chain above the element may be compressed, so `class
/// DD` and `method4` share the chain [F] with no annotations on the element but
/// inheriting `late:check` from the enclosing library scope.
///
///     @pragma('dart2js:late:check')
///     library foo;  // [B]
///
///     @pragma('dart2js:late:trust')
///     class CC {  // [C]
///       method1(){}  // [D]
///       method2(){}  // [D]
///       @pragma('dart2js:noInline')
///       method3(){}  // [E]
///     }
///
///     class DD {  // [F]
///       method4(); // [F]
///     }
///
///
///     A: parent: null,  pragmas: {}
///
///     B: parent: A,     pragmas: {late:check}
///
///     C: parent: B,     pragmas: {late:trust}
///
///     D: parent: C,     pragmas: {}
///     E: parent: C,     pragmas: {noInline}
///
///     F: parent: B,     pragmas: {}
///
/// The root scope [A] is empty. We could remove it and start the root scope at
/// the library, but the shared root might be a good place to put a set of
/// annotations derived from the command-line.
///
/// If we ever introduce a single annotation that means something different in
/// different positions (e.g. on a class vs. on a method), we might want to make
/// the [DirectivesContext] have a 'scope-kind'.
class DirectivesContext {
  final DirectivesContext? parent;
  final EnumSet<PragmaAnnotation> annotations;

  Map<EnumSet<PragmaAnnotation>, DirectivesContext>? _children;

  DirectivesContext._(this.parent, this.annotations);

  DirectivesContext.root() : this._(null, EnumSet<PragmaAnnotation>.empty());

  DirectivesContext extend(EnumSet<PragmaAnnotation> annotations) {
    // Shorten chains of equivalent sets of annotations.
    if (this.annotations == annotations) return this;
    final children = _children ??= {};
    return children[annotations] ??= DirectivesContext._(this, annotations);
  }
}
