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:
Anthony Van de Gejuchte
2016-10-19 15:34:26 +02:00
parent 7e80a979a7
commit 5f6825f9ec
3 changed files with 53 additions and 11 deletions

View File

@@ -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;

View File

@@ -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)
);
});

View File

@@ -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);
}
};
}
}