// 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 vm.metadata.direct_call;

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

/// Metadata for annotating invocations converted to direct calls.
class DirectCallMetadata {
  // Target of the direct call or enclosing member of a closure.
  final Reference _memberReference;
  final int _flags;
  final int _closureId;

  static const int flagCheckReceiverForNull = 1 << 0;
  static const int flagClosure = 1 << 1;

  DirectCallMetadata.targetMember(Member target, bool checkReceiverForNull)
    : this._(
        getNonNullableMemberReferenceGetter(target),
        checkReceiverForNull ? flagCheckReceiverForNull : 0,
        0,
      );

  DirectCallMetadata.targetClosure(
    Member closureMember,
    int closureId,
    bool checkReceiverForNull,
  ) : this._(
        getNonNullableMemberReferenceGetter(closureMember),
        (checkReceiverForNull ? flagCheckReceiverForNull : 0) | flagClosure,
        closureId,
      );

  DirectCallMetadata._(this._memberReference, this._flags, this._closureId)
    : assert(_closureId >= 0);

  // Target member or enclosing member of a closure.
  Member get _member => _memberReference.asMember;

  Member? get targetMember => isClosure ? null : _member;

  bool get checkReceiverForNull => (_flags & flagCheckReceiverForNull) != 0;
  bool get isClosure => (_flags & flagClosure) != 0;

  /// When calling a closure, the enclosing member of the closure, and the
  /// closure index.
  ///
  /// Closures in a member are assigned ids based on pre-order traversal of the
  /// member body, and the member itself also counts as a closure (for
  /// tear-offs). So index 0 is the member itself, called as a closure
  /// (tear-off).
  (Member, int)? get targetClosure => isClosure ? (_member, _closureId) : null;

  @override
  String toString() =>
      isClosure
          ? 'closure ${_closureId} in ${_member.toText(astTextStrategyForTesting)}'
          : '${_member.toText(astTextStrategyForTesting)}${checkReceiverForNull ? '??' : ''}';
}

/// Repository for [DirectCallMetadata].
class DirectCallMetadataRepository
    extends MetadataRepository<DirectCallMetadata> {
  static const repositoryTag = 'vm.direct-call.metadata';

  @override
  String get tag => repositoryTag;

  @override
  final Map<TreeNode, DirectCallMetadata> mapping =
      <TreeNode, DirectCallMetadata>{};

  @override
  void writeToBinary(DirectCallMetadata metadata, Node node, BinarySink sink) {
    sink.writeNullAllowedCanonicalNameReference(
      getMemberReferenceGetter(metadata._member),
    );
    sink.writeByte(metadata._flags);
    if (metadata.isClosure) {
      sink.writeUInt30(metadata._closureId);
    }
  }

  @override
  DirectCallMetadata readFromBinary(Node node, BinarySource source) {
    final memberReference =
        source.readNullableCanonicalNameReference()?.reference;
    if (memberReference == null) {
      throw 'DirectCallMetadata should have a non-null member';
    }
    final flags = source.readByte();
    final closureId =
        (flags & DirectCallMetadata.flagClosure) != 0 ? source.readUInt30() : 0;
    return DirectCallMetadata._(memberReference, flags, closureId);
  }
}
