224 lines
14 KiB
JavaScript
224 lines
14 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
|
|
* 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.
|
|
*/
|
|
|
|
exports.getInitialProps = getInitialProps;
|
|
exports.getInitialContext = getInitialContext;
|
|
exports.createSimpleClassInstance = createSimpleClassInstance;
|
|
exports.createClassInstance = createClassInstance;
|
|
|
|
var _realm = require("../realm.js");
|
|
|
|
var _index = require("../values/index.js");
|
|
|
|
var _utils = require("../flow/utils.js");
|
|
|
|
var _babelTypes = require("babel-types");
|
|
|
|
var t = _interopRequireWildcard(_babelTypes);
|
|
|
|
var _abstractObjectFactories = require("../flow/abstractObjectFactories.js");
|
|
|
|
var _utils2 = require("./utils");
|
|
|
|
var _errors = require("./errors.js");
|
|
|
|
var _index2 = require("../methods/index.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 }; }
|
|
|
|
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; } }
|
|
|
|
var lifecycleMethods = new Set(["componentWillUnmount", "componentDidMount", "componentWillMount", "componentDidUpdate", "componentWillUpdate", "componentDidCatch", "componentWillReceiveProps"]);
|
|
|
|
function getInitialProps(realm, componentType) {
|
|
var propsName = null;
|
|
var propTypes = null;
|
|
if ((0, _utils2.valueIsClassComponent)(realm, componentType)) {
|
|
propsName = "this.props";
|
|
// if flow is not required, do not try to construct the object from Flow types
|
|
if (realm.react.flowRequired) {
|
|
// it's a class component, so we need to check the type on for props of the component prototype
|
|
var superTypeParameters = componentType.$SuperTypeParameters;
|
|
if (superTypeParameters !== undefined) {
|
|
throw new _errors.ExpectedBailOut("props on class components not yet supported");
|
|
}
|
|
}
|
|
} else {
|
|
// otherwise it's a functional component, where the first paramater of the function is "props" (if it exists)
|
|
if (componentType.$FormalParameters.length > 0) {
|
|
var firstParam = componentType.$FormalParameters[0];
|
|
if (t.isIdentifier(firstParam)) {
|
|
propsName = firstParam.name;
|
|
}
|
|
// if flow is not required, do not try to construct the object from Flow types
|
|
if (realm.react.flowRequired) {
|
|
var propsTypeAnnotation = firstParam.typeAnnotation !== undefined && firstParam.typeAnnotation;
|
|
// we expect that if there's a props paramater, it should always have Flow annotations
|
|
if (!propsTypeAnnotation) {
|
|
throw new _errors.ExpectedBailOut("root component missing Flow type annotations for the \"props\" paramater");
|
|
}
|
|
propTypes = (0, _utils.flowAnnotationToObjectTypeTemplate)(propsTypeAnnotation);
|
|
}
|
|
}
|
|
}
|
|
return (0, _abstractObjectFactories.createAbstractObjectFromFlowTypes)(realm, propsName, propTypes);
|
|
}
|
|
|
|
function getInitialContext(realm, componentType) {
|
|
var contextName = null;
|
|
var contextTypes = null;
|
|
if ((0, _utils2.valueIsClassComponent)(realm, componentType)) {
|
|
// it's a class component, so we need to check the type on for context of the component prototype
|
|
var superTypeParameters = componentType.$SuperTypeParameters;
|
|
contextName = "this.context";
|
|
|
|
if (superTypeParameters !== undefined) {
|
|
throw new _errors.ExpectedBailOut("context on class components not yet supported");
|
|
}
|
|
} else {
|
|
// otherwise it's a functional component, where the second paramater of the function is "context" (if it exists)
|
|
if (componentType.$FormalParameters.length > 1) {
|
|
var secondParam = componentType.$FormalParameters[1];
|
|
if (t.isIdentifier(secondParam)) {
|
|
contextName = secondParam.name;
|
|
}
|
|
var contextTypeAnnotation = secondParam.typeAnnotation !== undefined && secondParam.typeAnnotation;
|
|
// we expect that if there's a context param, it should always have Flow annotations
|
|
if (!contextTypeAnnotation) {
|
|
throw new _errors.ExpectedBailOut("root component missing Flow type annotations for the \"context\" paramater");
|
|
}
|
|
contextTypes = (0, _utils.flowAnnotationToObjectTypeTemplate)(contextTypeAnnotation);
|
|
}
|
|
}
|
|
return (0, _abstractObjectFactories.createAbstractObjectFromFlowTypes)(realm, contextName, contextTypes);
|
|
}
|
|
|
|
function createSimpleClassInstance(realm, componentType, props, context) {
|
|
var componentPrototype = (0, _index2.Get)(realm, componentType, "prototype");
|
|
(0, _invariant2.default)(componentPrototype instanceof _index.ObjectValue);
|
|
// create an instance object and disable serialization as we don't want to output the internals we set below
|
|
var instance = new _index.ObjectValue(realm, componentPrototype, "this", true);
|
|
var allowedPropertyAccess = new Set(["props", "context"]);
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = componentPrototype.properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var _ref = _step.value;
|
|
|
|
var _ref2 = _slicedToArray(_ref, 1);
|
|
|
|
var name = _ref2[0];
|
|
|
|
if (lifecycleMethods.has(name)) {
|
|
// this error will result in the simple class falling back to a complex class
|
|
throw new _errors.SimpleClassBailOut("lifecycle methods are not supported on simple classes");
|
|
} else if (name !== "constructor") {
|
|
allowedPropertyAccess.add(name);
|
|
_singletons.Properties.Set(realm, instance, name, (0, _index2.Get)(realm, componentPrototype, name), true);
|
|
}
|
|
}
|
|
// assign props
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
_singletons.Properties.Set(realm, instance, "props", props, true);
|
|
// assign context
|
|
_singletons.Properties.Set(realm, instance, "context", context, true);
|
|
// as this object is simple, we want to check if any access to anything other than
|
|
// "this.props" or "this.context" or methods on the class occur
|
|
var $GetOwnProperty = instance.$GetOwnProperty;
|
|
instance.$GetOwnProperty = function (P) {
|
|
if (!allowedPropertyAccess.has(P)) {
|
|
// this error will result in the simple class falling back to a complex class
|
|
throw new _errors.SimpleClassBailOut("access to basic class instance properties is not supported on simple classes");
|
|
}
|
|
return $GetOwnProperty.call(instance, P);
|
|
};
|
|
// enable serialization to support simple instance variables properties
|
|
instance.refuseSerialization = false;
|
|
// return the instance
|
|
return instance;
|
|
}
|
|
|
|
function createClassInstance(realm, componentType, props, context) {
|
|
var componentPrototype = (0, _index2.Get)(realm, componentType, "prototype");
|
|
(0, _invariant2.default)(componentPrototype instanceof _index.ObjectValue);
|
|
// create an instance object and disable serialization as we don't want to output the internals we set below
|
|
var instance = new _index.ObjectValue(realm, componentPrototype, "this", true);
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = componentPrototype.properties[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var _ref3 = _step2.value;
|
|
|
|
var _ref4 = _slicedToArray(_ref3, 1);
|
|
|
|
var name = _ref4[0];
|
|
|
|
if (name !== "constructor") {
|
|
_singletons.Properties.Set(realm, instance, name, (0, _index2.Get)(realm, componentPrototype, name), true);
|
|
}
|
|
}
|
|
// assign state
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
|
|
_singletons.Properties.Set(realm, instance, "state", (0, _abstractObjectFactories.createAbstractObject)(realm, "this.state", null), true);
|
|
// assign refs
|
|
_singletons.Properties.Set(realm, instance, "refs", (0, _abstractObjectFactories.createAbstractObject)(realm, "this.refs", null), true);
|
|
// assign props
|
|
_singletons.Properties.Set(realm, instance, "props", props, true);
|
|
// assign context
|
|
_singletons.Properties.Set(realm, instance, "context", context, true);
|
|
// enable serialization to support simple instance variables properties
|
|
instance.refuseSerialization = false;
|
|
// return the instance in an abstract object
|
|
return (0, _abstractObjectFactories.createAbstractObject)(realm, "this", null, instance);
|
|
}
|
|
//# sourceMappingURL=components.js.map
|