All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.js.es6.util.construct.js Maven / Gradle / Ivy

/*
 * Copyright 2016 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview
 * @suppress {uselessCode}
 */

'require util/objectcreate';

/**
 * Polyfill for Reflect.construct() method:
 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct
 *
 * Calls a constructor as with the 'new' operator.
 * TODO(sdh): how to type 'target' with (new: TARGET) if opt_newTarget missing?
 *
 * @param {function(new: ?, ...?)} target The constructor to call.
 * @param {!Array} argList The arguments as a list.
 * @param {function(new: TARGET, ...?)=} opt_newTarget The constructor to instantiate.
 * @return {TARGET} The result of the function call.
 * @template TARGET
 */
$jscomp.construct = /** @type {function(): !Function} */ (function() {

  // Check for https://github.com/Microsoft/ChakraCore/issues/3217
  /** @return {boolean} */
  function reflectConstructWorks() {
    /** @constructor */ function Base() {}
    /** @constructor */ function Derived() {}
    new Base();
    Reflect.construct(Base, [], Derived);
    return new Base() instanceof Base;
  }

  if (typeof Reflect != 'undefined' && Reflect.construct) {
    if (reflectConstructWorks()) return Reflect.construct;
    var brokenConstruct = Reflect.construct;
    /**
     * @param {function(new: ?, ...?)} target The constructor to call.
     * @param {!Array} argList The arguments as a list.
     * @param {function(new: TARGET, ...?)=} opt_newTarget The constructor to instantiate.
     * @return {TARGET} The result of the function call.
     * @template TARGET
     * @suppress {reportUnknownTypes}
     */
    var patchedConstruct = function(target, argList, opt_newTarget) {
      var out = brokenConstruct(target, argList);
      if (opt_newTarget) Reflect.setPrototypeOf(out, opt_newTarget.prototype);
      return out;
    };
    return patchedConstruct;
  }

  /**
   * @param {function(new: ?, ...?)} target The constructor to call.
   * @param {!Array} argList The arguments as a list.
   * @param {function(new: TARGET, ...?)=} opt_newTarget The constructor to instantiate.
   * @return {TARGET} The result of the function call.
   * @template TARGET
   * @suppress {reportUnknownTypes}
   */
  function construct(target, argList, opt_newTarget) {
    if (opt_newTarget === undefined) opt_newTarget = target;
    var proto = opt_newTarget.prototype || Object.prototype;
    var obj = $jscomp.objectCreate(proto);
    var apply = Function.prototype.apply;
    var out = apply.call(target, obj, argList);
    return out || obj;
  }
  return construct;
})();




© 2015 - 2024 Weber Informatics LLC | Privacy Policy