diff --git a/CHANGELOG.md b/CHANGELOG.md index 803abe9..7efda3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ Behavioural changes in TerserJS are listed [here](https://github.com/terser/terser/blob/master/CHANGELOG.md). ## Unreleased +## 1.2.7 (23 March 2026) - added a new module option to enable minification of ES6 modules (default is false) +- update TerserJS to [5.46.1] ## 1.2.6 (19 June 2025) - update TerserJS to [5.43.1] diff --git a/lib/terser.js b/lib/terser.js index b47a3fa..387b49d 100644 --- a/lib/terser.js +++ b/lib/terser.js @@ -132,6 +132,15 @@ function make_node(ctor, orig, props) { return new ctor(props); } +/** Makes a `void 0` expression. Use instead of AST_Undefined which may conflict + * with an existing variable called `undefined` */ +function make_void_0(orig) { + return make_node(AST_UnaryPrefix, orig, { + operator: "void", + expression: make_node(AST_Number, orig, { value: 0 }) + }); +} + function push_uniq(array, el) { if (!array.includes(el)) array.push(el); @@ -336,6 +345,8 @@ var RE_BIN_NUMBER = /^0b[01]+$/i; var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i; var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i; +var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y; + var OPERATORS = makePredicate([ "in", "instanceof", @@ -660,6 +671,56 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { next(); } + function peek_next_token_start_or_newline() { + var pos = S.pos; + for (var in_multiline_comment = false; pos < S.text.length; ) { + var ch = get_full_char(S.text, pos); + if (NEWLINE_CHARS.has(ch)) { + return { char: ch, pos: pos }; + } else if (in_multiline_comment) { + if (ch == "*" && get_full_char(S.text, pos + 1) == "/") { + pos += 2; + in_multiline_comment = false; + } else { + pos++; + } + } else if (!WHITESPACE_CHARS.has(ch)) { + if (ch == "/") { + var next_ch = get_full_char(S.text, pos + 1); + if (next_ch == "/") { + pos = find_eol(); + return { char: get_full_char(S.text, pos), pos: pos }; + } else if (next_ch == "*") { + in_multiline_comment = true; + pos += 2; + continue; + } + } + return { char: ch, pos: pos }; + } else { + pos++; + } + } + return { char: null, pos: pos }; + } + + function ch_starts_binding_identifier(ch, pos) { + if (ch == "\\") { + return true; + } else if (is_identifier_start(ch)) { + RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos; + if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) { + var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex); + if (!is_identifier_char(after) && after != "\\") { + // "in" or "instanceof" are keywords, not binding identifiers + return false; + } + } + return true; + } + return false; + } + function read_while(pred) { var ret = "", ch, i = 0; while ((ch = peek()) && pred(ch, i++)) @@ -902,7 +963,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z") ); - if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch)) { + // 0x7F is very rare in actual code, so we compare it to "~" (0x7E) + if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch) && ch <= "~") { S.pos += end - start; S.col += end - start; return S.text.slice(start, S.pos); @@ -1163,6 +1225,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) { return S.directives[directive] > 0; }; + next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline; + next_token.ch_starts_binding_identifier = ch_starts_binding_identifier; + return next_token; } @@ -1384,10 +1449,6 @@ function parse($TEXT, options) { return simple_statement(); case "name": - case "privatename": - if(is("privatename") && !S.in_class) - croak("Private field must be used in an enclosing class"); - if (S.token.value == "async" && is_token(peek(), "keyword", "function")) { next(); next(); @@ -1402,10 +1463,31 @@ function parse($TEXT, options) { semicolon(); return node; } + if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) { + next(); + var node = using_(); + semicolon(); + return node; + } + if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) { + var next_next = S.input.peek_next_token_start_or_newline(); + if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) { + next(); + // The "using" token will be consumed by the await_using_ function. + var node = await_using_(); + semicolon(); + return node; + } + } return is_token(peek(), "punc", ":") ? labeled_statement() : simple_statement(); + case "privatename": + if(!S.in_class) + croak("Private field must be used in an enclosing class"); + return simple_statement(); + case "punc": switch (S.token.value) { case "{": @@ -1630,6 +1712,8 @@ function parse($TEXT, options) { is("keyword", "var") ? (next(), var_(true)) : is("keyword", "let") ? (next(), let_(true)) : is("keyword", "const") ? (next(), const_(true)) : + is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) : + is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) : expression(true, true); var is_in = is("operator", "in"); var is_of = is("name", "of"); @@ -1637,9 +1721,12 @@ function parse($TEXT, options) { token_error(await_tok, for_await_error); } if (is_in || is_of) { - if (init instanceof AST_Definitions) { + if (init instanceof AST_DefinitionsLike) { if (init.definitions.length > 1) token_error(init.start, "Only one variable declaration allowed in for..in loop"); + if (is_in && init instanceof AST_Using) { + token_error(init.start, "Invalid using declaration in for..in loop"); + } } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) { token_error(init.start, "Invalid left-hand side in for..in loop"); } @@ -1671,7 +1758,7 @@ function parse($TEXT, options) { } function for_of(init, is_await) { - var lhs = init instanceof AST_Definitions ? init.definitions[0].name : null; + var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null; var obj = expression(true); expect(")"); return new AST_ForOf({ @@ -2267,23 +2354,26 @@ function parse($TEXT, options) { var sym_type = kind === "var" ? AST_SymbolVar : kind === "const" ? AST_SymbolConst : - kind === "let" ? AST_SymbolLet : null; + kind === "let" ? AST_SymbolLet : + kind === "using" ? AST_SymbolUsing : + kind === "await using" ? AST_SymbolUsing : null; + var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef; // var { a } = b if (is("punc", "{") || is("punc", "[")) { - def = new AST_VarDef({ + def = new def_type({ start: S.token, name: binding_element(undefined, sym_type), value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null, end: prev() }); } else { - def = new AST_VarDef({ + def = new def_type({ start : S.token, name : as_symbol(sym_type), value : is("operator", "=") ? (next(), expression(false, no_in)) - : !no_in && kind === "const" - ? croak("Missing initializer in const declaration") : null, + : !no_in && (kind === "const" || kind === "using" || kind === "await using") + ? croak("Missing initializer in " + kind + " declaration") : null, end : prev() }); if (def.name.name == "import") croak("Unexpected token: import"); @@ -2320,6 +2410,25 @@ function parse($TEXT, options) { }); }; + var using_ = function(no_in) { + return new AST_Using({ + start : prev(), + await : false, + definitions : vardefs(no_in, "using"), + end : prev() + }); + }; + + var await_using_ = function(no_in) { + // Assumption: When await_using_ is called, only the `await` token has been consumed. + return new AST_Using({ + start : prev(), + await : true, + definitions : (next(), vardefs(no_in, "await using")), + end : prev() + }); + }; + var new_ = function(allow_calls) { var start = S.token; expect_token("operator", "new"); @@ -2355,12 +2464,20 @@ function parse($TEXT, options) { ret = _make_symbol(AST_SymbolRef); break; case "num": - ret = new AST_Number({ - start: tok, - end: tok, - value: tok.value, - raw: LATEST_RAW - }); + if (tok.value === Infinity) { + // very large float values are parsed as Infinity + ret = new AST_Infinity({ + start: tok, + end: tok, + }); + } else { + ret = new AST_Number({ + start: tok, + end: tok, + value: tok.value, + raw: LATEST_RAW + }); + } break; case "big_int": ret = new AST_BigInt({ @@ -2738,13 +2855,13 @@ function parse($TEXT, options) { return name; }; + var is_private = prev().type === "privatename"; const is_not_method_start = () => - !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "="); + !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private; var is_async = false; var is_static = false; var is_generator = false; - var is_private = false; var accessor_type = null; if (is_class && name === "static" && is_not_method_start()) { @@ -2767,7 +2884,7 @@ function parse($TEXT, options) { accessor_type = name; name = as_property_name(); } - if (prev().type === "privatename") { + if (!is_private && prev().type === "privatename") { is_private = true; } @@ -4995,7 +5112,7 @@ var AST_Finally = DEFNODE("Finally", null, function AST_Finally(props) { /* -----[ VAR/CONST ]----- */ -var AST_Definitions = DEFNODE("Definitions", "definitions", function AST_Definitions(props) { +var AST_DefinitionsLike = DEFNODE("DefinitionsLike", "definitions", function AST_DefinitionsLike(props) { if (props) { this.definitions = props.definitions; this.start = props.start; @@ -5004,9 +5121,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", function AST_Definit this.flags = 0; }, { - $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", + $documentation: "Base class for variable definitions and `using`", $propdoc: { - definitions: "[AST_VarDef*] array of variable definitions" + definitions: "[AST_VarDef*|AST_UsingDef*] array of variable definitions" }, _walk: function(visitor) { return visitor._visit(this, function() { @@ -5022,6 +5139,18 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", function AST_Definit }, }, AST_Statement); +var AST_Definitions = DEFNODE("Definitions", null, function AST_Definitions(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", +}, AST_DefinitionsLike); + var AST_Var = DEFNODE("Var", null, function AST_Var(props) { if (props) { this.definitions = props.definitions; @@ -5058,7 +5187,23 @@ var AST_Const = DEFNODE("Const", null, function AST_Const(props) { $documentation: "A `const` statement" }, AST_Definitions); -var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) { +var AST_Using = DEFNODE("Using", "await", function AST_Using(props) { + if (props) { + this.await = props.await; + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `using` statement", + $propdoc: { + await: "[boolean] Whether it's `await using`" + }, +}, AST_DefinitionsLike); + +var AST_VarDefLike = DEFNODE("VarDefLike", "name value", function AST_VarDefLike(props) { if (props) { this.name = props.name; this.value = props.value; @@ -5068,9 +5213,9 @@ var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) { this.flags = 0; }, { - $documentation: "A variable declaration; only appears in a AST_Definitions node", + $documentation: "A name=value pair in a variable definition statement or `using`", $propdoc: { - name: "[AST_Destructuring|AST_SymbolConst|AST_SymbolLet|AST_SymbolVar] name of the variable", + name: "[AST_Destructuring|AST_SymbolDeclaration] name of the variable", value: "[AST_Node?] initializer, or null of there's no initializer" }, _walk: function(visitor) { @@ -5085,13 +5230,39 @@ var AST_VarDef = DEFNODE("VarDef", "name value", function AST_VarDef(props) { }, declarations_as_names() { if (this.name instanceof AST_SymbolDeclaration) { - return [this]; + return [this.name]; } else { return this.name.all_symbols(); } } }); +var AST_VarDef = DEFNODE("VarDef", null, function AST_VarDef(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A variable declaration; only appears in a AST_Definitions node", +}, AST_VarDefLike); + +var AST_UsingDef = DEFNODE("UsingDef", null, function AST_UsingDef(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Like VarDef but specific to AST_Using", +}, AST_VarDefLike); + var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) { if (props) { this.foreign_name = props.foreign_name; @@ -6187,6 +6358,21 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, function AST_SymbolConst(prop $documentation: "A constant declaration" }, AST_SymbolBlockDeclaration); +var AST_SymbolUsing = DEFNODE("SymbolUsing", null, function AST_SymbolUsing(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `using` declaration" +}, AST_SymbolBlockDeclaration); + var AST_SymbolLet = DEFNODE("SymbolLet", null, function AST_SymbolLet(props) { if (props) { this.init = props.init; @@ -7032,11 +7218,11 @@ def_transform(AST_Catch, function(self, tw) { self.body = MAP(self.body, tw); }); -def_transform(AST_Definitions, function(self, tw) { +def_transform(AST_DefinitionsLike, function(self, tw) { self.definitions = MAP(self.definitions, tw); }); -def_transform(AST_VarDef, function(self, tw) { +def_transform(AST_VarDefLike, function(self, tw) { self.name = self.name.transform(tw); if (self.value) self.value = self.value.transform(tw); }); @@ -7570,19 +7756,30 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) { VariableDeclaration: function(M) { let decl_type; + let defs_type = AST_VarDef; let sym_type; + let await_using = false; if (M.kind === "const") { decl_type = AST_Const; sym_type = AST_SymbolConst; } else if (M.kind === "let") { decl_type = AST_Let; sym_type = AST_SymbolLet; + } else if (M.kind === "using") { + decl_type = AST_Using; + defs_type = AST_UsingDef; + sym_type = AST_SymbolUsing; + } else if (M.kind === "await using") { + decl_type = AST_Using; + defs_type = AST_UsingDef; + sym_type = AST_SymbolUsing; + await_using = true; } else { decl_type = AST_Var; sym_type = AST_SymbolVar; } const definitions = M.declarations.map(M => { - return new AST_VarDef({ + return new defs_type({ start: my_start_token(M), end: my_end_token(M), name: from_moz_pattern(M.id, sym_type), @@ -7593,6 +7790,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) { start : my_start_token(M), end : my_end_token(M), definitions : definitions, + await : await_using, }); }, @@ -8192,7 +8390,7 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) { type: "DebuggerStatement" }; }); - def_to_moz(AST_VarDef, function To_Moz_VariableDeclarator(M) { + def_to_moz(AST_VarDefLike, function To_Moz_VariableDeclarator(M) { return { type: "VariableDeclarator", id: to_moz(M.name), @@ -8408,12 +8606,14 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) { }; }); - def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) { + def_to_moz(AST_DefinitionsLike, function To_Moz_VariableDeclaration(M) { return { type: "VariableDeclaration", kind: M instanceof AST_Const ? "const" : - M instanceof AST_Let ? "let" : "var", + M instanceof AST_Let ? "let" : + M instanceof AST_Using ? (M.await ? "await using" : "using") : + "var", declarations: M.definitions.map(to_moz) }; }); @@ -10080,21 +10280,21 @@ function OutputStream(options) { PARENS(AST_Sequence, function(output) { var p = output.parent(); - return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) - || p instanceof AST_Unary // !(foo, bar, baz) - || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 - || p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4 - || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 - || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] - || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 - || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) - * ==> 20 (side effect, set a := 10 and b := 20) */ - || p instanceof AST_Arrow // x => (x, x) - || p instanceof AST_DefaultAssign // x => (x = (0, function(){})) - || p instanceof AST_Expansion // [...(a, b)] - || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {} - || p instanceof AST_Yield // yield (foo, bar) - || p instanceof AST_Export // export default (foo, bar) + return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) + || p instanceof AST_Unary // !(foo, bar, baz) + || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 + || p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4 + || p instanceof AST_PropAccess && this !== p.property // (1, {foo:2}).foo, (1, {foo:2})["foo"], not foo[1, 2] + || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] + || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 + || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) + * ==> 20 (side effect, set a := 10 and b := 20) */ + || p instanceof AST_Arrow // x => (x, x) + || p instanceof AST_DefaultAssign // x => (x = (0, function(){})) + || p instanceof AST_Expansion // [...(a, b)] + || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {} + || p instanceof AST_Yield // yield (foo, bar) + || p instanceof AST_Export // export default (foo, bar) ; }); @@ -10415,7 +10615,7 @@ function OutputStream(options) { output.space(); output.with_parens(function() { if (self.init) { - if (self.init instanceof AST_Definitions) { + if (self.init instanceof AST_DefinitionsLike) { self.init.print(output); } else { parenthesize_for_noin(self.init, output, true); @@ -10775,7 +10975,7 @@ function OutputStream(options) { }); /* -----[ var/const ]----- */ - AST_Definitions.DEFMETHOD("_do_print", function(output, kind) { + AST_DefinitionsLike.DEFMETHOD("_do_print", function(output, kind) { output.print(kind); output.space(); this.definitions.forEach(function(def, i) { @@ -10797,6 +10997,9 @@ function OutputStream(options) { DEFPRINT(AST_Const, function(self, output) { self._do_print(output, "const"); }); + DEFPRINT(AST_Using, function(self, output) { + self._do_print(output, self.await ? "await using" : "using"); + }); DEFPRINT(AST_Import, function(self, output) { output.print("import"); output.space(); @@ -10964,7 +11167,7 @@ function OutputStream(options) { node.print(output, parens); } - DEFPRINT(AST_VarDef, function(self, output) { + DEFPRINT(AST_VarDefLike, function(self, output) { self.name.print(output); if (self.value) { output.space(); @@ -11440,7 +11643,7 @@ function OutputStream(options) { } else { if (!stat || stat instanceof AST_EmptyStatement) output.force_semicolon(); - else if (stat instanceof AST_Let || stat instanceof AST_Const || stat instanceof AST_Class) + else if ((stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) || stat instanceof AST_Class) make_block(stat, output); else stat.print(output); @@ -11520,7 +11723,7 @@ function OutputStream(options) { AST_Class, AST_Constant, AST_Debugger, - AST_Definitions, + AST_DefinitionsLike, AST_Directive, AST_Finally, AST_Jump, @@ -11683,9 +11886,9 @@ AST_Catch.prototype.shallow_cmp = function(other) { AST_Finally.prototype.shallow_cmp = pass_through; -AST_Definitions.prototype.shallow_cmp = pass_through; +AST_DefinitionsLike.prototype.shallow_cmp = pass_through; -AST_VarDef.prototype.shallow_cmp = function(other) { +AST_VarDefLike.prototype.shallow_cmp = function(other) { return this.value == null ? other.value == null : this.value === other.value; }; @@ -12054,6 +12257,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undef node instanceof AST_SymbolVar || node instanceof AST_SymbolLet || node instanceof AST_SymbolConst + || node instanceof AST_SymbolUsing || node instanceof AST_SymbolCatch ) { var def; @@ -12067,7 +12271,7 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undef if (node instanceof AST_SymbolBlockDeclaration) { return sym instanceof AST_SymbolLambda; } - return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst); + return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst || sym instanceof AST_SymbolUsing); })) { js_error( `"${node.name}" is redeclared`, @@ -12947,7 +13151,12 @@ AST_Const.prototype._size = function () { return 6 + list_overhead(this.definitions); }; -AST_VarDef.prototype._size = function () { +AST_Using.prototype._size = function () { + const await_size = this.await ? 6 : 0; + return await_size + 6 + list_overhead(this.definitions); +}; + +AST_VarDefLike.prototype._size = function () { return this.value ? 1 : 0; }; @@ -13366,7 +13575,7 @@ function make_node_from_constant(val, orig) { case "boolean": return make_node(val ? AST_True : AST_False, orig); case "undefined": - return make_node(AST_Undefined, orig); + return make_void_0(orig); default: if (val === null) { return make_node(AST_Null, orig, { value: null }); @@ -13417,7 +13626,7 @@ function get_simple_key(key) { if (key instanceof AST_UnaryPrefix && key.operator == "void" && key.expression instanceof AST_Constant) { - return; + return undefined; } return key; } @@ -13527,6 +13736,7 @@ function can_be_evicted_from_block(node) { node instanceof AST_Defun || node instanceof AST_Let || node instanceof AST_Const || + node instanceof AST_Using || node instanceof AST_Export || node instanceof AST_Import ); @@ -14667,10 +14877,13 @@ var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date e AST_Call.DEFMETHOD("is_callee_pure", function(compressor) { if (compressor.option("unsafe")) { var expr = this.expression; - var first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor)); + var first_arg; if ( expr.expression && expr.expression.name === "hasOwnProperty" && - (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) + ( + (first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor))) == null + || first_arg.thedef && first_arg.thedef.undeclared + ) ) { return false; } @@ -15173,6 +15386,15 @@ def_eval(AST_SymbolRef, function (compressor, depth) { return value; }); +def_eval(AST_Chain, function (compressor, depth) { + const evaluated = this.expression._eval(compressor, depth, /*ast_chain=*/true); + return evaluated === nullish + ? undefined + : evaluated === this.expression + ? this + : evaluated; +}); + const global_objs = { Array, Math, Number, Object, String }; const regexp_flags = new Set([ @@ -15184,9 +15406,13 @@ const regexp_flags = new Set([ "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; +def_eval(AST_PropAccess, function (compressor, depth, ast_chain) { + let obj = (ast_chain || this.property === "length" || compressor.option("unsafe")) + && this.expression._eval(compressor, depth + 1, ast_chain); + + if (ast_chain) { + if (obj === nullish || (this.optional && obj == null)) return nullish; + } // `.length` of strings and arrays is always safe if (this.property === "length") { @@ -15257,26 +15483,19 @@ def_eval(AST_PropAccess, function (compressor, depth) { 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) { +def_eval(AST_Call, function (compressor, depth, ast_chain) { var exp = this.expression; - const callee = exp._eval(compressor, depth); - if (callee === nullish || (this.optional && callee == null)) return nullish; + if (ast_chain) { + const callee = exp._eval(compressor, depth, ast_chain); + 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) + if (typeof key !== "string" && typeof key !== "number") return this; } var val; @@ -15294,7 +15513,8 @@ def_eval(AST_Call, function (compressor, depth) { if (!is_pure_native_fn(e.name, key)) return this; val = global_objs[e.name]; } else { - val = e._eval(compressor, depth + 1); + val = e._eval(compressor, depth + 1, /* don't pass ast_chain (exponential work) */); + if (val === e || !val) return this; if (!is_pure_native_method(val.constructor.name, key)) @@ -16215,7 +16435,7 @@ function safe_to_read(tw, def) { if (def.fixed == null) { var orig = def.orig[0]; if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false; - def.fixed = make_node(AST_Undefined, orig); + def.fixed = make_void_0(orig); } return true; } @@ -16280,7 +16500,7 @@ function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) { parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New) || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope - || parent instanceof AST_VarDef && node === parent.value + || parent instanceof AST_VarDefLike && node === parent.value || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope ) { if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1; @@ -16513,7 +16733,7 @@ function mark_lambda(tw, descend, compressor) { if (d.orig.length > 1) return; if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) { d.fixed = function() { - return iife.args[i] || make_node(AST_Undefined, iife); + return iife.args[i] || make_void_0(iife); }; tw.loop_ids.set(d.id, tw.in_loop); mark(tw, d, true); @@ -16663,7 +16883,7 @@ function handle_defined_after_hoist(parent) { // Refine `defun_first_read_map` to be as high as possible for (const [defun, defun_first_read] of defun_first_read_map) { - // Update all depdencies of `defun` + // Update all dependencies of `defun` const queue = new Set(defun_dependencies_map.get(defun)); for (const enclosed_defun of queue) { let enclosed_defun_first_read = defun_first_read_map.get(enclosed_defun); @@ -16892,6 +17112,10 @@ def_reduce_vars(AST_VarDef, function(tw, descend) { } }); +def_reduce_vars(AST_UsingDef, function() { + suppress(this.name); +}); + def_reduce_vars(AST_While, function(tw, descend, compressor) { reset_block_variables(compressor, this); const saved_loop = tw.in_loop; @@ -16989,8 +17213,8 @@ function remove_initializers(var_statement) { return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null; } -/** Called on code which we know is unreachable, to keep elements that affect outside of it. */ -function trim_unreachable_code(compressor, stat, target) { +/** Called on code which won't be executed but has an effect outside of itself: `var`, `function` statements, `export`, `import`. */ +function extract_from_unreachable_code(compressor, stat, target) { walk(stat, node => { if (node instanceof AST_Var) { const no_initializers = remove_initializers(node); @@ -17015,7 +17239,8 @@ function trim_unreachable_code(compressor, stat, target) { target.push(node); return true; } - if (node instanceof AST_Scope) { + if (node instanceof AST_Scope || node instanceof AST_Class) { + // Do not go into nested scopes return true; } }); @@ -17099,6 +17324,7 @@ function tighten_body(statements, compressor) { if (node instanceof AST_Assign && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left)) || node instanceof AST_Await + || node instanceof AST_Using || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression) || (node instanceof AST_Call || node instanceof AST_PropAccess) @@ -17197,6 +17423,7 @@ function tighten_body(statements, compressor) { && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node)) || node instanceof AST_VarDef && node.value && (lvalues.has(node.name.name) || side_effects && may_modify(node.name)) + || node instanceof AST_Using || (sym = is_lhs(node.left, node)) && (sym instanceof AST_PropAccess || lvalues.has(sym.name)) || may_throw @@ -17430,7 +17657,7 @@ function tighten_body(statements, compressor) { } } else { if (!arg) { - arg = make_node(AST_Undefined, sym).transform(compressor); + arg = make_void_0(sym).transform(compressor); } else if (arg instanceof AST_Lambda && arg.pinned() || has_overlapping_symbol(fn, arg, fn_strict)) { arg = null; @@ -17611,7 +17838,9 @@ function tighten_body(statements, compressor) { ? expr.left : expr.expression; return !is_ref_of(lhs, AST_SymbolConst) - && !is_ref_of(lhs, AST_SymbolLet) && lhs; + && !is_ref_of(lhs, AST_SymbolLet) + && !is_ref_of(lhs, AST_SymbolUsing) + && lhs; } } @@ -17668,7 +17897,7 @@ function tighten_body(statements, compressor) { found = true; if (node instanceof AST_VarDef) { node.value = node.name instanceof AST_SymbolConst - ? make_node(AST_Undefined, node.value) // `const` always needs value. + ? make_void_0(node.value) // `const` always needs value. : null; return node; } @@ -17946,7 +18175,7 @@ function tighten_body(statements, compressor) { return false; for (var j = i + 1, len = statements.length; j < len; j++) { var stat = statements[j]; - if (stat instanceof AST_Const || stat instanceof AST_Let) + if (stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) return false; } var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; @@ -18035,7 +18264,7 @@ function tighten_body(statements, compressor) { CHANGED = n != len; if (has_quit) has_quit.forEach(function (stat) { - trim_unreachable_code(compressor, stat, statements); + extract_from_unreachable_code(compressor, stat, statements); }); } @@ -18086,7 +18315,7 @@ function tighten_body(statements, compressor) { var line = block.body[i]; if (line instanceof AST_Var && declarations_only(line)) { decls.push(line); - } else if (stat || line instanceof AST_Const || line instanceof AST_Let) { + } else if (stat || line instanceof AST_DefinitionsLike && !(line instanceof AST_Var)) { return false; } else { stat = line; @@ -18107,9 +18336,9 @@ function tighten_body(statements, compressor) { var stat = statements[i]; if (prev) { if (stat instanceof AST_Exit) { - stat.value = cons_seq(stat.value || make_node(AST_Undefined, stat).transform(compressor)); + stat.value = cons_seq(stat.value || make_void_0(stat).transform(compressor)); } else if (stat instanceof AST_For) { - if (!(stat.init instanceof AST_Definitions)) { + if (!(stat.init instanceof AST_DefinitionsLike)) { const abort = walk(prev.body, node => { if (node instanceof AST_Scope) return true; @@ -18129,7 +18358,7 @@ function tighten_body(statements, compressor) { } } } else if (stat instanceof AST_ForIn) { - if (!(stat.init instanceof AST_Const) && !(stat.init instanceof AST_Let)) { + if (!(stat.init instanceof AST_DefinitionsLike) || stat.init instanceof AST_Var) { stat.object = cons_seq(stat.object); } } else if (stat instanceof AST_If) { @@ -18246,6 +18475,12 @@ function tighten_body(statements, compressor) { statements[++j] = stat; defs = stat; } + } else if ( + stat instanceof AST_Using + && prev instanceof AST_Using + && prev.await === stat.await + ) { + prev.definitions = prev.definitions.concat(stat.definitions); } else if (stat instanceof AST_Exit) { stat.value = extract_object_assignments(stat.value); } else if (stat instanceof AST_For) { @@ -18605,7 +18840,7 @@ function inline_into_call(self, compressor) { if (returned) { returned = returned.clone(true); } else { - returned = make_node(AST_Undefined, self); + returned = make_void_0(self); } const args = self.args.concat(returned); return make_sequence(self, args).optimize(compressor); @@ -18621,7 +18856,7 @@ function inline_into_call(self, compressor) { && returned.name === fn.argnames[0].name ) { const replacement = - (self.args[0] || make_node(AST_Undefined)).optimize(compressor); + (self.args[0] || make_void_0()).optimize(compressor); let parent; if ( @@ -18703,7 +18938,7 @@ function inline_into_call(self, 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)); + var args = self.args.concat(make_void_0(self)); return make_sequence(self, args).optimize(compressor); } @@ -18722,9 +18957,9 @@ function inline_into_call(self, compressor) { return self; function return_value(stat) { - if (!stat) return make_node(AST_Undefined, self); + if (!stat) return make_void_0(self); if (stat instanceof AST_Return) { - if (!stat.value) return make_node(AST_Undefined, self); + if (!stat.value) return make_void_0(self); return stat.value.clone(true); } if (stat instanceof AST_SimpleStatement) { @@ -18870,7 +19105,7 @@ function inline_into_call(self, compressor) { } else { var symbol = make_node(AST_SymbolVar, name, name); name.definition().orig.push(symbol); - if (!value && in_loop) value = make_node(AST_Undefined, self); + if (!value && in_loop) value = make_void_0(self); append_var(decls, expressions, symbol, value); } } @@ -18897,7 +19132,7 @@ function inline_into_call(self, compressor) { operator: "=", logical: false, left: sym, - right: make_node(AST_Undefined, name) + right: make_void_0(name), })); } } @@ -19210,6 +19445,11 @@ class Compressor extends TreeWalker { } } + /** True if compressor.self()'s result will be turned into a 32-bit integer. + * ex: + * ~{expr} + * (1, 2, {expr}) | 0 + **/ in_32_bit_context(other_operand_must_be_number) { if (!this.option("evaluate")) return false; var self = this.self(); @@ -19227,9 +19467,10 @@ class Compressor extends TreeWalker { if ( p instanceof AST_Binary && ( - p.operator == "&&" - || p.operator == "||" - || p.operator == "??" + // Don't talk about p.left. Can change branch taken + p.operator == "&&" && p.right === self + || p.operator == "||" && p.right === self + || p.operator == "??" && p.right === self ) || p instanceof AST_Conditional && p.condition !== self || p.tail_node() === self @@ -19388,7 +19629,7 @@ AST_Toplevel.DEFMETHOD("drop_console", function(options) { set_flag(exp.expression, SQUEEZED); self.args = []; } else { - return make_node(AST_Undefined, self); + return make_void_0(self); } } }); @@ -19416,12 +19657,7 @@ AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) { : make_node(AST_EmptyStatement, node); } return make_node(AST_SimpleStatement, node, { - body: node.value || make_node(AST_UnaryPrefix, node, { - operator: "void", - expression: make_node(AST_Number, node, { - value: 0 - }) - }) + body: node.value || make_void_0(node) }); } if (node instanceof AST_Class || node instanceof AST_Lambda && node !== self) { @@ -19534,6 +19770,7 @@ function can_be_extracted_from_if_block(node) { return !( node instanceof AST_Const || node instanceof AST_Let + || node instanceof AST_Using || node instanceof AST_Class ); } @@ -19712,6 +19949,7 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) { let def; let value; if (sym.scope === self + && !(sym instanceof AST_SymbolUsing) && (def = sym.definition()).escaped != 1 && !def.assignments && !def.direct_access @@ -19830,7 +20068,7 @@ function if_break_in_loop(self, compressor) { body: self.condition })); } - trim_unreachable_code(compressor, self.body, body); + extract_from_unreachable_code(compressor, self.body, body); return make_node(AST_BlockStatement, self, { body: body }); @@ -19901,7 +20139,7 @@ def_optimize(AST_For, function(self, compressor) { if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor); if (!cond) { var body = []; - trim_unreachable_code(compressor, self.body, body); + extract_from_unreachable_code(compressor, self.body, body); if (self.init instanceof AST_Statement) { body.push(self.init); } else if (self.init) { @@ -19937,7 +20175,7 @@ def_optimize(AST_If, function(self, compressor) { if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor); if (!cond) { var body = []; - trim_unreachable_code(compressor, self.body, body); + extract_from_unreachable_code(compressor, self.body, body); body.push(make_node(AST_SimpleStatement, self.condition, { body: self.condition })); @@ -19950,7 +20188,7 @@ def_optimize(AST_If, function(self, compressor) { })); body.push(self.body); if (self.alternative) { - trim_unreachable_code(compressor, self.alternative, body); + extract_from_unreachable_code(compressor, self.alternative, body); } return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); } @@ -20022,8 +20260,8 @@ def_optimize(AST_If, function(self, compressor) { return make_node(self.body.CTOR, self, { value: make_node(AST_Conditional, self, { condition : self.condition, - consequent : self.body.value || make_node(AST_Undefined, self.body), - alternative : self.alternative.value || make_node(AST_Undefined, self.alternative) + consequent : self.body.value || make_void_0(self.body), + alternative : self.alternative.value || make_void_0(self.alternative), }).transform(compressor) }).optimize(compressor); } @@ -20078,6 +20316,9 @@ def_optimize(AST_Switch, function(self, compressor) { var body = []; var default_branch; var exact_match; + // - compress self.body into `body` + // - find and deduplicate default branch + // - find the exact match (`case 1234` inside `switch(1234)`) for (var i = 0, len = self.body.length; i < len && !exact_match; i++) { branch = self.body[i]; if (branch instanceof AST_Default) { @@ -20107,6 +20348,7 @@ def_optimize(AST_Switch, function(self, compressor) { } body.push(branch); } + // i < len if we found an exact_match. eliminate the rest while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]); self.body = body; @@ -20178,7 +20420,7 @@ def_optimize(AST_Switch, function(self, compressor) { let i = body.length - 1; for (; i >= 0; i--) { let bbody = body[i].body; - if (is_break(bbody[bbody.length - 1], compressor)) bbody.pop(); + while (is_break(bbody[bbody.length - 1], compressor)) bbody.pop(); if (!is_inert_body(body[i])) break; } // i now points to the index of a branch that contains a body. By incrementing, it's @@ -20194,9 +20436,9 @@ def_optimize(AST_Switch, function(self, compressor) { let branch = body[j]; if (branch === default_or_exact) { default_or_exact = null; - body.pop(); + eliminate_branch(body.pop()); } else if (!branch.expression.has_side_effects(compressor)) { - body.pop(); + eliminate_branch(body.pop()); } else { break; } @@ -20310,15 +20552,16 @@ def_optimize(AST_Switch, function(self, compressor) { // and there's a side-effect somewhere. Just let the below paths take care of it. } + // Reintegrate `decl` (var statements) if (body.length > 0) { body[0].body = decl.concat(body[0].body); } - if (body.length == 0) { return make_node(AST_BlockStatement, self, { body: decl.concat(statement(self.expression)) }).optimize(compressor); } + if (body.length == 1 && !has_nested_break(self)) { // This is the last case body, and we've already pruned any breaks, so it's // safe to hoist. @@ -20398,7 +20641,7 @@ def_optimize(AST_Switch, function(self, compressor) { if (prev && !aborts(prev)) { prev.body = prev.body.concat(branch.body); } else { - trim_unreachable_code(compressor, branch, decl); + extract_from_unreachable_code(compressor, branch, decl); } } function branches_equivalent(branch, prev, insertBreak) { @@ -20452,7 +20695,7 @@ def_optimize(AST_Try, function(self, compressor) { if (compressor.option("dead_code") && self.body.body.every(is_empty)) { var body = []; if (self.bcatch) { - trim_unreachable_code(compressor, self.bcatch, body); + extract_from_unreachable_code(compressor, self.bcatch, body); } if (self.bfinally) body.push(...self.bfinally.body); return make_node(AST_BlockStatement, self, { @@ -20571,7 +20814,7 @@ def_optimize(AST_Call, function(self, compressor) { const value = condition.evaluate(compressor); if (value === 1 || value === true) { - return make_node(AST_Undefined, self); + return make_void_0(self).optimize(compressor); } } } @@ -20933,6 +21176,10 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) { ) { return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor); } + // Short-circuit common `void 0` + if (self.operator === "void" && e instanceof AST_Number && e.value === 0) { + return unsafe_undefined_ref(self, compressor) || self; + } var seq = self.lift_sequences(compressor); if (seq !== self) { return seq; @@ -20943,7 +21190,7 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) { self.expression = e; return self; } else { - return make_node(AST_Undefined, self).optimize(compressor); + return make_void_0(self).optimize(compressor); } } if (compressor.in_boolean_context()) { @@ -21129,7 +21376,7 @@ def_optimize(AST_Binary, function(self, compressor) { if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) { self.right = expr; - self.left = make_node(AST_Undefined, self.left).optimize(compressor); + self.left = make_void_0(self.left).optimize(compressor); if (self.operator.length == 2) self.operator += "="; } } else if (compressor.option("typeofs") @@ -21142,7 +21389,7 @@ def_optimize(AST_Binary, function(self, compressor) { if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) { self.left = expr; - self.right = make_node(AST_Undefined, self.right).optimize(compressor); + self.right = make_void_0(self.right).optimize(compressor); if (self.operator.length == 2) self.operator += "="; } } else if (self.left instanceof AST_SymbolRef @@ -21783,7 +22030,8 @@ function is_atomic(lhs, self) { return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE; } -def_optimize(AST_Undefined, function(self, compressor) { +/** Apply the `unsafe_undefined` option: find a variable called `undefined` and turn `self` into a reference to it. */ +function unsafe_undefined_ref(self, compressor) { if (compressor.option("unsafe_undefined")) { var undef = find_variable(compressor, "undefined"); if (undef) { @@ -21796,14 +22044,15 @@ def_optimize(AST_Undefined, function(self, compressor) { return ref; } } + return null; +} + +def_optimize(AST_Undefined, function(self, compressor) { + var symbolref = unsafe_undefined_ref(self, compressor); + if (symbolref) return symbolref; var lhs = compressor.is_lhs(); if (lhs && is_atomic(lhs, self)) return self; - return make_node(AST_UnaryPrefix, self, { - operator: "void", - expression: make_node(AST_Number, self, { - value: 0 - }) - }); + return make_void_0(self); }); def_optimize(AST_Infinity, function(self, compressor) { @@ -22490,7 +22739,7 @@ def_optimize(AST_Sub, function(self, compressor) { } } if (retValue instanceof AST_Expansion) break FLATTEN; - retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue; + retValue = retValue instanceof AST_Hole ? make_void_0(retValue) : retValue; if (!flatten) values.unshift(retValue); while (--i >= 0) { var value = elements[i]; @@ -22529,7 +22778,7 @@ def_optimize(AST_Chain, function (self, compressor) { if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") { return make_node_from_constant(0, self); } - return make_node(AST_Undefined, self); + return make_void_0(self).optimize(compressor); } if ( self.expression instanceof AST_PropAccess @@ -23277,6 +23526,7 @@ var domprops = [ "Array", "ArrayBuffer", "ArrayType", + "AsyncDisposableStack", "Atomics", "Attr", "Audio", @@ -23415,6 +23665,7 @@ var domprops = [ "COPY_WRITE_BUFFER", "COPY_WRITE_BUFFER_BINDING", "COUNTER_STYLE_RULE", + "CSPViolationReportBody", "CSS", "CSS2Properties", "CSSAnimation", @@ -23425,6 +23676,9 @@ var domprops = [ "CSSFontFaceRule", "CSSFontFeatureValuesRule", "CSSFontPaletteValuesRule", + "CSSFunctionDeclarations", + "CSSFunctionDescriptors", + "CSSFunctionRule", "CSSGroupingRule", "CSSImageValue", "CSSImportRule", @@ -23468,6 +23722,7 @@ var domprops = [ "CSSSkewY", "CSSStartingStyleRule", "CSSStyleDeclaration", + "CSSStyleProperties", "CSSStyleRule", "CSSStyleSheet", "CSSStyleValue", @@ -23601,6 +23856,7 @@ var domprops = [ "CookieStoreManager", "CountQueuingStrategy", "Counter", + "CreateMonitor", "CreateType", "Credential", "CredentialsContainer", @@ -24110,11 +24366,14 @@ var domprops = [ "DeviceMotionEventAcceleration", "DeviceMotionEventRotationRate", "DeviceOrientationEvent", + "DevicePosture", "DeviceProximityEvent", "DeviceStorage", "DeviceStorageChangeEvent", + "DigitalCredential", "Directory", "DisplayNames", + "DisposableStack", "Document", "DocumentFragment", "DocumentPictureInPicture", @@ -24122,6 +24381,7 @@ var domprops = [ "DocumentTimeline", "DocumentType", "DragEvent", + "Duration", "DurationFormat", "DynamicsCompressorNode", "E", @@ -24229,6 +24489,7 @@ var domprops = [ "FeedEntry", "Fence", "FencedFrameConfig", + "FetchLaterResult", "File", "FileError", "FileList", @@ -24241,6 +24502,7 @@ var domprops = [ "FileSystemFileEntry", "FileSystemFileHandle", "FileSystemHandle", + "FileSystemObserver", "FileSystemWritableFileStream", "FinalizationRegistry", "FindInPage", @@ -24406,6 +24668,7 @@ var domprops = [ "HTMLQuoteElement", "HTMLScriptElement", "HTMLSelectElement", + "HTMLSelectedContentElement", "HTMLShadowElement", "HTMLSlotElement", "HTMLSourceElement", @@ -24450,6 +24713,7 @@ var domprops = [ "IDBMutableFile", "IDBObjectStore", "IDBOpenDBRequest", + "IDBRecord", "IDBRequest", "IDBTransaction", "IDBVersionChangeEvent", @@ -24512,10 +24776,13 @@ var domprops = [ "InstallTrigger", "InstallTriggerImpl", "Instance", + "Instant", "Int16Array", "Int32Array", "Int8Array", + "IntegrityViolationReportBody", "Intent", + "InterestEvent", "InternalError", "IntersectionObserver", "IntersectionObserverEntry", @@ -24565,6 +24832,7 @@ var domprops = [ "LUMINANCE", "LUMINANCE_ALPHA", "LanguageCode", + "LanguageDetector", "LargestContentfulPaint", "LaunchParams", "LaunchQueue", @@ -24894,6 +25162,7 @@ var domprops = [ "NavigationCurrentEntryChangeEvent", "NavigationDestination", "NavigationHistoryEntry", + "NavigationPrecommitController", "NavigationPreloadManager", "NavigationTransition", "Navigator", @@ -24911,6 +25180,7 @@ var domprops = [ "Notation", "Notification", "NotifyPaintEvent", + "Now", "Number", "NumberFormat", "OBJECT_TYPE", @@ -24932,6 +25202,7 @@ var domprops = [ "OTPCredential", "OUT_OF_MEMORY", "Object", + "Observable", "OfflineAudioCompletionEvent", "OfflineAudioContext", "OfflineResourceList", @@ -25033,6 +25304,11 @@ var domprops = [ "PhotoCapabilities", "PictureInPictureEvent", "PictureInPictureWindow", + "PlainDate", + "PlainDateTime", + "PlainMonthDay", + "PlainTime", + "PlainYearMonth", "PlatformArch", "PlatformInfo", "PlatformNaclArch", @@ -25073,6 +25349,7 @@ var domprops = [ "QUOTA_ERR", "QUOTA_EXCEEDED_ERR", "QueryInterface", + "QuotaExceededError", "R11F_G11F_B10F", "R16F", "R16I", @@ -25213,6 +25490,7 @@ var domprops = [ "ResizeObserverEntry", "ResizeObserverSize", "Response", + "RestrictionTarget", "RuntimeError", "SAMPLER_2D", "SAMPLER_2D_ARRAY", @@ -25619,6 +25897,11 @@ var domprops = [ "ShadowRoot", "SharedArrayBuffer", "SharedStorage", + "SharedStorageAppendMethod", + "SharedStorageClearMethod", + "SharedStorageDeleteMethod", + "SharedStorageModifierMethod", + "SharedStorageSetMethod", "SharedStorageWorklet", "SharedWorker", "SharingState", @@ -25626,6 +25909,12 @@ var domprops = [ "SnapEvent", "SourceBuffer", "SourceBufferList", + "SpeechGrammar", + "SpeechGrammarList", + "SpeechRecognition", + "SpeechRecognitionErrorEvent", + "SpeechRecognitionEvent", + "SpeechRecognitionPhrase", "SpeechSynthesis", "SpeechSynthesisErrorEvent", "SpeechSynthesisEvent", @@ -25646,7 +25935,12 @@ var domprops = [ "StyleSheet", "StyleSheetList", "SubmitEvent", + "Subscriber", "SubtleCrypto", + "Summarizer", + "SuppressedError", + "SuspendError", + "Suspending", "Symbol", "SyncManager", "SyntaxError", @@ -25757,6 +26051,7 @@ var domprops = [ "TaskController", "TaskPriorityChangeEvent", "TaskSignal", + "Temporal", "Text", "TextDecoder", "TextDecoderStream", @@ -25781,6 +26076,7 @@ var domprops = [ "TransformStream", "TransformStreamDefaultController", "TransitionEvent", + "Translator", "TreeWalker", "TrustedHTML", "TrustedScript", @@ -25925,6 +26221,7 @@ var domprops = [ "ViewTransition", "ViewTransitionTypeSet", "ViewType", + "Viewport", "VirtualKeyboard", "VirtualKeyboardGeometryChangeEvent", "VisibilityStateEntry", @@ -26134,6 +26431,7 @@ var domprops = [ "XRWebGLLayer", "XSLTProcessor", "ZERO", + "ZonedDateTime", "ZoomSettings", "ZoomSettingsMode", "ZoomSettingsScope", @@ -26183,6 +26481,7 @@ var domprops = [ "activeSourceCount", "activeTexture", "activeVRDisplays", + "activeViewTransition", "activityLog", "actualBoundingBoxAscent", "actualBoundingBoxDescent", @@ -26190,6 +26489,7 @@ var domprops = [ "actualBoundingBoxRight", "adAuctionComponents", "adAuctionHeaders", + "adapterInfo", "add", "addAll", "addBehavior", @@ -26215,6 +26515,7 @@ var domprops = [ "addSearchEngine", "addSourceBuffer", "addStream", + "addTeardown", "addTextTrack", "addTrack", "addTransceiver", @@ -26229,6 +26530,7 @@ var domprops = [ "addressModeU", "addressModeV", "addressModeW", + "adopt", "adoptNode", "adoptedCallback", "adoptedStyleSheets", @@ -26276,8 +26578,10 @@ var domprops = [ "amplitude", "ancestorOrigins", "anchor", + "anchorName", "anchorNode", "anchorOffset", + "anchorScope", "anchorSpace", "anchors", "and", @@ -26313,6 +26617,7 @@ var domprops = [ "animationTimingFunction", "animationsPaused", "anniversary", + "annotation", "antialias", "anticipatedRemoval", "any", @@ -26347,6 +26652,7 @@ var domprops = [ "archive", "areas", "arguments", + "ariaActiveDescendantElement", "ariaAtomic", "ariaAutoComplete", "ariaBrailleLabel", @@ -26357,21 +26663,29 @@ var domprops = [ "ariaColIndex", "ariaColIndexText", "ariaColSpan", + "ariaControlsElements", "ariaCurrent", + "ariaDescribedByElements", "ariaDescription", + "ariaDetailsElements", "ariaDisabled", + "ariaErrorMessageElements", "ariaExpanded", + "ariaFlowToElements", "ariaHasPopup", "ariaHidden", "ariaInvalid", "ariaKeyShortcuts", "ariaLabel", + "ariaLabelledByElements", "ariaLevel", "ariaLive", "ariaModal", "ariaMultiLine", "ariaMultiSelectable", + "ariaNotify", "ariaOrientation", + "ariaOwnsElements", "ariaPlaceholder", "ariaPosInSet", "ariaPressed", @@ -26514,6 +26828,7 @@ var domprops = [ "baseline-source", "baselineShift", "baselineSource", + "batchUpdate", "battery", "bday", "before", @@ -26566,6 +26881,7 @@ var domprops = [ "blockDirection", "blockSize", "blockedURI", + "blockedURL", "blocking", "blockingDuration", "blue", @@ -26576,6 +26892,7 @@ var domprops = [ "bold", "bookmarks", "booleanValue", + "boost", "border", "border-block", "border-block-color", @@ -26841,6 +27158,7 @@ var domprops = [ "characterData", "characterDataOldValue", "characterSet", + "characterVariant", "characteristic", "charging", "chargingTime", @@ -26927,6 +27245,7 @@ var domprops = [ "closeCode", "closePath", "closed", + "closedBy", "closest", "clz", "clz32", @@ -26984,11 +27303,13 @@ var domprops = [ "columnWidth", "columns", "command", + "commandForElement", "commands", "commit", "commitLoadTime", "commitPreferences", "commitStyles", + "committed", "commonAncestorContainer", "compact", "compare", @@ -27024,6 +27345,7 @@ var domprops = [ "coneOuterAngle", "coneOuterGain", "config", + "configURL", "configurable", "configuration", "configurationName", @@ -27042,6 +27364,7 @@ var domprops = [ "connectStart", "connected", "connectedCallback", + "connectedMoveCallback", "connection", "connectionInfo", "connectionList", @@ -27082,6 +27405,7 @@ var domprops = [ "contentBoxSize", "contentDocument", "contentEditable", + "contentEncoding", "contentHint", "contentOverflow", "contentRect", @@ -27362,6 +27686,7 @@ var domprops = [ "decodedBodySize", "decoding", "decodingInfo", + "decreaseZoomLevel", "decrypt", "default", "defaultCharset", @@ -27432,6 +27757,7 @@ var domprops = [ "deprecatedReplaceInURN", "deprecatedRunAdAuctionEnforcesKAnonymity", "deprecatedURNToURL", + "depthActive", "depthBias", "depthBiasClamp", "depthBiasSlopeScale", @@ -27451,6 +27777,7 @@ var domprops = [ "depthStencilAttachment", "depthStencilFormat", "depthStoreOp", + "depthType", "depthUsage", "depthWriteEnabled", "deref", @@ -27479,6 +27806,7 @@ var domprops = [ "deviceMemory", "devicePixelContentBoxSize", "devicePixelRatio", + "devicePosture", "deviceProtocol", "deviceSubclass", "deviceVersionMajor", @@ -27518,6 +27846,8 @@ var domprops = [ "displayName", "displayWidth", "dispose", + "disposeAsync", + "disposed", "disposition", "distanceModel", "div", @@ -27539,6 +27869,7 @@ var domprops = [ "documentOrigins", "documentPictureInPicture", "documentURI", + "documentURL", "documentUrl", "documentUrls", "dolphin", @@ -27725,7 +28056,9 @@ var domprops = [ "expandEntityReferences", "expando", "expansion", + "expectedContextLanguages", "expectedImprovement", + "expectedInputLanguages", "experiments", "expiration", "expirationTime", @@ -27768,6 +28101,7 @@ var domprops = [ "fence", "fenceSync", "fetch", + "fetchLater", "fetchPriority", "fetchStart", "fftSize", @@ -27799,6 +28133,7 @@ var domprops = [ "filterResY", "filterUnits", "filters", + "finalResponseHeadersStart", "finally", "find", "findIndex", @@ -27812,6 +28147,7 @@ var domprops = [ "finished", "fireEvent", "firesTouchEvents", + "first", "firstChild", "firstElementChild", "firstInterimResponseStart", @@ -27836,6 +28172,7 @@ var domprops = [ "flexGrow", "flexShrink", "flexWrap", + "flip", "flipX", "flipY", "float", @@ -27897,6 +28234,7 @@ var domprops = [ "fontVariantAlternates", "fontVariantCaps", "fontVariantEastAsian", + "fontVariantEmoji", "fontVariantLigatures", "fontVariantNumeric", "fontVariantPosition", @@ -27926,6 +28264,7 @@ var domprops = [ "formatToParts", "forms", "forward", + "forwardWheel", "forwardX", "forwardY", "forwardZ", @@ -28002,6 +28341,7 @@ var domprops = [ "getAdjacentText", "getAll", "getAllKeys", + "getAllRecords", "getAllResponseHeaders", "getAllowlistForFeature", "getAnimations", @@ -28050,11 +28390,13 @@ var domprops = [ "getCharNumAtPosition", "getCharacteristic", "getCharacteristics", + "getClientCapabilities", "getClientExtensionResults", "getClientRect", "getClientRects", "getCoalescedEvents", "getCompilationInfo", + "getComposedRanges", "getCompositionAlternatives", "getComputedStyle", "getComputedTextLength", @@ -28178,6 +28520,8 @@ var domprops = [ "getNotifier", "getNumberOfChars", "getOffsetReferenceSpace", + "getOrInsert", + "getOrInsertComputed", "getOutputTimestamp", "getOverrideHistoryNavigationMode", "getOverrideStyle", @@ -28189,7 +28533,9 @@ var domprops = [ "getParameter", "getParameters", "getParent", + "getPathData", "getPathSegAtLength", + "getPathSegmentAtLength", "getPermissionWarningsByManifest", "getPhotoCapabilities", "getPhotoSettings", @@ -28271,6 +28617,7 @@ var domprops = [ "getSupportedConstraints", "getSupportedExtensions", "getSupportedFormats", + "getSupportedZoomLevels", "getSyncParameter", "getSynchronizationSources", "getTags", @@ -28443,6 +28790,7 @@ var domprops = [ "highWaterMark", "highlight", "highlights", + "highlightsFromPoint", "hint", "hints", "history", @@ -28464,6 +28812,7 @@ var domprops = [ "hwTimestamp", "hyphenate-character", "hyphenateCharacter", + "hyphenateLimitChars", "hyphens", "hypot", "i18n", @@ -28517,6 +28866,7 @@ var domprops = [ "incomingHighWaterMark", "incomingMaxAge", "incomingUnidirectionalStreams", + "increaseZoomLevel", "incremental", "indeterminate", "index", @@ -28594,6 +28944,7 @@ var domprops = [ "inputEncoding", "inputMethod", "inputMode", + "inputQuota", "inputSource", "inputSources", "inputType", @@ -28623,6 +28974,7 @@ var domprops = [ "insetInline", "insetInlineEnd", "insetInlineStart", + "inspect", "install", "installing", "instanceRoot", @@ -28633,9 +28985,11 @@ var domprops = [ "int32", "int8", "integrity", + "interactionCount", "interactionId", "interactionMode", "intercept", + "interestForElement", "interfaceClass", "interfaceName", "interfaceNumber", @@ -28685,6 +29039,7 @@ var domprops = [ "isEnabled", "isEqual", "isEqualNode", + "isError", "isExtended", "isExtensible", "isExternalCTAP2SecurityKeySupported", @@ -28808,6 +29163,7 @@ var domprops = [ "language", "languages", "largeArcFlag", + "last", "lastChild", "lastElementChild", "lastError", @@ -29040,6 +29396,7 @@ var domprops = [ "math-depth", "math-style", "mathDepth", + "mathShift", "mathStyle", "matrix", "matrixTransform", @@ -29102,6 +29459,7 @@ var domprops = [ "maxWidth", "maximumLatency", "measure", + "measureInputUsage", "measureText", "media", "mediaCapabilities", @@ -29163,6 +29521,7 @@ var domprops = [ "module", "mount", "move", + "moveBefore", "moveBy", "moveEnd", "moveFirst", @@ -29506,6 +29865,7 @@ var domprops = [ "objectStoreNames", "objectType", "observe", + "observedAttributes", "occlusionQuerySet", "of", "off", @@ -29636,6 +29996,7 @@ var domprops = [ "onclick", "onclose", "onclosing", + "oncommand", "oncompassneedscalibration", "oncomplete", "oncompositionend", @@ -29673,6 +30034,7 @@ var domprops = [ "ondisplay", "ondispose", "ondownloading", + "ondownloadprogress", "ondrag", "ondragend", "ondragenter", @@ -29949,6 +30311,7 @@ var domprops = [ "onwebkittransitionend", "onwheel", "onzoom", + "onzoomlevelchange", "opacity", "open", "openCursor", @@ -29984,6 +30347,7 @@ var domprops = [ "originAgentCluster", "originalPolicy", "originalTarget", + "ornaments", "orphans", "os", "oscpu", @@ -30004,8 +30368,10 @@ var domprops = [ "outlineWidth", "outputBuffer", "outputChannelCount", + "outputLanguage", "outputLatency", "outputs", + "overallProgress", "overflow", "overflow-anchor", "overflow-block", @@ -30094,6 +30460,7 @@ var domprops = [ "paint-order", "paintOrder", "paintRequests", + "paintTime", "paintType", "paintWorklet", "palette", @@ -30135,6 +30502,7 @@ var domprops = [ "patternUnits", "pause", "pauseAnimations", + "pauseDepthSensing", "pauseDuration", "pauseOnExit", "pauseProfilers", @@ -30167,6 +30535,8 @@ var domprops = [ "phoneticFamilyName", "phoneticGivenName", "photo", + "phrase", + "phrases", "pictureInPictureChild", "pictureInPictureElement", "pictureInPictureEnabled", @@ -30177,6 +30547,7 @@ var domprops = [ "pitch", "pixelBottom", "pixelDepth", + "pixelFormat", "pixelHeight", "pixelLeft", "pixelRight", @@ -30247,6 +30618,9 @@ var domprops = [ "positionAlign", "positionAnchor", "positionArea", + "positionTry", + "positionTryFallbacks", + "positionVisibility", "positionX", "positionY", "positionZ", @@ -30273,6 +30647,7 @@ var domprops = [ "presentation", "presentationArea", "presentationStyle", + "presentationTime", "preserveAlpha", "preserveAspectRatio", "preserveAspectRatioString", @@ -30311,6 +30686,7 @@ var domprops = [ "probeSpace", "process", "processIceMessage", + "processLocally", "processingEnd", "processingStart", "processorOptions", @@ -30323,6 +30699,7 @@ var domprops = [ "profiles", "projectionMatrix", "promise", + "promising", "prompt", "properties", "propertyIsEnumerable", @@ -30367,6 +30744,7 @@ var domprops = [ "querySet", "queue", "queueMicrotask", + "quota", "quote", "quotes", "r", @@ -30545,6 +30923,7 @@ var domprops = [ "reportError", "reportEvent", "reportId", + "reportOnly", "reportValidity", "request", "requestAdapter", @@ -30580,6 +30959,7 @@ var domprops = [ "requestVideoFrameCallback", "requestViewportScale", "requestWindow", + "requested", "requestingWindow", "requireInteraction", "required", @@ -30590,6 +30970,7 @@ var domprops = [ "resetLatency", "resetPose", "resetTransform", + "resetZoomLevel", "resizable", "resize", "resizeBy", @@ -30614,14 +30995,17 @@ var domprops = [ "restartAfterDelay", "restartIce", "restore", + "restrictTo", "result", "resultIndex", "resultType", "results", "resume", + "resumeDepthSensing", "resumeProfilers", "resumeTransformFeedback", "retry", + "returnType", "returnValue", "rev", "reverse", @@ -30820,12 +31204,14 @@ var domprops = [ "searchParams", "sectionRowIndex", "secureConnectionStart", + "securePaymentConfirmationAvailability", "security", "seed", "seek", "seekToNextFrame", "seekable", "seeking", + "segments", "select", "selectAllChildren", "selectAlternateInterface", @@ -30960,6 +31346,7 @@ var domprops = [ "setPaint", "setParameter", "setParameters", + "setPathData", "setPeriodicWave", "setPipeline", "setPointerCapture", @@ -31058,6 +31445,7 @@ var domprops = [ "shapeOutside", "shapeRendering", "share", + "sharedContext", "sharedStorage", "sharedStorageWritable", "sheet", @@ -31082,6 +31470,9 @@ var domprops = [ "sidebarAction", "sign", "signal", + "signalAllAcceptedCredentials", + "signalCurrentUserDetails", + "signalUnknownCredential", "signalingState", "signature", "silent", @@ -31123,9 +31514,11 @@ var domprops = [ "sourceBuffers", "sourceCapabilities", "sourceCharPosition", + "sourceElement", "sourceFile", "sourceFunctionName", "sourceIndex", + "sourceLanguage", "sourceMap", "sourceURL", "sources", @@ -31266,8 +31659,12 @@ var domprops = [ "styleSheet", "styleSheetSets", "styleSheets", + "styleset", + "stylistic", "sub", "subarray", + "subgroupMaxSize", + "subgroupMinSize", "subject", "submit", "submitFrame", @@ -31280,6 +31677,9 @@ var domprops = [ "subtree", "suffix", "suffixes", + "sumPrecise", + "summarize", + "summarizeStreaming", "summary", "sup", "supported", @@ -31290,6 +31690,7 @@ var domprops = [ "supportsFiber", "supportsSession", "supportsText", + "suppressed", "surfaceScale", "surroundContents", "suspend", @@ -31302,7 +31703,9 @@ var domprops = [ "svw", "swapCache", "swapNode", + "swash", "sweepFlag", + "switchMap", "symbols", "symmetricDifference", "sync", @@ -31336,12 +31739,14 @@ var domprops = [ "take", "takePhoto", "takeRecords", + "takeUntil", "tan", "tangentialPressure", "tanh", "target", "targetAddressSpace", "targetElement", + "targetLanguage", "targetRayMode", "targetRaySpace", "targetTouches", @@ -31400,6 +31805,7 @@ var domprops = [ "textDecoration", "textDecorationBlink", "textDecorationColor", + "textDecorationInset", "textDecorationLine", "textDecorationLineThrough", "textDecorationNone", @@ -31490,6 +31896,7 @@ var domprops = [ "toString", "toStringTag", "toSum", + "toTemporalInstant", "toTimeString", "toUTCString", "toUpperCase", @@ -31561,6 +31968,7 @@ var domprops = [ "transitionTimingFunction", "translate", "translateSelf", + "translateStreaming", "translationX", "translationY", "transport", @@ -31709,6 +32117,7 @@ var domprops = [ "usbVersionMajor", "usbVersionMinor", "usbVersionSubminor", + "use", "useCurrentView", "useMap", "useProgram", @@ -31716,6 +32125,7 @@ var domprops = [ "user-select", "userActivation", "userAgent", + "userAgentAllowsProtocol", "userAgentData", "userChoice", "userHandle", @@ -31799,6 +32209,8 @@ var domprops = [ "viewTarget", "viewTargetString", "viewTransition", + "viewTransitionClass", + "viewTransitionName", "viewport", "viewportAnchorX", "viewportAnchorY", @@ -32033,6 +32445,7 @@ var domprops = [ "wheelDelta", "wheelDeltaX", "wheelDeltaY", + "when", "whenDefined", "which", "white-space", @@ -32060,6 +32473,10 @@ var domprops = [ "wordBreak", "wordSpacing", "wordWrap", + "workerCacheLookupStart", + "workerFinalSourceType", + "workerMatchedSourceType", + "workerRouterEvaluationStart", "workerStart", "worklet", "wow64", @@ -32104,6 +32521,7 @@ var domprops = [ "zIndex", "zoom", "zoomAndPan", + "zoomLevel", "zoomRectScreen", ]; diff --git a/lib/terser/version.rb b/lib/terser/version.rb index bcbc278..95d1872 100644 --- a/lib/terser/version.rb +++ b/lib/terser/version.rb @@ -2,5 +2,5 @@ class Terser # Current version of Terser. - VERSION = "1.2.6" + VERSION = "1.2.7" end diff --git a/vendor/terser b/vendor/terser index da1e6fb..e186a01 160000 --- a/vendor/terser +++ b/vendor/terser @@ -1 +1 @@ -Subproject commit da1e6fb2acd90e62bac69967718b89d6f00aab79 +Subproject commit e186a011f53f2403edbf4461cc501a36ac9eaf5e