declare some properties in the node constructor so that they're copied in clone
authorMihai Bazon <mihai@bazon.net>
Tue, 21 Aug 2012 17:06:57 +0000 (20:06 +0300)
committerMihai Bazon <mihai@bazon.net>
Tue, 21 Aug 2012 21:01:55 +0000 (00:01 +0300)
lib/ast.js
lib/output.js
lib/scope.js
tmp/test-node.js

index 3fd197e..97480cc 100644 (file)
@@ -157,7 +157,7 @@ var AST_With = DEFNODE("With", "expression", {
 
 /* -----[ scope and functions ]----- */
 
-var AST_Scope = DEFNODE("Scope", null, {
+var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
     $documentation: "Base class for all statements introducing a lexical scope"
 }, AST_BlockStatement);
 
@@ -165,7 +165,7 @@ var AST_Toplevel = DEFNODE("Toplevel", null, {
     $documentation: "The toplevel scope"
 }, AST_Scope);
 
-var AST_Lambda = DEFNODE("Lambda", "name argnames", {
+var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
     $documentation: "Base class for functions",
     _walk: function(visitor) {
         return visitor._visit(this, function(){
@@ -470,10 +470,10 @@ var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
 var AST_ObjectGetter = DEFNODE("ObjectGetter", null, {
 }, AST_ObjectProperty);
 
-var AST_Symbol = DEFNODE("Symbol", "scope name", {
+var AST_Symbol = DEFNODE("Symbol", "scope name global undeclared", {
 });
 
-var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", null, {
+var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "references", {
 }, AST_Symbol);
 
 var AST_SymbolVar = DEFNODE("SymbolVar", null, {
index 6152423..990fcce 100644 (file)
@@ -8,6 +8,7 @@ function OutputStream(options) {
         ascii_only    : false,
         inline_script : false,
         width         : 80,
+        ie_proof      : true,
         beautify      : true
     });
 
@@ -262,14 +263,14 @@ function OutputStream(options) {
 
     PARENS(AST_Seq, function(output){
         var p = output.parent();
-        return p instanceof AST_Call             // (foo, bar)() —or— foo(1, (2, 3), 4)
-            || p instanceof AST_Binary           // 1 + (2, 3) + 4  7
-            || p instanceof AST_VarDef           // var a = (1, 2), b = a + a; → b = 4
-            || p instanceof AST_Dot              // (1, {foo:2}).foo  2
-            || p instanceof AST_Array            // [ 1, (2, 3), 4 ]  [ 1, 3, 4 ]
-            || p instanceof AST_ObjectProperty   // { foo: (1, 2) }.foo  2
+        return p instanceof AST_Call             // (foo, bar)() or foo(1, (2, 3), 4)
+            || p instanceof AST_Binary           // 1 + (2, 3) + 4 ==> 7
+            || p instanceof AST_VarDef           // var a = (1, 2), b = a + a; ==> b == 4
+            || p instanceof AST_Dot              // (1, {foo:2}).foo ==> 2
+            || p instanceof AST_Array            // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
+            || p instanceof AST_ObjectProperty   // { foo: (1, 2) }.foo ==> 2
             || p instanceof AST_Conditional      /* (false, true) ? (a = 10, b = 20) : (c = 30)
-                                                  * → 20 (side effect, set a = 10 and b = 20) */
+                                                  * ==> 20 (side effect, set a := 10 and b := 20) */
         ;
     });
 
@@ -324,7 +325,7 @@ function OutputStream(options) {
         // !(a = false) → true
         if (p instanceof AST_Unary)
             return true;
-        // 1 + (a = 2) + 3 → 3, side effect setting a = 2
+        // 1 + (a = 2) + 3 → 6, side effect setting a = 2
         if (p instanceof AST_Binary && !(p instanceof AST_Assign))
             return true;
         // (a = func)() —or— new (a = Object)()
@@ -529,7 +530,8 @@ function OutputStream(options) {
         // adds the block brackets if needed.
         if (!self.consequent)
             return output.semicolon();
-        if (self.consequent instanceof AST_Do) {
+        if (self.consequent instanceof AST_Do
+            && output.option("ie_proof")) {
             // https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
             // croaks with "syntax error" on code like this: if (foo)
             // do ... while(cond); else ...  we need block brackets
@@ -546,10 +548,10 @@ function OutputStream(options) {
                 }
                 b = b.alternative;
             }
-            else if (b instanceof AST_While ||
-                     b instanceof AST_Do ||
-                     b instanceof AST_For ||
-                     b instanceof AST_ForIn) {
+            else if (b instanceof AST_While
+                     || b instanceof AST_Do
+                     || b instanceof AST_For
+                     || b instanceof AST_ForIn) {
                 b = b.body;
             }
             else break;
index a017056..5ee0fb4 100644 (file)
@@ -231,9 +231,9 @@ AST_Scope.DEFMETHOD("next_mangled", function(){
     out: while (true) {
         var m = base54(++this.cname);
         if (!is_identifier(m)) continue; // skip over "do"
-        // if it's for functions or variables, we must ensure that the
-        // mangled name does not shadow a name from some parent scope
-        // that is referenced in this or in inner scopes.
+        // we must ensure that the mangled name does not shadow a name
+        // from some parent scope that is referenced in this or in
+        // inner scopes.
         for (var i = n; --i >= 0;) {
             var sym = ext[i];
             var name = sym.mangled_name || sym.name;
index 8b1251b..377d001 100755 (executable)
@@ -18,6 +18,9 @@ time_it("scope", function(){
 time_it("mangle", function(){
     ast.mangle_names();
 });
+
+ast.scope_warnings();
+
 time_it("compress", function(){
     var compressor = new UglifyJS.Compressor({
     });