Files
asciidisco.com/build/node_modules/prepack/lib/react/utils.js
2023-08-01 13:49:46 +02:00

255 lines
9.9 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isReactElement = isReactElement;
exports.getReactSymbol = getReactSymbol;
exports.isTagName = isTagName;
exports.isReactComponent = isReactComponent;
exports.valueIsClassComponent = valueIsClassComponent;
exports.valueIsReactLibraryObject = valueIsReactLibraryObject;
exports.valueIsLegacyCreateClassComponent = valueIsLegacyCreateClassComponent;
exports.addKeyToReactElement = addKeyToReactElement;
exports.getUniqueReactElementKey = getUniqueReactElementKey;
exports.mapOverArrayValue = mapOverArrayValue;
exports.convertSimpleClassComponentToFunctionalComponent = convertSimpleClassComponentToFunctionalComponent;
var _realm = require("../realm.js");
var _index = require("../values/index.js");
var _index2 = require("../methods/index.js");
var _BinaryExpression = require("../evaluators/BinaryExpression.js");
require("../serializer/types.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
var _singletons = require("../singletons.js");
var _babelTraverse = require("babel-traverse");
var _babelTraverse2 = _interopRequireDefault(_babelTraverse);
var _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
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 }; }
/**
* 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 isReactElement(val) {
if (val instanceof _index.ObjectValue && val.properties.has("$$typeof")) {
var realm = val.$Realm;
var $$typeof = (0, _index2.Get)(realm, val, "$$typeof");
var globalObject = realm.$GlobalObject;
var globalSymbolValue = (0, _index2.Get)(realm, globalObject, "Symbol");
if (globalSymbolValue === realm.intrinsics.undefined) {
if ($$typeof instanceof _index.NumberValue) {
return $$typeof.value === 0xeac7;
}
} else if ($$typeof instanceof _index.SymbolValue) {
var symbolFromRegistry = realm.globalSymbolRegistry.find(function (e) {
return e.$Symbol === $$typeof;
});
return symbolFromRegistry !== undefined && symbolFromRegistry.$Key === "react.element";
}
}
return false;
}
function getReactSymbol(symbolKey, realm) {
var reactSymbol = realm.react.symbols.get(symbolKey);
if (reactSymbol !== undefined) {
return reactSymbol;
}
var SymbolFor = realm.intrinsics.Symbol.properties.get("for");
if (SymbolFor !== undefined) {
var SymbolForDescriptor = SymbolFor.descriptor;
if (SymbolForDescriptor !== undefined) {
var SymbolForValue = SymbolForDescriptor.value;
if (SymbolForValue !== undefined && typeof SymbolForValue.$Call === "function") {
reactSymbol = SymbolForValue.$Call(realm.intrinsics.Symbol, [new _index.StringValue(realm, symbolKey)]);
realm.react.symbols.set(symbolKey, reactSymbol);
}
}
}
(0, _invariant2.default)(reactSymbol instanceof _index.SymbolValue, "Symbol(\"" + symbolKey + "\") could not be found in realm");
return reactSymbol;
}
function isTagName(ast) {
return ast.type === "JSXIdentifier" && /^[a-z]|\-/.test(ast.name);
}
function isReactComponent(name) {
return name.length > 0 && name[0] === name[0].toUpperCase();
}
function valueIsClassComponent(realm, value) {
if (!(value instanceof _index.FunctionValue)) {
return false;
}
if (value.$Prototype instanceof _index.ObjectValue) {
var prototype = (0, _index2.Get)(realm, value.$Prototype, "prototype");
if (prototype instanceof _index.ObjectValue) {
return prototype.properties.has("isReactComponent");
}
}
return false;
}
// logger isn't typed otherwise it will increase flow cycle length :()
function valueIsReactLibraryObject(realm, value, logger) {
if (realm.react.reactLibraryObject === value) {
return true;
}
// we check that the object is the React or React-like library by checking for
// core properties that should exist on it
var reactVersion = logger.tryQuery(function () {
return (0, _index2.Get)(realm, value, "version");
}, undefined, false);
if (!(reactVersion instanceof _index.StringValue)) {
return false;
}
var reactCreateElement = logger.tryQuery(function () {
return (0, _index2.Get)(realm, value, "createElement");
}, undefined, false);
if (!(reactCreateElement instanceof _index.FunctionValue)) {
return false;
}
var reactCloneElement = logger.tryQuery(function () {
return (0, _index2.Get)(realm, value, "cloneElement");
}, undefined, false);
if (!(reactCloneElement instanceof _index.FunctionValue)) {
return false;
}
var reactIsValidElement = logger.tryQuery(function () {
return (0, _index2.Get)(realm, value, "isValidElement");
}, undefined, false);
if (!(reactIsValidElement instanceof _index.FunctionValue)) {
return false;
}
var reactComponent = logger.tryQuery(function () {
return (0, _index2.Get)(realm, value, "Component");
}, undefined, false);
if (!(reactComponent instanceof _index.FunctionValue)) {
return false;
}
var reactChildren = logger.tryQuery(function () {
return (0, _index2.Get)(realm, value, "Children");
}, undefined, false);
if (!(reactChildren instanceof _index.ObjectValue)) {
return false;
}
return false;
}
function valueIsLegacyCreateClassComponent(realm, value) {
if (!(value instanceof _index.FunctionValue)) {
return false;
}
var prototype = (0, _index2.Get)(realm, value, "prototype");
if (prototype instanceof _index.ObjectValue) {
return prototype.properties.has("__reactAutoBindPairs");
}
return false;
}
function addKeyToReactElement(realm, reactSerializerState, reactElement) {
// we need to apply a key when we're branched
var currentKeyValue = (0, _index2.Get)(realm, reactElement, "key") || realm.intrinsics.null;
var uniqueKey = getUniqueReactElementKey("", reactSerializerState.usedReactElementKeys);
var newKeyValue = new _index.StringValue(realm, uniqueKey);
if (currentKeyValue !== realm.intrinsics.null) {
newKeyValue = (0, _BinaryExpression.computeBinary)(realm, "+", currentKeyValue, newKeyValue);
}
// TODO: This might not be safe in DEV because these objects are frozen (Object.freeze).
// We should probably go behind the scenes in this case to by-pass that.
reactElement.$Set("key", newKeyValue, reactElement);
}
// we create a unique key for each JSXElement to prevent collisions
// otherwise React will detect a missing/conflicting key at runtime and
// this can break the reconcilation of JSXElements in arrays
function getUniqueReactElementKey(index, usedReactElementKeys) {
var key = void 0;
do {
key = Math.random().toString(36).replace(/[^a-z]+/g, "").substring(0, 2);
} while (usedReactElementKeys.has(key));
usedReactElementKeys.add(key);
if (index !== undefined) {
return "" + key + index;
}
return key;
}
// a helper function to map over ArrayValues
function mapOverArrayValue(realm, array, mapFunc) {
var lengthValue = (0, _index2.Get)(realm, array, "length");
(0, _invariant2.default)(lengthValue instanceof _index.NumberValue, "Invalid length on ArrayValue during reconcilation");
var length = lengthValue.value;
for (var i = 0; i < length; i++) {
var elementProperty = array.properties.get("" + i);
var elementPropertyDescriptor = elementProperty && elementProperty.descriptor;
(0, _invariant2.default)(elementPropertyDescriptor, "Invalid ArrayValue[" + i + "] descriptor");
var elementValue = elementPropertyDescriptor.value;
if (elementValue instanceof _index.Value) {
mapFunc(elementValue, elementPropertyDescriptor);
}
}
}
function convertSimpleClassComponentToFunctionalComponent(realm, componentType, additionalFunctionEffects) {
var prototype = componentType.properties.get("prototype");
(0, _invariant2.default)(prototype);
(0, _invariant2.default)(prototype.descriptor);
prototype.descriptor.configurable = true;
_singletons.Properties.DeletePropertyOrThrow(realm, componentType, "prototype");
// set the prototype back to an object
componentType.$Prototype = realm.intrinsics.FunctionPrototype;
// give the function the functional components params
componentType.$FormalParameters = [t.identifier("props"), t.identifier("context")];
// add a transform to occur after the additional function has serialized the body of the class
additionalFunctionEffects.transforms.push(function (body) {
// as this was a class before and is now a functional component, we need to replace
// this.props and this.context to props and context, via the function arugments
var funcNode = t.functionExpression(null, [], t.blockStatement(body));
(0, _babelTraverse2.default)(t.file(t.program([t.expressionStatement(funcNode)])), {
"Identifier|ThisExpression": function IdentifierThisExpression(path) {
var node = path.node;
if (t.isIdentifier(node) && node.name === "this" || t.isThisExpression(node)) {
var parentPath = path.parentPath;
var parentNode = parentPath.node;
if (t.isMemberExpression(parentNode)) {
// remove the "this" from the member
parentPath.replaceWith(parentNode.property);
} else {
throw new _errors.FatalError("conversion of a simple class component to functional component failed due to \"this\" not being replaced");
}
}
}
}, undefined, undefined, undefined);
});
}
//# sourceMappingURL=utils.js.map