support for directives
This commit is contained in:
@@ -126,7 +126,7 @@ var AST_Debugger = DEFNODE("Debugger", null, {
|
|||||||
$documentation: "Represents a debugger statement"
|
$documentation: "Represents a debugger statement"
|
||||||
}, AST_StatementBase);
|
}, AST_StatementBase);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "value", {
|
var AST_Directive = DEFNODE("Directive", "value scope", {
|
||||||
$documentation: "Represents a directive, like \"use strict\";"
|
$documentation: "Represents a directive, like \"use strict\";"
|
||||||
}, AST_StatementBase);
|
}, AST_StatementBase);
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
|
|
||||||
/* -----[ scope and functions ]----- */
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
var AST_Scope = DEFNODE("Scope", "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",
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
|
|||||||
@@ -742,6 +742,13 @@ function Compressor(options, false_by_default) {
|
|||||||
|
|
||||||
/* -----[ node squeezers ]----- */
|
/* -----[ node squeezers ]----- */
|
||||||
|
|
||||||
|
SQUEEZE(AST_Directive, function(self, compressor){
|
||||||
|
if (self.hoisted || self.scope.has_directive(self.value) !== self.scope) {
|
||||||
|
return new AST_EmptyStatement(self);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
});
|
||||||
|
|
||||||
SQUEEZE(AST_Debugger, function(self, compressor){
|
SQUEEZE(AST_Debugger, function(self, compressor){
|
||||||
if (compressor.option("drop_debugger"))
|
if (compressor.option("drop_debugger"))
|
||||||
return new AST_EmptyStatement(self);
|
return new AST_EmptyStatement(self);
|
||||||
@@ -796,6 +803,10 @@ function Compressor(options, false_by_default) {
|
|||||||
var vars = {}, vars_found = 0, vardecl = [];
|
var vars = {}, vars_found = 0, vardecl = [];
|
||||||
var tw = new TreeWalker(function(node){
|
var tw = new TreeWalker(function(node){
|
||||||
if (node !== self) {
|
if (node !== self) {
|
||||||
|
if (node instanceof AST_Directive && (hoist_funs || hoist_vars) && !node.hoisted) {
|
||||||
|
hoisted.unshift(node.clone());
|
||||||
|
node.hoisted = true;
|
||||||
|
}
|
||||||
if (node instanceof AST_Defun && hoist_funs && !node.hoisted) {
|
if (node instanceof AST_Defun && hoist_funs && !node.hoisted) {
|
||||||
hoisted.push(node.clone());
|
hoisted.push(node.clone());
|
||||||
node.hoisted = true;
|
node.hoisted = true;
|
||||||
|
|||||||
@@ -428,6 +428,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
DEFPRINT(AST_Directive, function(self, output){
|
DEFPRINT(AST_Directive, function(self, output){
|
||||||
output.print_string(self.value);
|
output.print_string(self.value);
|
||||||
|
output.semicolon();
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Debugger, function(self, output){
|
DEFPRINT(AST_Debugger, function(self, output){
|
||||||
output.print("debugger");
|
output.print("debugger");
|
||||||
|
|||||||
@@ -773,8 +773,8 @@ function parse($TEXT, exigent_mode) {
|
|||||||
case "string":
|
case "string":
|
||||||
var dir = S.in_directives, stat = simple_statement();
|
var dir = S.in_directives, stat = simple_statement();
|
||||||
// XXXv2: decide how to fix directives
|
// XXXv2: decide how to fix directives
|
||||||
// if (dir && stat instanceof AST_String && !is("punc", ","))
|
if (dir && stat.body instanceof AST_String && !is("punc", ","))
|
||||||
// return new AST_Directive({ value: stat.value });
|
return new AST_Directive({ value: stat.body.value });
|
||||||
return stat;
|
return stat;
|
||||||
case "num":
|
case "num":
|
||||||
case "regexp":
|
case "regexp":
|
||||||
|
|||||||
11
lib/scope.js
11
lib/scope.js
@@ -82,6 +82,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
|
|||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
return true; // don't descend again in TreeWalker
|
return true; // don't descend again in TreeWalker
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Directive) {
|
||||||
|
node.scope = scope;
|
||||||
|
push_uniq(scope.directives, node.value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_With) {
|
if (node instanceof AST_With) {
|
||||||
for (var s = scope; s; s = s.parent_scope)
|
for (var s = scope; s; s = s.parent_scope)
|
||||||
s.uses_with = true;
|
s.uses_with = true;
|
||||||
@@ -193,6 +198,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("init_scope_vars", function(){
|
AST_Scope.DEFMETHOD("init_scope_vars", function(){
|
||||||
|
this.directives = []; // contains the directives defined in this scope, i.e. "use strict"
|
||||||
this.variables = {}; // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
this.variables = {}; // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||||
this.functions = {}; // map name to AST_SymbolDefun (functions defined in this scope)
|
this.functions = {}; // map name to AST_SymbolDefun (functions defined in this scope)
|
||||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||||
@@ -233,6 +239,11 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
|||||||
: (this.parent_scope && this.parent_scope.find_variable(name));
|
: (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("has_directive", function(value){
|
||||||
|
return this.parent_scope && this.parent_scope.has_directive(value)
|
||||||
|
|| (this.directives.indexOf(value) >= 0 ? this : null);
|
||||||
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||||
this.functions[symbol.name] = this.def_variable(symbol);
|
this.functions[symbol.name] = this.def_variable(symbol);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user