UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

179 lines (139 loc) 5.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _invariant = _interopRequireDefault(require("../invariant.js")); var _index = require("../values/index.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 */ /* An abstract domain for the type of value a variable might have. */ class TypesDomain { constructor(type) { (0, _invariant.default)(type !== _index.ConcreteValue, "Concrete values must be specific"); this._type = type === _index.Value ? undefined : type; } isBottom() { return this._type instanceof _index.EmptyValue; } isTop() { return this._type === undefined; } getType() { return this._type || _index.Value; } // return the type of the result in the case where there is no exception static binaryOp(op, left, right) { if (left.isBottom() || right.isBottom()) return TypesDomain.bottomVal; let lType = left._type; let rType = right._type; let resultType = _index.Value; switch (op) { case "+": if (lType === undefined || rType === undefined) return TypesDomain.topVal; if (_index.Value.isTypeCompatibleWith(lType, _index.StringValue) || _index.Value.isTypeCompatibleWith(rType, _index.StringValue)) { resultType = _index.StringValue; break; } // eslint-disable-line no-fallthrough case "-": if (lType === undefined || rType === undefined) return TypesDomain.topVal; if (lType === _index.IntegralValue && rType === _index.IntegralValue) resultType = _index.IntegralValue;else if (_index.Value.isTypeCompatibleWith(lType, _index.NumberValue) && _index.Value.isTypeCompatibleWith(rType, _index.NumberValue)) resultType = _index.NumberValue; break; case "<": case ">": case ">=": case "<=": case "!=": case "==": case "!==": case "===": case "in": case "instanceof": resultType = _index.BooleanValue; break; case ">>>": case "<<": case ">>": case "&": case "|": case "^": resultType = _index.IntegralValue; break; case "**": case "%": case "/": case "*": resultType = _index.NumberValue; break; default: (0, _invariant.default)(false); } return new TypesDomain(resultType); } static joinValues(v1, v2) { if (v1 === undefined && v2 === undefined) return new TypesDomain(_index.UndefinedValue); if (v1 === undefined || v2 === undefined) return TypesDomain.topVal; if (v1 instanceof _index.AbstractValue) return v1.types.joinWith(v2.getType()); if (v2 instanceof _index.AbstractValue) return v2.types.joinWith(v1.getType()); return new TypesDomain(v1.getType()).joinWith(v2.getType()); } joinWith(t) { if (this.isBottom()) return t === _index.EmptyValue ? TypesDomain.bottomVal : new TypesDomain(t); let type = this.getType(); if (type === t || t instanceof _index.EmptyValue) return this; if (_index.Value.isTypeCompatibleWith(type, _index.NumberValue) && _index.Value.isTypeCompatibleWith(t, _index.NumberValue)) { return new TypesDomain(_index.NumberValue); } if (_index.Value.isTypeCompatibleWith(type, _index.FunctionValue) && _index.Value.isTypeCompatibleWith(t, _index.FunctionValue)) { return new TypesDomain(_index.FunctionValue); } if (_index.Value.isTypeCompatibleWith(type, _index.ObjectValue) && _index.Value.isTypeCompatibleWith(t, _index.ObjectValue)) { return new TypesDomain(_index.ObjectValue); } if (_index.Value.isTypeCompatibleWith(type, _index.PrimitiveValue) && _index.Value.isTypeCompatibleWith(t, _index.PrimitiveValue)) { return new TypesDomain(_index.PrimitiveValue); } return TypesDomain.topVal; } static logicalOp(op, left, right) { return left.joinWith(right.getType()); } // return the type of the result in the case where there is no exception // note that the type of the operand has no influence on the type of the non exceptional result static unaryOp(op, operand) { if (operand.isBottom()) return TypesDomain.bottomVal; const type = operand._type; let resultType = _index.Value; switch (op) { case "-": case "+": resultType = type === _index.IntegralValue ? _index.IntegralValue : _index.NumberValue; break; case "~": resultType = _index.IntegralValue; break; case "!": case "delete": resultType = _index.BooleanValue; break; case "typeof": resultType = _index.StringValue; break; case "void": resultType = _index.UndefinedValue; break; default: (0, _invariant.default)(false); } return new TypesDomain(resultType); } } exports.default = TypesDomain; //# sourceMappingURL=TypesDomain.js.map