diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2020-12-19 12:28:38 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-19 12:28:38 +0800 |
commit | e6dd471f8fff84c878153008139150a090c5ba19 (patch) | |
tree | ec207ca4b7416a79b9abba17fdda35b44e5ef743 /lib | |
parent | 0f55bd92f18bd27628f1cfd10c9fb5d70f4d4d29 (diff) | |
download | tracifyjs-e6dd471f8fff84c878153008139150a090c5ba19.tar.gz tracifyjs-e6dd471f8fff84c878153008139150a090c5ba19.zip |
support destructuring of `catch` variable (#4412)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ast.js | 10 | ||||
-rw-r--r-- | lib/compress.js | 76 | ||||
-rw-r--r-- | lib/parse.js | 2 |
3 files changed, 48 insertions, 40 deletions
@@ -786,7 +786,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", { var AST_Catch = DEFNODE("Catch", "argname", { $documentation: "A `catch` node; only makes sense as part of a `try` statement", $propdoc: { - argname: "[AST_SymbolCatch?] symbol for the exception, or null if not present", + argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present", }, walk: function(visitor) { var node = this; @@ -796,9 +796,9 @@ var AST_Catch = DEFNODE("Catch", "argname", { }); }, _validate: function() { - if (this.argname != null) { - if (!(this.argname instanceof AST_SymbolCatch)) throw new Error("argname must be AST_SymbolCatch"); - } + if (this.argname != null) validate_destructured(this.argname, function(node) { + if (!(node instanceof AST_SymbolCatch)) throw new Error("argname must be AST_SymbolCatch"); + }); }, }, AST_Block); @@ -868,7 +868,7 @@ var AST_Var = DEFNODE("Var", null, { var AST_VarDef = DEFNODE("VarDef", "name value", { $documentation: "A variable declaration; only appears in a AST_Definitions node", $propdoc: { - name: "[AST_SymbolVar] name of the variable", + name: "[AST_Destructured|AST_SymbolVar] name of the variable", value: "[AST_Node?] initializer, or null of there's no initializer" }, walk: function(visitor) { diff --git a/lib/compress.js b/lib/compress.js index f33b97bc..1aab3680 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4949,11 +4949,13 @@ merge(Compressor.prototype, { walk_body(node, tw); pop(); if (node.bcatch) { - if (node.bcatch.argname) { - var def = node.bcatch.argname.definition(); - references[def.id] = false; - if (def = def.redefined()) references[def.id] = false; - } + if (node.bcatch.argname) node.bcatch.argname.mark_symbol(function(node) { + if (node instanceof AST_SymbolCatch) { + var def = node.definition(); + references[def.id] = false; + if (def = def.redefined()) references[def.id] = false; + } + }, tw); push(); if (node.bfinally) segment.block = node.bcatch; walk_body(node.bcatch, tw); @@ -5317,6 +5319,34 @@ merge(Compressor.prototype, { var unused_fn_names = []; var calls_to_drop_args = []; var fns_with_marked_args = []; + var trimmer = new TreeTransformer(function(node) { + if (node instanceof AST_DestructuredArray) { + var trim = true; + for (var i = node.elements.length; --i >= 0;) { + var sym = node.elements[i]; + if (!(sym instanceof AST_SymbolDeclaration)) { + node.elements[i] = sym.transform(trimmer); + trim = false; + } else if (sym.definition().id in in_use_ids) { + trim = false; + } else if (trim) { + node.elements.pop(); + } else { + node.elements[i] = make_node(AST_Hole, sym); + } + } + return node; + } + if (node instanceof AST_DestructuredKeyVal) { + if (!(node.value instanceof AST_SymbolDeclaration)) { + node.value = node.value.transform(trimmer); + return node; + } + if (typeof node.key != "string") return node; + if (node.value.definition().id in in_use_ids) return node; + return List.skip; + } + }); var tt = new TreeTransformer(function(node, descend, in_list) { var parent = tt.parent(); if (drop_vars) { @@ -5383,34 +5413,7 @@ merge(Compressor.prototype, { for (var a = node.argnames, i = a.length; --i >= 0;) { var sym = a[i]; if (sym instanceof AST_Destructured) { - sym.transform(new TreeTransformer(function(node) { - if (node instanceof AST_DestructuredArray) { - var trim = true; - for (var i = node.elements.length; --i >= 0;) { - var sym = node.elements[i]; - if (!(sym instanceof AST_SymbolFunarg)) { - node.elements[i] = sym.transform(this); - trim = false; - } else if (sym.definition().id in in_use_ids) { - trim = false; - } else if (trim) { - node.elements.pop(); - } else { - node.elements[i] = make_node(AST_Hole, sym); - } - } - return node; - } - if (node instanceof AST_DestructuredKeyVal) { - if (!(node.value instanceof AST_SymbolFunarg)) { - node.value = node.value.transform(this); - return node; - } - if (typeof node.key != "string") return node; - if (node.value.definition().id in in_use_ids) return node; - return List.skip; - } - })); + sym.transform(trimmer); trim = false; continue; } @@ -5429,6 +5432,9 @@ merge(Compressor.prototype, { fns_with_marked_args.push(node); } } + if (node instanceof AST_Catch && node.argname instanceof AST_Destructured) { + node.argname.transform(trimmer); + } if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) { // place uninitialized names at the start var body = [], head = [], tail = []; @@ -7263,7 +7269,9 @@ merge(Compressor.prototype, { self.body = tighten_body(self.body, compressor); if (compressor.option("dead_code")) { if (has_declarations_only(self) - && !(self.bcatch && self.bcatch.argname && !can_drop_symbol(self.bcatch.argname))) { + && !(self.bcatch && self.bcatch.argname && self.bcatch.argname.match_symbol(function(node) { + return node instanceof AST_SymbolCatch && !can_drop_symbol(node); + }, true))) { var body = []; if (self.bcatch) { extract_declarations_from_unreachable_code(compressor, self.bcatch, body); diff --git a/lib/parse.js b/lib/parse.js index f760d0de..3b7d15ca 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1216,7 +1216,7 @@ function parse($TEXT, options) { var name = null; if (is("punc", "(")) { next(); - name = as_symbol(AST_SymbolCatch); + name = maybe_destructured(AST_SymbolCatch); expect(")"); } bcatch = new AST_Catch({ |