Compare commits

...

4 Commits

Author SHA1 Message Date
Mihai Bazon
a790c09c91 v2.4.7 2013-12-09 12:09:31 +02:00
Mihai Bazon
8f35a363d9 AST_Catch shouldn't really inherit from AST_Scope. Fix #363
I hereby acknowledge that figure_out_scope has become a mess.
2013-12-05 13:30:29 +02:00
Mihai Bazon
d2190c2bf3 Properly scope catch identifier when --screw-ie8
Fix #344
2013-11-28 16:43:30 +02:00
Mihai Bazon
ea10642572 v2.4.6, because npm is foobar 2013-11-28 15:05:32 +02:00
5 changed files with 70 additions and 30 deletions

View File

@@ -498,12 +498,6 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
}
}, AST_Block);
// XXX: this is wrong according to ECMA-262 (12.4). the catch block
// should introduce another scope, as the argname should be visible
// only inside the catch block. However, doing it this way because of
// IE which simply introduces the name in the surrounding scope. If
// we ever want to fix this then AST_Catch should inherit from
// AST_Scope.
var AST_Catch = DEFNODE("Catch", "argname", {
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
$propdoc: {

View File

@@ -1669,10 +1669,10 @@ merge(Compressor.prototype, {
return arg.value;
}).join(",") + "){" + self.args[self.args.length - 1].value + "})()";
var ast = parse(code);
ast.figure_out_scope();
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
var comp = new Compressor(compressor.options);
ast = ast.transform(comp);
ast.figure_out_scope();
ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") });
ast.mangle_names();
var fun;
try {

View File

@@ -71,27 +71,34 @@ SymbolDef.prototype = {
}
};
AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
// This does what ast_add_scope did in UglifyJS v1.
//
// Part of it could be done at parse time, but it would complicate
// the parser (and it's already kinda complex). It's also worth
// having it separated because we might need to call it multiple
// times on the same tree.
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
options = defaults(options, {
screw_ie8: false
});
// pass 1: setup scope chaining and handle definitions
var self = this;
var scope = self.parent_scope = null;
var defun = null;
var nesting = 0;
var tw = new TreeWalker(function(node, descend){
if (options.screw_ie8 && node instanceof AST_Catch) {
var save_scope = scope;
scope = new AST_Scope(node);
scope.init_scope_vars(nesting);
scope.parent_scope = save_scope;
descend();
scope = save_scope;
return true;
}
if (node instanceof AST_Scope) {
node.init_scope_vars(nesting);
var save_scope = node.parent_scope = scope;
++nesting;
scope = node;
descend();
var save_defun = defun;
defun = scope = node;
++nesting; descend(); --nesting;
scope = save_scope;
--nesting;
defun = save_defun;
return true; // don't descend again in TreeWalker
}
if (node instanceof AST_Directive) {
@@ -108,7 +115,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
node.scope = scope;
}
if (node instanceof AST_SymbolLambda) {
scope.def_function(node);
defun.def_function(node);
}
else if (node instanceof AST_SymbolDefun) {
// Careful here, the scope where this should be defined is
@@ -116,22 +123,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
// scope when we encounter the AST_Defun node (which is
// instanceof AST_Scope) but we get to the symbol a bit
// later.
(node.scope = scope.parent_scope).def_function(node);
(node.scope = defun.parent_scope).def_function(node);
}
else if (node instanceof AST_SymbolVar
|| node instanceof AST_SymbolConst) {
var def = scope.def_variable(node);
var def = defun.def_variable(node);
def.constant = node instanceof AST_SymbolConst;
def.init = tw.parent().value;
}
else if (node instanceof AST_SymbolCatch) {
// XXX: this is wrong according to ECMA-262 (12.4). the
// `catch` argument name should be visible only inside the
// catch block. For a quick fix AST_Catch should inherit
// from AST_Scope. Keeping it this way because of IE,
// which doesn't obey the standard. (it introduces the
// identifier in the enclosing scope)
scope.def_variable(node);
(options.screw_ie8 ? scope : defun)
.def_variable(node);
}
});
self.walk(tw);

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"homepage": "http://lisperator.net/uglifyjs",
"main": "tools/node.js",
"version": "2.4.5",
"version": "2.4.7",
"engines": { "node" : ">=0.4.0" },
"maintainers": [{
"name": "Mihai Bazon",

View File

@@ -119,3 +119,47 @@ unused_keep_setter_arg: {
}
}
}
unused_var_in_catch: {
options = { unused: true };
input: {
function foo() {
try {
foo();
} catch(ex) {
var x = 10;
}
}
}
expect: {
function foo() {
try {
foo();
} catch(ex) {}
}
}
}
used_var_in_catch: {
options = { unused: true };
input: {
function foo() {
try {
foo();
} catch(ex) {
var x = 10;
}
return x;
}
}
expect: {
function foo() {
try {
foo();
} catch(ex) {
var x = 10;
}
return x;
}
}
}