prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
140 lines (116 loc) • 6.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createReactElement = createReactElement;
var _index = require("../values/index.js");
var _singletons = require("../singletons.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _index2 = require("../methods/index.js");
var _utils = require("./utils.js");
var _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
var _BinaryExpression = require("../evaluators/BinaryExpression.js");
var _errors = require("../errors.js");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createPropsObject(realm, type, config, children) {
let defaultProps = type instanceof _index.ObjectValue ? (0, _index2.Get)(realm, type, "defaultProps") : realm.intrinsics.undefined;
let props = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
// start by having key and ref deleted, if they actually exist, they will be add later
(0, _utils.deleteRefAndKeyFromProps)(realm, props);
let key = realm.intrinsics.null;
let ref = realm.intrinsics.null;
const setProp = (name, value) => {
if (name === "key" && value !== realm.intrinsics.null) {
key = (0, _BinaryExpression.computeBinary)(realm, "+", realm.intrinsics.emptyString, value);
} else if (name === "ref") {
ref = value;
} else if (name !== "__self" && name !== "__source") {
(0, _invariant2.default)(props instanceof _index.ObjectValue);
_singletons.Properties.Set(realm, props, name, value, true);
}
};
if (config instanceof _index.AbstractObjectValue && config.isPartialObject() || config instanceof _index.AbstractValue || config instanceof _index.ObjectValue && config.isPartialObject() && config.isSimpleObject()) {
// if we have defaultProps, we need to create a new merge of the objects along with our config
if (defaultProps !== realm.intrinsics.undefined || children !== realm.intrinsics.undefined) {
if ((0, _utils.objectHasNoPartialKeyAndRef)(realm, config)) {
let args = [];
if (defaultProps !== realm.intrinsics.undefined) {
args.push(defaultProps);
}
args.push(config);
// create a new props object that will be the target of the Object.assign
props = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
// as this is "props" that is abstract, we need to make it partial and simple
props.makePartial();
props.makeSimple();
// props objects also don't have a key and ref, so we remove them
(0, _utils.deleteRefAndKeyFromProps)(realm, props);
// get the global Object.assign
let globalObj = (0, _index2.Get)(realm, realm.$GlobalObject, "Object");
(0, _invariant2.default)(globalObj instanceof _index.ObjectValue);
let objAssign = (0, _index2.Get)(realm, globalObj, "assign");
(0, _invariant2.default)(realm.generator);
_index.AbstractValue.createTemporalFromBuildFunction(realm, _index.FunctionValue, [objAssign, props, ...args], ([methodNode, ..._args]) => {
return t.callExpression(methodNode, _args);
});
if (children !== realm.intrinsics.undefined) {
setProp("children", children);
}
} else {
// if either are abstract, this will impact the reconcilation process
// and ultimately prevent us from folding ReactElements properly
let diagnostic = new _errors.CompilerDiagnostic(`unable to evaluate "key" and "ref" on a ReactElement due to an abstract config passed to createElement`, realm.currentLocation, "PP0025", "FatalError");
realm.handleError(diagnostic);
if (realm.handleError(diagnostic) === "Fail") throw new _errors.FatalError();
}
} else {
// as the config is partial and simple, we don't know about its prototype or properties
// we don't have to worry about non-enumerable properties as its properties will never
// be serialized, rather this object will be serialized as a spread.
props = config;
}
} else {
if (config instanceof _index.ObjectValue) {
for (let [propKey, binding] of config.properties) {
if (binding && binding.descriptor && binding.descriptor.enumerable) {
setProp(propKey, (0, _index2.Get)(realm, config, propKey));
}
}
}
if (children !== realm.intrinsics.undefined) {
setProp("children", children);
}
if (defaultProps instanceof _index.ObjectValue) {
for (let [propKey, binding] of defaultProps.properties) {
if (binding && binding.descriptor && binding.descriptor.enumerable) {
if ((0, _index2.Get)(realm, props, propKey) === realm.intrinsics.undefined) {
setProp(propKey, (0, _index2.Get)(realm, defaultProps, propKey));
}
}
}
}
}
return { key, props, ref };
} /**
* 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 createReactElement(realm, type, config, children) {
let { key, props, ref } = createPropsObject(realm, type, config, children);
let obj = _singletons.Create.ObjectCreate(realm, realm.intrinsics.ObjectPrototype);
_singletons.Create.CreateDataPropertyOrThrow(realm, obj, "$$typeof", (0, _utils.getReactSymbol)("react.element", realm));
_singletons.Create.CreateDataPropertyOrThrow(realm, obj, "type", type);
_singletons.Create.CreateDataPropertyOrThrow(realm, obj, "key", key);
_singletons.Create.CreateDataPropertyOrThrow(realm, obj, "ref", ref);
_singletons.Create.CreateDataPropertyOrThrow(realm, obj, "props", props);
_singletons.Create.CreateDataPropertyOrThrow(realm, obj, "_owner", realm.intrinsics.null);
return obj;
}
//# sourceMappingURL=elements.js.map