prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
132 lines (99 loc) • 4.67 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.concretize = concretize;
var _index = require("../values/index.js");
var t = _interopRequireWildcard(require("@babel/types"));
var _invariant = _interopRequireDefault(require("../invariant.js"));
var _errors = require("../errors.js");
var _index2 = require("../methods/index.js");
var _singletons = require("../singletons.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.
*/
/**
* This file contains code that converts abstract models into concrete values.
*/
function reportCompileError(realm, message, loc) {
let error = new _errors.CompilerDiagnostic(message, loc, "PP9000", "RecoverableError");
realm.handleError(error);
}
function createEmptyFunction(realm) {
const concreteFunction = new _index.ECMAScriptSourceFunctionValue(realm);
concreteFunction.initialize([], t.blockStatement([]));
return concreteFunction;
}
/**
* Convert abstract model value into concrete value.
*/
function concretize(realm, val) {
if (val instanceof _index.ConcreteValue) {
return val;
}
(0, _invariant.default)(val instanceof _index.AbstractValue);
if (val.kind === "abstractConcreteUnion") {
(0, _invariant.default)(val.args.length >= 2);
return concretize(realm, val.args[0]);
}
const type = val.types.getType();
if (val.types.isTop()) {
return new _index.UndefinedValue(realm);
} else if (type.prototype instanceof _index.PrimitiveValue) {
if (val.values.isTop()) {
switch (type) {
case _index.StringValue:
return new _index.StringValue(realm, "__concreteModel");
case _index.NumberValue:
return new _index.NumberValue(realm, 42);
case _index.SymbolValue:
return new _index.SymbolValue(realm, new _index.StringValue(realm, "__concreteModel"));
case _index.BooleanValue:
return new _index.BooleanValue(realm, true);
case _index.NullValue:
return new _index.NullValue(realm);
case _index.UndefinedValue:
return new _index.UndefinedValue(realm);
default:
(0, _invariant.default)(false, "Not yet implemented");
}
} else {
// TODO: This was broken. Is this actually used?
const values = val.values.getElements();
(0, _invariant.default)(values.size === 1, "Concrete model should only have one value");
for (let value in values) {
(0, _invariant.default)(value instanceof _index.ConcreteValue, "Concrete model should only contain one concrete value");
return value;
}
(0, _invariant.default)(false);
}
} else if (type === _index.FunctionValue) {
return createEmptyFunction(realm);
} else if (type === _index.ArrayValue) {
reportCompileError(realm, "Emitting a concrete model for abstract array value is not supported yet.", val.expressionLocation);
} else if (val instanceof _index.AbstractObjectValue) {
if (val.values.isTop()) {
return new _index.ObjectValue(realm);
} else {
let template = val.getTemplate();
let concreteObj = _singletons.Create.ObjectCreate(realm, template.$GetPrototypeOf());
let keys = (0, _index2.EnumerableOwnProperties)(realm, template, "key", true);
for (let P of keys) {
(0, _invariant.default)(P instanceof _index.StringValue);
let newElement = (0, _index2.Get)(realm, template, P);
_singletons.Create.CreateDataProperty(realm, concreteObj, P, concretize(realm, newElement));
}
return concreteObj;
}
}
reportCompileError(realm, "Emitting a concrete model for this abstract value is not supported yet.", val.expressionLocation); // Return undefined to make flow happy.
return new _index.UndefinedValue(realm);
}
//# sourceMappingURL=ConcreteModelConverter.js.map