UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

134 lines (109 loc) 5.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PreludeGenerator = exports.DisablePlaceholderSuffix = exports.Placeholders = void 0; var t = _interopRequireWildcard(require("@babel/types")); var _babelhelpers = require("./babelhelpers.js"); var _NameGenerator = require("./NameGenerator.js"); var _template = _interopRequireDefault(require("@babel/template")); var _invariant = _interopRequireDefault(require("../invariant.js")); 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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } /** * 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. */ const Placeholders = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); exports.Placeholders = Placeholders; const placeholderDefaultWhiteList = new Set(["global"]); const placeholderWhitelist = new Set([...placeholderDefaultWhiteList, ...Placeholders]); const DisablePlaceholderSuffix = "// disable placeholders"; exports.DisablePlaceholderSuffix = DisablePlaceholderSuffix; class PreludeGenerator { constructor(debugNames, uniqueSuffix) { this.prelude = []; this.memoizedRefs = new Map(); this.nameGenerator = new _NameGenerator.NameGenerator(new Set(), !!debugNames, uniqueSuffix || "", "_$"); this.usesThis = false; this.declaredGlobals = new Set(); this.nextInvariantId = 0; this._expressionTemplates = new Map(); } createNameGenerator(prefix) { return new _NameGenerator.NameGenerator(this.nameGenerator.forbiddenNames, this.nameGenerator.debugNames, this.nameGenerator.uniqueSuffix, prefix); } convertStringToMember(str) { return str.split(".").map(name => { if (name === "global") { return this.memoizeReference(name); } else if (name === "this") { return t.thisExpression(); } else { return t.identifier(name); } }).reduce((obj, prop) => t.memberExpression(obj, prop)); } globalReference(key, globalScope = false) { if (globalScope && t.isValidIdentifier(key)) return t.identifier(key); return (0, _babelhelpers.memberExpressionHelper)(this.memoizeReference("global"), key); } memoizeReference(key) { let ref = this.memoizedRefs.get(key); if (ref) return ref; let init; if (key.includes("(") || key.includes("[")) { // Horrible but effective hack: // Some internal object have intrinsic names such as // ([][Symbol.iterator]().__proto__.__proto__) // and // RegExp.prototype[Symbol.match] // which get turned into a babel node here. // TODO: We should properly parse such a string, and memoize all references in it separately. // Instead, we just turn it into a funky identifier, which Babel seems to accept. init = t.identifier(key); } else if (key === "global") { this.usesThis = true; init = t.thisExpression(); } else { let i = key.lastIndexOf("."); if (i === -1) { init = t.memberExpression(this.memoizeReference("global"), t.identifier(key)); } else { init = t.memberExpression(this.memoizeReference(key.substr(0, i)), t.identifier(key.substr(i + 1))); } } ref = t.identifier(this.nameGenerator.generate(key)); this.prelude.push(t.variableDeclaration("var", [t.variableDeclarator(ref, init)])); this.memoizedRefs.set(key, ref); return ref; } buildExpression(code, templateArguments) { let disablePlaceholders = false; const key = code; let template = this._expressionTemplates.get(key); if (template === undefined) { if (code.endsWith(DisablePlaceholderSuffix)) { code = code.substring(0, code.length - DisablePlaceholderSuffix.length); disablePlaceholders = true; } template = (0, _template.default)(code, { placeholderPattern: false, placeholderWhitelist: disablePlaceholders ? placeholderDefaultWhiteList : placeholderWhitelist }); this._expressionTemplates.set(key, template); } if (code.includes("global")) templateArguments = Object.assign({ global: this.memoizeReference("global") }, templateArguments); let result = template(templateArguments).expression; (0, _invariant.default)(result !== undefined, "Code does not represent an expression: " + code); return result; } } exports.PreludeGenerator = PreludeGenerator; //# sourceMappingURL=PreludeGenerator.js.map