// Copyright (c) 2016, 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.native_data;

import '../common.dart';
import '../elements/elements.dart'
    show ClassElement, Element, FieldElement, FunctionElement, MemberElement;
import '../native/behavior.dart' show NativeBehavior;

/// Additional element information for native classes and methods and js-interop
/// methods.
class NativeData {
  /// The JavaScript names for elements implemented via typed JavaScript
  /// interop.
  Map<Element, String> jsInteropNames = <Element, String>{};

  /// The JavaScript names for native JavaScript elements implemented.
  Map<Element, String> nativeMemberName = <Element, String>{};

  /// Tag info for native JavaScript classes names. See
  /// [setNativeClassTagInfo].
  Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{};

  /// Cache for [NativeBehavior]s for calling native methods.
  Map<FunctionElement, NativeBehavior> nativeMethodBehavior =
      <FunctionElement, NativeBehavior>{};

  /// Cache for [NativeBehavior]s for reading from native fields.
  Map<MemberElement, NativeBehavior> nativeFieldLoadBehavior =
      <FieldElement, NativeBehavior>{};

  /// Cache for [NativeBehavior]s for writing to native fields.
  Map<MemberElement, NativeBehavior> nativeFieldStoreBehavior =
      <FieldElement, NativeBehavior>{};

  /// Prefix used to escape JS names that are not valid Dart names
  /// when using JSInterop.
  static const String _jsInteropEscapePrefix = r'JS$';

  /// Returns `true` if [element] is explicitly marked as part of JsInterop.
  bool _isJsInterop(Element element) {
    return jsInteropNames.containsKey(element.declaration);
  }

  /// Returns [element] as an explicit part of JsInterop. The js interop name is
  /// expected to be computed later.
  void markAsJsInterop(Element element) {
    jsInteropNames[element.declaration] = null;
  }

  /// Sets the explicit js interop [name] for [element].
  void setJsInteropName(Element element, String name) {
    assert(invariant(element, isJsInterop(element),
        message:
            'Element $element is not js interop but given a js interop name.'));
    jsInteropNames[element.declaration] = name;
  }

  /// Returns the explicit js interop name for [element].
  String getJsInteropName(Element element) {
    return jsInteropNames[element.declaration];
  }

  /// Returns `true` if [element] is part of JsInterop.
  bool isJsInterop(Element element) {
    // An function is part of JsInterop in the following cases:
    // * It has a jsInteropName annotation
    // * It is external member of a class or library tagged as JsInterop.
    if (element.isFunction || element.isConstructor || element.isAccessor) {
      FunctionElement function = element;
      if (!function.isExternal) return false;

      if (_isJsInterop(function)) return true;
      if (function.isClassMember) return isJsInterop(function.contextClass);
      if (function.isTopLevel) return isJsInterop(function.library);
      return false;
    } else {
      return _isJsInterop(element);
    }
  }

  /// Returns `true` if the name of [element] is fixed for the generated
  /// JavaScript.
  bool hasFixedBackendName(Element element) {
    return isJsInterop(element) ||
        nativeMemberName.containsKey(element.declaration);
  }

  String _jsNameHelper(Element element) {
    String jsInteropName = jsInteropNames[element.declaration];
    assert(invariant(element, !(_isJsInterop(element) && jsInteropName == null),
        message:
            'Element $element is js interop but js interop name has not yet '
            'been computed.'));
    if (jsInteropName != null && jsInteropName.isNotEmpty) {
      return jsInteropName;
    }
    return element.isLibrary ? 'self' : getUnescapedJSInteropName(element.name);
  }

  /// Computes the name for [element] to use in the generated JavaScript. This
  /// is either given through a native annotation or a js interop annotation.
  String getFixedBackendName(Element element) {
    String name = nativeMemberName[element.declaration];
    if (name == null && isJsInterop(element)) {
      // If an element isJsInterop but _isJsInterop is false that means it is
      // considered interop as the parent class is interop.
      name = _jsNameHelper(
          element.isConstructor ? element.enclosingClass : element);
      nativeMemberName[element.declaration] = name;
    }
    return name;
  }

  /// Whether [element] corresponds to a native JavaScript construct either
  /// through the native mechanism (`@Native(...)` or the `native` pseudo
  /// keyword) which is only allowed for internal libraries or via the typed
  /// JavaScriptInterop mechanism which is allowed for user libraries.
  bool isNative(Element element) {
    if (isJsInterop(element)) return true;
    if (element.isClass) {
      return nativeClassTagInfo.containsKey(element.declaration);
    } else {
      return nativeMemberName.containsKey(element.declaration);
    }
  }

  /// Sets the native [name] for the member [element]. This name is used for
  /// [element] in the generated JavaScript.
  void setNativeMemberName(MemberElement element, String name) {
    // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
    // might enqueue [element] several times (before processing it) and computes
    // name on each call to `internalAddToWorkList`.
    assert(invariant(
        element,
        nativeMemberName[element.declaration] == null ||
            nativeMemberName[element.declaration] == name,
        message: "Native member name set inconsistently on $element: "
            "Existing name '${nativeMemberName[element.declaration]}', "
            "new name '$name'."));
    nativeMemberName[element.declaration] = name;
  }

  /// Sets the native tag info for [cls].
  ///
  /// The tag info string contains comma-separated 'words' which are either
  /// dispatch tags (having JavaScript identifier syntax) and directives that
  /// begin with `!`.
  void setNativeClassTagInfo(ClassElement cls, String tagInfo) {
    // TODO(johnniwinther): Assert that this is only called once. The memory
    // compiler copies pre-processed elements into a new compiler through
    // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
    // method.
    assert(invariant(
        cls,
        nativeClassTagInfo[cls.declaration] == null ||
            nativeClassTagInfo[cls.declaration] == tagInfo,
        message: "Native tag info set inconsistently on $cls: "
            "Existing tag info '${nativeClassTagInfo[cls.declaration]}', "
            "new tag info '$tagInfo'."));
    nativeClassTagInfo[cls.declaration] = tagInfo;
  }

  /// Returns the list of native tag words for [cls].
  List<String> getNativeTagsOfClassRaw(ClassElement cls) {
    String quotedName = nativeClassTagInfo[cls.declaration];
    return quotedName.substring(1, quotedName.length - 1).split(',');
  }

  /// Returns the list of non-directive native tag words for [cls].
  List<String> getNativeTagsOfClass(ClassElement cls) {
    return getNativeTagsOfClassRaw(cls)
        .where((s) => !s.startsWith('!'))
        .toList();
  }

  /// Returns `true` if [cls] has a `!nonleaf` tag word.
  bool hasNativeTagsForcedNonLeaf(ClassElement cls) {
    return getNativeTagsOfClassRaw(cls).contains('!nonleaf');
  }

  /// Returns the [NativeBehavior] for calling the native [method].
  NativeBehavior getNativeMethodBehavior(FunctionElement method) {
    assert(invariant(method, nativeMethodBehavior.containsKey(method),
        message: "No native method behavior has been computed for $method."));
    return nativeMethodBehavior[method];
  }

  /// Returns the [NativeBehavior] for reading from the native [field].
  NativeBehavior getNativeFieldLoadBehavior(FieldElement field) {
    assert(invariant(field, nativeFieldLoadBehavior.containsKey(field),
        message: "No native field load behavior has been "
            "computed for $field."));
    return nativeFieldLoadBehavior[field];
  }

  /// Returns the [NativeBehavior] for writing to the native [field].
  NativeBehavior getNativeFieldStoreBehavior(FieldElement field) {
    assert(invariant(field, nativeFieldStoreBehavior.containsKey(field),
        message: "No native field store behavior has been "
            "computed for $field."));
    return nativeFieldStoreBehavior[field];
  }

  /// Registers the [behavior] for calling the native [method].
  void setNativeMethodBehavior(
      FunctionElement method, NativeBehavior behavior) {
    nativeMethodBehavior[method] = behavior;
  }

  /// Registers the [behavior] for reading from the native [field].
  void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior) {
    nativeFieldLoadBehavior[field] = behavior;
  }

  /// Registers the [behavior] for writing to the native [field].
  void setNativeFieldStoreBehavior(
      FieldElement field, NativeBehavior behavior) {
    nativeFieldStoreBehavior[field] = behavior;
  }

  /// Apply JS$ escaping scheme to convert possible escaped Dart names into
  /// JS names.
  String getUnescapedJSInteropName(String name) {
    return name.startsWith(_jsInteropEscapePrefix)
        ? name.substring(_jsInteropEscapePrefix.length)
        : name;
  }
}
