prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
118 lines (92 loc) • 3.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.StepOutStepper = exports.StepOverStepper = exports.StepIntoStepper = exports.Stepper = void 0;
var _types = require("@babel/types");
var _invariant = _interopRequireDefault(require("./../common/invariant.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* 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.
*/
/* strict-local */
class Stepper {
constructor(filePath, line, column, stackSize) {
this._stepStartData = {
filePath: filePath,
line: line,
column: column,
stackSize: stackSize
};
}
isComplete(ast, currentStackSize) {
(0, _invariant.default)(false, "Abstract method, please override");
} // NOTE: Only checks if a node has changed within the same callstack.
// The same node in two different excutions contexts (e.g. recursive call)
// will not be detected. Check the stackSize (via realm) in those cases.
isAstLocationChanged(ast) {
let loc = ast.loc;
if (!loc) return false;
let filePath = loc.source;
let line = loc.start.line;
let column = loc.start.column;
if (filePath === null) return false;
if (this._stepStartData) {
if (filePath === this._stepStartData.filePath && line === this._stepStartData.line && column === this._stepStartData.column) {
return false;
}
} else {
return false;
}
return true;
}
}
exports.Stepper = Stepper;
class StepIntoStepper extends Stepper {
constructor(filePath, line, column, startStackSize) {
super(filePath, line, column, startStackSize);
} // Override
isComplete(ast, currentStackSize) {
// If stacksize has changed, the position has changed, regardless if
// the AST node is the same (e.g. a recursive call).
return this.isAstLocationChanged(ast) || currentStackSize !== this._stepStartData.stackSize;
}
}
exports.StepIntoStepper = StepIntoStepper;
class StepOverStepper extends Stepper {
constructor(filePath, line, column, stackSize) {
super(filePath, line, column, stackSize);
}
isComplete(ast, currentStackSize) {
return (// If current stack length < starting stack length, the program either
// hit an exception so this stepper is no longer relevant. Or, the program
// has stepped out of a function call, back up to the calling function.
currentStackSize < this._stepStartData.stackSize || // If current stack length === starting stack length, the program returned
// to the same stack depth. As long as the ast node has changed,
// the step over is complete.
currentStackSize === this._stepStartData.stackSize && this.isAstLocationChanged(ast)
);
}
}
exports.StepOverStepper = StepOverStepper;
class StepOutStepper extends Stepper {
constructor(filePath, line, column, stackSize) {
super(filePath, line, column, stackSize);
}
isComplete(ast, currentStackSize) {
// It is not sufficient to simply check if the AST location has changed,
// since it is possible in recursive calls to return to the same
// AST node, but in a *different* call stack.
// To step out of a function, we must finish executing it.
// When a function completes, its execution context will be
// popped off the stack.
return currentStackSize < this._stepStartData.stackSize;
}
}
exports.StepOutStepper = StepOutStepper;
//# sourceMappingURL=Stepper.js.map