first commit
This commit is contained in:
624
build/node_modules/prepack/lib/utils/generator.js
generated
vendored
Normal file
624
build/node_modules/prepack/lib/utils/generator.js
generated
vendored
Normal file
@@ -0,0 +1,624 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.PreludeGenerator = exports.NameGenerator = exports.Generator = undefined;
|
||||
|
||||
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"); } }; }();
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
var _index = require("../values/index.js");
|
||||
|
||||
var _index2 = require("../domains/index.js");
|
||||
|
||||
var _base = require("base62");
|
||||
|
||||
var base62 = _interopRequireWildcard(_base);
|
||||
|
||||
var _babelTypes = require("babel-types");
|
||||
|
||||
var t = _interopRequireWildcard(_babelTypes);
|
||||
|
||||
var _invariant = require("../invariant.js");
|
||||
|
||||
var _invariant2 = _interopRequireDefault(_invariant);
|
||||
|
||||
var _internalizer = require("./internalizer.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)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function serializeBody(generator, context) {
|
||||
var statements = context.serializeGenerator(generator);
|
||||
return t.blockStatement(statements);
|
||||
}
|
||||
|
||||
var Generator = exports.Generator = function () {
|
||||
function Generator(realm, name) {
|
||||
_classCallCheck(this, Generator);
|
||||
|
||||
(0, _invariant2.default)(realm.useAbstractInterpretation);
|
||||
var realmPreludeGenerator = realm.preludeGenerator;
|
||||
(0, _invariant2.default)(realmPreludeGenerator);
|
||||
this.preludeGenerator = realmPreludeGenerator;
|
||||
this.parent = realm.generator;
|
||||
this.realm = realm;
|
||||
this._entries = [];
|
||||
this.id = realm.nextGeneratorId++;
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
_createClass(Generator, [{
|
||||
key: "getName",
|
||||
value: function getName() {
|
||||
return this._name || "#" + this.id;
|
||||
}
|
||||
}, {
|
||||
key: "getAsPropertyNameExpression",
|
||||
value: function getAsPropertyNameExpression(key) {
|
||||
var canBeIdentifier = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
||||
|
||||
// If key is a non-negative numeric string literal, parse it and set it as a numeric index instead.
|
||||
var index = Number.parseInt(key, 10);
|
||||
if (index >= 0 && index.toString() === key) {
|
||||
return t.numericLiteral(index);
|
||||
}
|
||||
|
||||
if (canBeIdentifier) {
|
||||
// TODO #1020: revert this when Unicode identifiers are supported by all targetted JavaScript engines
|
||||
var keyIsAscii = /^[\u0000-\u007f]*$/.test(key);
|
||||
if (t.isValidIdentifier(key) && keyIsAscii) return t.identifier(key);
|
||||
}
|
||||
|
||||
return t.stringLiteral(key);
|
||||
}
|
||||
}, {
|
||||
key: "getParent",
|
||||
value: function getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
}, {
|
||||
key: "empty",
|
||||
value: function empty() {
|
||||
return this._entries.length === 0;
|
||||
}
|
||||
|
||||
// Will force the array of Values to be serialized but not emit anything for a buildNode
|
||||
|
||||
}, {
|
||||
key: "appendRoots",
|
||||
value: function appendRoots(values) {
|
||||
this._addEntry({
|
||||
args: values
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitGlobalDeclaration",
|
||||
value: function emitGlobalDeclaration(key, value) {
|
||||
this.preludeGenerator.declaredGlobals.add(key);
|
||||
if (!(value instanceof _index.UndefinedValue)) this.emitGlobalAssignment(key, value, true);
|
||||
}
|
||||
}, {
|
||||
key: "emitGlobalAssignment",
|
||||
value: function emitGlobalAssignment(key, value, strictMode) {
|
||||
var _this = this;
|
||||
|
||||
this._addEntry({
|
||||
args: [value],
|
||||
buildNode: function buildNode(_ref) {
|
||||
var _ref2 = _slicedToArray(_ref, 1),
|
||||
valueNode = _ref2[0];
|
||||
|
||||
return t.expressionStatement(t.assignmentExpression("=", _this.preludeGenerator.globalReference(key, !strictMode), valueNode));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitGlobalDelete",
|
||||
value: function emitGlobalDelete(key, strictMode) {
|
||||
var _this2 = this;
|
||||
|
||||
this._addEntry({
|
||||
args: [],
|
||||
buildNode: function buildNode(_ref3) {
|
||||
var _ref4 = _toArray(_ref3);
|
||||
|
||||
return t.expressionStatement(t.unaryExpression("delete", _this2.preludeGenerator.globalReference(key, !strictMode)));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitBindingAssignment",
|
||||
value: function emitBindingAssignment(binding, value) {
|
||||
this._addEntry({
|
||||
args: [value],
|
||||
buildNode: function buildNode(_ref5, context) {
|
||||
var _ref6 = _slicedToArray(_ref5, 1),
|
||||
valueNode = _ref6[0];
|
||||
|
||||
return t.expressionStatement(t.assignmentExpression("=", context.serializeBinding(binding), valueNode));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitPropertyAssignment",
|
||||
value: function emitPropertyAssignment(object, key, value) {
|
||||
if (object.refuseSerialization) return;
|
||||
var propName = this.getAsPropertyNameExpression(key);
|
||||
this._addEntry({
|
||||
args: [object, value],
|
||||
buildNode: function buildNode(_ref7) {
|
||||
var _ref8 = _slicedToArray(_ref7, 2),
|
||||
objectNode = _ref8[0],
|
||||
valueNode = _ref8[1];
|
||||
|
||||
return t.expressionStatement(t.assignmentExpression("=", t.memberExpression(objectNode, propName, !t.isIdentifier(propName)), valueNode));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitDefineProperty",
|
||||
value: function emitDefineProperty(object, key, desc) {
|
||||
var isDescChanged = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
||||
|
||||
if (object.refuseSerialization) return;
|
||||
if (desc.enumerable && desc.configurable && desc.writable && desc.value && !isDescChanged) {
|
||||
var descValue = desc.value;
|
||||
(0, _invariant2.default)(descValue instanceof _index.Value);
|
||||
this.emitPropertyAssignment(object, key, descValue);
|
||||
} else {
|
||||
desc = Object.assign({}, desc);
|
||||
var _descValue = desc.value || object.$Realm.intrinsics.undefined;
|
||||
(0, _invariant2.default)(_descValue instanceof _index.Value);
|
||||
this._addEntry({
|
||||
args: [object, _descValue, desc.get || object.$Realm.intrinsics.undefined, desc.set || object.$Realm.intrinsics.undefined],
|
||||
buildNode: function buildNode(_, context) {
|
||||
return context.emitDefinePropertyBody(object, key, desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "emitPropertyDelete",
|
||||
value: function emitPropertyDelete(object, key) {
|
||||
if (object.refuseSerialization) return;
|
||||
var propName = this.getAsPropertyNameExpression(key);
|
||||
this._addEntry({
|
||||
args: [object],
|
||||
buildNode: function buildNode(_ref9) {
|
||||
var _ref10 = _slicedToArray(_ref9, 1),
|
||||
objectNode = _ref10[0];
|
||||
|
||||
return t.expressionStatement(t.unaryExpression("delete", t.memberExpression(objectNode, propName, !t.isIdentifier(propName))));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitCall",
|
||||
value: function emitCall(createCallee, args) {
|
||||
this._addEntry({
|
||||
args: args,
|
||||
buildNode: function buildNode(values) {
|
||||
return t.expressionStatement(t.callExpression(createCallee(), [].concat(_toConsumableArray(values))));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitConsoleLog",
|
||||
value: function emitConsoleLog(method, args) {
|
||||
var _this3 = this;
|
||||
|
||||
this.emitCall(function () {
|
||||
return t.memberExpression(t.identifier("console"), t.identifier(method));
|
||||
}, args.map(function (v) {
|
||||
return typeof v === "string" ? new _index.StringValue(_this3.realm, v) : v;
|
||||
}));
|
||||
}
|
||||
|
||||
// test must be a temporal value, which means that it must have a defined intrinsicName
|
||||
|
||||
}, {
|
||||
key: "emitDoWhileStatement",
|
||||
value: function emitDoWhileStatement(test, body) {
|
||||
this._addEntry({
|
||||
args: [],
|
||||
buildNode: function buildNode(_ref11, context) {
|
||||
var _ref12 = _toArray(_ref11);
|
||||
|
||||
var testId = test.intrinsicName;
|
||||
(0, _invariant2.default)(testId !== undefined);
|
||||
var statements = context.serializeGenerator(body);
|
||||
var block = t.blockStatement(statements);
|
||||
return t.doWhileStatement(t.identifier(testId), block);
|
||||
},
|
||||
dependencies: [body]
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitInvariant",
|
||||
value: function emitInvariant(args, violationConditionFn, appendLastToInvariantFn) {
|
||||
if (this.realm.omitInvariants) return;
|
||||
this._addEntry({
|
||||
args: args,
|
||||
buildNode: function buildNode(nodes) {
|
||||
var throwString = t.stringLiteral("Prepack model invariant violation");
|
||||
if (appendLastToInvariantFn) {
|
||||
var last = nodes.pop();
|
||||
throwString = t.binaryExpression("+", t.stringLiteral("Prepack model invariant violation: "), appendLastToInvariantFn(last));
|
||||
}
|
||||
var condition = violationConditionFn(nodes);
|
||||
var throwblock = t.blockStatement([t.throwStatement(t.newExpression(t.identifier("Error"), [throwString]))]);
|
||||
return t.ifStatement(condition, throwblock);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitCallAndCaptureResult",
|
||||
value: function emitCallAndCaptureResult(types, values, createCallee, args, kind) {
|
||||
return this.derive(types, values, args, function (nodes) {
|
||||
return t.callExpression(createCallee(), nodes);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitStatement",
|
||||
value: function emitStatement(args, buildNode_) {
|
||||
this._addEntry({
|
||||
args: args,
|
||||
buildNode: buildNode_
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "emitVoidExpression",
|
||||
value: function emitVoidExpression(types, values, args, buildNode_) {
|
||||
this._addEntry({
|
||||
args: args,
|
||||
buildNode: function buildNode(nodes) {
|
||||
return t.expressionStatement(buildNode_ instanceof Function ? buildNode_(nodes) : buildNode_);
|
||||
}
|
||||
});
|
||||
return this.realm.intrinsics.undefined;
|
||||
}
|
||||
}, {
|
||||
key: "emitForInStatement",
|
||||
value: function emitForInStatement(o, lh, sourceObject, targetObject, boundName) {
|
||||
this._addEntry({
|
||||
// duplicate args to ensure refcount > 1
|
||||
args: [o, targetObject, sourceObject, targetObject, sourceObject],
|
||||
buildNode: function buildNode(_ref13) {
|
||||
var _ref14 = _slicedToArray(_ref13, 6),
|
||||
obj = _ref14[0],
|
||||
tgt = _ref14[1],
|
||||
src = _ref14[2],
|
||||
obj1 = _ref14[3],
|
||||
tgt1 = _ref14[4],
|
||||
src1 = _ref14[5];
|
||||
|
||||
return t.forInStatement(lh, obj, t.blockStatement([t.expressionStatement(t.assignmentExpression("=", t.memberExpression(tgt, boundName, true), t.memberExpression(src, boundName, true)))]));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "derive",
|
||||
value: function derive(types, values, args, buildNode_, optionalArgs) {
|
||||
(0, _invariant2.default)(buildNode_ instanceof Function || args.length === 0);
|
||||
var id = t.identifier(this.preludeGenerator.nameGenerator.generate("derived"));
|
||||
this.preludeGenerator.derivedIds.set(id.name, args);
|
||||
var options = {};
|
||||
if (optionalArgs && optionalArgs.kind) options.kind = optionalArgs.kind;
|
||||
var Constructor = _index.Value.isTypeCompatibleWith(types.getType(), _index.ObjectValue) ? _index.AbstractObjectValue : _index.AbstractValue;
|
||||
var res = new Constructor(this.realm, types, values, 0, [], id, options);
|
||||
this._addEntry({
|
||||
isPure: optionalArgs ? optionalArgs.isPure : undefined,
|
||||
declared: res,
|
||||
args: args,
|
||||
buildNode: function buildNode(nodes, context) {
|
||||
return t.variableDeclaration("var", [t.variableDeclarator(id, buildNode_ instanceof Function ? buildNode_(nodes, context) : buildNode_)]);
|
||||
}
|
||||
});
|
||||
var type = types.getType();
|
||||
res.intrinsicName = id.name;
|
||||
if (optionalArgs && optionalArgs.skipInvariant) return res;
|
||||
var typeofString = void 0;
|
||||
if (type instanceof _index.FunctionValue) typeofString = "function";else if (type === _index.UndefinedValue) (0, _invariant2.default)(false);else if (type === _index.NullValue) (0, _invariant2.default)(false);else if (type === _index.StringValue) typeofString = "string";else if (type === _index.BooleanValue) typeofString = "boolean";else if (type === _index.NumberValue) typeofString = "number";else if (type === _index.SymbolValue) typeofString = "symbol";else if (type === _index.ObjectValue) typeofString = "object";
|
||||
if (typeofString !== undefined) {
|
||||
// Verify that the types are as expected, a failure of this invariant
|
||||
// should mean the model is wrong.
|
||||
this.emitInvariant([res, res], function (nodes) {
|
||||
(0, _invariant2.default)(typeofString !== undefined);
|
||||
var condition = t.binaryExpression("!==", t.unaryExpression("typeof", nodes[0]), t.stringLiteral(typeofString));
|
||||
if (typeofString === "object") {
|
||||
condition = t.logicalExpression("&&", condition, t.binaryExpression("!==", t.unaryExpression("typeof", nodes[0]), t.stringLiteral("function")));
|
||||
condition = t.logicalExpression("||", condition, t.binaryExpression("===", nodes[0], _internalizer.nullExpression));
|
||||
}
|
||||
return condition;
|
||||
}, function (node) {
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}, {
|
||||
key: "serialize",
|
||||
value: function serialize(context) {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator = this._entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var entry = _step.value;
|
||||
|
||||
if (!entry.isPure || !entry.declared || !context.canOmit(entry.declared)) {
|
||||
var nodes = entry.args.map(function (boundArg, i) {
|
||||
return context.serializeValue(boundArg);
|
||||
});
|
||||
if (entry.buildNode) context.emit(entry.buildNode(nodes, context));
|
||||
if (entry.declared !== undefined) context.declare(entry.declared);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator.return) {
|
||||
_iterator.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "visitEntry",
|
||||
value: function visitEntry(entry, callbacks) {
|
||||
if (entry.isPure && entry.declared && callbacks.canSkip(entry.declared)) {
|
||||
callbacks.recordDelayedEntry(entry);
|
||||
} else {
|
||||
if (entry.declared) callbacks.recordDeclaration(entry.declared);
|
||||
callbacks.visitValues(entry.args);
|
||||
if (entry.dependencies) {
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = entry.dependencies[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var dependency = _step2.value;
|
||||
callbacks.visitGenerator(dependency);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
||||
_iterator2.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "visit",
|
||||
value: function visit(callbacks) {
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = this._entries[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var entry = _step3.value;
|
||||
this.visitEntry(entry, callbacks);
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
||||
_iterator3.return();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "_addEntry",
|
||||
value: function _addEntry(entry) {
|
||||
this._entries.push(entry);
|
||||
}
|
||||
}, {
|
||||
key: "appendGenerator",
|
||||
value: function appendGenerator(other, leadingComment) {
|
||||
if (other.empty()) return;
|
||||
this._addEntry({
|
||||
args: [],
|
||||
buildNode: function buildNode(args, context) {
|
||||
var statements = context.serializeGenerator(other);
|
||||
var block = t.blockStatement(statements);
|
||||
if (leadingComment.length > 0) block.leadingComments = [{ type: "BlockComment", value: leadingComment }];
|
||||
return block;
|
||||
},
|
||||
dependencies: [other]
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "composeGenerators",
|
||||
value: function composeGenerators(generator1, generator2) {
|
||||
this._addEntry({
|
||||
args: [],
|
||||
buildNode: function buildNode(_ref15, context) {
|
||||
var _ref16 = _toArray(_ref15);
|
||||
|
||||
var statements = [];
|
||||
if (!generator1.empty()) statements.push(serializeBody(generator1, context));
|
||||
if (!generator2.empty()) statements.push(serializeBody(generator2, context));
|
||||
return t.blockStatement(statements);
|
||||
},
|
||||
dependencies: [generator1, generator2]
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "joinGenerators",
|
||||
value: function joinGenerators(joinCondition, generator1, generator2) {
|
||||
this._addEntry({
|
||||
args: [joinCondition],
|
||||
buildNode: function buildNode(_ref17, context) {
|
||||
var _ref18 = _slicedToArray(_ref17, 1),
|
||||
cond = _ref18[0];
|
||||
|
||||
var block1 = generator1.empty() ? null : serializeBody(generator1, context);
|
||||
var block2 = generator2.empty() ? null : serializeBody(generator2, context);
|
||||
if (block1) return t.ifStatement(cond, block1, block2);
|
||||
(0, _invariant2.default)(block2);
|
||||
return t.ifStatement(t.unaryExpression("!", cond), block2);
|
||||
},
|
||||
dependencies: [generator1, generator2]
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return Generator;
|
||||
}();
|
||||
|
||||
// some characters are invalid within a JavaScript identifier,
|
||||
// such as: . , : ( ) ' " ` [ ] -
|
||||
// so we replace these character instacnes with an underscore
|
||||
|
||||
|
||||
function replaceInvalidCharactersWithUnderscore(string) {
|
||||
return string.replace(/[.,:\(\)\"\'\`\[\]\-]/g, "_");
|
||||
}
|
||||
|
||||
var NameGenerator = exports.NameGenerator = function () {
|
||||
function NameGenerator(forbiddenNames, debugNames, uniqueSuffix, prefix) {
|
||||
_classCallCheck(this, NameGenerator);
|
||||
|
||||
this.prefix = prefix;
|
||||
this.uidCounter = 0;
|
||||
this.debugNames = debugNames;
|
||||
this.forbiddenNames = forbiddenNames;
|
||||
this.uniqueSuffix = uniqueSuffix;
|
||||
}
|
||||
|
||||
_createClass(NameGenerator, [{
|
||||
key: "generate",
|
||||
value: function generate(debugSuffix) {
|
||||
var id = void 0;
|
||||
do {
|
||||
id = this.prefix + base62.encode(this.uidCounter++);
|
||||
if (this.uniqueSuffix.length > 0) id += this.uniqueSuffix;
|
||||
if (this.debugNames) {
|
||||
if (debugSuffix) id += "_" + replaceInvalidCharactersWithUnderscore(debugSuffix);else id += "_";
|
||||
}
|
||||
} while (this.forbiddenNames.has(id));
|
||||
return id;
|
||||
}
|
||||
}]);
|
||||
|
||||
return NameGenerator;
|
||||
}();
|
||||
|
||||
var PreludeGenerator = exports.PreludeGenerator = function () {
|
||||
function PreludeGenerator(debugNames, uniqueSuffix) {
|
||||
_classCallCheck(this, PreludeGenerator);
|
||||
|
||||
this.prelude = [];
|
||||
this.derivedIds = new Map();
|
||||
this.memoizedRefs = new Map();
|
||||
this.nameGenerator = new NameGenerator(new Set(), !!debugNames, uniqueSuffix || "", "_$");
|
||||
this.usesThis = false;
|
||||
this.declaredGlobals = new Set();
|
||||
}
|
||||
|
||||
_createClass(PreludeGenerator, [{
|
||||
key: "createNameGenerator",
|
||||
value: function createNameGenerator(prefix) {
|
||||
return new NameGenerator(this.nameGenerator.forbiddenNames, this.nameGenerator.debugNames, this.nameGenerator.uniqueSuffix, prefix);
|
||||
}
|
||||
}, {
|
||||
key: "convertStringToMember",
|
||||
value: function convertStringToMember(str) {
|
||||
var _this4 = this;
|
||||
|
||||
return str.split(".").map(function (name) {
|
||||
return name === "global" ? _this4.memoizeReference(name) : t.identifier(name);
|
||||
}).reduce(function (obj, prop) {
|
||||
return t.memberExpression(obj, prop);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: "globalReference",
|
||||
value: function globalReference(key) {
|
||||
var globalScope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||
|
||||
if (globalScope && t.isValidIdentifier(key)) return t.identifier(key);
|
||||
var keyNode = t.isValidIdentifier(key) ? t.identifier(key) : t.stringLiteral(key);
|
||||
return t.memberExpression(this.memoizeReference("global"), keyNode, !t.isIdentifier(keyNode));
|
||||
}
|
||||
}, {
|
||||
key: "memoizeReference",
|
||||
value: function memoizeReference(key) {
|
||||
var ref = this.memoizedRefs.get(key);
|
||||
if (ref) return ref;
|
||||
|
||||
var init = void 0;
|
||||
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 {
|
||||
var 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;
|
||||
}
|
||||
}]);
|
||||
|
||||
return PreludeGenerator;
|
||||
}();
|
||||
//# sourceMappingURL=generator.js.map
|
||||
Reference in New Issue
Block a user