diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:10:59 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2026-05-18 23:41:44 +0800 |
| commit | fc87c009806dcc98867f6b58efe29b042aa01dee (patch) | |
| tree | 8f59b3f4a5b66e9dfef2d40c8d318e258a521228 /node_modules/terser/lib/compress/evaluate.js | |
| parent | 3336b2356ee6152d9c6ae59bd9b87ccbc0958407 (diff) | |
node: updatemain
Diffstat (limited to 'node_modules/terser/lib/compress/evaluate.js')
| -rw-r--r-- | node_modules/terser/lib/compress/evaluate.js | 505 |
1 files changed, 0 insertions, 505 deletions
diff --git a/node_modules/terser/lib/compress/evaluate.js b/node_modules/terser/lib/compress/evaluate.js deleted file mode 100644 index 70b197cd..00000000 --- a/node_modules/terser/lib/compress/evaluate.js +++ /dev/null @@ -1,505 +0,0 @@ -/*********************************************************************** - - A JavaScript tokenizer / parser / beautifier / compressor. - https://github.com/mishoo/UglifyJS2 - - -------------------------------- (C) --------------------------------- - - Author: Mihai Bazon - <mihai.bazon@gmail.com> - http://mihai.bazon.net/blog - - Distributed under the BSD license: - - Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com> - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - ***********************************************************************/ - -import { - HOP, - makePredicate, - return_this, - string_template, - regexp_source_fix, - regexp_is_safe, -} from "../utils/index.js"; -import { - AST_Array, - AST_BigInt, - AST_Binary, - AST_Call, - AST_Chain, - AST_Class, - AST_Conditional, - AST_Constant, - AST_Dot, - AST_Expansion, - AST_Function, - AST_Lambda, - AST_New, - AST_Node, - AST_Object, - AST_PropAccess, - AST_RegExp, - AST_Statement, - AST_Symbol, - AST_SymbolRef, - AST_TemplateString, - AST_UnaryPrefix, - AST_With, -} from "../ast.js"; -import { is_undeclared_ref} from "./inference.js"; -import { is_pure_native_value, is_pure_native_fn, is_pure_native_method } from "./native-objects.js"; - -// methods to evaluate a constant expression - -function def_eval(node, func) { - node.DEFMETHOD("_eval", func); -} - -// Used to propagate a nullish short-circuit signal upwards through the chain. -export const nullish = Symbol("This AST_Chain is nullish"); - -// If the node has been successfully reduced to a constant, -// then its value is returned; otherwise the element itself -// is returned. -// They can be distinguished as constant value is never a -// descendant of AST_Node. -AST_Node.DEFMETHOD("evaluate", function (compressor) { - if (!compressor.option("evaluate")) - return this; - var val = this._eval(compressor, 1); - if (!val || val instanceof RegExp) - return val; - if (typeof val == "function" || typeof val == "object" || val == nullish) - return this; - - // Evaluated strings can be larger than the original expression - if (typeof val === "string") { - const unevaluated_size = this.size(compressor); - if (val.length + 2 > unevaluated_size) return this; - } - - return val; -}); - -var unaryPrefix = makePredicate("! ~ - + void"); -AST_Node.DEFMETHOD("is_constant", function () { - // Accomodate when compress option evaluate=false - // as well as the common constant expressions !0 and -1 - if (this instanceof AST_Constant) { - return !(this instanceof AST_RegExp); - } else { - return this instanceof AST_UnaryPrefix - && this.expression instanceof AST_Constant - && unaryPrefix.has(this.operator); - } -}); - -def_eval(AST_Statement, function () { - throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); -}); - -def_eval(AST_Lambda, return_this); -def_eval(AST_Class, return_this); -def_eval(AST_Node, return_this); -def_eval(AST_Constant, function () { - return this.getValue(); -}); - -const supports_bigint = typeof BigInt === "function"; -def_eval(AST_BigInt, function () { - if (supports_bigint) { - return BigInt(this.value); - } else { - return this; - } -}); - -def_eval(AST_RegExp, function (compressor) { - let evaluated = compressor.evaluated_regexps.get(this.value); - if (evaluated === undefined && regexp_is_safe(this.value.source)) { - try { - const { source, flags } = this.value; - evaluated = new RegExp(source, flags); - } catch (e) { - evaluated = null; - } - compressor.evaluated_regexps.set(this.value, evaluated); - } - return evaluated || this; -}); - -def_eval(AST_TemplateString, function () { - if (this.segments.length !== 1) return this; - return this.segments[0].value; -}); - -def_eval(AST_Function, function (compressor) { - if (compressor.option("unsafe")) { - var fn = function () { }; - fn.node = this; - fn.toString = () => this.print_to_string(); - return fn; - } - return this; -}); - -def_eval(AST_Array, function (compressor, depth) { - if (compressor.option("unsafe")) { - var elements = []; - for (var i = 0, len = this.elements.length; i < len; i++) { - var element = this.elements[i]; - var value = element._eval(compressor, depth); - if (element === value) - return this; - elements.push(value); - } - return elements; - } - return this; -}); - -def_eval(AST_Object, function (compressor, depth) { - if (compressor.option("unsafe")) { - var val = {}; - for (var i = 0, len = this.properties.length; i < len; i++) { - var prop = this.properties[i]; - if (prop instanceof AST_Expansion) - return this; - var key = prop.key; - if (key instanceof AST_Symbol) { - key = key.name; - } else if (key instanceof AST_Node) { - key = key._eval(compressor, depth); - if (key === prop.key) - return this; - } - if (typeof Object.prototype[key] === "function") { - return this; - } - if (prop.value instanceof AST_Function) - continue; - val[key] = prop.value._eval(compressor, depth); - if (val[key] === prop.value) - return this; - } - return val; - } - return this; -}); - -var non_converting_unary = makePredicate("! typeof void"); -def_eval(AST_UnaryPrefix, function (compressor, depth) { - var e = this.expression; - // Function would be evaluated to an array and so typeof would - // incorrectly return 'object'. Hence making is a special case. - if (compressor.option("typeofs") - && this.operator == "typeof" - && (e instanceof AST_Lambda - || e instanceof AST_SymbolRef - && e.fixed_value() instanceof AST_Lambda)) { - return typeof function () { }; - } - if (!non_converting_unary.has(this.operator)) - depth++; - e = e._eval(compressor, depth); - if (e === this.expression) - return this; - switch (this.operator) { - case "!": return !e; - case "typeof": - // typeof <RegExp> returns "object" or "function" on different platforms - // so cannot evaluate reliably - if (e instanceof RegExp) - return this; - return typeof e; - case "void": return void e; - case "~": return ~e; - case "-": return -e; - case "+": return +e; - } - return this; -}); - -var non_converting_binary = makePredicate("&& || ?? === !=="); -const identity_comparison = makePredicate("== != === !=="); -const has_identity = value => typeof value === "object" - || typeof value === "function" - || typeof value === "symbol"; - -def_eval(AST_Binary, function (compressor, depth) { - if (!non_converting_binary.has(this.operator)) - depth++; - - var left = this.left._eval(compressor, depth); - if (left === this.left) - return this; - var right = this.right._eval(compressor, depth); - if (right === this.right) - return this; - - if (left != null - && right != null - && identity_comparison.has(this.operator) - && has_identity(left) - && has_identity(right) - && typeof left === typeof right) { - // Do not compare by reference - return this; - } - - // Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n` - if ( - (typeof left === "bigint") !== (typeof right === "bigint") - || typeof left === "bigint" - && (this.operator === ">>>" - || this.operator === "/" && Number(right) === 0) - ) { - return this; - } - - var result; - switch (this.operator) { - case "&&": result = left && right; break; - case "||": result = left || right; break; - case "??": result = left != null ? left : right; break; - case "|": result = left | right; break; - case "&": result = left & right; break; - case "^": result = left ^ right; break; - case "+": result = left + right; break; - case "*": result = left * right; break; - case "**": result = left ** right; break; - case "/": result = left / right; break; - case "%": result = left % right; break; - case "-": result = left - right; break; - case "<<": result = left << right; break; - case ">>": result = left >> right; break; - case ">>>": result = left >>> right; break; - case "==": result = left == right; break; - case "===": result = left === right; break; - case "!=": result = left != right; break; - case "!==": result = left !== right; break; - case "<": result = left < right; break; - case "<=": result = left <= right; break; - case ">": result = left > right; break; - case ">=": result = left >= right; break; - default: - return this; - } - if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) { - // leave original expression as is - return this; - } - return result; -}); - -def_eval(AST_Conditional, function (compressor, depth) { - var condition = this.condition._eval(compressor, depth); - if (condition === this.condition) - return this; - var node = condition ? this.consequent : this.alternative; - var value = node._eval(compressor, depth); - return value === node ? this : value; -}); - -// Set of AST_SymbolRef which are currently being evaluated. -// Avoids infinite recursion of ._eval() -const reentrant_ref_eval = new Set(); -def_eval(AST_SymbolRef, function (compressor, depth) { - if (reentrant_ref_eval.has(this)) - return this; - - var fixed = this.fixed_value(); - if (!fixed) - return this; - - reentrant_ref_eval.add(this); - const value = fixed._eval(compressor, depth); - reentrant_ref_eval.delete(this); - - if (value === fixed) - return this; - - if (value && typeof value == "object") { - var escaped = this.definition().escaped; - if (escaped && depth > escaped) - return this; - } - return value; -}); - -const global_objs = { Array, Math, Number, Object, String }; - -const regexp_flags = new Set([ - "dotAll", - "global", - "ignoreCase", - "multiline", - "sticky", - "unicode", -]); - -def_eval(AST_PropAccess, function (compressor, depth) { - let obj = this.expression._eval(compressor, depth + 1); - if (obj === nullish || (this.optional && obj == null)) return nullish; - - // `.length` of strings and arrays is always safe - if (this.property === "length") { - if (typeof obj === "string") { - return obj.length; - } - - const is_spreadless_array = - obj instanceof AST_Array - && obj.elements.every(el => !(el instanceof AST_Expansion)); - - if ( - is_spreadless_array - && obj.elements.every(el => !el.has_side_effects(compressor)) - ) { - return obj.elements.length; - } - } - - if (compressor.option("unsafe")) { - var key = this.property; - if (key instanceof AST_Node) { - key = key._eval(compressor, depth); - if (key === this.property) - return this; - } - - var exp = this.expression; - if (is_undeclared_ref(exp)) { - var aa; - var first_arg = exp.name === "hasOwnProperty" - && key === "call" - && (aa = compressor.parent() && compressor.parent().args) - && (aa && aa[0] - && aa[0].evaluate(compressor)); - - first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg; - - if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) { - return this.clone(); - } - if (!is_pure_native_value(exp.name, key)) - return this; - obj = global_objs[exp.name]; - } else { - if (obj instanceof RegExp) { - if (key == "source") { - return regexp_source_fix(obj.source); - } else if (key == "flags" || regexp_flags.has(key)) { - return obj[key]; - } - } - if (!obj || obj === exp || !HOP(obj, key)) - return this; - - if (typeof obj == "function") - switch (key) { - case "name": - return obj.node.name ? obj.node.name.name : ""; - case "length": - return obj.node.length_property(); - default: - return this; - } - } - return obj[key]; - } - return this; -}); - -def_eval(AST_Chain, function (compressor, depth) { - const evaluated = this.expression._eval(compressor, depth); - return evaluated === nullish - ? undefined - : evaluated === this.expression - ? this - : evaluated; -}); - -def_eval(AST_Call, function (compressor, depth) { - var exp = this.expression; - - const callee = exp._eval(compressor, depth); - if (callee === nullish || (this.optional && callee == null)) return nullish; - - if (compressor.option("unsafe") && exp instanceof AST_PropAccess) { - var key = exp.property; - if (key instanceof AST_Node) { - key = key._eval(compressor, depth); - if (key === exp.property) - return this; - } - var val; - var e = exp.expression; - if (is_undeclared_ref(e)) { - var first_arg = e.name === "hasOwnProperty" && - key === "call" && - (this.args[0] && this.args[0].evaluate(compressor)); - - first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg; - - if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) { - return this.clone(); - } - if (!is_pure_native_fn(e.name, key)) return this; - val = global_objs[e.name]; - } else { - val = e._eval(compressor, depth + 1); - if (val === e || !val) - return this; - if (!is_pure_native_method(val.constructor.name, key)) - return this; - } - var args = []; - for (var i = 0, len = this.args.length; i < len; i++) { - var arg = this.args[i]; - var value = arg._eval(compressor, depth); - if (arg === value) - return this; - if (arg instanceof AST_Lambda) - return this; - args.push(value); - } - try { - return val[key].apply(val, args); - } catch (ex) { - // We don't really care - } - } - return this; -}); - -// Also a subclass of AST_Call -def_eval(AST_New, return_this); |
