Introduce is_block_scope to AST_Node to determine block scope.
Will return false if AST_Node is instance of AST_Scope for now.
This commit is contained in:
@@ -282,10 +282,9 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
|
|
||||||
/* -----[ scope and functions ]----- */
|
/* -----[ 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",
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
is_block_scope: "[boolean] identifies a block scope",
|
|
||||||
directives: "[string*/S] an array of directives declared in this 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",
|
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",
|
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 () {
|
get_defun_scope: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
while (self.is_block_scope && self.parent_scope) {
|
while (self.is_block_scope() && self.parent_scope) {
|
||||||
self = self.parent_scope;
|
self = self.parent_scope;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
17
lib/scope.js
17
lib/scope.js
@@ -110,15 +110,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
var in_destructuring = null;
|
var in_destructuring = null;
|
||||||
var in_export;
|
var in_export;
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
var create_a_block_scope =
|
if (node.is_block_scope()) {
|
||||||
(options.screw_ie8 && node instanceof AST_Catch) ||
|
|
||||||
((node instanceof AST_Block) && node.creates_block_scope());
|
|
||||||
if (create_a_block_scope) {
|
|
||||||
var save_scope = scope;
|
var save_scope = scope;
|
||||||
scope = new AST_Scope(node);
|
scope = new AST_Scope(node);
|
||||||
scope.init_scope_vars(nesting);
|
scope.init_scope_vars(nesting);
|
||||||
scope.parent_scope = save_scope;
|
scope.parent_scope = save_scope;
|
||||||
scope.is_block_scope = true;
|
|
||||||
if (!(node instanceof AST_Scope)) {
|
if (!(node instanceof AST_Scope)) {
|
||||||
scope.uses_with = save_scope.uses_with;
|
scope.uses_with = save_scope.uses_with;
|
||||||
scope.uses_eval = save_scope.uses_eval;
|
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
|
// instanceof AST_Scope) but we get to the symbol a bit
|
||||||
// later.
|
// later.
|
||||||
var parent_lambda = defun.parent_scope;
|
var parent_lambda = defun.parent_scope;
|
||||||
while (parent_lambda.is_block_scope) {
|
while (parent_lambda.is_block_scope()) {
|
||||||
parent_lambda = parent_lambda.parent_scope;
|
parent_lambda = parent_lambda.parent_scope;
|
||||||
}
|
}
|
||||||
(node.scope = parent_lambda).def_function(node, in_export);
|
(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)
|
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 (
|
return (
|
||||||
!(this instanceof AST_Lambda) &&
|
!(this instanceof AST_Lambda) &&
|
||||||
!(this instanceof AST_Toplevel) &&
|
!(this instanceof AST_Toplevel) &&
|
||||||
!(this instanceof AST_Class)
|
!(this instanceof AST_Class) &&
|
||||||
|
!(this instanceof AST_SwitchBranch)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user