prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
139 lines (121 loc) • 4.83 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Logger = undefined;
var _realm = require("../realm.js");
var _errors = require("../errors.js");
var _index = require("../methods/index.js");
var _completions = require("../completions.js");
var _index2 = require("../values/index.js");
var _singletons = require("../singletons.js");
var _invariant = require("../invariant.js");
var _invariant2 = _interopRequireDefault(_invariant);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Logger {
constructor(realm, internalDebug) {
this.realm = realm;
this._hasErrors = false;
this.internalDebug = internalDebug;
}
// Wraps a query that might potentially execute user code.
tryQuery(f, defaultValue) {
let realm = this.realm;
let context = new _realm.ExecutionContext();
context.isStrict = realm.isStrict;
let env = realm.$GlobalEnv;
context.lexicalEnvironment = env;
context.variableEnvironment = env;
context.realm = realm;
realm.pushContext(context);
// We use partial evaluation so that we can throw away any state mutations
let oldErrorHandler = realm.errorHandler;
realm.errorHandler = d => {
if (d.severity === "Information" || d.severity === "Warning") return "Recover";
return "Fail";
};
try {
let result;
let effects = realm.evaluateForEffects(() => {
try {
result = f();
} catch (e) {
if (e instanceof _completions.Completion) {
result = defaultValue;
} else if (e instanceof _errors.FatalError) {
result = defaultValue;
} else {
throw e;
}
}
return realm.intrinsics.undefined;
}, undefined, "tryQuery");
(0, _invariant2.default)(effects[0] === realm.intrinsics.undefined);
return result;
} finally {
realm.errorHandler = oldErrorHandler;
realm.popContext(context);
}
}
logCompletion(res) {
let realm = this.realm;
let value = res.value;
if (this.internalDebug) console.error(`=== ${res.constructor.name} ===`);
if (this.tryQuery(() => value instanceof _index2.ObjectValue && (0, _index.InstanceofOperator)(realm, value, realm.intrinsics.Error), false)) {
let object = value;
try {
let err = new _errors.FatalError(this.tryQuery(() => _singletons.To.ToStringPartial(realm, (0, _index.Get)(realm, object, "message")), "(unknown message)"));
err.stack = this.tryQuery(() => _singletons.To.ToStringPartial(realm, (0, _index.Get)(realm, object, "stack")), "(unknown stack)");
console.error(err.message);
console.error(err.stack);
if (this.internalDebug && res instanceof _completions.ThrowCompletion) console.error(res.nativeStack);
} catch (err) {
let message = object.properties.get("message");
console.error(message && message.descriptor && message.descriptor.value instanceof _index2.StringValue ? message.descriptor.value.value : "(no message available)");
console.error(err.stack);
if (object.$ErrorData) {
console.error(object.$ErrorData.contextStack);
}
}
} else {
try {
value = _singletons.To.ToStringPartial(realm, value);
} catch (err) {
value = err.message;
}
console.error(value);
if (this.internalDebug && res instanceof _completions.ThrowCompletion) console.error(res.nativeStack);
}
this._hasErrors = true;
}
logError(value, message) {
this._log(value, message, "RecoverableError");
this._hasErrors = true;
}
logWarning(value, message) {
this._log(value, message, "Warning");
}
logInformation(message) {
this._log(this.realm.intrinsics.undefined, message, "Information");
}
_log(value, message, severity) {
let loc = value.expressionLocation;
if (value.intrinsicName) {
message = `${message}\nintrinsic name: ${value.intrinsicName}`;
}
let diagnostic = new _errors.CompilerDiagnostic(message, loc, "PP9000", severity);
if (this.realm.handleError(diagnostic) === "Fail") throw new _errors.FatalError();
}
hasErrors() {
return this._hasErrors;
}
}
exports.Logger = Logger; /**
* 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.
*/
//# sourceMappingURL=logger.js.map