231 lines
8.4 KiB
JavaScript
231 lines
8.4 KiB
JavaScript
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
exports.MakeConstructor = MakeConstructor;
|
||
exports.Construct = Construct;
|
||
exports.SpeciesConstructor = SpeciesConstructor;
|
||
exports.MakeClassConstructor = MakeClassConstructor;
|
||
exports.ConstructorMethod = ConstructorMethod;
|
||
exports.NonConstructorMethodDefinitions = NonConstructorMethodDefinitions;
|
||
|
||
var _index = require("../values/index.js");
|
||
|
||
var _is = require("./is.js");
|
||
|
||
var _get = require("./get.js");
|
||
|
||
var _has = require("./has.js");
|
||
|
||
var _singletons = require("../singletons.js");
|
||
|
||
var _invariant = require("../invariant.js");
|
||
|
||
var _invariant2 = _interopRequireDefault(_invariant);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
// ECMA262 9.2.8
|
||
function MakeConstructor(realm, F, writablePrototype, prototype) {
|
||
// 1. Assert: F is an ECMAScript function object.
|
||
(0, _invariant2.default)(F instanceof _index.ECMAScriptSourceFunctionValue, "expected function value");
|
||
|
||
// 2. Assert: F has a [[Construct]] internal method.
|
||
(0, _invariant2.default)(F.$Construct !== undefined, "expected construct internal method");
|
||
|
||
// 3. Assert: F is an extensible object that does not have a prototype own property.
|
||
(0, _invariant2.default)(F.getExtensible(), "expected extensible object that doesn't have prototype own property");
|
||
|
||
// 4. If the writablePrototype argument was not provided, let writablePrototype be true.
|
||
if (writablePrototype === null || writablePrototype === undefined) {
|
||
writablePrototype = true;
|
||
}
|
||
|
||
// 5. If the prototype argument was not provided, then
|
||
if (!prototype) {
|
||
// a. Let prototype be ObjectCreate(%ObjectPrototype%).
|
||
prototype = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
|
||
prototype.originalConstructor = F;
|
||
|
||
// b. Perform ! DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor{[[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true }).
|
||
_singletons.Properties.DefinePropertyOrThrow(realm, prototype, "constructor", {
|
||
value: F,
|
||
writable: writablePrototype,
|
||
enumerable: false,
|
||
configurable: true
|
||
});
|
||
}
|
||
|
||
// 6. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false}).
|
||
_singletons.Properties.DefinePropertyOrThrow(realm, F, "prototype", {
|
||
value: prototype,
|
||
writable: writablePrototype,
|
||
enumerable: false,
|
||
configurable: false
|
||
});
|
||
|
||
// 7. Return NormalCompletion(undefined).
|
||
return realm.intrinsics.undefined;
|
||
}
|
||
|
||
// ECMA262 7.3.13
|
||
/**
|
||
* Copyright (c) 2017-present, Facebook, Inc.
|
||
* All rights reserved.
|
||
*
|
||
* This source code is licensed under the BSD-style license found in the
|
||
* LICENSE file in the root directory of this source tree. An additional grant
|
||
* of patent rights can be found in the PATENTS file in the same directory.
|
||
*/
|
||
|
||
function Construct(realm, F, argumentsList, newTarget) {
|
||
// If newTarget was not passed, let newTarget be F.
|
||
if (!newTarget) newTarget = F;
|
||
|
||
// If argumentsList was not passed, let argumentsList be a new empty List.
|
||
if (!argumentsList) argumentsList = [];
|
||
|
||
// Assert: IsConstructor(F) is true.
|
||
(0, _invariant2.default)((0, _is.IsConstructor)(realm, F), "expected constructor");
|
||
|
||
// Assert: IsConstructor(newTarget) is true.
|
||
(0, _invariant2.default)((0, _is.IsConstructor)(realm, newTarget), "expected constructor");
|
||
|
||
// Return ? F.[[Construct]](argumentsList, newTarget).
|
||
(0, _invariant2.default)(F.$Construct !== undefined, "no construct method on realm value");
|
||
return F.$Construct(argumentsList, newTarget);
|
||
}
|
||
|
||
// ECMA262 7.3.20
|
||
function SpeciesConstructor(realm, O, defaultConstructor) {
|
||
// 1. Assert: Type(O) is Object.
|
||
(0, _invariant2.default)(O instanceof _index.ObjectValue, "Type(O) is Object");
|
||
|
||
// 2. Let C be ? Get(O, "constructor").
|
||
var C = (0, _get.Get)(realm, O, "constructor");
|
||
|
||
// 3. If C is undefined, return defaultConstructor.
|
||
if (C instanceof _index.UndefinedValue) return defaultConstructor;
|
||
|
||
// 4. If Type(C) is not Object, throw a TypeError exception.
|
||
if (C.mightNotBeObject()) {
|
||
if (C.mightBeObject()) C.throwIfNotConcrete();
|
||
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "Type(C) is not an object");
|
||
}
|
||
(0, _invariant2.default)(C instanceof _index.ObjectValue || C instanceof _index.AbstractObjectValue);
|
||
|
||
// 5. Let S be ? Get(C, @@species).
|
||
var S = (0, _get.Get)(realm, C, realm.intrinsics.SymbolSpecies);
|
||
|
||
// 6. If S is either undefined or null, return defaultConstructor.
|
||
if ((0, _has.HasSomeCompatibleType)(S, _index.UndefinedValue, _index.NullValue)) return defaultConstructor;
|
||
|
||
// 7. If IsConstructor(S) is true, return S.
|
||
if ((0, _is.IsConstructor)(realm, S)) {
|
||
(0, _invariant2.default)(S instanceof _index.ObjectValue);
|
||
return S;
|
||
}
|
||
|
||
// 8. Throw a TypeError exception.
|
||
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "Throw a TypeError exception");
|
||
}
|
||
|
||
// ECMA 9.2.9
|
||
function MakeClassConstructor(realm, F) {
|
||
// 1. Assert: F is an ECMAScript function object.
|
||
(0, _invariant2.default)(F instanceof _index.ECMAScriptSourceFunctionValue, "expected function value");
|
||
|
||
// 2. Assert: F’s [[FunctionKind]] internal slot is "normal".
|
||
(0, _invariant2.default)(F.$FunctionKind === "normal");
|
||
|
||
// 3. Set F’s [[FunctionKind]] internal slot to "classConstructor".
|
||
F.$FunctionKind = "classConstructor";
|
||
|
||
// 4. Return NormalCompletion(undefined).
|
||
return realm.intrinsics.undefined;
|
||
}
|
||
|
||
// ECMA 14.5.3
|
||
function ConstructorMethod(realm, ClassElementList) {
|
||
var ClassElement = void 0;
|
||
// ClassElementList : ClassElement
|
||
if (ClassElementList.length === 1) {
|
||
ClassElement = ClassElementList[0];
|
||
// 1. If ClassElement is the production ClassElement : ; , return empty.
|
||
// It looks like Babel parses out ClassElements that are only ;
|
||
|
||
// 2. If IsStatic of ClassElement is true, return empty.
|
||
if ((0, _is.IsStatic)(ClassElement)) {
|
||
return realm.intrinsics.empty;
|
||
}
|
||
// 3. If PropName of ClassElement is not "constructor", return empty.
|
||
if (ClassElement.key.name !== "constructor") {
|
||
return realm.intrinsics.empty;
|
||
}
|
||
|
||
// 4. Return ClassElement.
|
||
return ClassElement;
|
||
} else {
|
||
// ClassElementList : ClassElementList ClassElement
|
||
// 1. Let head be ConstructorMethod of ClassElementList.
|
||
var head = ConstructorMethod(realm, ClassElementList.slice(0, -1));
|
||
// 2. If head is not empty, return head.
|
||
if (!(head instanceof _index.EmptyValue)) {
|
||
return head;
|
||
}
|
||
|
||
ClassElement = ClassElementList[ClassElementList.length - 1];
|
||
// 3. If ClassElement is the production ClassElement : ; , return empty.
|
||
// It looks like Babel parses out ClassElements that are only ;
|
||
|
||
// 4. If IsStatic of ClassElement is true, return empty.
|
||
if ((0, _is.IsStatic)(ClassElement)) {
|
||
return realm.intrinsics.empty;
|
||
}
|
||
// If PropName of ClassElement is not "constructor", return empty.
|
||
if (ClassElement.key.name !== "constructor") {
|
||
return realm.intrinsics.empty;
|
||
}
|
||
|
||
// Return ClassElement.
|
||
return ClassElement;
|
||
}
|
||
}
|
||
|
||
// ECMA 14.5.10
|
||
function NonConstructorMethodDefinitions(realm, ClassElementList) {
|
||
var ClassElement = void 0;
|
||
// ClassElementList : ClassElement
|
||
if (ClassElementList.length === 1) {
|
||
ClassElement = ClassElementList[0];
|
||
// If ClassElement is the production ClassElement : ; , return a new empty List.
|
||
|
||
// If IsStatic of ClassElement is false and PropName of ClassElement is "constructor", return a new empty List.
|
||
if (!(0, _is.IsStatic)(ClassElement) && ClassElement.key.name === "constructor") {
|
||
return [];
|
||
}
|
||
// Return a List containing ClassElement.
|
||
return [ClassElement];
|
||
} else {
|
||
// ClassElementList : ClassElementList ClassElement
|
||
ClassElement = ClassElementList[ClassElementList.length - 1];
|
||
|
||
// Let list be NonConstructorMethodDefinitions of ClassElementList.
|
||
var list = NonConstructorMethodDefinitions(realm, ClassElementList.slice(0, -1));
|
||
|
||
// If ClassElement is the production ClassElement : ; , return list.
|
||
|
||
// If IsStatic of ClassElement is false and PropName of ClassElement is "constructor", return list.
|
||
if (!(0, _is.IsStatic)(ClassElement) && ClassElement.key.name === "constructor") {
|
||
return list;
|
||
}
|
||
|
||
// Append ClassElement to the end of list.
|
||
list.push(ClassElement);
|
||
|
||
// Return list.
|
||
return list;
|
||
}
|
||
}
|
||
//# sourceMappingURL=construct.js.map
|