first commit

This commit is contained in:
s.golasch
2023-08-01 13:49:46 +02:00
commit 1fc239fd54
20238 changed files with 3112246 additions and 0 deletions

239
build/node_modules/prepack/lib/serializer/visitors.js generated vendored Normal file
View File

@@ -0,0 +1,239 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ClosureRefVisitor = exports.ClosureRefReplacer = undefined;
var _realm = require("../realm.js");
var _index = require("../values/index.js");
var _babelTypes = require("babel-types");
var t = _interopRequireWildcard(_babelTypes);
var _jsx = require("../react/jsx");
var _internalizer = require("../utils/internalizer.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 markVisited(node, data) {
node._renamedOnce = data;
} /**
* 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 shouldVisit(node, data) {
return node._renamedOnce !== data;
}
// replaceWith causes the node to be re-analyzed, so to prevent double replacement
// we add this property on the node to mark it such that it does not get replaced
// again on this pass
// TODO: Make this work when replacing with arbitrary BabelNodeExpressions. Currently
// if the node that we're substituting contains identifiers as children,
// they will be visited again and possibly transformed.
// If necessary we could implement this by following node.parentPath and checking
// if any parent nodes are marked visited, but that seem unnecessary right now.let closureRefReplacer = {
function replaceName(path, residualFunctionBinding, name, data) {
if (path.scope.hasBinding(name, /*noGlobals*/true)) return;
if (residualFunctionBinding && shouldVisit(path.node, data)) {
markVisited(residualFunctionBinding.serializedValue, data);
var serializedValue = residualFunctionBinding.serializedValue;
if (path.node.type === "JSXIdentifier" || path.node.type === "JSXMemberIdentifier") {
path.replaceWith((0, _jsx.convertExpressionToJSXIdentifier)(serializedValue, true));
} else {
path.replaceWith(serializedValue);
}
}
}
function getLiteralTruthiness(node) {
// In the return value, 'known' is true only if this is a literal of known truthiness and with no side effects; if 'known' is true, 'value' is its truthiness.
if (t.isBooleanLiteral(node) || t.isNumericLiteral(node) || t.isStringLiteral(node)) {
return { known: true, value: !!node.value };
}
if (t.isFunctionExpression(node) || t.isArrowFunctionExpression(node) || t.isRegExpLiteral(node) || t.isClassExpression(node) && node.superClass === null && node.body.body.length === 0 || t.isObjectExpression(node) && node.properties.length === 0 || t.isArrayExpression(node) && node.elements.length === 0) {
return { known: true, value: true };
}
if (t.isNullLiteral(node)) {
return { known: true, value: false };
}
return { known: false };
}
function canShareFunctionBody(duplicateFunctionInfo) {
// Only share function when:
// 1. it does not access any free variables.
// 2. it does not use "this".
var _duplicateFunctionInf = duplicateFunctionInfo.functionInfo,
unbound = _duplicateFunctionInf.unbound,
modified = _duplicateFunctionInf.modified,
usesThis = _duplicateFunctionInf.usesThis;
return unbound.size === 0 && modified.size === 0 && !usesThis;
}
var ClosureRefReplacer = exports.ClosureRefReplacer = {
ReferencedIdentifier: function ReferencedIdentifier(path, state) {
if (ignorePath(path)) return;
var residualFunctionBindings = state.residualFunctionBindings;
var name = path.node.name;
var residualFunctionBinding = residualFunctionBindings.get(name);
if (residualFunctionBinding) replaceName(path, residualFunctionBinding, name, residualFunctionBindings);
},
CallExpression: function CallExpression(path, state) {
// Here we apply the require optimization by replacing require calls with their
// corresponding initialized modules.
var requireReturns = state.requireReturns;
if (!state.isRequire || !state.isRequire(path.scope, path.node)) return;
state.requireStatistics.count++;
if (state.modified.has(path.node.callee.name)) return;
var moduleId = "" + path.node.arguments[0].value;
var new_node = requireReturns.get(moduleId);
if (new_node !== undefined) {
markVisited(new_node, state.residualFunctionBindings);
path.replaceWith(new_node);
state.requireStatistics.replaced++;
}
},
"AssignmentExpression|UpdateExpression": function AssignmentExpressionUpdateExpression(path, state) {
var residualFunctionBindings = state.residualFunctionBindings;
var ids = path.getBindingIdentifierPaths();
for (var name in ids) {
var residualFunctionBinding = residualFunctionBindings.get(name);
if (residualFunctionBinding) {
var nestedPath = ids[name];
replaceName(nestedPath, residualFunctionBinding, name, residualFunctionBindings);
}
}
},
// TODO: handle FunctionDeclaration.
// Replace "function () {}" ==> "factory_id.bind(null)".
FunctionExpression: function FunctionExpression(path, state) {
if (t.isProgram(path.parentPath.parentPath.node)) {
// Our goal is replacing duplicate nested function so skip root residual function itself.
// This assumes the root function is wrapped with: t.file(t.program([t.expressionStatement(rootFunction).
return;
}
var functionExpression = path.node;
var functionTag = functionExpression.body.uniqueOrderedTag;
if (!functionTag) {
// Un-interpreted nested function.
return;
}
var duplicateFunctionInfo = state.factoryFunctionInfos.get(functionTag);
if (duplicateFunctionInfo && canShareFunctionBody(duplicateFunctionInfo)) {
var factoryId = duplicateFunctionInfo.factoryId;
path.replaceWith(t.callExpression(t.memberExpression(factoryId, t.identifier("bind")), [_internalizer.nullExpression]));
}
},
// A few very simple dead code elimination helpers. Eventually these should be subsumed by the partial evaluators.
IfStatement: {
exit: function exit(path, state) {
var node = path.node;
var testTruthiness = getLiteralTruthiness(node.test);
if (testTruthiness.known) {
if (testTruthiness.value) {
// Strictly speaking this is not safe: Annex B.3.4 allows FunctionDeclarations as the body of IfStatements in sloppy mode,
// which have weird hoisting behavior: `console.log(typeof f); if (true) function f(){} console.log(typeof f)` will print 'undefined', 'function', but
// `console.log(typeof f); function f(){} console.log(typeof f)` will print 'function', 'function'.
// However, Babylon can't parse these, so it doesn't come up.
path.replaceWith(node.consequent);
} else {
if (node.alternate !== null) {
path.replaceWith(node.alternate);
} else {
path.remove();
}
}
}
}
},
ConditionalExpression: {
exit: function exit(path, state) {
var node = path.node;
var testTruthiness = getLiteralTruthiness(node.test);
if (testTruthiness.known) {
path.replaceWith(testTruthiness.value ? node.consequent : node.alternate);
}
}
},
LogicalExpression: {
exit: function exit(path, state) {
var node = path.node;
var leftTruthiness = getLiteralTruthiness(node.left);
if (node.operator === "&&" && leftTruthiness.known) {
path.replaceWith(leftTruthiness.value ? node.right : node.left);
} else if (node.operator === "||" && leftTruthiness.known) {
path.replaceWith(leftTruthiness.value ? node.left : node.right);
}
}
},
WhileStatement: {
exit: function exit(path, state) {
var node = path.node;
var testTruthiness = getLiteralTruthiness(node.test);
if (testTruthiness.known && !testTruthiness.value) {
path.remove();
}
}
}
};
function visitName(path, state, name, modified) {
// Is the name bound to some local identifier? If so, we don't need to do anything
if (path.scope.hasBinding(name, /*noGlobals*/true)) return;
// Otherwise, let's record that there's an unbound identifier
state.functionInfo.unbound.add(name);
if (modified) state.functionInfo.modified.add(name);
}
function ignorePath(path) {
var parent = path.parent;
return t.isLabeledStatement(parent) || t.isBreakStatement(parent) || t.isContinueStatement(parent);
}
// TODO #886: doesn't check that `arguments` and `this` is in top function
var ClosureRefVisitor = exports.ClosureRefVisitor = {
ReferencedIdentifier: function ReferencedIdentifier(path, state) {
if (ignorePath(path)) return;
var innerName = path.node.name;
if (innerName === "arguments") {
state.functionInfo.usesArguments = true;
return;
}
visitName(path, state, innerName, false);
},
ThisExpression: function ThisExpression(path, state) {
state.functionInfo.usesThis = true;
},
"AssignmentExpression|UpdateExpression": function AssignmentExpressionUpdateExpression(path, state) {
for (var name in path.getBindingIdentifiers()) {
visitName(path, state, name, true);
}
}
};
//# sourceMappingURL=visitors.js.map