From 5f6825f9ecc7a98fc04b33851275c5eea30f9360 Mon Sep 17 00:00:00 2001 From: Anthony Van de Gejuchte Date: Wed, 19 Oct 2016 15:34:26 +0200 Subject: [PATCH] Introduce is_block_scope to AST_Node to determine block scope. Will return false if AST_Node is instance of AST_Scope for now. --- lib/ast.js | 5 ++--- lib/scope.js | 17 ++++++++------- test/compress/block-scope.js | 42 ++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 2b835e88..e09150c5 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -282,10 +282,9 @@ var AST_With = DEFNODE("With", "expression", { /* -----[ scope and functions ]----- */ -var AST_Scope = DEFNODE("Scope", "is_block_scope directives variables functions uses_with uses_eval parent_scope enclosed cname", { +var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", { $documentation: "Base class for all statements introducing a lexical scope", $propdoc: { - is_block_scope: "[boolean] identifies a block scope", directives: "[string*/S] an array of directives declared in this scope", variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope", functions: "[Object/S] like `variables`, but only lists function declarations", @@ -297,7 +296,7 @@ var AST_Scope = DEFNODE("Scope", "is_block_scope directives variables functions }, get_defun_scope: function () { var self = this; - while (self.is_block_scope && self.parent_scope) { + while (self.is_block_scope() && self.parent_scope) { self = self.parent_scope; } return self; diff --git a/lib/scope.js b/lib/scope.js index 17cd7222..b17d04e3 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -110,15 +110,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ var in_destructuring = null; var in_export; var tw = new TreeWalker(function(node, descend){ - var create_a_block_scope = - (options.screw_ie8 && node instanceof AST_Catch) || - ((node instanceof AST_Block) && node.creates_block_scope()); - if (create_a_block_scope) { + if (node.is_block_scope()) { var save_scope = scope; scope = new AST_Scope(node); scope.init_scope_vars(nesting); scope.parent_scope = save_scope; - scope.is_block_scope = true; if (!(node instanceof AST_Scope)) { scope.uses_with = save_scope.uses_with; scope.uses_eval = save_scope.uses_eval; @@ -188,7 +184,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ // instanceof AST_Scope) but we get to the symbol a bit // later. var parent_lambda = defun.parent_scope; - while (parent_lambda.is_block_scope) { + while (parent_lambda.is_block_scope()) { parent_lambda = parent_lambda.parent_scope; } (node.scope = parent_lambda).def_function(node, in_export); @@ -305,11 +301,16 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){ this.nesting = nesting; // the nesting level of this scope (0 means toplevel) }); -AST_Block.DEFMETHOD("creates_block_scope", function() { +AST_Node.DEFMETHOD("is_block_scope", function(){ + return false; // Behaviour will be overridden by AST_Block +}); + +AST_Block.DEFMETHOD("is_block_scope", function(){ return ( !(this instanceof AST_Lambda) && !(this instanceof AST_Toplevel) && - !(this instanceof AST_Class) + !(this instanceof AST_Class) && + !(this instanceof AST_SwitchBranch) ); }); diff --git a/test/compress/block-scope.js b/test/compress/block-scope.js index dd243009..cc2c316f 100644 --- a/test/compress/block-scope.js +++ b/test/compress/block-scope.js @@ -130,3 +130,45 @@ regression_block_scope_resolves: { }()); } } + +switch_block_scope_mangler: { + mangle = {} + input: { + var fn = function(code) { + switch (code) { + case 1: + let apple = code + 1; + let dog = code + 4; + console.log(apple, dog); + break; + case 2: + let banana = code + 2; + console.log(banana); + break; + default: + let cat = code + 3; + console.log(cat); + } + }; + } + expect: { + var fn = function(o) { + switch (o) { + case 1: + let e = o + 1 + let c = o + 4; + console.log(e, c); + break; + + case 2: + let l = o + 2; + console.log(l); + break; + + default: + let a = o + 3; + console.log(a); + } + }; + } +}