[Pkg-javascript-commits] [uglifyjs] 61/190: Rework has_directive

Antonio Terceiro terceiro at moszumanska.debian.org
Sun Aug 7 23:17:13 UTC 2016


This is an automated email from the git hooks/post-receive script.

terceiro pushed a commit to annotated tag upstream/2.7.0
in repository uglifyjs.

commit 7691bebea525e96cb74d52e0bb8f294cf778c966
Author: Mihai Bazon <mihai.bazon at gmail.com>
Date:   Wed Nov 11 22:15:25 2015 +0200

    Rework has_directive
    
    It's now available during tree walking, i.e. walker.has_directive("use
    asm"), rather than as part of the scope.  It's thus no longer necessary
    to call `figure_out_scope` before codegen.  Added special bits in the
    code generator to overcome the fact that it doesn't inherit from
    TreeWalker.
    
    Fix #861
---
 bin/uglifyjs     | 29 +++++++++++++++++------------
 lib/ast.js       | 30 ++++++++++++++++++++++++------
 lib/compress.js  |  2 +-
 lib/output.js    | 16 +++++++++++-----
 lib/parse.js     | 11 +++++------
 lib/scope.js     | 19 -------------------
 lib/transform.js |  2 +-
 tools/node.js    | 10 +---------
 8 files changed, 60 insertions(+), 59 deletions(-)

diff --git a/bin/uglifyjs b/bin/uglifyjs
index 8d4fe4d..f7f2221 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -409,14 +409,17 @@ async.eachLimit(files, 1, function (file, cb) {
         writeNameCache("props", cache);
     })();
 
+    var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
     var TL_CACHE = readNameCache("vars");
 
-    time_it("scope", function(){
-        TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
-        if (ARGS.lint) {
-            TOPLEVEL.scope_warnings();
-        }
-    });
+    if (SCOPE_IS_NEEDED) {
+        time_it("scope", function(){
+            TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
+            if (ARGS.lint) {
+                TOPLEVEL.scope_warnings();
+            }
+        });
+    }
 
     if (COMPRESS) {
         time_it("squeeze", function(){
@@ -424,12 +427,14 @@ async.eachLimit(files, 1, function (file, cb) {
         });
     }
 
-    time_it("scope", function(){
-        TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
-        if (MANGLE && !TL_CACHE) {
-            TOPLEVEL.compute_char_frequency(MANGLE);
-        }
-    });
+    if (SCOPE_IS_NEEDED) {
+        time_it("scope", function(){
+            TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
+            if (MANGLE && !TL_CACHE) {
+                TOPLEVEL.compute_char_frequency(MANGLE);
+            }
+        });
+    }
 
     if (MANGLE) time_it("mangle", function(){
         MANGLE.cache = TL_CACHE;
diff --git a/lib/ast.js b/lib/ast.js
index e795284..f5225d7 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) {
     return ctor;
 };
 
-var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file", {
+var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file literal", {
 }, null);
 
 var AST_Node = DEFNODE("Node", "start end", {
@@ -927,27 +927,36 @@ var AST_True = DEFNODE("True", null, {
 function TreeWalker(callback) {
     this.visit = callback;
     this.stack = [];
+    this.directives = Object.create(null);
 };
 TreeWalker.prototype = {
     _visit: function(node, descend) {
-        this.stack.push(node);
+        this.push(node);
         var ret = this.visit(node, descend ? function(){
             descend.call(node);
         } : noop);
         if (!ret && descend) {
             descend.call(node);
         }
-        this.stack.pop();
+        this.pop(node);
         return ret;
     },
     parent: function(n) {
         return this.stack[this.stack.length - 2 - (n || 0)];
     },
     push: function (node) {
+        if (node instanceof AST_Lambda) {
+            this.directives = Object.create(this.directives);
+        } else if (node instanceof AST_Directive) {
+            this.directives[node.value] = this.directives[node.value] ? "up" : true;
+        }
         this.stack.push(node);
     },
-    pop: function() {
-        return this.stack.pop();
+    pop: function(node) {
+        this.stack.pop();
+        if (node instanceof AST_Lambda) {
+            this.directives = Object.getPrototypeOf(this.directives);
+        }
     },
     self: function() {
         return this.stack[this.stack.length - 1];
@@ -960,7 +969,16 @@ TreeWalker.prototype = {
         }
     },
     has_directive: function(type) {
-        return this.find_parent(AST_Scope).has_directive(type);
+        var dir = this.directives[type];
+        if (dir) return dir;
+        var node = this.stack[this.stack.length - 1];
+        if (node instanceof AST_Scope) {
+            for (var i = 0; i < node.body.length; ++i) {
+                var st = node.body[i];
+                if (!(st instanceof AST_Directive)) break;
+                if (st.value == type) return true;
+            }
+        }
     },
     in_boolean_context: function() {
         var stack = this.stack;
diff --git a/lib/compress.js b/lib/compress.js
index 50353fe..3efca41 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -991,7 +991,7 @@ merge(Compressor.prototype, {
     /* -----[ optimizers ]----- */
 
     OPT(AST_Directive, function(self, compressor){
-        if (self.scope.has_directive(self.value) !== self.scope) {
+        if (compressor.has_directive(self.value) === "up") {
             return make_node(AST_EmptyStatement, self);
         }
         return self;
diff --git a/lib/output.js b/lib/output.js
index b7f6971..9dadf0e 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -382,8 +382,13 @@ function OutputStream(options) {
         nodetype.DEFMETHOD("_codegen", generator);
     };
 
+    var use_asm = false;
+
     AST_Node.DEFMETHOD("print", function(stream, force_parens){
-        var self = this, generator = self._codegen;
+        var self = this, generator = self._codegen, prev_use_asm = use_asm;
+        if (self instanceof AST_Directive && self.value == "use asm") {
+            use_asm = true;
+        }
         function doit() {
             self.add_comments(stream);
             self.add_source_map(stream);
@@ -396,6 +401,9 @@ function OutputStream(options) {
             doit();
         }
         stream.pop_node();
+        if (self instanceof AST_Lambda) {
+            use_asm = prev_use_asm;
+        }
     });
 
     AST_Node.DEFMETHOD("print_to_string", function(options){
@@ -1170,10 +1178,8 @@ function OutputStream(options) {
         output.print_string(self.getValue(), self.quote);
     });
     DEFPRINT(AST_Number, function(self, output){
-        if (self.literal !== undefined
-            && +self.literal === self.value  /* paranoid check */
-            && self.scope && self.scope.has_directive('use asm')) {
-            output.print(self.literal);
+        if (use_asm) {
+            output.print(self.start.literal);
         } else {
             output.print(make_num(self.getValue()));
         }
diff --git a/lib/parse.js b/lib/parse.js
index cb35118..901d10a 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -285,6 +285,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
             nlb     : S.newline_before,
             file    : filename
         };
+        if (/^(?:num|string|regexp)$/i.test(type)) {
+            ret.literal = $TEXT.substring(ret.pos, ret.endpos);
+        }
         if (!is_comment) {
             ret.comments_before = S.comments_before;
             S.comments_before = [];
@@ -335,11 +338,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
         if (prefix) num = prefix + num;
         var valid = parse_js_number(num);
         if (!isNaN(valid)) {
-            var tok = token("num", valid);
-            if (num.indexOf('.') >= 0) {
-                tok.literal = num;
-            }
-            return tok;
+            return token("num", valid);
         } else {
             parse_error("Invalid syntax: " + num);
         }
@@ -1152,7 +1151,7 @@ function parse($TEXT, options) {
             ret = _make_symbol(AST_SymbolRef);
             break;
           case "num":
-            ret = new AST_Number({ start: tok, end: tok, value: tok.value, literal: tok.literal });
+            ret = new AST_Number({ start: tok, end: tok, value: tok.value });
             break;
           case "string":
             ret = new AST_String({
diff --git a/lib/scope.js b/lib/scope.js
index 06bd65a..4a3739c 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -114,15 +114,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
             defun = save_defun;
             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_Number) {
-            node.scope = scope;
-            return true;
-        }
         if (node instanceof AST_With) {
             for (var s = scope; s; s = s.parent_scope)
                 s.uses_with = true;
@@ -202,7 +193,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
 });
 
 AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
-    this.directives = [];     // contains the directives defined in this scope, i.e. "use strict"
     this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
     this.functions = new Dictionary(); // 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
@@ -213,10 +203,6 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
     this.nesting = nesting;   // the nesting level of this scope (0 means toplevel)
 });
 
-AST_Scope.DEFMETHOD("strict", function(){
-    return this.has_directive("use strict");
-});
-
 AST_Lambda.DEFMETHOD("init_scope_vars", function(){
     AST_Scope.prototype.init_scope_vars.apply(this, arguments);
     this.uses_arguments = false;
@@ -240,11 +226,6 @@ AST_Scope.DEFMETHOD("find_variable", function(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){
     this.functions.set(symbol.name, this.def_variable(symbol));
 });
diff --git a/lib/transform.js b/lib/transform.js
index c3c34f5..62e6e02 100644
--- a/lib/transform.js
+++ b/lib/transform.js
@@ -70,7 +70,7 @@ TreeTransformer.prototype = new TreeWalker;
                     if (y !== undefined) x = y;
                 }
             }
-            tw.pop();
+            tw.pop(this);
             return x;
         });
     };
diff --git a/tools/node.js b/tools/node.js
index 7e61d2a..f604866 100644
--- a/tools/node.js
+++ b/tools/node.js
@@ -45,7 +45,6 @@ exports.minify = function(files, options) {
     UglifyJS.base54.reset();
 
     // 1. parse
-    var haveScope = false;
     var toplevel = null,
         sourcesContent = {};
 
@@ -74,7 +73,6 @@ exports.minify = function(files, options) {
         var compress = { warnings: options.warnings };
         UglifyJS.merge(compress, options.compress);
         toplevel.figure_out_scope();
-        haveScope = true;
         var sq = UglifyJS.Compressor(compress);
         toplevel = toplevel.transform(sq);
     }
@@ -82,17 +80,11 @@ exports.minify = function(files, options) {
     // 3. mangle
     if (options.mangle) {
         toplevel.figure_out_scope(options.mangle);
-        haveScope = true;
         toplevel.compute_char_frequency(options.mangle);
         toplevel.mangle_names(options.mangle);
     }
 
-    // 4. scope (if needed)
-    if (!haveScope) {
-        toplevel.figure_out_scope();
-    }
-
-    // 5. output
+    // 4. output
     var inMap = options.inSourceMap;
     var output = {};
     if (typeof options.inSourceMap == "string") {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list