diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2023-10-31 15:37:35 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2023-10-31 15:37:35 +0800 |
| commit | d5f14083061f2ce6a42313188443a42e30796320 (patch) | |
| tree | cc6a9889e08b29595a76a33b9e7b4ef84866468b /node_modules/terser/lib/compress/common.js | |
| parent | b1a6ea021f29f182b62f9f81024a3d8ac8621b7f (diff) | |
added make browserlist(autoprefixer) work fixed
Diffstat (limited to 'node_modules/terser/lib/compress/common.js')
| -rw-r--r-- | node_modules/terser/lib/compress/common.js | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/node_modules/terser/lib/compress/common.js b/node_modules/terser/lib/compress/common.js new file mode 100644 index 00000000..0b6cac51 --- /dev/null +++ b/node_modules/terser/lib/compress/common.js @@ -0,0 +1,348 @@ +/*********************************************************************** + + 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 { + AST_Array, + AST_Arrow, + AST_BlockStatement, + AST_Call, + AST_Chain, + AST_Class, + AST_Const, + AST_Constant, + AST_DefClass, + AST_Defun, + AST_EmptyStatement, + AST_Export, + AST_False, + AST_Function, + AST_Import, + AST_Infinity, + AST_LabeledStatement, + AST_Lambda, + AST_Let, + AST_LoopControl, + AST_NaN, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectKeyVal, + AST_PropAccess, + AST_RegExp, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_String, + AST_SymbolRef, + AST_True, + AST_UnaryPrefix, + AST_Undefined, + + TreeWalker, + walk, + walk_abort, + walk_parent, +} from "../ast.js"; +import { make_node, regexp_source_fix, string_template, makePredicate } from "../utils/index.js"; +import { first_in_statement } from "../utils/first_in_statement.js"; +import { has_flag, TOP } from "./compressor-flags.js"; + +export function merge_sequence(array, node) { + if (node instanceof AST_Sequence) { + array.push(...node.expressions); + } else { + array.push(node); + } + return array; +} + +export function make_sequence(orig, expressions) { + if (expressions.length == 1) return expressions[0]; + if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!"); + return make_node(AST_Sequence, orig, { + expressions: expressions.reduce(merge_sequence, []) + }); +} + +export function make_node_from_constant(val, orig) { + switch (typeof val) { + case "string": + return make_node(AST_String, orig, { + value: val + }); + case "number": + if (isNaN(val)) return make_node(AST_NaN, orig); + if (isFinite(val)) { + return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Number, orig, { value: -val }) + }) : make_node(AST_Number, orig, { value: val }); + } + return val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Infinity, orig) + }) : make_node(AST_Infinity, orig); + case "boolean": + return make_node(val ? AST_True : AST_False, orig); + case "undefined": + return make_node(AST_Undefined, orig); + default: + if (val === null) { + return make_node(AST_Null, orig, { value: null }); + } + if (val instanceof RegExp) { + return make_node(AST_RegExp, orig, { + value: { + source: regexp_source_fix(val.source), + flags: val.flags + } + }); + } + throw new Error(string_template("Can't handle constant of type: {type}", { + type: typeof val + })); + } +} + +export function best_of_expression(ast1, ast2) { + return ast1.size() > ast2.size() ? ast2 : ast1; +} + +export function best_of_statement(ast1, ast2) { + return best_of_expression( + make_node(AST_SimpleStatement, ast1, { + body: ast1 + }), + make_node(AST_SimpleStatement, ast2, { + body: ast2 + }) + ).body; +} + +/** Find which node is smaller, and return that */ +export function best_of(compressor, ast1, ast2) { + if (first_in_statement(compressor)) { + return best_of_statement(ast1, ast2); + } else { + return best_of_expression(ast1, ast2); + } +} + +/** Simplify an object property's key, if possible */ +export function get_simple_key(key) { + if (key instanceof AST_Constant) { + return key.getValue(); + } + if (key instanceof AST_UnaryPrefix + && key.operator == "void" + && key.expression instanceof AST_Constant) { + return; + } + return key; +} + +export function read_property(obj, key) { + key = get_simple_key(key); + if (key instanceof AST_Node) return; + + var value; + if (obj instanceof AST_Array) { + var elements = obj.elements; + if (key == "length") return make_node_from_constant(elements.length, obj); + if (typeof key == "number" && key in elements) value = elements[key]; + } else if (obj instanceof AST_Object) { + key = "" + key; + var props = obj.properties; + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + if (!(prop instanceof AST_ObjectKeyVal)) return; + if (!value && props[i].key === key) value = props[i].value; + } + } + + return value instanceof AST_SymbolRef && value.fixed_value() || value; +} + +export function has_break_or_continue(loop, parent) { + var found = false; + var tw = new TreeWalker(function(node) { + if (found || node instanceof AST_Scope) return true; + if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) { + return found = true; + } + }); + if (parent instanceof AST_LabeledStatement) tw.push(parent); + tw.push(loop); + loop.body.walk(tw); + return found; +} + +// we shouldn't compress (1,func)(something) to +// func(something) because that changes the meaning of +// the func (becomes lexical instead of global). +export function maintain_this_binding(parent, orig, val) { + if ( + parent instanceof AST_UnaryPrefix && parent.operator == "delete" + || parent instanceof AST_Call && parent.expression === orig + && ( + val instanceof AST_Chain + || val instanceof AST_PropAccess + || val instanceof AST_SymbolRef && val.name == "eval" + ) + ) { + const zero = make_node(AST_Number, orig, { value: 0 }); + return make_sequence(orig, [ zero, val ]); + } else { + return val; + } +} + +export function is_func_expr(node) { + return node instanceof AST_Arrow || node instanceof AST_Function; +} + +/** + * Used to determine whether the node can benefit from negation. + * Not the case with arrow functions (you need an extra set of parens). */ +export function is_iife_call(node) { + if (node.TYPE != "Call") return false; + return node.expression instanceof AST_Function || is_iife_call(node.expression); +} + +export function is_empty(thing) { + if (thing === null) return true; + if (thing instanceof AST_EmptyStatement) return true; + if (thing instanceof AST_BlockStatement) return thing.body.length == 0; + return false; +} + +export const identifier_atom = makePredicate("Infinity NaN undefined"); +export function is_identifier_atom(node) { + return node instanceof AST_Infinity + || node instanceof AST_NaN + || node instanceof AST_Undefined; +} + +/** Check if this is a SymbolRef node which has one def of a certain AST type */ +export function is_ref_of(ref, type) { + if (!(ref instanceof AST_SymbolRef)) return false; + var orig = ref.definition().orig; + for (var i = orig.length; --i >= 0;) { + if (orig[i] instanceof type) return true; + } +} + +/**Can we turn { block contents... } into just the block contents ? + * Not if one of these is inside. + **/ +export function can_be_evicted_from_block(node) { + return !( + node instanceof AST_DefClass || + node instanceof AST_Defun || + node instanceof AST_Let || + node instanceof AST_Const || + node instanceof AST_Export || + node instanceof AST_Import + ); +} + +export function as_statement_array(thing) { + if (thing === null) return []; + if (thing instanceof AST_BlockStatement) return thing.body; + if (thing instanceof AST_EmptyStatement) return []; + if (thing instanceof AST_Statement) return [ thing ]; + throw new Error("Can't convert thing to statement array"); +} + +export function is_reachable(scope_node, defs) { + const find_ref = node => { + if (node instanceof AST_SymbolRef && defs.includes(node.definition())) { + return walk_abort; + } + }; + + return walk_parent(scope_node, (node, info) => { + if (node instanceof AST_Scope && node !== scope_node) { + var parent = info.parent(); + + if ( + parent instanceof AST_Call + && parent.expression === node + // Async/Generators aren't guaranteed to sync evaluate all of + // their body steps, so it's possible they close over the variable. + && !(node.async || node.is_generator) + ) { + return; + } + + if (walk(node, find_ref)) return walk_abort; + + return true; + } + }); +} + +/** Check if a ref refers to the name of a function/class it's defined within */ +export function is_recursive_ref(compressor, def) { + var node; + for (var i = 0; node = compressor.parent(i); i++) { + if (node instanceof AST_Lambda || node instanceof AST_Class) { + var name = node.name; + if (name && name.definition() === def) { + return true; + } + } + } + return false; +} + +// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions? +export function retain_top_func(fn, compressor) { + return compressor.top_retain + && fn instanceof AST_Defun + && has_flag(fn, TOP) + && fn.name + && compressor.top_retain(fn.name.definition()); +} |
