UNPKG

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
"use strict"; 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