From 3f912af14dab4817867fbf5982efb183f34efdbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Santos?= Date: Mon, 1 Apr 2024 15:21:17 +0100 Subject: [PATCH] avoid optimizations inside computed keys. Closes #1514. Closes #272 --- lib/compress/index.js | 11 ++++++++++ lib/compress/inline.js | 4 ++++ lib/compress/tighten-body.js | 4 +++- test/compress/collapse_vars.js | 3 ++- test/compress/harmony.js | 8 ++++--- test/compress/properties.js | 40 ++++++++++++++++++++++++++++++++++ 6 files changed, 65 insertions(+), 5 deletions(-) diff --git a/lib/compress/index.js b/lib/compress/index.js index f7251f936..0cd730e10 100644 --- a/lib/compress/index.js +++ b/lib/compress/index.js @@ -401,6 +401,17 @@ class Compressor extends TreeWalker { } } + in_computed_key() { + if (!this.option("evaluate")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_ObjectProperty && p.key === self) { + return true; + } + } + return false; + } + get_toplevel() { return this._toplevel; } diff --git a/lib/compress/inline.js b/lib/compress/inline.js index 294f35b39..1dda72be4 100644 --- a/lib/compress/inline.js +++ b/lib/compress/inline.js @@ -167,6 +167,8 @@ function is_const_symbol_short_than_init_value(def, fixed_value) { } export function inline_into_symbolref(self, compressor) { + if (compressor.in_computed_key()) return self; + const parent = compressor.parent(); const def = self.definition(); const nearest_scope = compressor.find_scope(); @@ -316,6 +318,8 @@ export function inline_into_symbolref(self, compressor) { } export function inline_into_call(self, compressor) { + if (compressor.in_computed_key()) return self; + var exp = self.expression; var fn = exp; var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion)); diff --git a/lib/compress/tighten-body.js b/lib/compress/tighten-body.js index 7f6ce31bf..4ff8f0763 100644 --- a/lib/compress/tighten-body.js +++ b/lib/compress/tighten-body.js @@ -82,6 +82,7 @@ import { AST_Number, AST_Object, AST_ObjectKeyVal, + AST_ObjectProperty, AST_PropAccess, AST_RegExp, AST_Return, @@ -116,7 +117,7 @@ import { walk, walk_abort, - _NOINLINE + _NOINLINE, } from "../ast.js"; import { make_node, @@ -328,6 +329,7 @@ export function tighten_body(statements, compressor) { || node instanceof AST_SymbolRef && parent instanceof AST_Call && has_annotation(parent, _NOINLINE) + || node instanceof AST_ObjectProperty && node.key instanceof AST_Node ) { abort = true; return node; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 7c4ee31c9..f324029d4 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -1348,9 +1348,10 @@ collapse_vars_object: { } expect: { function f0(x, y) { + var z = x + y; return { get b() { return 7; }, - r: x + y + r: z, }; } function f1(x, y) { diff --git a/test/compress/harmony.js b/test/compress/harmony.js index fa1322c94..178662a0e 100644 --- a/test/compress/harmony.js +++ b/test/compress/harmony.js @@ -979,9 +979,11 @@ issue_2349b: { }, "blah")); } expect: { - console.log([ { - blah: 42 - } ].map(({["blah"]: l}) => l)); + console.log(( + a = "blah", + [{ blah: 42 }].map(({[a]: l}) => l) + )); + var a; } expect_stdout: [ "[ 42 ]", diff --git a/test/compress/properties.js b/test/compress/properties.js index b376d4d96..ed1ee046f 100644 --- a/test/compress/properties.js +++ b/test/compress/properties.js @@ -1352,6 +1352,46 @@ computed_property: { ] } +skip_computed_properties: { + options = { + evaluate: true, + inline: true, + } + input: { + export class A { + [(() => class {})()] = 1; + } + } + expect: { + export class A { + [(() => class {})()] = 1; + } + } +} + +skip_computed_properties_2: { + options = { + toplevel: true, + evaluate: true, + inline: true, + reduce_vars: true, + unused: true, + collapse_vars: true, + } + input: { + function f(o) { + return {[o.key]: o}; + } + var obj = {key: 'xyz'.slice(1, -1)}; + console.log(f(obj)); + } + expect: { + var obj = {key: 'xyz'.slice(1, -1)}; + console.log((o=obj, {[o.key]: o})); + var o; + } +} + new_this: { options = { properties: true,