[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