From: Mihai Bazon Date: Thu, 6 Dec 2012 10:27:57 +0000 (+0200) Subject: Add proper parens in "NoIn" expressions. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=98978fc827635617c763bcfb40ada026da00b852;p=UglifyJS.git Add proper parens in "NoIn" expressions. fix #60. --- diff --git a/lib/output.js b/lib/output.js index 8f43245a..72f49b94 100644 --- a/lib/output.js +++ b/lib/output.js @@ -340,10 +340,10 @@ function OutputStream(options) { /* -----[ utils ]----- */ function DEFPRINT(nodetype, generator) { - nodetype.DEFMETHOD("print", function(stream){ + nodetype.DEFMETHOD("print", function(stream, force_parens){ var self = this; stream.push_node(self); - if (self.needs_parens(stream)) { + if (force_parens || self.needs_parens(stream)) { stream.with_parens(function(){ self.add_comments(stream); self.add_source_map(stream); @@ -467,18 +467,6 @@ function OutputStream(options) { return true; } } - // for (var i = (foo in bar);;); ← perhaps useless, but valid syntax - if (this.operator == "in") { - // the “NoIn” stuff :-\ - // UglifyJS 1.3.3 misses this one. - if ((p instanceof AST_For || p instanceof AST_ForIn) && p.init === this) - return true; - if (p instanceof AST_VarDef) { - var v = output.parent(1), p2 = output.parent(2); - if ((p2 instanceof AST_For || p2 instanceof AST_ForIn) && p2.init === v) - return true; - } - } }); PARENS(AST_PropAccess, function(output){ @@ -622,7 +610,11 @@ function OutputStream(options) { output.space(); output.with_parens(function(){ if (self.init) { - self.init.print(output); + if (self.init instanceof AST_Definitions) { + self.init.print(output); + } else { + parenthesize_for_noin(self.init, output, true); + } output.print(";"); output.space(); } else { @@ -866,13 +858,32 @@ function OutputStream(options) { DEFPRINT(AST_Const, function(self, output){ self._do_print(output, "const"); }); + + function parenthesize_for_noin(node, output, noin) { + if (!noin) node.print(output); + else try { + // need to take some precautions here: + // https://github.com/mishoo/UglifyJS2/issues/60 + node.walk(new TreeWalker(function(node){ + if (node instanceof AST_Binary && node.operator == "in") + throw output; + })); + node.print(output); + } catch(ex) { + if (ex !== output) throw ex; + node.print(output, true); + } + }; + DEFPRINT(AST_VarDef, function(self, output){ self.name.print(output); if (self.value) { output.space(); output.print("="); output.space(); - self.value.print(output); + var p = output.parent(1); + var noin = p instanceof AST_For || p instanceof AST_ForIn; + parenthesize_for_noin(self.value, output, noin); } });