You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.1 KiB
178 lines
4.1 KiB
"use strict"; |
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); |
|
|
|
var _assert = _interopRequireDefault(require("assert")); |
|
|
|
var _emit = require("./emit"); |
|
|
|
var _util = require("util"); |
|
|
|
var _util2 = require("./util"); |
|
|
|
/** |
|
* Copyright (c) 2014-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
*/ |
|
function Entry() { |
|
_assert["default"].ok(this instanceof Entry); |
|
} |
|
|
|
function FunctionEntry(returnLoc) { |
|
Entry.call(this); |
|
(0, _util2.getTypes)().assertLiteral(returnLoc); |
|
this.returnLoc = returnLoc; |
|
} |
|
|
|
(0, _util.inherits)(FunctionEntry, Entry); |
|
exports.FunctionEntry = FunctionEntry; |
|
|
|
function LoopEntry(breakLoc, continueLoc, label) { |
|
Entry.call(this); |
|
var t = (0, _util2.getTypes)(); |
|
t.assertLiteral(breakLoc); |
|
t.assertLiteral(continueLoc); |
|
|
|
if (label) { |
|
t.assertIdentifier(label); |
|
} else { |
|
label = null; |
|
} |
|
|
|
this.breakLoc = breakLoc; |
|
this.continueLoc = continueLoc; |
|
this.label = label; |
|
} |
|
|
|
(0, _util.inherits)(LoopEntry, Entry); |
|
exports.LoopEntry = LoopEntry; |
|
|
|
function SwitchEntry(breakLoc) { |
|
Entry.call(this); |
|
(0, _util2.getTypes)().assertLiteral(breakLoc); |
|
this.breakLoc = breakLoc; |
|
} |
|
|
|
(0, _util.inherits)(SwitchEntry, Entry); |
|
exports.SwitchEntry = SwitchEntry; |
|
|
|
function TryEntry(firstLoc, catchEntry, finallyEntry) { |
|
Entry.call(this); |
|
var t = (0, _util2.getTypes)(); |
|
t.assertLiteral(firstLoc); |
|
|
|
if (catchEntry) { |
|
_assert["default"].ok(catchEntry instanceof CatchEntry); |
|
} else { |
|
catchEntry = null; |
|
} |
|
|
|
if (finallyEntry) { |
|
_assert["default"].ok(finallyEntry instanceof FinallyEntry); |
|
} else { |
|
finallyEntry = null; |
|
} // Have to have one or the other (or both). |
|
|
|
|
|
_assert["default"].ok(catchEntry || finallyEntry); |
|
|
|
this.firstLoc = firstLoc; |
|
this.catchEntry = catchEntry; |
|
this.finallyEntry = finallyEntry; |
|
} |
|
|
|
(0, _util.inherits)(TryEntry, Entry); |
|
exports.TryEntry = TryEntry; |
|
|
|
function CatchEntry(firstLoc, paramId) { |
|
Entry.call(this); |
|
var t = (0, _util2.getTypes)(); |
|
t.assertLiteral(firstLoc); |
|
t.assertIdentifier(paramId); |
|
this.firstLoc = firstLoc; |
|
this.paramId = paramId; |
|
} |
|
|
|
(0, _util.inherits)(CatchEntry, Entry); |
|
exports.CatchEntry = CatchEntry; |
|
|
|
function FinallyEntry(firstLoc, afterLoc) { |
|
Entry.call(this); |
|
var t = (0, _util2.getTypes)(); |
|
t.assertLiteral(firstLoc); |
|
t.assertLiteral(afterLoc); |
|
this.firstLoc = firstLoc; |
|
this.afterLoc = afterLoc; |
|
} |
|
|
|
(0, _util.inherits)(FinallyEntry, Entry); |
|
exports.FinallyEntry = FinallyEntry; |
|
|
|
function LabeledEntry(breakLoc, label) { |
|
Entry.call(this); |
|
var t = (0, _util2.getTypes)(); |
|
t.assertLiteral(breakLoc); |
|
t.assertIdentifier(label); |
|
this.breakLoc = breakLoc; |
|
this.label = label; |
|
} |
|
|
|
(0, _util.inherits)(LabeledEntry, Entry); |
|
exports.LabeledEntry = LabeledEntry; |
|
|
|
function LeapManager(emitter) { |
|
_assert["default"].ok(this instanceof LeapManager); |
|
|
|
_assert["default"].ok(emitter instanceof _emit.Emitter); |
|
|
|
this.emitter = emitter; |
|
this.entryStack = [new FunctionEntry(emitter.finalLoc)]; |
|
} |
|
|
|
var LMp = LeapManager.prototype; |
|
exports.LeapManager = LeapManager; |
|
|
|
LMp.withEntry = function (entry, callback) { |
|
_assert["default"].ok(entry instanceof Entry); |
|
|
|
this.entryStack.push(entry); |
|
|
|
try { |
|
callback.call(this.emitter); |
|
} finally { |
|
var popped = this.entryStack.pop(); |
|
|
|
_assert["default"].strictEqual(popped, entry); |
|
} |
|
}; |
|
|
|
LMp._findLeapLocation = function (property, label) { |
|
for (var i = this.entryStack.length - 1; i >= 0; --i) { |
|
var entry = this.entryStack[i]; |
|
var loc = entry[property]; |
|
|
|
if (loc) { |
|
if (label) { |
|
if (entry.label && entry.label.name === label.name) { |
|
return loc; |
|
} |
|
} else if (entry instanceof LabeledEntry) {// Ignore LabeledEntry entries unless we are actually breaking to |
|
// a label. |
|
} else { |
|
return loc; |
|
} |
|
} |
|
} |
|
|
|
return null; |
|
}; |
|
|
|
LMp.getBreakLoc = function (label) { |
|
return this._findLeapLocation("breakLoc", label); |
|
}; |
|
|
|
LMp.getContinueLoc = function (label) { |
|
return this._findLeapLocation("continueLoc", label); |
|
}; |