Merge branch 'master' into harmony
This commit is contained in:
@@ -1357,6 +1357,7 @@ merge(Compressor.prototype, {
|
||||
if (compressor.has_directive("use asm")) return self;
|
||||
if (compressor.option("unused")
|
||||
&& !self.uses_eval
|
||||
&& !self.uses_with
|
||||
) {
|
||||
var in_use = [];
|
||||
var in_use_ids = {}; // avoid expensive linear scans of in_use
|
||||
|
||||
@@ -88,7 +88,8 @@ function OutputStream(options) {
|
||||
|
||||
function make_string(str, quote) {
|
||||
var dq = 0, sq = 0;
|
||||
str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){
|
||||
str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g,
|
||||
function(s, i){
|
||||
switch (s) {
|
||||
case '"': ++dq; return '"';
|
||||
case "'": ++sq; return "'";
|
||||
@@ -101,8 +102,9 @@ function OutputStream(options) {
|
||||
case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B";
|
||||
case "\u2028": return "\\u2028";
|
||||
case "\u2029": return "\\u2029";
|
||||
case "\0": return "\\x00";
|
||||
case "\ufeff": return "\\ufeff";
|
||||
case "\0":
|
||||
return /[0-7]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
|
||||
}
|
||||
return s;
|
||||
});
|
||||
@@ -611,7 +613,7 @@ function OutputStream(options) {
|
||||
|
||||
PARENS(AST_New, function(output){
|
||||
var p = output.parent();
|
||||
if (no_constructor_parens(this, output)
|
||||
if (!need_constructor_parens(this, output)
|
||||
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|
||||
|| p instanceof AST_Call && p.expression === this)) // (new foo)(bar)
|
||||
return true;
|
||||
@@ -1175,7 +1177,7 @@ function OutputStream(options) {
|
||||
/* -----[ other expressions ]----- */
|
||||
DEFPRINT(AST_Call, function(self, output){
|
||||
self.expression.print(output);
|
||||
if (self instanceof AST_New && no_constructor_parens(self, output))
|
||||
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
||||
return;
|
||||
output.with_parens(function(){
|
||||
self.args.forEach(function(expr, i){
|
||||
@@ -1531,13 +1533,9 @@ function OutputStream(options) {
|
||||
};
|
||||
|
||||
// self should be AST_New. decide if we want to show parens or not.
|
||||
function no_constructor_parens(self, output) {
|
||||
return self.args.length == 0 && !output.option("beautify") ||
|
||||
!(self.expression instanceof AST_SymbolRef ||
|
||||
self.expression instanceof AST_Call ||
|
||||
self.expression instanceof AST_Function ||
|
||||
self.expression instanceof AST_Assign
|
||||
);
|
||||
function need_constructor_parens(self, output) {
|
||||
// Always print parentheses with arguments
|
||||
return self.args.length > 0;
|
||||
};
|
||||
|
||||
function best_of(a) {
|
||||
|
||||
63
lib/parse.js
63
lib/parse.js
@@ -234,7 +234,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
tokcol : 0,
|
||||
newline_before : false,
|
||||
regex_allowed : false,
|
||||
comments_before : []
|
||||
comments_before : [],
|
||||
directives : {},
|
||||
directive_stack : []
|
||||
};
|
||||
|
||||
function peek() { return S.text.charAt(S.pos); };
|
||||
@@ -403,8 +405,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
for (;;) {
|
||||
var ch = next(true, true);
|
||||
if (ch == "\\") {
|
||||
// read OctalEscapeSequence (XXX: deprecated if "strict mode")
|
||||
// https://github.com/mishoo/UglifyJS/issues/178
|
||||
var octal_len = 0, first = null;
|
||||
ch = read_while(function(ch){
|
||||
if (ch >= "0" && ch <= "7") {
|
||||
@@ -417,8 +417,13 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (octal_len > 0) ch = String.fromCharCode(parseInt(ch, 8));
|
||||
else ch = read_escaped_char(true);
|
||||
if (octal_len > 0) {
|
||||
if (ch !== "0" && next_token.has_directive("use strict"))
|
||||
parse_error("Octal literals are not allowed in strict mode");
|
||||
ch = String.fromCharCode(parseInt(ch, 8));
|
||||
} else {
|
||||
ch = read_escaped_char(true);
|
||||
}
|
||||
}
|
||||
else if ("\r\n\u2028\u2029".indexOf(ch) >= 0) parse_error("Unterminated string constant");
|
||||
else if (ch == quote) break;
|
||||
@@ -640,6 +645,35 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return S;
|
||||
};
|
||||
|
||||
next_token.add_directive = function(directive) {
|
||||
S.directive_stack[S.directive_stack.length - 1].push(directive);
|
||||
|
||||
if (S.directives[directive] === undefined) {
|
||||
S.directives[directive] = 1;
|
||||
} else {
|
||||
S.directives[directive]++;
|
||||
}
|
||||
}
|
||||
|
||||
next_token.push_directives_stack = function() {
|
||||
S.directive_stack.push([]);
|
||||
}
|
||||
|
||||
next_token.pop_directives_stack = function() {
|
||||
var directives = S.directive_stack[S.directive_stack.length - 1];
|
||||
|
||||
for (var i = 0; i < directives.length; i++) {
|
||||
S.directives[directives[i]]--;
|
||||
}
|
||||
|
||||
S.directive_stack.pop();
|
||||
}
|
||||
|
||||
next_token.has_directive = function(directive) {
|
||||
return S.directives[directive] !== undefined &&
|
||||
S.directives[directive] > 0;
|
||||
}
|
||||
|
||||
return next_token;
|
||||
|
||||
};
|
||||
@@ -818,9 +852,15 @@ function parse($TEXT, options) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
if (S.in_directives) {
|
||||
if (is_token(peek(), "punc", ";") || peek().nlb) {
|
||||
S.input.add_directive(S.token.raw.substr(1, S.token.raw.length - 2));
|
||||
} else {
|
||||
S.in_directives = false;
|
||||
}
|
||||
}
|
||||
var dir = S.in_directives, stat = simple_statement();
|
||||
// XXXv2: decide how to fix directives
|
||||
if (dir && stat.body instanceof AST_String && !is("punc", ",")) {
|
||||
if (dir) {
|
||||
return new AST_Directive({
|
||||
start : stat.body.start,
|
||||
end : stat.body.end,
|
||||
@@ -1153,10 +1193,13 @@ function parse($TEXT, options) {
|
||||
S.in_directives = true;
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
if (block)
|
||||
if (block) {
|
||||
S.input.push_directives_stack();
|
||||
var a = block_();
|
||||
else
|
||||
S.input.pop_directives_stack();
|
||||
} else {
|
||||
var a = expression(false);
|
||||
}
|
||||
--S.in_function;
|
||||
S.in_loop = loop;
|
||||
S.labels = labels;
|
||||
@@ -2082,8 +2125,10 @@ function parse($TEXT, options) {
|
||||
return (function(){
|
||||
var start = S.token;
|
||||
var body = [];
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev();
|
||||
var toplevel = options.toplevel;
|
||||
if (toplevel) {
|
||||
|
||||
Reference in New Issue
Block a user