summaryrefslogtreecommitdiff
path: root/node_modules/terser/lib/compress/inline.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-10-31 15:37:35 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-10-31 15:37:35 +0800
commitd5f14083061f2ce6a42313188443a42e30796320 (patch)
treecc6a9889e08b29595a76a33b9e7b4ef84866468b /node_modules/terser/lib/compress/inline.js
parentb1a6ea021f29f182b62f9f81024a3d8ac8621b7f (diff)
added make browserlist(autoprefixer) work fixed
Diffstat (limited to 'node_modules/terser/lib/compress/inline.js')
-rw-r--r--node_modules/terser/lib/compress/inline.js640
1 files changed, 640 insertions, 0 deletions
diff --git a/node_modules/terser/lib/compress/inline.js b/node_modules/terser/lib/compress/inline.js
new file mode 100644
index 00000000..34f090da
--- /dev/null
+++ b/node_modules/terser/lib/compress/inline.js
@@ -0,0 +1,640 @@
+/***********************************************************************
+
+ 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_Assign,
+ AST_Block,
+ AST_Call,
+ AST_Catch,
+ AST_Class,
+ AST_ClassExpression,
+ AST_DefaultAssign,
+ AST_DefClass,
+ AST_Defun,
+ AST_Destructuring,
+ AST_EmptyStatement,
+ AST_Expansion,
+ AST_Export,
+ AST_Function,
+ AST_IterationStatement,
+ AST_Lambda,
+ AST_Node,
+ AST_Number,
+ AST_Object,
+ AST_ObjectKeyVal,
+ AST_PropAccess,
+ AST_Return,
+ AST_Scope,
+ AST_SimpleStatement,
+ AST_Statement,
+ AST_SymbolDefun,
+ AST_SymbolFunarg,
+ AST_SymbolLambda,
+ AST_SymbolRef,
+ AST_SymbolVar,
+ AST_This,
+ AST_Toplevel,
+ AST_UnaryPrefix,
+ AST_Undefined,
+ AST_Var,
+ AST_VarDef,
+
+ walk,
+
+ _INLINE,
+ _NOINLINE,
+ _PURE
+} from "../ast.js";
+import { make_node, has_annotation } from "../utils/index.js";
+import "../size.js";
+
+import "./evaluate.js";
+import "./drop-side-effect-free.js";
+import "./reduce-vars.js";
+import {
+ SQUEEZED,
+ INLINED,
+ UNUSED,
+
+ has_flag,
+ set_flag,
+} from "./compressor-flags.js";
+import {
+ make_sequence,
+ best_of,
+ make_node_from_constant,
+ identifier_atom,
+ is_empty,
+ is_func_expr,
+ is_iife_call,
+ is_reachable,
+ is_recursive_ref,
+ retain_top_func,
+} from "./common.js";
+
+/**
+ * Module that contains the inlining logic.
+ *
+ * @module
+ *
+ * The stars of the show are `inline_into_symbolref` and `inline_into_call`.
+ */
+
+function within_array_or_object_literal(compressor) {
+ var node, level = 0;
+ while (node = compressor.parent(level++)) {
+ if (node instanceof AST_Statement) return false;
+ if (node instanceof AST_Array
+ || node instanceof AST_ObjectKeyVal
+ || node instanceof AST_Object) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function scope_encloses_variables_in_this_scope(scope, pulled_scope) {
+ for (const enclosed of pulled_scope.enclosed) {
+ if (pulled_scope.variables.has(enclosed.name)) {
+ continue;
+ }
+ const looked_up = scope.find_variable(enclosed.name);
+ if (looked_up) {
+ if (looked_up === enclosed) continue;
+ return true;
+ }
+ }
+ return false;
+}
+
+export function inline_into_symbolref(self, compressor) {
+ const parent = compressor.parent();
+
+ const def = self.definition();
+ const nearest_scope = compressor.find_scope();
+ if (compressor.top_retain && def.global && compressor.top_retain(def)) {
+ def.fixed = false;
+ def.single_use = false;
+ return self;
+ }
+
+ let fixed = self.fixed_value();
+ let single_use = def.single_use
+ && !(parent instanceof AST_Call
+ && (parent.is_callee_pure(compressor))
+ || has_annotation(parent, _NOINLINE))
+ && !(parent instanceof AST_Export
+ && fixed instanceof AST_Lambda
+ && fixed.name);
+
+ if (single_use && fixed instanceof AST_Node) {
+ single_use =
+ !fixed.has_side_effects(compressor)
+ && !fixed.may_throw(compressor);
+ }
+
+ if (fixed instanceof AST_Class && def.scope !== self.scope) {
+ return self;
+ }
+
+ if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
+ if (retain_top_func(fixed, compressor)) {
+ single_use = false;
+ } else if (def.scope !== self.scope
+ && (def.escaped == 1
+ || has_flag(fixed, INLINED)
+ || within_array_or_object_literal(compressor)
+ || !compressor.option("reduce_funcs"))) {
+ single_use = false;
+ } else if (is_recursive_ref(compressor, def)) {
+ single_use = false;
+ } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
+ single_use = fixed.is_constant_expression(self.scope);
+ if (single_use == "f") {
+ var scope = self.scope;
+ do {
+ if (scope instanceof AST_Defun || is_func_expr(scope)) {
+ set_flag(scope, INLINED);
+ }
+ } while (scope = scope.parent_scope);
+ }
+ }
+ }
+
+ if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
+ single_use =
+ def.scope === self.scope
+ && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
+ || parent instanceof AST_Call
+ && parent.expression === self
+ && !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
+ && !(fixed.name && fixed.name.definition().recursive_refs > 0);
+ }
+
+ if (single_use && fixed) {
+ if (fixed instanceof AST_DefClass) {
+ set_flag(fixed, SQUEEZED);
+ fixed = make_node(AST_ClassExpression, fixed, fixed);
+ }
+ if (fixed instanceof AST_Defun) {
+ set_flag(fixed, SQUEEZED);
+ fixed = make_node(AST_Function, fixed, fixed);
+ }
+ if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) {
+ const defun_def = fixed.name.definition();
+ let lambda_def = fixed.variables.get(fixed.name.name);
+ let name = lambda_def && lambda_def.orig[0];
+ if (!(name instanceof AST_SymbolLambda)) {
+ name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
+ name.scope = fixed;
+ fixed.name = name;
+ lambda_def = fixed.def_function(name);
+ }
+ walk(fixed, node => {
+ if (node instanceof AST_SymbolRef && node.definition() === defun_def) {
+ node.thedef = lambda_def;
+ lambda_def.references.push(node);
+ }
+ });
+ }
+ if (
+ (fixed instanceof AST_Lambda || fixed instanceof AST_Class)
+ && fixed.parent_scope !== nearest_scope
+ ) {
+ fixed = fixed.clone(true, compressor.get_toplevel());
+
+ nearest_scope.add_child_scope(fixed);
+ }
+ return fixed.optimize(compressor);
+ }
+
+ // multiple uses
+ if (fixed) {
+ let replace;
+
+ if (fixed instanceof AST_This) {
+ if (!(def.orig[0] instanceof AST_SymbolFunarg)
+ && def.references.every((ref) =>
+ def.scope === ref.scope
+ )) {
+ replace = fixed;
+ }
+ } else {
+ var ev = fixed.evaluate(compressor);
+ if (
+ ev !== fixed
+ && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))
+ ) {
+ replace = make_node_from_constant(ev, fixed);
+ }
+ }
+
+ if (replace) {
+ const name_length = self.size(compressor);
+ const replace_size = replace.size(compressor);
+
+ let overhead = 0;
+ if (compressor.option("unused") && !compressor.exposed(def)) {
+ overhead =
+ (name_length + 2 + replace_size) /
+ (def.references.length - def.assignments);
+ }
+
+ if (replace_size <= name_length + overhead) {
+ return replace;
+ }
+ }
+ }
+
+ return self;
+}
+
+export function inline_into_call(self, compressor) {
+ var exp = self.expression;
+ var fn = exp;
+ var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion));
+
+ if (compressor.option("reduce_vars")
+ && fn instanceof AST_SymbolRef
+ && !has_annotation(self, _NOINLINE)
+ ) {
+ const fixed = fn.fixed_value();
+
+ if (
+ retain_top_func(fixed, compressor)
+ || !compressor.toplevel.funcs && exp.definition().global
+ ) {
+ return self;
+ }
+
+ fn = fixed;
+ }
+
+ var is_func = fn instanceof AST_Lambda;
+
+ var stat = is_func && fn.body[0];
+ var is_regular_func = is_func && !fn.is_generator && !fn.async;
+ var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor);
+ if (can_inline && stat instanceof AST_Return) {
+ let returned = stat.value;
+ if (!returned || returned.is_constant_expression()) {
+ if (returned) {
+ returned = returned.clone(true);
+ } else {
+ returned = make_node(AST_Undefined, self);
+ }
+ const args = self.args.concat(returned);
+ return make_sequence(self, args).optimize(compressor);
+ }
+
+ // optimize identity function
+ if (
+ fn.argnames.length === 1
+ && (fn.argnames[0] instanceof AST_SymbolFunarg)
+ && self.args.length < 2
+ && !(self.args[0] instanceof AST_Expansion)
+ && returned instanceof AST_SymbolRef
+ && returned.name === fn.argnames[0].name
+ ) {
+ const replacement =
+ (self.args[0] || make_node(AST_Undefined)).optimize(compressor);
+
+ let parent;
+ if (
+ replacement instanceof AST_PropAccess
+ && (parent = compressor.parent()) instanceof AST_Call
+ && parent.expression === self
+ ) {
+ // identity function was being used to remove `this`, like in
+ //
+ // id(bag.no_this)(...)
+ //
+ // Replace with a larger but more effish (0, bag.no_this) wrapper.
+
+ return make_sequence(self, [
+ make_node(AST_Number, self, { value: 0 }),
+ replacement
+ ]);
+ }
+ // replace call with first argument or undefined if none passed
+ return replacement;
+ }
+ }
+
+ if (can_inline) {
+ var scope, in_loop, level = -1;
+ let def;
+ let returned_value;
+ let nearest_scope;
+ if (simple_args
+ && !fn.uses_arguments
+ && !(compressor.parent() instanceof AST_Class)
+ && !(fn.name && fn instanceof AST_Function)
+ && (returned_value = can_flatten_body(stat))
+ && (exp === fn
+ || has_annotation(self, _INLINE)
+ || compressor.option("unused")
+ && (def = exp.definition()).references.length == 1
+ && !is_recursive_ref(compressor, def)
+ && fn.is_constant_expression(exp.scope))
+ && !has_annotation(self, _PURE | _NOINLINE)
+ && !fn.contains_this()
+ && can_inject_symbols()
+ && (nearest_scope = compressor.find_scope())
+ && !scope_encloses_variables_in_this_scope(nearest_scope, fn)
+ && !(function in_default_assign() {
+ // Due to the fact function parameters have their own scope
+ // which can't use `var something` in the function body within,
+ // we simply don't inline into DefaultAssign.
+ let i = 0;
+ let p;
+ while ((p = compressor.parent(i++))) {
+ if (p instanceof AST_DefaultAssign) return true;
+ if (p instanceof AST_Block) break;
+ }
+ return false;
+ })()
+ && !(scope instanceof AST_Class)
+ ) {
+ set_flag(fn, SQUEEZED);
+ nearest_scope.add_child_scope(fn);
+ return make_sequence(self, flatten_fn(returned_value)).optimize(compressor);
+ }
+ }
+
+ if (can_inline && has_annotation(self, _INLINE)) {
+ set_flag(fn, SQUEEZED);
+ fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn);
+ fn = fn.clone(true);
+ fn.figure_out_scope({}, {
+ parent_scope: compressor.find_scope(),
+ toplevel: compressor.get_toplevel()
+ });
+
+ return make_node(AST_Call, self, {
+ expression: fn,
+ args: self.args,
+ }).optimize(compressor);
+ }
+
+ const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty);
+ if (can_drop_this_call) {
+ var args = self.args.concat(make_node(AST_Undefined, self));
+ return make_sequence(self, args).optimize(compressor);
+ }
+
+ if (compressor.option("negate_iife")
+ && compressor.parent() instanceof AST_SimpleStatement
+ && is_iife_call(self)) {
+ return self.negate(compressor, true);
+ }
+
+ var ev = self.evaluate(compressor);
+ if (ev !== self) {
+ ev = make_node_from_constant(ev, self).optimize(compressor);
+ return best_of(compressor, ev, self);
+ }
+
+ return self;
+
+ function return_value(stat) {
+ if (!stat) return make_node(AST_Undefined, self);
+ if (stat instanceof AST_Return) {
+ if (!stat.value) return make_node(AST_Undefined, self);
+ return stat.value.clone(true);
+ }
+ if (stat instanceof AST_SimpleStatement) {
+ return make_node(AST_UnaryPrefix, stat, {
+ operator: "void",
+ expression: stat.body.clone(true)
+ });
+ }
+ }
+
+ function can_flatten_body(stat) {
+ var body = fn.body;
+ var len = body.length;
+ if (compressor.option("inline") < 3) {
+ return len == 1 && return_value(stat);
+ }
+ stat = null;
+ for (var i = 0; i < len; i++) {
+ var line = body[i];
+ if (line instanceof AST_Var) {
+ if (stat && !line.definitions.every((var_def) =>
+ !var_def.value
+ )) {
+ return false;
+ }
+ } else if (stat) {
+ return false;
+ } else if (!(line instanceof AST_EmptyStatement)) {
+ stat = line;
+ }
+ }
+ return return_value(stat);
+ }
+
+ function can_inject_args(block_scoped, safe_to_inject) {
+ for (var i = 0, len = fn.argnames.length; i < len; i++) {
+ var arg = fn.argnames[i];
+ if (arg instanceof AST_DefaultAssign) {
+ if (has_flag(arg.left, UNUSED)) continue;
+ return false;
+ }
+ if (arg instanceof AST_Destructuring) return false;
+ if (arg instanceof AST_Expansion) {
+ if (has_flag(arg.expression, UNUSED)) continue;
+ return false;
+ }
+ if (has_flag(arg, UNUSED)) continue;
+ if (!safe_to_inject
+ || block_scoped.has(arg.name)
+ || identifier_atom.has(arg.name)
+ || scope.conflicting_def(arg.name)) {
+ return false;
+ }
+ if (in_loop) in_loop.push(arg.definition());
+ }
+ return true;
+ }
+
+ function can_inject_vars(block_scoped, safe_to_inject) {
+ var len = fn.body.length;
+ for (var i = 0; i < len; i++) {
+ var stat = fn.body[i];
+ if (!(stat instanceof AST_Var)) continue;
+ if (!safe_to_inject) return false;
+ for (var j = stat.definitions.length; --j >= 0;) {
+ var name = stat.definitions[j].name;
+ if (name instanceof AST_Destructuring
+ || block_scoped.has(name.name)
+ || identifier_atom.has(name.name)
+ || scope.conflicting_def(name.name)) {
+ return false;
+ }
+ if (in_loop) in_loop.push(name.definition());
+ }
+ }
+ return true;
+ }
+
+ function can_inject_symbols() {
+ var block_scoped = new Set();
+ do {
+ scope = compressor.parent(++level);
+ if (scope.is_block_scope() && scope.block_scope) {
+ // TODO this is sometimes undefined during compression.
+ // But it should always have a value!
+ scope.block_scope.variables.forEach(function (variable) {
+ block_scoped.add(variable.name);
+ });
+ }
+ if (scope instanceof AST_Catch) {
+ // TODO can we delete? AST_Catch is a block scope.
+ if (scope.argname) {
+ block_scoped.add(scope.argname.name);
+ }
+ } else if (scope instanceof AST_IterationStatement) {
+ in_loop = [];
+ } else if (scope instanceof AST_SymbolRef) {
+ if (scope.fixed_value() instanceof AST_Scope) return false;
+ }
+ } while (!(scope instanceof AST_Scope));
+
+ var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
+ var inline = compressor.option("inline");
+ if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false;
+ if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false;
+ return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
+ }
+
+ function append_var(decls, expressions, name, value) {
+ var def = name.definition();
+
+ // Name already exists, only when a function argument had the same name
+ const already_appended = scope.variables.has(name.name);
+ if (!already_appended) {
+ scope.variables.set(name.name, def);
+ scope.enclosed.push(def);
+ decls.push(make_node(AST_VarDef, name, {
+ name: name,
+ value: null
+ }));
+ }
+
+ var sym = make_node(AST_SymbolRef, name, name);
+ def.references.push(sym);
+ if (value) expressions.push(make_node(AST_Assign, self, {
+ operator: "=",
+ logical: false,
+ left: sym,
+ right: value.clone()
+ }));
+ }
+
+ function flatten_args(decls, expressions) {
+ var len = fn.argnames.length;
+ for (var i = self.args.length; --i >= len;) {
+ expressions.push(self.args[i]);
+ }
+ for (i = len; --i >= 0;) {
+ var name = fn.argnames[i];
+ var value = self.args[i];
+ if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) {
+ if (value) expressions.push(value);
+ } else {
+ var symbol = make_node(AST_SymbolVar, name, name);
+ name.definition().orig.push(symbol);
+ if (!value && in_loop) value = make_node(AST_Undefined, self);
+ append_var(decls, expressions, symbol, value);
+ }
+ }
+ decls.reverse();
+ expressions.reverse();
+ }
+
+ function flatten_vars(decls, expressions) {
+ var pos = expressions.length;
+ for (var i = 0, lines = fn.body.length; i < lines; i++) {
+ var stat = fn.body[i];
+ if (!(stat instanceof AST_Var)) continue;
+ for (var j = 0, defs = stat.definitions.length; j < defs; j++) {
+ var var_def = stat.definitions[j];
+ var name = var_def.name;
+ append_var(decls, expressions, name, var_def.value);
+ if (in_loop && fn.argnames.every((argname) =>
+ argname.name != name.name
+ )) {
+ var def = fn.variables.get(name.name);
+ var sym = make_node(AST_SymbolRef, name, name);
+ def.references.push(sym);
+ expressions.splice(pos++, 0, make_node(AST_Assign, var_def, {
+ operator: "=",
+ logical: false,
+ left: sym,
+ right: make_node(AST_Undefined, name)
+ }));
+ }
+ }
+ }
+ }
+
+ function flatten_fn(returned_value) {
+ var decls = [];
+ var expressions = [];
+ flatten_args(decls, expressions);
+ flatten_vars(decls, expressions);
+ expressions.push(returned_value);
+
+ if (decls.length) {
+ const i = scope.body.indexOf(compressor.parent(level - 1)) + 1;
+ scope.body.splice(i, 0, make_node(AST_Var, fn, {
+ definitions: decls
+ }));
+ }
+
+ return expressions.map(exp => exp.clone(true));
+ }
+}