| 
									
										
										
										
											2013-01-31 01:49:25 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | /** @typedef {import("estree").Node} Node */ | 
					
						
							| 
									
										
										
										
											2023-06-03 06:16:53 +08:00
										 |  |  | /** @typedef {import("./JavascriptParser").Range} Range */ | 
					
						
							| 
									
										
										
										
											2025-03-07 21:12:22 +08:00
										 |  |  | /** @typedef {import("./JavascriptParser").VariableInfo} VariableInfo */ | 
					
						
							| 
									
										
										
										
											2025-09-11 08:10:10 +08:00
										 |  |  | /** @typedef {import("./JavascriptParser").Members} Members */ | 
					
						
							|  |  |  | /** @typedef {import("./JavascriptParser").MembersOptionals} MembersOptionals */ | 
					
						
							|  |  |  | /** @typedef {import("./JavascriptParser").MemberRanges} MemberRanges */ | 
					
						
							| 
									
										
										
										
											2020-07-23 00:58:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | const TypeUnknown = 0; | 
					
						
							| 
									
										
										
										
											2020-07-06 23:13:09 +08:00
										 |  |  | 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; | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-11 08:10:10 +08:00
										 |  |  | /** @typedef {() => Members} GetMembers */ | 
					
						
							|  |  |  | /** @typedef {() => MembersOptionals} GetMembersOptionals */ | 
					
						
							|  |  |  | /** @typedef {() => MemberRanges} GetMemberRanges */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | class BasicEvaluatedExpression { | 
					
						
							|  |  |  | 	constructor() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeUnknown; | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 		/** @type {Range | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.range = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {boolean} */ | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.falsy = false; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {boolean} */ | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.truthy = false; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {boolean | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-07-20 15:19:18 +08:00
										 |  |  | 		this.nullish = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		/** @type {boolean} */ | 
					
						
							|  |  |  | 		this.sideEffects = true; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {boolean | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.bool = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {number | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.number = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {bigint | undefined} */ | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 		this.bigint = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {RegExp | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.regExp = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {string | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.string = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.quasis = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.parts = undefined; | 
					
						
							| 
									
										
										
										
											2025-03-07 21:12:22 +08:00
										 |  |  | 		/** @type {EXPECTED_ANY[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.array = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.items = undefined; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.options = undefined; | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression | undefined | null} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.prefix = undefined; | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression | undefined | null} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.postfix = undefined; | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 		/** @type {BasicEvaluatedExpression[] | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.wrappedInnerExpressions = undefined; | 
					
						
							| 
									
										
										
										
											2025-03-07 21:12:22 +08:00
										 |  |  | 		/** @type {string | VariableInfo | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.identifier = undefined; | 
					
						
							| 
									
										
										
										
											2025-03-07 21:12:22 +08:00
										 |  |  | 		/** @type {string | VariableInfo | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.rootInfo = undefined; | 
					
						
							| 
									
										
										
										
											2025-09-11 08:10:10 +08:00
										 |  |  | 		/** @type {GetMembers | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.getMembers = undefined; | 
					
						
							| 
									
										
										
										
											2025-09-11 08:10:10 +08:00
										 |  |  | 		/** @type {GetMembersOptionals | undefined} */ | 
					
						
							| 
									
										
										
										
											2022-03-01 03:50:37 +08:00
										 |  |  | 		this.getMembersOptionals = undefined; | 
					
						
							| 
									
										
										
										
											2025-09-11 08:10:10 +08:00
										 |  |  | 		/** @type {GetMemberRanges | undefined} */ | 
					
						
							| 
									
										
										
										
											2023-06-03 06:16:53 +08:00
										 |  |  | 		this.getMemberRanges = undefined; | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 		/** @type {Node | undefined} */ | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.expression = undefined; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 	isUnknown() { | 
					
						
							|  |  |  | 		return this.type === TypeUnknown; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	isNull() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeNull; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 23:13:09 +08:00
										 |  |  | 	isUndefined() { | 
					
						
							|  |  |  | 		return this.type === TypeUndefined; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	isString() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeString; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isNumber() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeNumber; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 	isBigInt() { | 
					
						
							|  |  |  | 		return this.type === TypeBigInt; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	isBoolean() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeBoolean; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isRegExp() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeRegExp; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isConditional() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeConditional; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isArray() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeArray; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isConstArray() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeConstArray; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isIdentifier() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeIdentifier; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isWrapped() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeWrapped; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isTemplateString() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		return this.type === TypeTemplateString; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 	 * Is expression a primitive or an object type value? | 
					
						
							|  |  |  | 	 * @returns {boolean | undefined} true: primitive type, false: object type, undefined: unknown/runtime-defined | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 	isPrimitiveType() { | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 		switch (this.type) { | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 			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; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * Is expression a runtime or compile-time value? | 
					
						
							|  |  |  | 	 * @returns {boolean} true: compile time value, false: runtime value | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	isCompileTimeValue() { | 
					
						
							|  |  |  | 		switch (this.type) { | 
					
						
							|  |  |  | 			case TypeUndefined: | 
					
						
							|  |  |  | 			case TypeNull: | 
					
						
							|  |  |  | 			case TypeString: | 
					
						
							|  |  |  | 			case TypeNumber: | 
					
						
							|  |  |  | 			case TypeBoolean: | 
					
						
							|  |  |  | 			case TypeRegExp: | 
					
						
							|  |  |  | 			case TypeConstArray: | 
					
						
							|  |  |  | 			case TypeBigInt: | 
					
						
							|  |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 			default: | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 				return false; | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 	 * Gets the compile-time value of the expression | 
					
						
							| 
									
										
										
										
											2025-04-16 22:04:11 +08:00
										 |  |  | 	 * @returns {undefined | null | string | number | boolean | RegExp | EXPECTED_ANY[] | bigint} the javascript value | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 	asCompileTimeValue() { | 
					
						
							|  |  |  | 		switch (this.type) { | 
					
						
							|  |  |  | 			case TypeUndefined: | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 				return; | 
					
						
							| 
									
										
										
										
											2020-07-20 18:07:08 +08:00
										 |  |  | 			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" | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 21:58:24 +08:00
										 |  |  | 	isTruthy() { | 
					
						
							|  |  |  | 		return this.truthy; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	isFalsy() { | 
					
						
							|  |  |  | 		return this.falsy; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:19:18 +08:00
										 |  |  | 	isNullish() { | 
					
						
							|  |  |  | 		return this.nullish; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Can this expression have side effects? | 
					
						
							|  |  |  | 	 * @returns {boolean} false: never has side effects | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	couldHaveSideEffects() { | 
					
						
							|  |  |  | 		return this.sideEffects; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 01:59:30 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Creates a boolean representation of this evaluated expression. | 
					
						
							|  |  |  | 	 * @returns {boolean | undefined} true: truthy, false: falsy, undefined: unknown | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	asBool() { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (this.truthy) return true; | 
					
						
							| 
									
										
										
										
											2020-07-18 20:06:17 +08:00
										 |  |  | 		if (this.falsy || this.nullish) return false; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 		if (this.isBoolean()) return this.bool; | 
					
						
							|  |  |  | 		if (this.isNull()) return false; | 
					
						
							| 
									
										
										
										
											2020-07-06 23:13:09 +08:00
										 |  |  | 		if (this.isUndefined()) return false; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 		if (this.isString()) return this.string !== ""; | 
					
						
							|  |  |  | 		if (this.isNumber()) return this.number !== 0; | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 		if (this.isBigInt()) return this.bigint !== BigInt(0); | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 		if (this.isRegExp()) return true; | 
					
						
							|  |  |  | 		if (this.isArray()) return true; | 
					
						
							|  |  |  | 		if (this.isConstArray()) return true; | 
					
						
							|  |  |  | 		if (this.isWrapped()) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 			return (this.prefix && this.prefix.asBool()) || | 
					
						
							|  |  |  | 				(this.postfix && this.postfix.asBool()) | 
					
						
							|  |  |  | 				? true | 
					
						
							|  |  |  | 				: undefined; | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (this.isTemplateString()) { | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 			const str = this.asString(); | 
					
						
							|  |  |  | 			if (typeof str === "string") return str !== ""; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 01:59:30 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Creates a nullish coalescing representation of this evaluated expression. | 
					
						
							|  |  |  | 	 * @returns {boolean | undefined} true: nullish, false: not nullish, undefined: unknown | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-07-20 15:19:18 +08:00
										 |  |  | 	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; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Creates a string representation of this evaluated expression. | 
					
						
							|  |  |  | 	 * @returns {string | undefined} the string representation or undefined if not possible | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 	asString() { | 
					
						
							|  |  |  | 		if (this.isBoolean()) return `${this.bool}`; | 
					
						
							|  |  |  | 		if (this.isNull()) return "null"; | 
					
						
							| 
									
										
										
										
											2020-07-06 23:13:09 +08:00
										 |  |  | 		if (this.isUndefined()) return "undefined"; | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 		if (this.isString()) return this.string; | 
					
						
							|  |  |  | 		if (this.isNumber()) return `${this.number}`; | 
					
						
							| 
									
										
										
										
											2020-03-02 19:09:54 +08:00
										 |  |  | 		if (this.isBigInt()) return `${this.bigint}`; | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 		if (this.isRegExp()) return `${this.regExp}`; | 
					
						
							|  |  |  | 		if (this.isArray()) { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:09:42 +08:00
										 |  |  | 			const array = []; | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 			for (const item of /** @type {BasicEvaluatedExpression[]} */ ( | 
					
						
							|  |  |  | 				this.items | 
					
						
							|  |  |  | 			)) { | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 				const itemStr = item.asString(); | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 				if (itemStr === undefined) return; | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 				array.push(itemStr); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return `${array}`; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (this.isConstArray()) return `${this.array}`; | 
					
						
							|  |  |  | 		if (this.isTemplateString()) { | 
					
						
							|  |  |  | 			let str = ""; | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 			for (const part of /** @type {BasicEvaluatedExpression[]} */ ( | 
					
						
							|  |  |  | 				this.parts | 
					
						
							|  |  |  | 			)) { | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 				const partStr = part.asString(); | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 				if (partStr === undefined) return; | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 				str += partStr; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 			return str; | 
					
						
							| 
									
										
										
										
											2016-11-15 21:03:53 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} string value | 
					
						
							|  |  |  | 	 * @returns {BasicEvaluatedExpression} basic evaluated expression | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 	setString(string) { | 
					
						
							|  |  |  | 		this.type = TypeString; | 
					
						
							|  |  |  | 		this.string = string; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-06 23:13:09 +08:00
										 |  |  | 	setUndefined() { | 
					
						
							|  |  |  | 		this.type = TypeUndefined; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2020-07-06 23:13:09 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	setNull() { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeNull; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to a number | 
					
						
							|  |  |  | 	 * @param {number} number number to set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 	setNumber(number) { | 
					
						
							|  |  |  | 		this.type = TypeNumber; | 
					
						
							|  |  |  | 		this.number = number; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to a BigInt | 
					
						
							|  |  |  | 	 * @param {bigint} bigint bigint to set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 	setBigInt(bigint) { | 
					
						
							|  |  |  | 		this.type = TypeBigInt; | 
					
						
							|  |  |  | 		this.bigint = bigint; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2020-02-29 01:09:59 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to a boolean | 
					
						
							|  |  |  | 	 * @param {boolean} bool boolean to set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	setBoolean(bool) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeBoolean; | 
					
						
							|  |  |  | 		this.bool = bool; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to a regular expression | 
					
						
							|  |  |  | 	 * @param {RegExp} regExp regular expression to set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	setRegExp(regExp) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeRegExp; | 
					
						
							|  |  |  | 		this.regExp = regExp; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to a particular identifier and its members. | 
					
						
							| 
									
										
										
										
											2025-03-07 21:12:22 +08:00
										 |  |  | 	 * @param {string | VariableInfo} identifier identifier to set | 
					
						
							|  |  |  | 	 * @param {string | VariableInfo} rootInfo root info | 
					
						
							| 
									
										
										
										
											2025-09-11 08:10:10 +08:00
										 |  |  | 	 * @param {GetMembers} getMembers members | 
					
						
							|  |  |  | 	 * @param {GetMembersOptionals=} getMembersOptionals optional members | 
					
						
							|  |  |  | 	 * @param {GetMemberRanges=} getMemberRanges ranges of progressively increasing sub-expressions | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2023-05-24 06:29:25 +08:00
										 |  |  | 	setIdentifier( | 
					
						
							|  |  |  | 		identifier, | 
					
						
							|  |  |  | 		rootInfo, | 
					
						
							|  |  |  | 		getMembers, | 
					
						
							|  |  |  | 		getMembersOptionals, | 
					
						
							| 
									
										
										
										
											2023-06-03 06:16:53 +08:00
										 |  |  | 		getMemberRanges | 
					
						
							| 
									
										
										
										
											2023-05-24 06:29:25 +08:00
										 |  |  | 	) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeIdentifier; | 
					
						
							|  |  |  | 		this.identifier = identifier; | 
					
						
							| 
									
										
										
										
											2019-08-29 21:28:19 +08:00
										 |  |  | 		this.rootInfo = rootInfo; | 
					
						
							|  |  |  | 		this.getMembers = getMembers; | 
					
						
							| 
									
										
										
										
											2022-03-01 03:50:37 +08:00
										 |  |  | 		this.getMembersOptionals = getMembersOptionals; | 
					
						
							| 
									
										
										
										
											2023-06-03 06:16:53 +08:00
										 |  |  | 		this.getMemberRanges = getMemberRanges; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = true; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Wraps an array of expressions with a prefix and postfix expression. | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 	 * @param {BasicEvaluatedExpression | null | undefined} prefix Expression to be added before the innerExpressions | 
					
						
							|  |  |  | 	 * @param {BasicEvaluatedExpression | null | undefined} postfix Expression to be added after the innerExpressions | 
					
						
							| 
									
										
										
										
											2024-03-14 23:15:13 +08:00
										 |  |  | 	 * @param {BasicEvaluatedExpression[] | undefined} innerExpressions Expressions to be wrapped | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-11-05 22:17:10 +08:00
										 |  |  | 	setWrapped(prefix, postfix, innerExpressions) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeWrapped; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		this.prefix = prefix; | 
					
						
							|  |  |  | 		this.postfix = postfix; | 
					
						
							| 
									
										
										
										
											2018-11-05 22:17:10 +08:00
										 |  |  | 		this.wrappedInnerExpressions = innerExpressions; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = true; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Stores the options of a conditional expression. | 
					
						
							|  |  |  | 	 * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 	setOptions(options) { | 
					
						
							|  |  |  | 		this.type = TypeConditional; | 
					
						
							|  |  |  | 		this.options = options; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = true; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Adds options to a conditional expression. | 
					
						
							|  |  |  | 	 * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be added | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 	addOptions(options) { | 
					
						
							| 
									
										
										
										
											2018-02-25 09:00:20 +08:00
										 |  |  | 		if (!this.options) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 			this.type = TypeConditional; | 
					
						
							|  |  |  | 			this.options = []; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 			this.sideEffects = true; | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-05-29 20:50:40 +08:00
										 |  |  | 		for (const item of options) { | 
					
						
							|  |  |  | 			this.options.push(item); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to an array of expressions. | 
					
						
							|  |  |  | 	 * @param {BasicEvaluatedExpression[]} items expressions to set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	setItems(items) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeArray; | 
					
						
							|  |  |  | 		this.items = items; | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 		this.sideEffects = items.some((i) => i.couldHaveSideEffects()); | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to an array of strings. | 
					
						
							|  |  |  | 	 * @param {string[]} array array to set | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	setArray(array) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeConstArray; | 
					
						
							|  |  |  | 		this.array = array; | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 		this.sideEffects = false; | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of this expression to a processed/unprocessed template string. Used | 
					
						
							|  |  |  | 	 * for evaluating TemplateLiteral expressions in the JavaScript Parser. | 
					
						
							|  |  |  | 	 * @param {BasicEvaluatedExpression[]} quasis template string quasis | 
					
						
							|  |  |  | 	 * @param {BasicEvaluatedExpression[]} parts template string parts | 
					
						
							|  |  |  | 	 * @param {"cooked" | "raw"} kind template string kind | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 	setTemplateString(quasis, parts, kind) { | 
					
						
							| 
									
										
										
										
											2018-01-04 05:42:57 +08:00
										 |  |  | 		this.type = TypeTemplateString; | 
					
						
							|  |  |  | 		this.quasis = quasis; | 
					
						
							| 
									
										
										
										
											2018-10-30 19:39:43 +08:00
										 |  |  | 		this.parts = parts; | 
					
						
							| 
									
										
										
										
											2018-11-03 18:14:15 +08:00
										 |  |  | 		this.templateStringKind = kind; | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 		this.sideEffects = parts.some((p) => p.sideEffects); | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 20:38:42 +08:00
										 |  |  | 	setTruthy() { | 
					
						
							|  |  |  | 		this.falsy = false; | 
					
						
							|  |  |  | 		this.truthy = true; | 
					
						
							|  |  |  | 		this.nullish = false; | 
					
						
							| 
									
										
										
										
											2017-06-02 19:24:47 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 20:38:42 +08:00
										 |  |  | 	setFalsy() { | 
					
						
							|  |  |  | 		this.falsy = true; | 
					
						
							|  |  |  | 		this.truthy = false; | 
					
						
							| 
									
										
										
										
											2017-06-02 19:24:47 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the value of the expression to nullish. | 
					
						
							|  |  |  | 	 * @param {boolean} value true, if the expression is nullish | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-07-20 15:19:18 +08:00
										 |  |  | 	setNullish(value) { | 
					
						
							|  |  |  | 		this.nullish = value; | 
					
						
							| 
									
										
										
										
											2021-09-20 20:38:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (value) return this.setFalsy(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 15:19:18 +08:00
										 |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set's the range for the expression. | 
					
						
							| 
									
										
										
										
											2025-04-17 06:54:48 +08:00
										 |  |  | 	 * @param {Range} range range to set | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 	setRange(range) { | 
					
						
							|  |  |  | 		this.range = range; | 
					
						
							|  |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-30 19:39:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set whether or not the expression has side effects. | 
					
						
							|  |  |  | 	 * @param {boolean} sideEffects true, if the expression has side effects | 
					
						
							|  |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-07-21 18:57:32 +08:00
										 |  |  | 	setSideEffects(sideEffects = true) { | 
					
						
							|  |  |  | 		this.sideEffects = sideEffects; | 
					
						
							|  |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * Set the expression node for the expression. | 
					
						
							| 
									
										
										
										
											2023-06-13 01:24:59 +08:00
										 |  |  | 	 * @param {Node | undefined} expression expression | 
					
						
							| 
									
										
										
										
											2023-04-29 03:21:02 +08:00
										 |  |  | 	 * @returns {this} this | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-10-30 19:39:43 +08:00
										 |  |  | 	setExpression(expression) { | 
					
						
							|  |  |  | 		this.expression = expression; | 
					
						
							|  |  |  | 		return this; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-15 21:03:53 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-10 03:17:19 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {string} flags regexp flags | 
					
						
							|  |  |  |  * @returns {boolean} is valid flags | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | BasicEvaluatedExpression.isValidRegExpFlags = (flags) => { | 
					
						
							| 
									
										
										
										
											2020-08-10 03:17:19 +08:00
										 |  |  | 	const len = flags.length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (len === 0) return true; | 
					
						
							|  |  |  | 	if (len > 4) return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-15 17:25:41 +08:00
										 |  |  | 	// cspell:word gimy
 | 
					
						
							|  |  |  | 	let remaining = 0b0000; // bit per RegExp flag: gimy
 | 
					
						
							| 
									
										
										
										
											2020-08-10 03:17:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 	for (let i = 0; i < len; i++) { | 
					
						
							| 
									
										
										
										
											2020-08-15 17:25:41 +08:00
										 |  |  | 		switch (flags.charCodeAt(i)) { | 
					
						
							|  |  |  | 			case 103 /* g */: | 
					
						
							|  |  |  | 				if (remaining & 0b1000) return false; | 
					
						
							|  |  |  | 				remaining |= 0b1000; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 105 /* i */: | 
					
						
							|  |  |  | 				if (remaining & 0b0100) return false; | 
					
						
							|  |  |  | 				remaining |= 0b0100; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 109 /* m */: | 
					
						
							|  |  |  | 				if (remaining & 0b0010) return false; | 
					
						
							|  |  |  | 				remaining |= 0b0010; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 121 /* y */: | 
					
						
							|  |  |  | 				if (remaining & 0b0001) return false; | 
					
						
							|  |  |  | 				remaining |= 0b0001; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-08-10 03:17:19 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-03 05:32:23 +08:00
										 |  |  | module.exports = BasicEvaluatedExpression; |