"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