123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609 |
- "use strict";
- const TypeUnknown = 0;
- const TypeUndefined = 1;
- const TypeNull = 2;
- const TypeString = 3;
- const TypeNumber = 4;
- const TypeBoolean = 5;
- const TypeRegExp = 6;
- const TypeConditional = 7;
- const TypeArray = 8;
- const TypeConstArray = 9;
- const TypeIdentifier = 10;
- const TypeWrapped = 11;
- const TypeTemplateString = 12;
- const TypeBigInt = 13;
- class BasicEvaluatedExpression {
- constructor() {
- this.type = TypeUnknown;
-
- this.range = undefined;
-
- this.falsy = false;
-
- this.truthy = false;
-
- this.nullish = undefined;
-
- this.sideEffects = true;
-
- this.bool = undefined;
-
- this.number = undefined;
-
- this.bigint = undefined;
-
- this.regExp = undefined;
-
- this.string = undefined;
-
- this.quasis = undefined;
-
- this.parts = undefined;
-
- this.array = undefined;
-
- this.items = undefined;
-
- this.options = undefined;
-
- this.prefix = undefined;
-
- this.postfix = undefined;
-
- this.wrappedInnerExpressions = undefined;
-
- this.identifier = undefined;
-
- this.rootInfo = undefined;
-
- this.getMembers = undefined;
-
- this.getMembersOptionals = undefined;
-
- this.getMemberRanges = undefined;
-
- this.expression = undefined;
- }
- isUnknown() {
- return this.type === TypeUnknown;
- }
- isNull() {
- return this.type === TypeNull;
- }
- isUndefined() {
- return this.type === TypeUndefined;
- }
- isString() {
- return this.type === TypeString;
- }
- isNumber() {
- return this.type === TypeNumber;
- }
- isBigInt() {
- return this.type === TypeBigInt;
- }
- isBoolean() {
- return this.type === TypeBoolean;
- }
- isRegExp() {
- return this.type === TypeRegExp;
- }
- isConditional() {
- return this.type === TypeConditional;
- }
- isArray() {
- return this.type === TypeArray;
- }
- isConstArray() {
- return this.type === TypeConstArray;
- }
- isIdentifier() {
- return this.type === TypeIdentifier;
- }
- isWrapped() {
- return this.type === TypeWrapped;
- }
- isTemplateString() {
- return this.type === TypeTemplateString;
- }
-
- isPrimitiveType() {
- switch (this.type) {
- case TypeUndefined:
- case TypeNull:
- case TypeString:
- case TypeNumber:
- case TypeBoolean:
- case TypeBigInt:
- case TypeWrapped:
- case TypeTemplateString:
- return true;
- case TypeRegExp:
- case TypeArray:
- case TypeConstArray:
- return false;
- default:
- return undefined;
- }
- }
-
- isCompileTimeValue() {
- switch (this.type) {
- case TypeUndefined:
- case TypeNull:
- case TypeString:
- case TypeNumber:
- case TypeBoolean:
- case TypeRegExp:
- case TypeConstArray:
- case TypeBigInt:
- return true;
- default:
- return false;
- }
- }
-
- asCompileTimeValue() {
- switch (this.type) {
- case TypeUndefined:
- return undefined;
- case TypeNull:
- return null;
- case TypeString:
- return this.string;
- case TypeNumber:
- return this.number;
- case TypeBoolean:
- return this.bool;
- case TypeRegExp:
- return this.regExp;
- case TypeConstArray:
- return this.array;
- case TypeBigInt:
- return this.bigint;
- default:
- throw new Error(
- "asCompileTimeValue must only be called for compile-time values"
- );
- }
- }
- isTruthy() {
- return this.truthy;
- }
- isFalsy() {
- return this.falsy;
- }
- isNullish() {
- return this.nullish;
- }
-
- couldHaveSideEffects() {
- return this.sideEffects;
- }
-
- asBool() {
- if (this.truthy) return true;
- if (this.falsy || this.nullish) return false;
- if (this.isBoolean()) return this.bool;
- if (this.isNull()) return false;
- if (this.isUndefined()) return false;
- if (this.isString()) return this.string !== "";
- if (this.isNumber()) return this.number !== 0;
- if (this.isBigInt()) return this.bigint !== BigInt(0);
- if (this.isRegExp()) return true;
- if (this.isArray()) return true;
- if (this.isConstArray()) return true;
- if (this.isWrapped()) {
- return (this.prefix && this.prefix.asBool()) ||
- (this.postfix && this.postfix.asBool())
- ? true
- : undefined;
- }
- if (this.isTemplateString()) {
- const str = this.asString();
- if (typeof str === "string") return str !== "";
- }
- return undefined;
- }
-
- asNullish() {
- const nullish = this.isNullish();
- if (nullish === true || this.isNull() || this.isUndefined()) return true;
- if (nullish === false) return false;
- if (this.isTruthy()) return false;
- if (this.isBoolean()) return false;
- if (this.isString()) return false;
- if (this.isNumber()) return false;
- if (this.isBigInt()) return false;
- if (this.isRegExp()) return false;
- if (this.isArray()) return false;
- if (this.isConstArray()) return false;
- if (this.isTemplateString()) return false;
- if (this.isRegExp()) return false;
- return undefined;
- }
-
- asString() {
- if (this.isBoolean()) return `${this.bool}`;
- if (this.isNull()) return "null";
- if (this.isUndefined()) return "undefined";
- if (this.isString()) return this.string;
- if (this.isNumber()) return `${this.number}`;
- if (this.isBigInt()) return `${this.bigint}`;
- if (this.isRegExp()) return `${this.regExp}`;
- if (this.isArray()) {
- let array = [];
- for (const item of (
- this.items
- )) {
- const itemStr = item.asString();
- if (itemStr === undefined) return undefined;
- array.push(itemStr);
- }
- return `${array}`;
- }
- if (this.isConstArray()) return `${this.array}`;
- if (this.isTemplateString()) {
- let str = "";
- for (const part of (
- this.parts
- )) {
- const partStr = part.asString();
- if (partStr === undefined) return undefined;
- str += partStr;
- }
- return str;
- }
- return undefined;
- }
-
- setString(string) {
- this.type = TypeString;
- this.string = string;
- this.sideEffects = false;
- return this;
- }
- setUndefined() {
- this.type = TypeUndefined;
- this.sideEffects = false;
- return this;
- }
- setNull() {
- this.type = TypeNull;
- this.sideEffects = false;
- return this;
- }
-
- setNumber(number) {
- this.type = TypeNumber;
- this.number = number;
- this.sideEffects = false;
- return this;
- }
-
- setBigInt(bigint) {
- this.type = TypeBigInt;
- this.bigint = bigint;
- this.sideEffects = false;
- return this;
- }
-
- setBoolean(bool) {
- this.type = TypeBoolean;
- this.bool = bool;
- this.sideEffects = false;
- return this;
- }
-
- setRegExp(regExp) {
- this.type = TypeRegExp;
- this.regExp = regExp;
- this.sideEffects = false;
- return this;
- }
-
- setIdentifier(
- identifier,
- rootInfo,
- getMembers,
- getMembersOptionals,
- getMemberRanges
- ) {
- this.type = TypeIdentifier;
- this.identifier = identifier;
- this.rootInfo = rootInfo;
- this.getMembers = getMembers;
- this.getMembersOptionals = getMembersOptionals;
- this.getMemberRanges = getMemberRanges;
- this.sideEffects = true;
- return this;
- }
-
- setWrapped(prefix, postfix, innerExpressions) {
- this.type = TypeWrapped;
- this.prefix = prefix;
- this.postfix = postfix;
- this.wrappedInnerExpressions = innerExpressions;
- this.sideEffects = true;
- return this;
- }
-
- setOptions(options) {
- this.type = TypeConditional;
- this.options = options;
- this.sideEffects = true;
- return this;
- }
-
- addOptions(options) {
- if (!this.options) {
- this.type = TypeConditional;
- this.options = [];
- this.sideEffects = true;
- }
- for (const item of options) {
- this.options.push(item);
- }
- return this;
- }
-
- setItems(items) {
- this.type = TypeArray;
- this.items = items;
- this.sideEffects = items.some(i => i.couldHaveSideEffects());
- return this;
- }
-
- setArray(array) {
- this.type = TypeConstArray;
- this.array = array;
- this.sideEffects = false;
- return this;
- }
-
- setTemplateString(quasis, parts, kind) {
- this.type = TypeTemplateString;
- this.quasis = quasis;
- this.parts = parts;
- this.templateStringKind = kind;
- this.sideEffects = parts.some(p => p.sideEffects);
- return this;
- }
- setTruthy() {
- this.falsy = false;
- this.truthy = true;
- this.nullish = false;
- return this;
- }
- setFalsy() {
- this.falsy = true;
- this.truthy = false;
- return this;
- }
-
- setNullish(value) {
- this.nullish = value;
- if (value) return this.setFalsy();
- return this;
- }
-
- setRange(range) {
- this.range = range;
- return this;
- }
-
- setSideEffects(sideEffects = true) {
- this.sideEffects = sideEffects;
- return this;
- }
-
- setExpression(expression) {
- this.expression = expression;
- return this;
- }
- }
- BasicEvaluatedExpression.isValidRegExpFlags = flags => {
- const len = flags.length;
- if (len === 0) return true;
- if (len > 4) return false;
-
- let remaining = 0b0000;
- for (let i = 0; i < len; i++)
- switch (flags.charCodeAt(i)) {
- case 103 :
- if (remaining & 0b1000) return false;
- remaining |= 0b1000;
- break;
- case 105 :
- if (remaining & 0b0100) return false;
- remaining |= 0b0100;
- break;
- case 109 :
- if (remaining & 0b0010) return false;
- remaining |= 0b0010;
- break;
- case 121 :
- if (remaining & 0b0001) return false;
- remaining |= 0b0001;
- break;
- default:
- return false;
- }
- return true;
- };
- module.exports = BasicEvaluatedExpression;
|