Merge branch 'master' into fix-harmony
This commit is contained in:
@@ -1102,8 +1102,6 @@ merge(Compressor.prototype, {
|
||||
case "<=" : return ev(left, c) <= ev(right, c);
|
||||
case ">" : return ev(left, c) > ev(right, c);
|
||||
case ">=" : return ev(left, c) >= ev(right, c);
|
||||
case "in" : return ev(left, c) in ev(right, c);
|
||||
case "instanceof" : return ev(left, c) instanceof ev(right, c);
|
||||
}
|
||||
throw def;
|
||||
});
|
||||
@@ -2580,9 +2578,11 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
self = best_of(self, negated);
|
||||
}
|
||||
switch (self.operator) {
|
||||
case "<": reverse(">"); break;
|
||||
case "<=": reverse(">="); break;
|
||||
if (compressor.option("unsafe_comps")) {
|
||||
switch (self.operator) {
|
||||
case "<": reverse(">"); break;
|
||||
case "<=": reverse(">="); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.operator == "+" && self.right instanceof AST_String
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPECT_DIRECTIVE = /^$|[;{][\s\n]*$/;
|
||||
|
||||
function OutputStream(options) {
|
||||
|
||||
options = defaults(options, {
|
||||
@@ -64,7 +66,8 @@ function OutputStream(options) {
|
||||
preserve_line : false,
|
||||
screw_ie8 : false,
|
||||
preamble : null,
|
||||
quote_style : 0
|
||||
quote_style : 0,
|
||||
keep_quoted_props: false
|
||||
}, true);
|
||||
|
||||
var indentation = 0;
|
||||
@@ -359,7 +362,18 @@ function OutputStream(options) {
|
||||
force_semicolon : force_semicolon,
|
||||
to_ascii : to_ascii,
|
||||
print_name : function(name) { print(make_name(name)) },
|
||||
print_string : function(str, quote) { print(encode_string(str, quote)) },
|
||||
print_string : function(str, quote, escape_directive) {
|
||||
var encoded = encode_string(str, quote);
|
||||
if (escape_directive === true && encoded.indexOf("\\") === -1) {
|
||||
// Insert semicolons to break directive prologue
|
||||
if (!EXPECT_DIRECTIVE.test(OUTPUT)) {
|
||||
force_semicolon();
|
||||
}
|
||||
force_semicolon();
|
||||
}
|
||||
print(encoded);
|
||||
},
|
||||
encode_string : encode_string,
|
||||
next_indent : next_indent,
|
||||
with_indent : with_indent,
|
||||
with_block : with_block,
|
||||
@@ -391,10 +405,11 @@ function OutputStream(options) {
|
||||
};
|
||||
|
||||
var use_asm = false;
|
||||
var in_directive = false;
|
||||
|
||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||
var self = this, generator = self._codegen, prev_use_asm = use_asm;
|
||||
if (self instanceof AST_Directive && self.value == "use asm") {
|
||||
if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) {
|
||||
use_asm = true;
|
||||
}
|
||||
function doit() {
|
||||
@@ -409,7 +424,7 @@ function OutputStream(options) {
|
||||
doit();
|
||||
}
|
||||
stream.pop_node();
|
||||
if (self instanceof AST_Lambda) {
|
||||
if (self instanceof AST_Scope) {
|
||||
use_asm = prev_use_asm;
|
||||
}
|
||||
});
|
||||
@@ -683,9 +698,16 @@ function OutputStream(options) {
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
function display_body(body, is_toplevel, output) {
|
||||
function display_body(body, is_toplevel, output, allow_directives) {
|
||||
var last = body.length - 1;
|
||||
in_directive = allow_directives;
|
||||
body.forEach(function(stmt, i){
|
||||
if (in_directive === true && !(stmt instanceof AST_Directive ||
|
||||
stmt instanceof AST_EmptyStatement ||
|
||||
(stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String)
|
||||
)) {
|
||||
in_directive = false;
|
||||
}
|
||||
if (!(stmt instanceof AST_EmptyStatement)) {
|
||||
output.indent();
|
||||
stmt.print(output);
|
||||
@@ -694,7 +716,14 @@ function OutputStream(options) {
|
||||
if (is_toplevel) output.newline();
|
||||
}
|
||||
}
|
||||
if (in_directive === true &&
|
||||
stmt instanceof AST_SimpleStatement &&
|
||||
stmt.body instanceof AST_String
|
||||
) {
|
||||
in_directive = false;
|
||||
}
|
||||
});
|
||||
in_directive = false;
|
||||
};
|
||||
|
||||
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
|
||||
@@ -706,7 +735,7 @@ function OutputStream(options) {
|
||||
output.semicolon();
|
||||
});
|
||||
DEFPRINT(AST_Toplevel, function(self, output){
|
||||
display_body(self.body, true, output);
|
||||
display_body(self.body, true, output, true);
|
||||
output.print("");
|
||||
});
|
||||
DEFPRINT(AST_LabeledStatement, function(self, output){
|
||||
@@ -718,9 +747,9 @@ function OutputStream(options) {
|
||||
self.body.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
function print_bracketed(body, output) {
|
||||
function print_bracketed(body, output, allow_directives) {
|
||||
if (body.length > 0) output.with_block(function(){
|
||||
display_body(body, false, output);
|
||||
display_body(body, false, output, allow_directives);
|
||||
});
|
||||
else output.print("{}");
|
||||
};
|
||||
@@ -829,7 +858,7 @@ function OutputStream(options) {
|
||||
});
|
||||
});
|
||||
output.space();
|
||||
print_bracketed(self.body, output);
|
||||
print_bracketed(self.body, output, true);
|
||||
});
|
||||
DEFPRINT(AST_Lambda, function(self, output){
|
||||
self._do_print(output);
|
||||
@@ -1363,7 +1392,11 @@ function OutputStream(options) {
|
||||
&& parseFloat(key) >= 0) {
|
||||
output.print(make_num(key));
|
||||
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
|
||||
output.print_name(key);
|
||||
if (quote && output.option("keep_quoted_props")) {
|
||||
output.print_string(key, quote);
|
||||
} else {
|
||||
output.print_name(key);
|
||||
}
|
||||
} else {
|
||||
output.print_string(key, quote);
|
||||
}
|
||||
@@ -1433,10 +1466,10 @@ function OutputStream(options) {
|
||||
output.print(self.getValue());
|
||||
});
|
||||
DEFPRINT(AST_String, function(self, output){
|
||||
output.print_string(self.getValue(), self.quote);
|
||||
output.print_string(self.getValue(), self.quote, in_directive);
|
||||
});
|
||||
DEFPRINT(AST_Number, function(self, output){
|
||||
if (use_asm && self.start.raw != null) {
|
||||
if (use_asm && self.start && self.start.raw != null) {
|
||||
output.print(self.start.raw);
|
||||
} else {
|
||||
output.print(make_num(self.getValue()));
|
||||
@@ -1535,7 +1568,9 @@ function OutputStream(options) {
|
||||
// self should be AST_New. decide if we want to show parens or not.
|
||||
function need_constructor_parens(self, output) {
|
||||
// Always print parentheses with arguments
|
||||
return self.args.length > 0;
|
||||
if (self.args.length > 0) return true;
|
||||
|
||||
return output.option("beautify");
|
||||
};
|
||||
|
||||
function best_of(a) {
|
||||
|
||||
37
lib/parse.js
37
lib/parse.js
@@ -852,9 +852,10 @@ 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));
|
||||
var dir = false;
|
||||
if (S.in_directives === true) {
|
||||
if ((is_token(peek(), "punc", ";") || peek().nlb) && S.token.raw.indexOf("\\") === -1) {
|
||||
S.input.add_directive(S.token.value);
|
||||
} else {
|
||||
S.in_directives = false;
|
||||
}
|
||||
@@ -893,6 +894,7 @@ function parse($TEXT, options) {
|
||||
case "`":
|
||||
return simple_statement();
|
||||
case ";":
|
||||
S.in_directives = false;
|
||||
next();
|
||||
return new AST_EmptyStatement();
|
||||
default:
|
||||
@@ -937,7 +939,7 @@ function parse($TEXT, options) {
|
||||
|
||||
case "return":
|
||||
if (S.in_function == 0 && !options.bare_returns)
|
||||
croak("'return' outside of function");
|
||||
croak("SyntaxError: 'return' outside of function");
|
||||
return new AST_Return({
|
||||
value: ( is("punc", ";")
|
||||
? (next(), null)
|
||||
@@ -954,7 +956,7 @@ function parse($TEXT, options) {
|
||||
|
||||
case "throw":
|
||||
if (S.token.nlb)
|
||||
croak("Illegal newline after 'throw'");
|
||||
croak("SyntaxError: Illegal newline after 'throw'");
|
||||
return new AST_Throw({
|
||||
value: (tmp = expression(true), semicolon(), tmp)
|
||||
});
|
||||
@@ -972,6 +974,9 @@ function parse($TEXT, options) {
|
||||
return tmp = const_(), semicolon(), tmp;
|
||||
|
||||
case "with":
|
||||
if (S.input.has_directive("use strict")) {
|
||||
croak("SyntaxError: Strict mode may not include a with statement");
|
||||
}
|
||||
return new AST_With({
|
||||
expression : parenthesised(),
|
||||
body : statement()
|
||||
@@ -1000,7 +1005,7 @@ function parse($TEXT, options) {
|
||||
// syntactically incorrect if it contains a
|
||||
// LabelledStatement that is enclosed by a
|
||||
// LabelledStatement with the same Identifier as label.
|
||||
croak("Label " + label.name + " defined twice");
|
||||
croak("SyntaxError: Label " + label.name + " defined twice");
|
||||
}
|
||||
expect(":");
|
||||
S.labels.push(label);
|
||||
@@ -1013,7 +1018,7 @@ function parse($TEXT, options) {
|
||||
label.references.forEach(function(ref){
|
||||
if (ref instanceof AST_Continue) {
|
||||
ref = ref.label.start;
|
||||
croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
|
||||
croak("SyntaxError: Continue label `" + label.name + "` refers to non-IterationStatement.",
|
||||
ref.line, ref.col, ref.pos);
|
||||
}
|
||||
});
|
||||
@@ -1033,11 +1038,11 @@ function parse($TEXT, options) {
|
||||
if (label != null) {
|
||||
ldef = find_if(function(l){ return l.name == label.name }, S.labels);
|
||||
if (!ldef)
|
||||
croak("Undefined label " + label.name);
|
||||
croak("SyntaxError: Undefined label " + label.name);
|
||||
label.thedef = ldef;
|
||||
}
|
||||
else if (S.in_loop == 0)
|
||||
croak(type.TYPE + " not inside a loop or switch");
|
||||
croak("SyntaxError: " + type.TYPE + " not inside a loop or switch");
|
||||
semicolon();
|
||||
var stat = new type({ label: label });
|
||||
if (ldef) ldef.references.push(stat);
|
||||
@@ -1058,7 +1063,7 @@ function parse($TEXT, options) {
|
||||
if (is_in || is_of) {
|
||||
if ((init instanceof AST_Definitions) &&
|
||||
init.definitions.length > 1)
|
||||
croak("Only one variable declaration allowed in for..in loop");
|
||||
croak("SyntaxError: Only one variable declaration allowed in for..in loop");
|
||||
next();
|
||||
if (is_in) {
|
||||
return for_in(init);
|
||||
@@ -1330,7 +1335,7 @@ function parse($TEXT, options) {
|
||||
});
|
||||
}
|
||||
if (!bcatch && !bfinally)
|
||||
croak("Missing catch/finally blocks");
|
||||
croak("SyntaxError: Missing catch/finally blocks");
|
||||
return new AST_Try({
|
||||
body : body,
|
||||
bcatch : bcatch,
|
||||
@@ -1497,8 +1502,8 @@ function parse($TEXT, options) {
|
||||
break;
|
||||
case "operator":
|
||||
if (!is_identifier_string(tok.value)) {
|
||||
throw new JS_Parse_Error("Invalid getter/setter name: " + tok.value,
|
||||
tok.file, tok.line, tok.col, tok.pos);
|
||||
croak("SyntaxError: Invalid getter/setter name: " + tok.value,
|
||||
tok.line, tok.col, tok.pos);
|
||||
}
|
||||
ret = _make_symbol(AST_SymbolRef);
|
||||
break;
|
||||
@@ -1917,7 +1922,7 @@ function parse($TEXT, options) {
|
||||
|
||||
function as_symbol(type, noerror) {
|
||||
if (!is("name")) {
|
||||
if (!noerror) croak("Name expected");
|
||||
if (!noerror) croak("SyntaxError: Name expected");
|
||||
return null;
|
||||
}
|
||||
if (is("name", "yield") && S.input.has_directive("use strict")) {
|
||||
@@ -2003,7 +2008,7 @@ function parse($TEXT, options) {
|
||||
|
||||
function make_unary(ctor, op, expr) {
|
||||
if ((op == "++" || op == "--") && !is_assignable(expr))
|
||||
croak("Invalid use of " + op + " operator");
|
||||
croak("SyntaxError: Invalid use of " + op + " operator");
|
||||
return new ctor({ operator: op, expression: expr });
|
||||
};
|
||||
|
||||
@@ -2087,7 +2092,7 @@ function parse($TEXT, options) {
|
||||
end : prev()
|
||||
});
|
||||
}
|
||||
croak("Invalid assignment");
|
||||
croak("SyntaxError: Invalid assignment");
|
||||
}
|
||||
if (is("arrow")) {
|
||||
left = new AST_SymbolFunarg({
|
||||
|
||||
@@ -71,7 +71,8 @@ function mangle_properties(ast, options) {
|
||||
reserved : null,
|
||||
cache : null,
|
||||
only_cache : false,
|
||||
regex : null
|
||||
regex : null,
|
||||
ignore_quoted : false
|
||||
});
|
||||
|
||||
var reserved = options.reserved;
|
||||
@@ -87,6 +88,7 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
|
||||
var regex = options.regex;
|
||||
var ignore_quoted = options.ignore_quoted;
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
@@ -94,7 +96,8 @@ function mangle_properties(ast, options) {
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
add(node.key);
|
||||
if (!(ignore_quoted && node.quote))
|
||||
add(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
@@ -107,7 +110,8 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
if (this.parent() instanceof AST_Assign) {
|
||||
addStrings(node.property);
|
||||
if (!ignore_quoted)
|
||||
addStrings(node.property);
|
||||
}
|
||||
}
|
||||
else if (node instanceof AST_ConciseMethod) {
|
||||
@@ -118,7 +122,8 @@ function mangle_properties(ast, options) {
|
||||
// step 2: transform the tree, renaming properties
|
||||
return ast.transform(new TreeTransformer(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
node.key = mangle(node.key);
|
||||
if (!(ignore_quoted && node.quote))
|
||||
node.key = mangle(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter
|
||||
@@ -128,7 +133,8 @@ function mangle_properties(ast, options) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
node.property = mangleStrings(node.property);
|
||||
if (!ignore_quoted)
|
||||
node.property = mangleStrings(node.property);
|
||||
}
|
||||
else if (node instanceof AST_ConciseMethod) {
|
||||
if (should_mangle(node.name.name)) {
|
||||
|
||||
Reference in New Issue
Block a user