// Copyright (c) 2012, 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 _interceptors;

import 'dart:collection';
import 'dart:_collection-dev' hide Symbol;
import "dart:_collection-dev" as _symbol_dev show Symbol;
import 'dart:_js_helper' show allMatchesInStringUnchecked,
                              Null,
                              JSSyntaxRegExp,
                              Primitives,
                              checkNull,
                              checkNum,
                              checkString,
                              defineProperty,
                              getRuntimeType,
                              regExpGetNative,
                              stringContainsUnchecked,
                              stringLastIndexOfUnchecked,
                              stringReplaceAllFuncUnchecked,
                              stringReplaceAllUnchecked,
                              stringReplaceFirstUnchecked,
                              lookupDispatchRecord,
                              StringMatch,
                              firstMatchAfter;
import 'dart:_foreign_helper' show JS;

part 'js_array.dart';
part 'js_number.dart';
part 'js_string.dart';

String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);

_symbolMapToStringMap(Map<Symbol, dynamic> map) {
  if (map == null) return null;
  var result = new Map<String, dynamic>();
  map.forEach((Symbol key, value) {
    result[_symbolToString(key)] = value;
  });
  return result;
}

/**
 * Get the interceptor for [object]. Called by the compiler when it needs
 * to emit a call to an intercepted method, that is a method that is
 * defined in an interceptor class.
 */
getInterceptor(object) {
  // This is a magic method: the compiler does specialization of it
  // depending on the uses of intercepted methods and instantiated
  // primitive types.
  // This method is recursive to prevent the type analyzer from thinking that
  // the method returns `null`.
  return getInterceptor(object);
}

/**
 * The name of the property used on native classes and `Object.prototype` to get
 * the interceptor for a native class instance.  The value is initialized on
 * isolate startup to ensure no two Dart programs in the same page use the same
 * property.
 */
var dispatchPropertyName = null;

getDispatchProperty(object) {
  // This is a magic method: the compiler replaces it with a runtime generated
  // function
  //
  //     function(object){return object._zzyzx;}
  //
  // where `_zzyzx` is replaced with the actual [dispatchPropertyName].
  //
  // The CSP compliant version replaces this function with one of a few
  // pre-compiled accessors, unless the pre-compiled versions are all in use,
  // when it falls back on this code.
  return JS('', '#[#]', object, dispatchPropertyName);
}

setDispatchProperty(object, value) {
  defineProperty(object, dispatchPropertyName, value);
}

makeDispatchRecord(interceptor, proto, extension, indexability) {
  // Dispatch records are stored in the prototype chain, and in some cases, on
  // instances.
  //
  // The record layout and field usage is designed to minimize the number of
  // operations on the common paths.
  //
  // [interceptor] is the interceptor - a holder of methods for the object,
  // i.e. the prototype of the interceptor class.
  //
  // [proto] is usually the prototype, used to check that the dispatch record
  // matches the object and is not the dispatch record of a superclass.  Other
  // values:
  //  - `false` for leaf classes that need no check.
  //  - `true` for Dart classes where the object is its own interceptor (unused)
  //  - a function used to continue matching.
  //
  // [extension] is used for irregular cases.
  //
  // [indexability] is used to cache whether or not the object
  // implements JavaScriptIndexingBehavior.
  //
  //     proto  interceptor extension action
  //     -----  ----------- --------- ------
  //     false  I                     use interceptor I
  //     true   -                     use object
  //     P      I                     if object's prototype is P, use I
  //     F      -           P         if object's prototype is P, call F

  // BUG(10903): Remove this hack. It is needed to avoid inlining this
  // method because inlining gives us multiple allocation points for
  // records which is bad because it leads to polymorphic access.
  if (false) return null;
  return JS('', '{i: #, p: #, e: #, x: #}',
            interceptor, proto, extension, indexability);
}

dispatchRecordInterceptor(record) => JS('', '#.i', record);
dispatchRecordProto(record) => JS('', '#.p', record);
dispatchRecordExtension(record) => JS('', '#.e', record);
dispatchRecordIndexability(record) => JS('bool|Null', '#.x', record);

/**
 * Returns the interceptor for a native class instance. Used by
 * [getInterceptor].
 */
getNativeInterceptor(object) {
  var record = getDispatchProperty(object);

  if (record != null) {
    var proto = dispatchRecordProto(record);
    if (false == proto) return dispatchRecordInterceptor(record);
    if (true == proto) return object;
    var objectProto = JS('', 'Object.getPrototypeOf(#)', object);
    if (JS('bool', '# === #', proto, objectProto)) {
      return dispatchRecordInterceptor(record);
    }

    var extension = dispatchRecordExtension(record);
    if (JS('bool', '# === #', extension, objectProto)) {
      // The extension handler will do any required patching.  A typical use
      // case is where one native class represents two Dart classes.  The
      // extension method will inspect the native object instance to determine
      // its class and patch the instance.  Needed to fix dartbug.com/9654.
      return JS('', '(#)(#, #)', proto, object, record);
    }
  }

  record = lookupDispatchRecord(object);
  if (record == null) {
    return const JSUnknown();
  }
  setDispatchProperty(JS('', 'Object.getPrototypeOf(#)', object), record);
  return getNativeInterceptor(object);
}

/**
 * Initializes the [getDispatchProperty] function and [dispatchPropertyName]
 * variable.  Each isolate running in a web page needs a different
 * [dispatchPropertyName], so if a given dispatch property name is in use by
 * some other program loaded into the web page, another name is chosen.
 *
 * The non-CSP version is called like this:
 *
 *     initializeDispatchProperty(
 *         function(x){$.getDispatchProperty=x},
 *         '_f4$Dxv7S',
 *         $.Interceptor);
 *
 * The [getDispatchProperty] function is generated from the chosen name of the
 * property.
 *
 * The CSP version can't create functions via `new Function(...)`, so it is
 * given a fixed set of functions to choose from.  If all the property names in
 * the fixed set of functions are in use, it falls back on the definition of
 * [getDispatchProperty] above.
 *
 *     initializeDispatchPropertyCSP(
 *         function(x){$.getDispatchProperty=x},
 *         [function(a){return a._f4$Dxv7S},
 *          function(a){return a._Q2zpL9iY}],
 *         $.Interceptor);
 */
void initializeDispatchProperty(
    setGetDispatchPropertyFn, rootProperty, jsObjectInterceptor) {
  // We must be extremely careful to avoid any language feature that needs an
  // interceptor.  Avoid type annotations since they might generate type checks.
  var objectProto = JS('=Object', 'Object.prototype');
  for (var i = 0; ; i = JS('int', '# + 1', i)) {
    var property = rootProperty;
    if (JS('bool', '# > 0', i)) {
      property = JS('String', '# + "_" + #', rootProperty, i);
    }
    if (JS('bool', 'typeof #[#] === "undefined"', objectProto, property)) {
      dispatchPropertyName = property;
      var getter = JS('', 'new Function("a", "return a." + #)', property);
      JS('void', '#(#)', setGetDispatchPropertyFn, getter);
      setDispatchProperty(
          objectProto,
          makeDispatchRecord(jsObjectInterceptor, objectProto, null, null));
      return;
    }
  }
}

void initializeDispatchPropertyCSP(
    setGetDispatchPropertyFn, getterFunctions, jsObjectInterceptor) {
  // We must be extremely careful to avoid any language feature that needs an
  // interceptor.  Avoid type annotations since they might generate type checks.
  var objectProto = JS('=Object', 'Object.prototype');
  var property = null;
  var getter = null;
  var rootProperty = null;
  for (var i = 0; ; i = JS('int', '# + 1', i)) {
    if (JS('bool', '# < #.length', i, getterFunctions)) {
      getter = JS('', '#[#]', getterFunctions, i);
      var fnText = JS('String', '"" + #', getter);
      property =
          JS('String', '#.match(#)[1]', fnText, JS('', r'/\.([^;}]*)/'));
      rootProperty = property;
    } else {
      getter = null;
      property = JS('String', '# + "_" + #', rootProperty, i);
    }
    if (JS('bool', 'typeof #[#] === "undefined"', objectProto, property)) {
      dispatchPropertyName = property;
      if (!identical(getter, null)) {
        JS('void', '#(#)', setGetDispatchPropertyFn, getter);
      }
      setDispatchProperty(
          objectProto,
          makeDispatchRecord(jsObjectInterceptor, objectProto, null, null));
      return;
    }
  }
}

/**
 * If [JSInvocationMirror._invokeOn] is being used, this variable
 * contains a JavaScript array with the names of methods that are
 * intercepted.
 */
var interceptedNames;

/**
 * The base interceptor class.
 *
 * The code `r.foo(a)` is compiled to `getInterceptor(r).foo$1(r, a)`.  The
 * value returned by [getInterceptor] holds the methods separately from the
 * state of the instance.  The compiler converts the methods on an interceptor
 * to take the Dart `this` argument as an explicit `receiver` argument.  The
 * JavaScript `this` parameter is bound to the interceptor.
 *
 * In order to have uniform call sites, if a method is defined on an
 * interceptor, methods of that name on plain unintercepted classes also use the
 * interceptor calling convention.  The plain classes are _self-interceptors_,
 * and for them, `getInterceptor(r)` returns `r`.  Methods on plain
 * unintercepted classes have a redundant `receiver` argument and should ignore
 * it in favour of `this`.
 *
 * In the case of mixins, a method may be placed on both an intercepted class
 * and an unintercepted class.  In this case, the method must use the `receiver`
 * parameter.
 *
 *
 * There are various optimizations of the general call pattern.
 *
 * When the interceptor can be statically determined, it can be used directly:
 *
 *     CONSTANT_INTERCEPTOR.foo$1(r, a)
 *
 * If there are only a few classes, [getInterceptor] can be specialized with a
 * more efficient dispatch:
 *
 *     getInterceptor$specialized(r).foo$1(r, a)
 *
 * If it can be determined that the receiver is an unintercepted class, it can
 * be called directly:
 *
 *     r.foo$1(r, a)
 *
 * If, further, it is known that the call site cannot call a foo that is
 * mixed-in to a native class, then it is known that the explicit receiver is
 * ignored, and space-saving dummy value can be passed instead:
 *
 *     r.foo$1(0, a)
 *
 * This class defines implementations of *all* methods on [Object] so no
 * interceptor inherits an implementation from [Object].  This enables the
 * implementations on Object to ignore the explicit receiver argument, which
 * allows dummy receiver optimization.
 */
abstract class Interceptor {
  const Interceptor();

  bool operator ==(other) => identical(this, other);

  int get hashCode => Primitives.objectHashCode(this);

  String toString() => Primitives.objectToString(this);

  dynamic noSuchMethod(Invocation invocation) {
    throw new NoSuchMethodError(
        this,
        _symbolToString(invocation.memberName),
        invocation.positionalArguments,
        _symbolMapToStringMap(invocation.namedArguments));
  }

  Type get runtimeType => getRuntimeType(this);
}

/**
 * The interceptor class for [bool].
 */
class JSBool extends Interceptor implements bool {
  const JSBool();

  // Note: if you change this, also change the function [S].
  String toString() => JS('String', r'String(#)', this);

  // The values here are SMIs, co-prime and differ about half of the bit
  // positions, including the low bit, so they are different mod 2^k.
  int get hashCode => this ? (2 * 3 * 23 * 3761) : (269 * 811);

  Type get runtimeType => bool;
}

/**
 * The interceptor class for [Null].
 *
 * This class defines implementations for *all* methods on [Object] since the
 * the methods on Object assume the receiver is non-null.  This means that
 * JSNull will always be in the interceptor set for methods defined on Object.
 */
class JSNull extends Interceptor implements Null {
  const JSNull();

  bool operator ==(other) => identical(null, other);

  // Note: if you change this, also change the function [S].
  String toString() => 'null';

  int get hashCode => 0;

  Type get runtimeType => Null;
}

class JSUnknown extends Interceptor {
  const JSUnknown();

  String toString() => JS('String', 'String(#)', this);

  int get hashCode => 0;

  Type get runtimeType => null;
}

/**
 * The supertype for JSString and JSArray. Used by the backend as to
 * have a type mask that contains the objects that we can use the
 * native JS [] operator and length on.
 */
abstract class JSIndexable {
  int get length;
  operator[](int index);
}

/**
 * The supertype for JSMutableArray and
 * JavaScriptIndexingBehavior. Used by the backend to have a type mask
 * that contains the objects we can use the JS []= operator on.
 */
abstract class JSMutableIndexable extends JSIndexable {
  operator[]=(int index, var value);
}
