304 lines
15 KiB
JavaScript
304 lines
15 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.VariableManager = undefined;
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
|
|
* 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.
|
|
*/
|
|
|
|
var _ReferenceMap = require("./ReferenceMap.js");
|
|
|
|
var _environment = require("./../../environment.js");
|
|
|
|
var _index = require("./../../values/index.js");
|
|
|
|
var _invariant = require("./../common/invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
var _is = require("./../../methods/is.js");
|
|
|
|
var _DebuggerError = require("./../common/DebuggerError.js");
|
|
|
|
var _singletons = require("./../../singletons.js");
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
// This class manages the handling of variable requests in the debugger
|
|
// The DebugProtocol specifies collections of variables are to be fetched using a
|
|
// unique reference ID called a variablesReference. This class can generate new
|
|
// variablesReferences to pass to the UI and then perform lookups for those
|
|
// variablesReferences when they are requested.
|
|
var VariableManager = exports.VariableManager = function () {
|
|
function VariableManager(realm) {
|
|
_classCallCheck(this, VariableManager);
|
|
|
|
this._containerCache = new Map();
|
|
this._referenceMap = new _ReferenceMap.ReferenceMap();
|
|
this._realm = realm;
|
|
}
|
|
// cache for created references
|
|
|
|
// map for looking up references
|
|
|
|
|
|
_createClass(VariableManager, [{
|
|
key: "getReferenceForValue",
|
|
|
|
|
|
// Given a container, either returns a cached reference for that container if
|
|
// it exists or return a new reference
|
|
value: function getReferenceForValue(value) {
|
|
var cachedRef = this._containerCache.get(value);
|
|
if (cachedRef !== undefined) {
|
|
return cachedRef;
|
|
}
|
|
|
|
var varRef = this._referenceMap.add(value);
|
|
this._containerCache.set(value, varRef);
|
|
return varRef;
|
|
}
|
|
|
|
// The entry point for retrieving a collection of variables by a reference
|
|
|
|
}, {
|
|
key: "getVariablesByReference",
|
|
value: function getVariablesByReference(reference) {
|
|
var container = this._referenceMap.get(reference);
|
|
if (!container) return [];
|
|
if (container instanceof _environment.LexicalEnvironment) {
|
|
return this._getVariablesFromEnvRecord(container.environmentRecord);
|
|
} else if (container instanceof _index.ObjectValue) {
|
|
return this._getVariablesFromObject(container);
|
|
} else if (container instanceof _index.AbstractValue) {
|
|
return this._getAbstractValueContent(container);
|
|
} else {
|
|
(0, _invariant2.default)(false, "Invalid variable container");
|
|
}
|
|
}
|
|
}, {
|
|
key: "_getVariablesFromObject",
|
|
value: function _getVariablesFromObject(object) {
|
|
var variables = [];
|
|
var names = object.properties.keys();
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = names[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var name = _step.value;
|
|
|
|
var binding = object.properties.get(name);
|
|
(0, _invariant2.default)(binding !== undefined);
|
|
if (binding.descriptor) {
|
|
if ((0, _is.IsDataDescriptor)(this._realm, binding.descriptor)) {
|
|
var value = binding.descriptor.value;
|
|
if (value instanceof _index.Value) {
|
|
var variable = this._getVariableFromValue(name, value);
|
|
variables.push(variable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
return variables;
|
|
}
|
|
}, {
|
|
key: "_getAbstractValueContent",
|
|
value: function _getAbstractValueContent(value) {
|
|
var kindVar = {
|
|
name: "kind",
|
|
value: value.kind || "undefined",
|
|
variablesReference: 0
|
|
};
|
|
var contents = [kindVar];
|
|
var argCount = 1;
|
|
var _iteratorNormalCompletion2 = true;
|
|
var _didIteratorError2 = false;
|
|
var _iteratorError2 = undefined;
|
|
|
|
try {
|
|
for (var _iterator2 = value.args[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
var arg = _step2.value;
|
|
|
|
contents.push(this._getVariableFromValue("arg-" + argCount, arg));
|
|
argCount++;
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError2 = true;
|
|
_iteratorError2 = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
|
_iterator2.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError2) {
|
|
throw _iteratorError2;
|
|
}
|
|
}
|
|
}
|
|
|
|
return contents;
|
|
}
|
|
}, {
|
|
key: "_getVariablesFromEnvRecord",
|
|
value: function _getVariablesFromEnvRecord(envRecord) {
|
|
if (envRecord instanceof _environment.DeclarativeEnvironmentRecord) {
|
|
return this._getVariablesFromDeclarativeEnv(envRecord);
|
|
} else if (envRecord instanceof _environment.ObjectEnvironmentRecord) {
|
|
if (envRecord.object instanceof _index.ObjectValue) {
|
|
return this._getVariablesFromObject(envRecord.object);
|
|
} else if (envRecord.object instanceof _index.AbstractObjectValue) {
|
|
// TODO: call _getVariablesFromAbstractObject when it is implemented
|
|
return [];
|
|
} else {
|
|
(0, _invariant2.default)(false, "Invalid type of object environment record");
|
|
}
|
|
} else if (envRecord instanceof _environment.GlobalEnvironmentRecord) {
|
|
var declVars = this._getVariablesFromEnvRecord(envRecord.$DeclarativeRecord);
|
|
var objVars = this._getVariablesFromEnvRecord(envRecord.$ObjectRecord);
|
|
return declVars.concat(objVars);
|
|
} else {
|
|
(0, _invariant2.default)(false, "Invalid type of environment record");
|
|
}
|
|
}
|
|
}, {
|
|
key: "_getVariablesFromDeclarativeEnv",
|
|
value: function _getVariablesFromDeclarativeEnv(env) {
|
|
var variables = [];
|
|
var bindings = env.bindings;
|
|
for (var name in bindings) {
|
|
var binding = bindings[name];
|
|
if (binding.value) {
|
|
var variable = this._getVariableFromValue(name, binding.value);
|
|
variables.push(variable);
|
|
}
|
|
}
|
|
return variables;
|
|
}
|
|
}, {
|
|
key: "_getVariableFromValue",
|
|
value: function _getVariableFromValue(name, value) {
|
|
if (value instanceof _index.ConcreteValue) {
|
|
return this._getVariableFromConcreteValue(name, value);
|
|
} else if (value instanceof _index.AbstractValue) {
|
|
return this._getVariableFromAbstractValue(name, value);
|
|
} else {
|
|
(0, _invariant2.default)(false, "Value is neither concrete nor abstract");
|
|
}
|
|
}
|
|
}, {
|
|
key: "_getVariableFromAbstractValue",
|
|
value: function _getVariableFromAbstractValue(name, value) {
|
|
var variable = {
|
|
name: name,
|
|
value: this._getAbstractValueDisplay(value),
|
|
variablesReference: this.getReferenceForValue(value)
|
|
};
|
|
return variable;
|
|
}
|
|
}, {
|
|
key: "_getAbstractValueDisplay",
|
|
value: function _getAbstractValueDisplay(value) {
|
|
if (value.intrinsicName && !value.intrinsicName.startsWith("_")) {
|
|
return value.intrinsicName;
|
|
}
|
|
return "Abstract " + value.types.getType().name;
|
|
}
|
|
}, {
|
|
key: "_getVariableFromConcreteValue",
|
|
value: function _getVariableFromConcreteValue(name, value) {
|
|
if (value instanceof _index.PrimitiveValue) {
|
|
var variable = {
|
|
name: name,
|
|
value: value.toDisplayString(),
|
|
variablesReference: 0
|
|
};
|
|
return variable;
|
|
} else if (value instanceof _index.ObjectValue) {
|
|
var _variable = {
|
|
name: name,
|
|
value: value.getKind(),
|
|
variablesReference: this.getReferenceForValue(value)
|
|
};
|
|
return _variable;
|
|
} else {
|
|
(0, _invariant2.default)(false, "Concrete value must be primitive or object");
|
|
}
|
|
}
|
|
}, {
|
|
key: "evaluate",
|
|
value: function evaluate(frameId, expression) {
|
|
var evalRealm = this._realm;
|
|
var isDirect = false;
|
|
var isStrict = false;
|
|
if (frameId !== undefined) {
|
|
if (frameId < 0 || frameId >= this._realm.contextStack.length) {
|
|
throw new _DebuggerError.DebuggerError("Invalid command", "Invalid value for frame ID");
|
|
}
|
|
// frameId's are in reverse order of context stack
|
|
var stackIndex = this._realm.contextStack.length - 1 - frameId;
|
|
var context = this._realm.contextStack[stackIndex];
|
|
isDirect = true;
|
|
isStrict = true;
|
|
evalRealm = context.realm;
|
|
}
|
|
|
|
var evalString = new _index.StringValue(this._realm, expression);
|
|
try {
|
|
var value = _singletons.Functions.PerformEval(this._realm, evalString, evalRealm, isStrict, isDirect);
|
|
var varInfo = this._getVariableFromValue(expression, value);
|
|
var result = {
|
|
kind: "evaluate",
|
|
displayValue: varInfo.value,
|
|
type: value.getType().name,
|
|
variablesReference: varInfo.variablesReference
|
|
};
|
|
return result;
|
|
} catch (e) {
|
|
var _result = {
|
|
kind: "evaluate",
|
|
displayValue: "Failed to evaluate: " + expression,
|
|
type: "unknown",
|
|
variablesReference: 0
|
|
};
|
|
return _result;
|
|
}
|
|
}
|
|
}, {
|
|
key: "clean",
|
|
value: function clean() {
|
|
this._containerCache = new Map();
|
|
this._referenceMap.clean();
|
|
}
|
|
}]);
|
|
|
|
return VariableManager;
|
|
}();
|
|
//# sourceMappingURL=VariableManager.js.map
|