Compare commits

...

31 Commits

Author SHA1 Message Date
Alex Lam S.L
fdee083465 v3.4.3 2018-07-02 06:03:18 +00:00
alexlamsl
5ffc17d4aa fix corner case in unused 2018-07-01 14:34:42 +08:00
alexlamsl
6aa750010f update dependencies
- acorn@5.7.1
- commander@2.16.0
2018-07-01 01:49:43 +08:00
Alex Lam S.L
76df77c08c implement directives (#3203)
fixes #3166
2018-06-28 18:16:49 +08:00
Alex Lam S.L
957d5537a8 improve unsafe comparisons (#3200) 2018-06-28 03:46:19 +08:00
Alex Lam S.L
88c8f4e363 v3.4.2 2018-06-26 01:29:48 +08:00
Alex Lam S.L
ab36b9b10a fix corner case in ie8 (#3198)
fixes #3197
2018-06-24 04:00:36 +08:00
Alex Lam S.L
28330913d8 improve mocha tests (#3195) 2018-06-24 04:00:36 +08:00
Alex Lam S.L
766a4147d4 enhance arguments (#3193)
fixes #3192
2018-06-24 04:00:21 +08:00
Alex Lam S.L
915c7e234d v3.4.1 2018-06-19 18:35:48 +00:00
Alex Lam S.L
e54ddcbb8a fix corner cases in properties (#3189)
fixes #3188
2018-06-19 18:20:11 +08:00
Alex Lam S.L
9e19e63551 general clean-ups (#3175) 2018-06-06 17:50:56 +08:00
Alex Lam S.L
bce7ee5f6a v3.4.0 2018-06-02 05:57:10 +00:00
Jiavan
b39043f3ab re-introduce enclose (#3163)
fixes #2443
2018-06-01 16:47:11 +08:00
Alex Lam S.L
caf96acb08 handle asynchronous test failures (#3164) 2018-05-31 20:21:39 +08:00
Alex Lam S.L
c76749084b update JetStream URL (#3165) 2018-05-31 16:23:49 +08:00
Alex Lam S.L
5843494ee2 v3.3.28 2018-05-29 12:25:42 +00:00
Alex Lam S.L
efa21ae3e6 fix corner case in reduce_vars (#3151) 2018-05-26 05:45:44 +08:00
Alex Lam S.L
24d9633a35 fix corner cases with eval() (#3147)
fixes #3146
2018-05-24 14:29:30 +08:00
Alex Lam S.L
7963b96681 augment tests for inline source maps (#3145) 2018-05-24 02:37:51 +08:00
Alex Lam S.L
8c62d854ce augment tests for RegExp (#3144) 2018-05-23 17:24:13 +08:00
Alex Lam S.L
69931574e1 v3.3.27 2018-05-22 17:09:12 +00:00
Alex Lam S.L
b5af8a1914 fix corner case in reduce_vars (#3141)
fixes #3140
2018-05-21 15:53:51 +08:00
Alex Lam S.L
c14d09ba84 v3.3.26 2018-05-20 17:32:32 +00:00
Alex Lam S.L
4fc39d8dad fix corner case in collapse_vars (#3139) 2018-05-19 05:45:14 +08:00
exvisory
0b7c70f726 Update README.md to clarify --source-map filename option (#3137)
Clarify that the --source-map filename option does NOT change the source map output filename but does set the 'file' attribute within the output source map. This was already documented in the API section of the README so I just copied that to the CLI options section, and a fragment to the CLI summary.
2018-05-18 15:50:36 +08:00
Alex Lam S.L
f72d3029dd v3.3.25 2018-05-12 23:50:40 +00:00
Alex Lam S.L
1a0d6edc81 remove colors dependency (#3133) 2018-05-13 07:50:02 +08:00
Alex Lam S.L
7b59b2f5b2 replace mocha dependency (#3131) 2018-05-11 20:15:34 +08:00
Alex Lam S.L
7bc7704edf fix corner case in reduce_vars (#3129) 2018-05-10 18:45:20 +08:00
Alex Lam S.L
14e712ee80 fix corner case in call binding (#3128)
fixes #3127
2018-05-10 06:16:35 +08:00
108 changed files with 4660 additions and 2913 deletions

View File

@@ -104,6 +104,8 @@ a double dash to prevent input files being used as option arguments:
sequences.
--config-file <file> Read `minify()` options from JSON file.
-d, --define <expr>[=value] Global definitions.
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
argument(s) & value(s).
--ie8 Support non-standard Internet Explorer 8.
Equivalent to setting `ie8: true` in `minify()`
for `compress`, `mangle` and `output` options.
@@ -118,7 +120,8 @@ a double dash to prevent input files being used as option arguments:
JS that was generated from some other original
code. Specify "inline" if the source map is
included within the sources.
`filename` Name and/or location of the output source.
`filename` Filename and/or location of the output source
(sets `file` attribute in source map).
`includeSources` Pass this flag if you want to include
the content of source files in the
source map as sourcesContent property.
@@ -149,7 +152,9 @@ debugging your compressed JavaScript. To get a source map, pass
Additional options:
- `--source-map "filename='<NAME>'"` to specify the name of the source map.
- `--source-map "filename='<NAME>'"` to specify the name of the source map. The value of
`filename` is only used to set `file` attribute (see [the spec][sm-spec])
in source map file.
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
@@ -615,6 +620,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
- `dead_code` (default: `true`) -- remove unreachable code
- `directives` (default: `true`) -- remove redundant or non-standard directives
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
`console.*` functions. If you wish to drop a specific function call
such as `console.info` and/or retain side effects from function arguments

View File

@@ -40,6 +40,7 @@ program.option("-o, --output <file>", "Output file (default STDOUT).");
program.option("--comments [filter]", "Preserve copyright comments in the output.");
program.option("--config-file <file>", "Read minify() options from JSON file.");
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed everything in a big function, with configurable argument(s) & value(s).");
program.option("--ie8", "Support non-standard Internet Explorer 8.");
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
program.option("--name-cache <file>", "File to hold mangled name mappings.");
@@ -47,7 +48,7 @@ program.option("--rename", "Force symbol expansion.");
program.option("--no-rename", "Disable symbol expansion.");
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
program.option("--timings", "Display operations run time on STDERR.")
program.option("--timings", "Display operations run time on STDERR.");
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
program.option("--verbose", "Print diagnostic messages.");
program.option("--warn", "Print warning messages.");
@@ -61,6 +62,7 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
}
[
"compress",
"enclose",
"ie8",
"mangle",
"sourceMap",

View File

@@ -44,21 +44,21 @@
"use strict";
function DEFNODE(type, props, methods, base) {
if (arguments.length < 4) base = AST_Node;
if (!props) props = [];
else props = props.split(/\s+/);
if (typeof base === "undefined") base = AST_Node;
props = props ? props.split(/\s+/) : [];
var self_props = props;
if (base && base.PROPS)
props = props.concat(base.PROPS);
var code = "return function AST_" + type + "(props){ if (props) { ";
for (var i = props.length; --i >= 0;) {
code += "this." + props[i] + " = props." + props[i] + ";";
}
if (base && base.PROPS) props = props.concat(base.PROPS);
var code = [
"return function AST_", type, "(props){",
"if(props){",
];
props.forEach(function(prop) {
code.push("this.", prop, "=props.", prop, ";");
});
var proto = base && new base;
if (proto && proto.initialize || (methods && methods.initialize))
code += "this.initialize();";
code += "}}";
var ctor = new Function(code)();
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
code.push("}}");
var ctor = new Function(code.join(""))();
if (proto) {
ctor.prototype = proto;
ctor.BASE = base;
@@ -71,11 +71,11 @@ function DEFNODE(type, props, methods, base) {
if (type) {
ctor.prototype.TYPE = ctor.TYPE = type;
}
if (methods) for (i in methods) if (HOP(methods, i)) {
if (/^\$/.test(i)) {
ctor[i.substr(1)] = methods[i];
if (methods) for (var name in methods) if (HOP(methods, name)) {
if (/^\$/.test(name)) {
ctor[name.substr(1)] = methods[name];
} else {
ctor.prototype[i] = methods[i];
ctor.prototype[name] = methods[name];
}
}
ctor.DEFMETHOD = function(name, method) {
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) {
exports["AST_" + type] = ctor;
}
return ctor;
};
}
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
}, null);
@@ -148,7 +148,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.body._walk(visitor);
});
}
@@ -158,11 +158,10 @@ function walk_body(node, visitor) {
var body = node.body;
if (body instanceof AST_Statement) {
body._walk(visitor);
}
else for (var i = 0, len = body.length; i < len; i++) {
body[i]._walk(visitor);
}
};
} else body.forEach(function(node) {
node._walk(visitor);
});
}
var AST_Block = DEFNODE("Block", "body", {
$documentation: "A body of statements (usually braced)",
@@ -170,7 +169,7 @@ var AST_Block = DEFNODE("Block", "body", {
body: "[AST_Statement*] an array of statements"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
walk_body(this, visitor);
});
}
@@ -197,7 +196,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
label: "[AST_Label] a label definition"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.label._walk(visitor);
this.body._walk(visitor);
});
@@ -233,7 +232,7 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
var AST_Do = DEFNODE("Do", null, {
$documentation: "A `do` statement",
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.body._walk(visitor);
this.condition._walk(visitor);
});
@@ -243,7 +242,7 @@ var AST_Do = DEFNODE("Do", null, {
var AST_While = DEFNODE("While", null, {
$documentation: "A `while` statement",
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.condition._walk(visitor);
this.body._walk(visitor);
});
@@ -258,7 +257,7 @@ var AST_For = DEFNODE("For", "init condition step", {
step: "[AST_Node?] the `for` update clause, or null if empty"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
if (this.init) this.init._walk(visitor);
if (this.condition) this.condition._walk(visitor);
if (this.step) this.step._walk(visitor);
@@ -274,7 +273,7 @@ var AST_ForIn = DEFNODE("ForIn", "init object", {
object: "[AST_Node] the object that we're looping through"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.init._walk(visitor);
this.object._walk(visitor);
this.body._walk(visitor);
@@ -288,7 +287,7 @@ var AST_With = DEFNODE("With", "expression", {
expression: "[AST_Node] the `with` expression"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expression._walk(visitor);
this.body._walk(visitor);
});
@@ -314,6 +313,9 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
if (this.functions) node.functions = this.functions.clone();
if (this.enclosed) node.enclosed = this.enclosed.slice();
return node;
},
pinned: function() {
return this.uses_eval || this.uses_with;
}
}, AST_Block);
@@ -326,12 +328,29 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
var body = this.body;
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
wrapped_tl = parse(wrapped_tl);
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) {
if (node instanceof AST_Directive && node.value == "$ORIG") {
return MAP.splice(body);
}
}));
return wrapped_tl;
},
wrap_enclose: function(args_values) {
if (typeof args_values != "string") args_values = "";
var index = args_values.indexOf(":");
if (index < 0) index = args_values.length;
var body = this.body;
return parse([
"(function(",
args_values.slice(0, index),
'){"$ORIG"})(',
args_values.slice(index + 1),
")"
].join("")).transform(new TreeTransformer(function(node) {
if (node instanceof AST_Directive && node.value == "$ORIG") {
return MAP.splice(body);
}
}));
}
}, AST_Scope);
@@ -343,12 +362,11 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
if (this.name) this.name._walk(visitor);
var argnames = this.argnames;
for (var i = 0, len = argnames.length; i < len; i++) {
argnames[i]._walk(visitor);
}
this.argnames.forEach(function(argname) {
argname._walk(visitor);
});
walk_body(this, visitor);
});
}
@@ -378,7 +396,7 @@ var AST_Exit = DEFNODE("Exit", "value", {
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
},
_walk: function(visitor) {
return visitor._visit(this, this.value && function(){
return visitor._visit(this, this.value && function() {
this.value._walk(visitor);
});
}
@@ -398,7 +416,7 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
label: "[AST_LabelRef?] the label, or null if none",
},
_walk: function(visitor) {
return visitor._visit(this, this.label && function(){
return visitor._visit(this, this.label && function() {
this.label._walk(visitor);
});
}
@@ -421,7 +439,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
alternative: "[AST_Statement?] the `else` part, or null if not present"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.condition._walk(visitor);
this.body._walk(visitor);
if (this.alternative) this.alternative._walk(visitor);
@@ -437,7 +455,7 @@ var AST_Switch = DEFNODE("Switch", "expression", {
expression: "[AST_Node] the `switch` “discriminant”"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expression._walk(visitor);
walk_body(this, visitor);
});
@@ -458,7 +476,7 @@ var AST_Case = DEFNODE("Case", "expression", {
expression: "[AST_Node] the `case` expression"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expression._walk(visitor);
walk_body(this, visitor);
});
@@ -474,7 +492,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
bfinally: "[AST_Finally?] the finally block, or null if not present"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
walk_body(this, visitor);
if (this.bcatch) this.bcatch._walk(visitor);
if (this.bfinally) this.bfinally._walk(visitor);
@@ -488,7 +506,7 @@ var AST_Catch = DEFNODE("Catch", "argname", {
argname: "[AST_SymbolCatch] symbol for the exception"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.argname._walk(visitor);
walk_body(this, visitor);
});
@@ -507,11 +525,10 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
definitions: "[AST_VarDef*] array of variable definitions"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
var definitions = this.definitions;
for (var i = 0, len = definitions.length; i < len; i++) {
definitions[i]._walk(visitor);
}
return visitor._visit(this, function() {
this.definitions.forEach(function(defn) {
defn._walk(visitor);
});
});
}
}, AST_Statement);
@@ -527,7 +544,7 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
value: "[AST_Node?] initializer, or null of there's no initializer"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.name._walk(visitor);
if (this.value) this.value._walk(visitor);
});
@@ -562,7 +579,7 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
expressions: "[AST_Node*] array of expressions (at least two)"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expressions.forEach(function(node) {
node._walk(visitor);
});
@@ -581,7 +598,7 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
var AST_Dot = DEFNODE("Dot", null, {
$documentation: "A dotted property access expression",
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expression._walk(visitor);
});
}
@@ -590,7 +607,7 @@ var AST_Dot = DEFNODE("Dot", null, {
var AST_Sub = DEFNODE("Sub", null, {
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expression._walk(visitor);
this.property._walk(visitor);
});
@@ -604,7 +621,7 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
expression: "[AST_Node] expression that this unary operator applies to"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.expression._walk(visitor);
});
}
@@ -626,7 +643,7 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
right: "[AST_Node] right-hand side expression"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.left._walk(visitor);
this.right._walk(visitor);
});
@@ -641,7 +658,7 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
alternative: "[AST_Node]"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.condition._walk(visitor);
this.consequent._walk(visitor);
this.alternative._walk(visitor);
@@ -661,11 +678,10 @@ var AST_Array = DEFNODE("Array", "elements", {
elements: "[AST_Node*] array of elements"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
var elements = this.elements;
for (var i = 0, len = elements.length; i < len; i++) {
elements[i]._walk(visitor);
}
return visitor._visit(this, function() {
this.elements.forEach(function(element) {
element._walk(visitor);
});
});
}
});
@@ -676,11 +692,10 @@ var AST_Object = DEFNODE("Object", "properties", {
properties: "[AST_ObjectProperty*] array of properties"
},
_walk: function(visitor) {
return visitor._visit(this, function(){
var properties = this.properties;
for (var i = 0, len = properties.length; i < len; i++) {
properties[i]._walk(visitor);
}
return visitor._visit(this, function() {
this.properties.forEach(function(prop) {
prop._walk(visitor);
});
});
}
});
@@ -692,7 +707,7 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
},
_walk: function(visitor) {
return visitor._visit(this, function(){
return visitor._visit(this, function() {
this.value._walk(visitor);
});
}
@@ -819,12 +834,12 @@ var AST_NaN = DEFNODE("NaN", null, {
var AST_Undefined = DEFNODE("Undefined", null, {
$documentation: "The `undefined` value",
value: (function(){}())
value: function(){}()
}, AST_Atom);
var AST_Hole = DEFNODE("Hole", null, {
$documentation: "A hole in an array",
value: (function(){}())
value: function(){}()
}, AST_Atom);
var AST_Infinity = DEFNODE("Infinity", null, {
@@ -852,11 +867,11 @@ function TreeWalker(callback) {
this.visit = callback;
this.stack = [];
this.directives = Object.create(null);
};
}
TreeWalker.prototype = {
_visit: function(node, descend) {
this.push(node);
var ret = this.visit(node, descend ? function(){
var ret = this.visit(node, descend ? function() {
descend.call(node);
} : noop);
if (!ret && descend) {

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,7 @@ function minify(files, options) {
try {
options = defaults(options, {
compress: {},
enclose: false,
ie8: false,
keep_fnames: false,
mangle: {},
@@ -157,6 +158,9 @@ function minify(files, options) {
if (options.wrap) {
toplevel = toplevel.wrap_commonjs(options.wrap);
}
if (options.enclose) {
toplevel = toplevel.wrap_enclose(options.enclose);
}
if (timings) timings.rename = Date.now();
if (options.rename) {
toplevel.figure_out_scope(options.mangle);

View File

@@ -43,11 +43,9 @@
"use strict";
(function(){
var normalize_directives = function(body) {
(function() {
function normalize_directives(body) {
var in_directive = true;
for (var i = 0; i < body.length; i++) {
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
body[i] = new AST_Directive({
@@ -59,9 +57,8 @@
in_directive = false;
}
}
return body;
};
}
var MOZ_TO_ME = {
Program: function(M) {
@@ -129,7 +126,7 @@
return new AST_Array({
start : my_start_token(M),
end : my_end_token(M),
elements : M.elements.map(function(elem){
elements : M.elements.map(function(elem) {
return elem === null ? new AST_Hole() : from_moz(elem);
})
});
@@ -138,7 +135,7 @@
return new AST_Object({
start : my_start_token(M),
end : my_end_token(M),
properties : M.properties.map(function(prop){
properties : M.properties.map(function(prop) {
prop.type = "Property";
return from_moz(prop)
})
@@ -480,7 +477,7 @@
endpos : range ? range[0] : moznode.start,
raw : raw_token(moznode),
});
};
}
function my_end_token(moznode) {
var loc = moznode.loc, end = loc && loc.end;
@@ -495,7 +492,7 @@
endpos : range ? range[1] : moznode.end,
raw : raw_token(moznode),
});
};
}
function map(moztype, mytype, propmap) {
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
@@ -507,7 +504,7 @@
me_to_moz += "return {\n" +
"type: " + JSON.stringify(moztype);
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
if (!m) throw new Error("Can't understand property map: " + prop);
var moz = m[1], how = m[2], my = m[3];
@@ -550,7 +547,7 @@
);
MOZ_TO_ME[moztype] = moz_to_me;
def_to_moz(mytype, me_to_moz);
};
}
var FROM_MOZ_STACK = null;
@@ -559,9 +556,9 @@
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
FROM_MOZ_STACK.pop();
return ret;
};
}
AST_Node.from_mozilla_ast = function(node){
AST_Node.from_mozilla_ast = function(node) {
var save_stack = FROM_MOZ_STACK;
FROM_MOZ_STACK = [];
var ast = from_moz(node);
@@ -600,24 +597,24 @@
}
}
return moznode;
};
}
function def_to_moz(mytype, handler) {
mytype.DEFMETHOD("to_mozilla_ast", function() {
return set_moz_loc(this, handler(this));
});
};
}
function to_moz(node) {
return node != null ? node.to_mozilla_ast() : null;
};
}
function to_moz_block(node) {
return {
type: "BlockStatement",
body: node.body.map(to_moz)
};
};
}
function to_moz_scope(type, node) {
var body = node.body.map(to_moz);
@@ -628,5 +625,5 @@
type: type,
body: body
};
};
}
})();

View File

@@ -137,7 +137,7 @@ 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, i){
function(s, i) {
switch (s) {
case '"': ++dq; return '"';
case "'": ++sq; return "'";
@@ -408,7 +408,7 @@ function OutputStream(options) {
var ret;
print("{");
newline();
with_indent(next_indent(), function(){
with_indent(next_indent(), function() {
ret = cont();
});
indent();
@@ -631,7 +631,7 @@ function OutputStream(options) {
/* -----[ code generators ]----- */
(function(){
(function() {
/* -----[ utils ]----- */
@@ -643,7 +643,7 @@ function OutputStream(options) {
var active_scope = null;
var use_asm = null;
AST_Node.DEFMETHOD("print", function(stream, force_parens){
AST_Node.DEFMETHOD("print", function(stream, force_parens) {
var self = this, generator = self._codegen;
if (self instanceof AST_Scope) {
active_scope = self;
@@ -670,7 +670,7 @@ function OutputStream(options) {
});
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
AST_Node.DEFMETHOD("print_to_string", function(options){
AST_Node.DEFMETHOD("print_to_string", function(options) {
var s = OutputStream(options);
this.print(s);
return s.get();
@@ -680,7 +680,7 @@ function OutputStream(options) {
function PARENS(nodetype, func) {
if (Array.isArray(nodetype)) {
nodetype.forEach(function(nodetype){
nodetype.forEach(function(nodetype) {
PARENS(nodetype, func);
});
} else {
@@ -692,7 +692,7 @@ function OutputStream(options) {
// a function expression needs parens around it when it's provably
// the first token to appear in a statement.
PARENS(AST_Function, function(output){
PARENS(AST_Function, function(output) {
if (!output.has_parens() && first_in_statement(output)) {
return true;
}
@@ -714,17 +714,17 @@ function OutputStream(options) {
// same goes for an object literal, because otherwise it would be
// interpreted as a block of code.
PARENS(AST_Object, function(output){
PARENS(AST_Object, function(output) {
return !output.has_parens() && first_in_statement(output);
});
PARENS(AST_Unary, function(output){
PARENS(AST_Unary, function(output) {
var p = output.parent();
return p instanceof AST_PropAccess && p.expression === this
|| p instanceof AST_Call && p.expression === this;
});
PARENS(AST_Sequence, function(output){
PARENS(AST_Sequence, function(output) {
var p = output.parent();
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|| p instanceof AST_Unary // !(foo, bar, baz)
@@ -738,7 +738,7 @@ function OutputStream(options) {
;
});
PARENS(AST_Binary, function(output){
PARENS(AST_Binary, function(output) {
var p = output.parent();
// (foo && bar)()
if (p instanceof AST_Call && p.expression === this)
@@ -761,7 +761,7 @@ function OutputStream(options) {
}
});
PARENS(AST_PropAccess, function(output){
PARENS(AST_PropAccess, function(output) {
var p = output.parent();
if (p instanceof AST_New && p.expression === this) {
// i.e. new (foo.bar().baz)
@@ -782,7 +782,7 @@ function OutputStream(options) {
}
});
PARENS(AST_Call, function(output){
PARENS(AST_Call, function(output) {
var p = output.parent(), p1;
if (p instanceof AST_New && p.expression === this)
return true;
@@ -796,7 +796,7 @@ function OutputStream(options) {
&& p1.left === p;
});
PARENS(AST_New, function(output){
PARENS(AST_New, function(output) {
var p = output.parent();
if (!need_constructor_parens(this, output)
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
@@ -804,7 +804,7 @@ function OutputStream(options) {
return true;
});
PARENS(AST_Number, function(output){
PARENS(AST_Number, function(output) {
var p = output.parent();
if (p instanceof AST_PropAccess && p.expression === this) {
var value = this.getValue();
@@ -814,7 +814,7 @@ function OutputStream(options) {
}
});
PARENS([ AST_Assign, AST_Conditional ], function(output){
PARENS([ AST_Assign, AST_Conditional ], function(output) {
var p = output.parent();
// !(a = false) → true
if (p instanceof AST_Unary)
@@ -835,11 +835,11 @@ function OutputStream(options) {
/* -----[ PRINTERS ]----- */
DEFPRINT(AST_Directive, function(self, output){
DEFPRINT(AST_Directive, function(self, output) {
output.print_string(self.value, self.quote);
output.semicolon();
});
DEFPRINT(AST_Debugger, function(self, output){
DEFPRINT(AST_Debugger, function(self, output) {
output.print("debugger");
output.semicolon();
});
@@ -849,7 +849,7 @@ function OutputStream(options) {
function display_body(body, is_toplevel, output, allow_directives) {
var last = body.length - 1;
in_directive = allow_directives;
body.forEach(function(stmt, i){
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)
@@ -874,24 +874,24 @@ function OutputStream(options) {
in_directive = false;
}
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) {
force_statement(this.body, output);
});
DEFPRINT(AST_Statement, function(self, output){
DEFPRINT(AST_Statement, function(self, output) {
self.body.print(output);
output.semicolon();
});
DEFPRINT(AST_Toplevel, function(self, output){
DEFPRINT(AST_Toplevel, function(self, output) {
display_body(self.body, true, output, true);
output.print("");
});
DEFPRINT(AST_LabeledStatement, function(self, output){
DEFPRINT(AST_LabeledStatement, function(self, output) {
self.label.print(output);
output.colon();
self.body.print(output);
});
DEFPRINT(AST_SimpleStatement, function(self, output){
DEFPRINT(AST_SimpleStatement, function(self, output) {
self.body.print(output);
output.semicolon();
});
@@ -909,37 +909,37 @@ function OutputStream(options) {
});
} else print_braced_empty(self, output);
}
DEFPRINT(AST_BlockStatement, function(self, output){
DEFPRINT(AST_BlockStatement, function(self, output) {
print_braced(self, output);
});
DEFPRINT(AST_EmptyStatement, function(self, output){
DEFPRINT(AST_EmptyStatement, function(self, output) {
output.semicolon();
});
DEFPRINT(AST_Do, function(self, output){
DEFPRINT(AST_Do, function(self, output) {
output.print("do");
output.space();
make_block(self.body, output);
output.space();
output.print("while");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.condition.print(output);
});
output.semicolon();
});
DEFPRINT(AST_While, function(self, output){
DEFPRINT(AST_While, function(self, output) {
output.print("while");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.condition.print(output);
});
output.space();
self._do_print_body(output);
});
DEFPRINT(AST_For, function(self, output){
DEFPRINT(AST_For, function(self, output) {
output.print("for");
output.space();
output.with_parens(function(){
output.with_parens(function() {
if (self.init) {
if (self.init instanceof AST_Definitions) {
self.init.print(output);
@@ -965,10 +965,10 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
DEFPRINT(AST_ForIn, function(self, output){
DEFPRINT(AST_ForIn, function(self, output) {
output.print("for");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.init.print(output);
output.space();
output.print("in");
@@ -978,10 +978,10 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
DEFPRINT(AST_With, function(self, output){
DEFPRINT(AST_With, function(self, output) {
output.print("with");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.expression.print(output);
});
output.space();
@@ -989,7 +989,7 @@ function OutputStream(options) {
});
/* -----[ functions ]----- */
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
var self = this;
if (!nokeyword) {
output.print("function");
@@ -998,8 +998,8 @@ function OutputStream(options) {
output.space();
self.name.print(output);
}
output.with_parens(function(){
self.argnames.forEach(function(arg, i){
output.with_parens(function() {
self.argnames.forEach(function(arg, i) {
if (i) output.comma();
arg.print(output);
});
@@ -1007,40 +1007,31 @@ function OutputStream(options) {
output.space();
print_braced(self, output, true);
});
DEFPRINT(AST_Lambda, function(self, output){
DEFPRINT(AST_Lambda, function(self, output) {
self._do_print(output);
});
/* -----[ exits ]----- */
AST_Exit.DEFMETHOD("_do_print", function(output, kind){
/* -----[ jumps ]----- */
function print_jump(output, kind, target) {
output.print(kind);
if (this.value) {
if (target) {
output.space();
this.value.print(output);
target.print(output);
}
output.semicolon();
});
DEFPRINT(AST_Return, function(self, output){
self._do_print(output, "return");
});
DEFPRINT(AST_Throw, function(self, output){
self._do_print(output, "throw");
});
}
/* -----[ loop control ]----- */
AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
output.print(kind);
if (this.label) {
output.space();
this.label.print(output);
}
output.semicolon();
DEFPRINT(AST_Return, function(self, output) {
print_jump(output, "return", self.value);
});
DEFPRINT(AST_Break, function(self, output){
self._do_print(output, "break");
DEFPRINT(AST_Throw, function(self, output) {
print_jump(output, "throw", self.value);
});
DEFPRINT(AST_Continue, function(self, output){
self._do_print(output, "continue");
DEFPRINT(AST_Break, function(self, output) {
print_jump(output, "break", self.label);
});
DEFPRINT(AST_Continue, function(self, output) {
print_jump(output, "continue", self.label);
});
/* -----[ if ]----- */
@@ -1072,10 +1063,10 @@ function OutputStream(options) {
}
force_statement(self.body, output);
}
DEFPRINT(AST_If, function(self, output){
DEFPRINT(AST_If, function(self, output) {
output.print("if");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.condition.print(output);
});
output.space();
@@ -1094,17 +1085,17 @@ function OutputStream(options) {
});
/* -----[ switch ]----- */
DEFPRINT(AST_Switch, function(self, output){
DEFPRINT(AST_Switch, function(self, output) {
output.print("switch");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.expression.print(output);
});
output.space();
var last = self.body.length - 1;
if (last < 0) print_braced_empty(self, output);
else output.with_block(function(){
self.body.forEach(function(branch, i){
else output.with_block(function() {
self.body.forEach(function(branch, i) {
output.indent(true);
branch.print(output);
if (i < last && branch.body.length > 0)
@@ -1112,19 +1103,19 @@ function OutputStream(options) {
});
});
});
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
output.newline();
this.body.forEach(function(stmt){
this.body.forEach(function(stmt) {
output.indent();
stmt.print(output);
output.newline();
});
});
DEFPRINT(AST_Default, function(self, output){
DEFPRINT(AST_Default, function(self, output) {
output.print("default:");
self._do_print_body(output);
});
DEFPRINT(AST_Case, function(self, output){
DEFPRINT(AST_Case, function(self, output) {
output.print("case");
output.space();
self.expression.print(output);
@@ -1133,7 +1124,7 @@ function OutputStream(options) {
});
/* -----[ exceptions ]----- */
DEFPRINT(AST_Try, function(self, output){
DEFPRINT(AST_Try, function(self, output) {
output.print("try");
output.space();
print_braced(self, output);
@@ -1146,37 +1137,30 @@ function OutputStream(options) {
self.bfinally.print(output);
}
});
DEFPRINT(AST_Catch, function(self, output){
DEFPRINT(AST_Catch, function(self, output) {
output.print("catch");
output.space();
output.with_parens(function(){
output.with_parens(function() {
self.argname.print(output);
});
output.space();
print_braced(self, output);
});
DEFPRINT(AST_Finally, function(self, output){
DEFPRINT(AST_Finally, function(self, output) {
output.print("finally");
output.space();
print_braced(self, output);
});
/* -----[ var/const ]----- */
AST_Definitions.DEFMETHOD("_do_print", function(output, kind){
output.print(kind);
DEFPRINT(AST_Var, function(self, output) {
output.print("var");
output.space();
this.definitions.forEach(function(def, i){
self.definitions.forEach(function(def, i) {
if (i) output.comma();
def.print(output);
});
var p = output.parent();
var in_for = p instanceof AST_For || p instanceof AST_ForIn;
var avoid_semicolon = in_for && p.init === this;
if (!avoid_semicolon)
output.semicolon();
});
DEFPRINT(AST_Var, function(self, output){
self._do_print(output, "var");
if (p.init !== self || !(p instanceof AST_For || p instanceof AST_ForIn)) output.semicolon();
});
function parenthesize_for_noin(node, output, noin) {
@@ -1193,7 +1177,7 @@ function OutputStream(options) {
node.print(output, parens);
}
DEFPRINT(AST_VarDef, function(self, output){
DEFPRINT(AST_VarDef, function(self, output) {
self.name.print(output);
if (self.value) {
output.space();
@@ -1206,28 +1190,27 @@ function OutputStream(options) {
});
/* -----[ other expressions ]----- */
DEFPRINT(AST_Call, function(self, output){
DEFPRINT(AST_Call, function(self, output) {
self.expression.print(output);
if (self instanceof AST_New && !need_constructor_parens(self, output))
return;
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
output.add_mapping(self.start);
}
output.with_parens(function(){
self.args.forEach(function(expr, i){
output.with_parens(function() {
self.args.forEach(function(expr, i) {
if (i) output.comma();
expr.print(output);
});
});
});
DEFPRINT(AST_New, function(self, output){
DEFPRINT(AST_New, function(self, output) {
output.print("new");
output.space();
AST_Call.prototype._codegen(self, output);
});
AST_Sequence.DEFMETHOD("_do_print", function(output){
this.expressions.forEach(function(node, index) {
DEFPRINT(AST_Sequence, function(self, output) {
self.expressions.forEach(function(node, index) {
if (index > 0) {
output.comma();
if (output.should_break()) {
@@ -1238,18 +1221,7 @@ function OutputStream(options) {
node.print(output);
});
});
DEFPRINT(AST_Sequence, function(self, output){
self._do_print(output);
// var p = output.parent();
// if (p instanceof AST_Statement) {
// output.with_indent(output.next_indent(), function(){
// self._do_print(output);
// });
// } else {
// self._do_print(output);
// }
});
DEFPRINT(AST_Dot, function(self, output){
DEFPRINT(AST_Dot, function(self, output) {
var expr = self.expression;
expr.print(output);
var prop = self.property;
@@ -1270,13 +1242,13 @@ function OutputStream(options) {
output.print_name(prop);
}
});
DEFPRINT(AST_Sub, function(self, output){
DEFPRINT(AST_Sub, function(self, output) {
self.expression.print(output);
output.print("[");
self.property.print(output);
output.print("]");
});
DEFPRINT(AST_UnaryPrefix, function(self, output){
DEFPRINT(AST_UnaryPrefix, function(self, output) {
var op = self.operator;
output.print(op);
if (/^[a-z]/i.test(op)
@@ -1287,11 +1259,11 @@ function OutputStream(options) {
}
self.expression.print(output);
});
DEFPRINT(AST_UnaryPostfix, function(self, output){
DEFPRINT(AST_UnaryPostfix, function(self, output) {
self.expression.print(output);
output.print(self.operator);
});
DEFPRINT(AST_Binary, function(self, output){
DEFPRINT(AST_Binary, function(self, output) {
var op = self.operator;
self.left.print(output);
if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
@@ -1317,7 +1289,7 @@ function OutputStream(options) {
}
self.right.print(output);
});
DEFPRINT(AST_Conditional, function(self, output){
DEFPRINT(AST_Conditional, function(self, output) {
self.condition.print(output);
output.space();
output.print("?");
@@ -1329,11 +1301,11 @@ function OutputStream(options) {
});
/* -----[ literals ]----- */
DEFPRINT(AST_Array, function(self, output){
output.with_square(function(){
DEFPRINT(AST_Array, function(self, output) {
output.with_square(function() {
var a = self.elements, len = a.length;
if (len > 0) output.space();
a.forEach(function(exp, i){
a.forEach(function(exp, i) {
if (i) output.comma();
exp.print(output);
// If the final element is a hole, we need to make sure it
@@ -1345,9 +1317,9 @@ function OutputStream(options) {
if (len > 0) output.space();
});
});
DEFPRINT(AST_Object, function(self, output){
if (self.properties.length > 0) output.with_block(function(){
self.properties.forEach(function(prop, i){
DEFPRINT(AST_Object, function(self, output) {
if (self.properties.length > 0) output.with_block(function() {
self.properties.forEach(function(prop, i) {
if (i) {
output.print(",");
output.newline();
@@ -1376,7 +1348,7 @@ function OutputStream(options) {
}
}
DEFPRINT(AST_ObjectKeyVal, function(self, output){
DEFPRINT(AST_ObjectKeyVal, function(self, output) {
print_property_name(self.key, self.quote, output);
output.colon();
self.value.print(output);
@@ -1387,27 +1359,27 @@ function OutputStream(options) {
print_property_name(this.key.name, this.quote, output);
this.value._do_print(output, true);
});
DEFPRINT(AST_ObjectSetter, function(self, output){
DEFPRINT(AST_ObjectSetter, function(self, output) {
self._print_getter_setter("set", output);
});
DEFPRINT(AST_ObjectGetter, function(self, output){
DEFPRINT(AST_ObjectGetter, function(self, output) {
self._print_getter_setter("get", output);
});
DEFPRINT(AST_Symbol, function(self, output){
DEFPRINT(AST_Symbol, function(self, output) {
var def = self.definition();
output.print_name(def ? def.mangled_name || def.name : self.name);
});
DEFPRINT(AST_Hole, noop);
DEFPRINT(AST_This, function(self, output){
DEFPRINT(AST_This, function(self, output) {
output.print("this");
});
DEFPRINT(AST_Constant, function(self, output){
DEFPRINT(AST_Constant, function(self, output) {
output.print(self.getValue());
});
DEFPRINT(AST_String, function(self, output){
DEFPRINT(AST_String, function(self, output) {
output.print_string(self.getValue(), self.quote, in_directive);
});
DEFPRINT(AST_Number, function(self, output){
DEFPRINT(AST_Number, function(self, output) {
if (use_asm && self.start && self.start.raw != null) {
output.print(self.start.raw);
} else {
@@ -1415,7 +1387,7 @@ function OutputStream(options) {
}
});
DEFPRINT(AST_RegExp, function(self, output){
DEFPRINT(AST_RegExp, function(self, output) {
var regexp = self.getValue();
var str = regexp.toString();
if (regexp.raw_source) {
@@ -1487,7 +1459,7 @@ function OutputStream(options) {
output.print("{}");
else if (stmt instanceof AST_BlockStatement)
stmt.print(output);
else output.with_block(function(){
else output.with_block(function() {
output.indent();
stmt.print(output);
output.newline();

View File

@@ -130,7 +130,7 @@ function is_letter(code) {
return (code >= 97 && code <= 122)
|| (code >= 65 && code <= 90)
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
};
}
function is_surrogate_pair_head(code) {
if (typeof code == "string")
@@ -146,11 +146,11 @@ function is_surrogate_pair_tail(code) {
function is_digit(code) {
return code >= 48 && code <= 57;
};
}
function is_alphanumeric_char(code) {
return is_digit(code) || is_letter(code);
};
}
function is_unicode_digit(code) {
return UNICODE.digit.test(String.fromCharCode(code));
@@ -158,19 +158,19 @@ function is_unicode_digit(code) {
function is_unicode_combining_mark(ch) {
return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
};
}
function is_unicode_connector_punctuation(ch) {
return UNICODE.connector_punctuation.test(ch);
};
}
function is_identifier(name) {
return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
};
}
function is_identifier_start(code) {
return code == 36 || code == 95 || is_letter(code);
};
}
function is_identifier_char(ch) {
var code = ch.charCodeAt(0);
@@ -182,11 +182,11 @@ function is_identifier_char(ch) {
|| is_unicode_connector_punctuation(ch)
|| is_unicode_digit(code)
;
};
}
function is_identifier_string(str){
function is_identifier_string(str) {
return /^[a-z_$][a-z0-9_$]*$/i.test(str);
};
}
function parse_js_number(num) {
if (RE_HEX_NUMBER.test(num)) {
@@ -197,7 +197,7 @@ function parse_js_number(num) {
var val = parseFloat(num);
if (val == num) return val;
}
};
}
function JS_Parse_Error(message, filename, line, col, pos) {
this.message = message;
@@ -205,7 +205,7 @@ function JS_Parse_Error(message, filename, line, col, pos) {
this.line = line;
this.col = col;
this.pos = pos;
};
}
JS_Parse_Error.prototype = Object.create(Error.prototype);
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
JS_Parse_Error.prototype.name = "SyntaxError";
@@ -213,11 +213,11 @@ configure_error_stack(JS_Parse_Error);
function js_error(message, filename, line, col, pos) {
throw new JS_Parse_Error(message, filename, line, col, pos);
};
}
function is_token(token, type, val) {
return token.type == type && (val == null || token.value == val);
};
}
var EX_EOF = {};
@@ -239,7 +239,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
directive_stack : []
};
function peek() { return S.text.charAt(S.pos); };
function peek() {
return S.text.charAt(S.pos);
}
function next(signal_eof, in_string) {
var ch = S.text.charAt(S.pos++);
@@ -258,15 +260,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
++S.col;
}
return ch;
};
}
function forward(i) {
while (i-- > 0) next();
};
}
function looking_at(str) {
return S.text.substr(S.pos, str.length) == str;
};
}
function find_eol() {
var text = S.text;
@@ -276,19 +278,19 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
return i;
}
return -1;
};
}
function find(what, signal_eof) {
var pos = S.text.indexOf(what, S.pos);
if (signal_eof && pos == -1) throw EX_EOF;
return pos;
};
}
function start_token() {
S.tokline = S.line;
S.tokcol = S.col;
S.tokpos = S.pos;
};
}
var prev_was_dot = false;
function token(type, value, is_comment) {
@@ -321,27 +323,27 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
S.newline_before = false;
return new AST_Token(ret);
};
}
function skip_whitespace() {
while (WHITESPACE_CHARS[peek()])
next();
};
}
function read_while(pred) {
var ret = "", ch, i = 0;
while ((ch = peek()) && pred(ch, i++))
ret += next();
return ret;
};
}
function parse_error(err) {
js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
};
}
function read_num(prefix) {
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
var num = read_while(function(ch, i){
var num = read_while(function(ch, i) {
var code = ch.charCodeAt(0);
switch (code) {
case 120: case 88: // xX
@@ -367,7 +369,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
} else {
parse_error("Invalid syntax: " + num);
}
};
}
function read_escaped_char(in_string) {
var ch = next(true, in_string);
@@ -390,7 +392,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
if (ch >= "0" && ch <= "7")
return read_octal_escape_sequence(ch);
return ch;
};
}
function read_octal_escape_sequence(ch) {
// Read
@@ -417,9 +419,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
num = (num << 4) | digit;
}
return num;
};
}
var read_string = with_eof_error("Unterminated string constant", function(quote_char){
var read_string = with_eof_error("Unterminated string constant", function(quote_char) {
var quote = next(), ret = "";
for (;;) {
var ch = next(true, true);
@@ -447,9 +449,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
S.comments_before.push(token(type, ret, true));
S.regex_allowed = regex_allowed;
return next_token;
};
}
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function(){
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
var regex_allowed = S.regex_allowed;
var i = find("*/", true);
var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, '\n');
@@ -481,7 +483,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
}
return name;
};
}
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
var prev_backslash = false, ch, in_class = false;
@@ -523,9 +525,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
} else {
return op;
}
};
}
return token("operator", grow(prefix || next()));
};
}
function handle_slash() {
next();
@@ -538,14 +540,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
return skip_multiline_comment();
}
return S.regex_allowed ? read_regexp("") : read_operator("/");
};
}
function handle_dot() {
next();
return is_digit(peek().charCodeAt(0))
? read_num(".")
: token("punc", ".");
};
}
function read_word() {
var word = read_name();
@@ -554,7 +556,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
: !KEYWORDS[word] ? token("name", word)
: OPERATORS[word] ? token("operator", word)
: token("keyword", word);
};
}
function with_eof_error(eof_error, cont) {
return function(x) {
@@ -565,7 +567,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
else throw ex;
}
};
};
}
function next_token(force_regexp) {
if (force_regexp != null)
@@ -609,7 +611,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
break;
}
parse_error("Unexpected character '" + ch + "'");
};
}
next_token.context = function(nc) {
if (nc) S = nc;
@@ -645,8 +647,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
return next_token;
};
}
/* -----[ Parser (constants) ]----- */
@@ -666,7 +667,7 @@ var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
var PRECEDENCE = (function(a, ret){
var PRECEDENCE = function(a, ret) {
for (var i = 0; i < a.length; ++i) {
var b = a[i];
for (var j = 0; j < b.length; ++j) {
@@ -674,28 +675,24 @@ var PRECEDENCE = (function(a, ret){
}
}
return ret;
})(
[
["||"],
["&&"],
["|"],
["^"],
["&"],
["==", "===", "!=", "!=="],
["<", ">", "<=", ">=", "in", "instanceof"],
[">>", "<<", ">>>"],
["+", "-"],
["*", "/", "%"]
],
{}
);
}([
["||"],
["&&"],
["|"],
["^"],
["&"],
["==", "===", "!=", "!=="],
["<", ">", "<=", ">=", "in", "instanceof"],
[">>", "<<", ">>>"],
["+", "-"],
["*", "/", "%"]
], {});
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
/* -----[ Parser ]----- */
function parse($TEXT, options) {
options = defaults(options, {
bare_returns : false,
expression : false,
@@ -724,9 +721,11 @@ function parse($TEXT, options) {
function is(type, value) {
return is_token(S.token, type, value);
};
}
function peek() { return S.peeked || (S.peeked = S.input()); };
function peek() {
return S.peeked || (S.peeked = S.input());
}
function next() {
S.prev = S.token;
@@ -740,11 +739,11 @@ function parse($TEXT, options) {
S.token.type == "string" || is("punc", ";")
);
return S.token;
};
}
function prev() {
return S.prev;
};
}
function croak(msg, line, col, pos) {
var ctx = S.input.context();
@@ -753,26 +752,28 @@ function parse($TEXT, options) {
line != null ? line : ctx.tokline,
col != null ? col : ctx.tokcol,
pos != null ? pos : ctx.tokpos);
};
}
function token_error(token, msg) {
croak(msg, token.line, token.col);
};
}
function unexpected(token) {
if (token == null)
token = S.token;
token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
};
}
function expect_token(type, val) {
if (is(type, val)) {
return next();
}
token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
};
}
function expect(punc) { return expect_token("punc", punc); };
function expect(punc) {
return expect_token("punc", punc);
}
function has_newline_before(token) {
return token.nlb || !all(token.comments_before, function(comment) {
@@ -783,19 +784,19 @@ function parse($TEXT, options) {
function can_insert_semicolon() {
return !options.strict
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
};
}
function semicolon(optional) {
if (is("punc", ";")) next();
else if (!optional && !can_insert_semicolon()) unexpected();
};
}
function parenthesised() {
expect("(");
var exp = expression(true);
expect(")");
return exp;
};
}
function embed_tokens(parser) {
return function() {
@@ -806,14 +807,14 @@ function parse($TEXT, options) {
expr.end = end;
return expr;
};
};
}
function handle_regexp() {
if (is("operator", "/") || is("operator", "/=")) {
S.peeked = null;
S.token = S.input(S.token.value.substr(1)); // force regexp
}
};
}
var statement = embed_tokens(function(strict_defun) {
handle_regexp();
@@ -986,7 +987,7 @@ function parse($TEXT, options) {
// check for `continue` that refers to this label.
// those should be reported as syntax errors.
// https://github.com/mishoo/UglifyJS2/issues/287
label.references.forEach(function(ref){
label.references.forEach(function(ref) {
if (ref instanceof AST_Continue) {
ref = ref.label.start;
croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
@@ -995,11 +996,11 @@ function parse($TEXT, options) {
});
}
return new AST_LabeledStatement({ body: stat, label: label });
};
}
function simple_statement(tmp) {
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
};
}
function break_cont(type) {
var label = null, ldef;
@@ -1007,18 +1008,17 @@ function parse($TEXT, options) {
label = as_symbol(AST_LabelRef, true);
}
if (label != null) {
ldef = find_if(function(l){ return l.name == label.name }, S.labels);
if (!ldef)
croak("Undefined label " + label.name);
ldef = find_if(function(l) {
return l.name == label.name;
}, S.labels);
if (!ldef) croak("Undefined label " + label.name);
label.thedef = ldef;
}
else if (S.in_loop == 0)
croak(type.TYPE + " not inside a loop or switch");
} else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch");
semicolon();
var stat = new type({ label: label });
if (ldef) ldef.references.push(stat);
return stat;
};
}
function for_() {
expect("(");
@@ -1039,7 +1039,7 @@ function parse($TEXT, options) {
}
}
return regular_for(init);
};
}
function regular_for(init) {
expect(";");
@@ -1053,7 +1053,7 @@ function parse($TEXT, options) {
step : step,
body : in_loop(statement)
});
};
}
function for_in(init) {
var obj = expression(true);
@@ -1063,7 +1063,7 @@ function parse($TEXT, options) {
object : obj,
body : in_loop(statement)
});
};
}
var function_ = function(ctor) {
var in_statement = ctor === AST_Defun;
@@ -1113,7 +1113,7 @@ function parse($TEXT, options) {
body : body,
alternative : belse
});
};
}
function block_(strict_defun) {
expect("{");
@@ -1124,7 +1124,7 @@ function parse($TEXT, options) {
}
next();
return a;
};
}
function switch_body_() {
expect("{");
@@ -1159,7 +1159,7 @@ function parse($TEXT, options) {
if (branch) branch.end = prev();
next();
return a;
};
}
function try_() {
var body = block_(), bcatch = null, bfinally = null;
@@ -1192,7 +1192,7 @@ function parse($TEXT, options) {
bcatch : bcatch,
bfinally : bfinally
});
};
}
function vardefs(no_in) {
var a = [];
@@ -1208,7 +1208,7 @@ function parse($TEXT, options) {
next();
}
return a;
};
}
var var_ = function(no_in) {
return new AST_Var({
@@ -1274,7 +1274,7 @@ function parse($TEXT, options) {
}
next();
return ret;
};
}
var expr_atom = function(allow_calls) {
if (is("operator", "new")) {
@@ -1340,7 +1340,7 @@ function parse($TEXT, options) {
}
next();
return a;
};
}
var array_ = embed_tokens(function() {
expect("[");
@@ -1417,14 +1417,14 @@ function parse($TEXT, options) {
default:
unexpected();
}
};
}
function as_name() {
var tmp = S.token;
if (tmp.type != "name") unexpected();
next();
return tmp.value;
};
}
function _make_symbol(type) {
var name = S.token.value;
@@ -1433,7 +1433,7 @@ function parse($TEXT, options) {
start : S.token,
end : S.token
});
};
}
function strict_verify_symbol(sym) {
if (sym.name == "arguments" || sym.name == "eval")
@@ -1451,7 +1451,7 @@ function parse($TEXT, options) {
}
next();
return sym;
};
}
function mark_pure(call) {
var start = call.start;
@@ -1536,7 +1536,7 @@ function parse($TEXT, options) {
break;
}
return new ctor({ operator: op, expression: expr });
};
}
var expr_op = function(left, min_prec, no_in) {
var op = is("operator") ? S.token.value : null;
@@ -1558,7 +1558,7 @@ function parse($TEXT, options) {
function expr_ops(no_in) {
return expr_op(maybe_unary(true), 0, no_in);
};
}
var maybe_conditional = function(no_in) {
var start = S.token;
@@ -1580,7 +1580,7 @@ function parse($TEXT, options) {
function is_assignable(expr) {
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
};
}
var maybe_assign = function(no_in) {
var start = S.token;
@@ -1622,13 +1622,13 @@ function parse($TEXT, options) {
var ret = cont();
--S.in_loop;
return ret;
};
}
if (options.expression) {
return expression(true);
}
return (function(){
return function() {
var start = S.token;
var body = [];
S.input.push_directives_stack();
@@ -1644,6 +1644,5 @@ function parse($TEXT, options) {
toplevel = new AST_Toplevel({ start: start, body: body, end: end });
}
return toplevel;
})();
};
}();
}

View File

@@ -56,7 +56,7 @@ function find_builtins(reserved) {
[ Object, Array, Function, Number,
String, Boolean, Error, Math,
Date, RegExp
].forEach(function(ctor){
].forEach(function(ctor) {
Object.getOwnPropertyNames(ctor).map(add);
if (ctor.prototype) {
Object.getOwnPropertyNames(ctor.prototype).map(add);
@@ -136,7 +136,7 @@ function mangle_properties(ast, options) {
var unmangleable = [];
// step 1: find candidates to mangle
ast.walk(new TreeWalker(function(node){
ast.walk(new TreeWalker(function(node) {
if (node instanceof AST_ObjectKeyVal) {
add(node.key);
}
@@ -157,7 +157,7 @@ function mangle_properties(ast, options) {
}));
// step 2: transform the tree, renaming properties
return ast.transform(new TreeTransformer(function(node){
return ast.transform(new TreeTransformer(function(node) {
if (node instanceof AST_ObjectKeyVal) {
node.key = mangle(node.key);
}
@@ -234,7 +234,7 @@ function mangle_properties(ast, options) {
}
function mangleStrings(node) {
return node.transform(new TreeTransformer(function(node){
return node.transform(new TreeTransformer(function(node) {
if (node instanceof AST_Sequence) {
var last = node.expressions.length - 1;
node.expressions[last] = mangleStrings(node.expressions[last]);

View File

@@ -63,12 +63,12 @@ SymbolDef.prototype = {
unmangleable: function(options) {
if (!options) options = {};
return (this.global && !options.toplevel)
return this.global && !options.toplevel
|| this.undeclared
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|| (options.keep_fnames
|| !options.eval && this.scope.pinned()
|| options.keep_fnames
&& (this.orig[0] instanceof AST_SymbolLambda
|| this.orig[0] instanceof AST_SymbolDefun));
|| this.orig[0] instanceof AST_SymbolDefun);
},
mangle: function(options) {
var cache = options.cache && options.cache.props;
@@ -91,7 +91,7 @@ SymbolDef.prototype = {
}
};
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
options = defaults(options, {
cache: null,
ie8: false,
@@ -101,7 +101,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
var self = this;
var scope = self.parent_scope = null;
var defun = null;
var tw = new TreeWalker(function(node, descend){
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_Catch) {
var save_scope = scope;
scope = new AST_Scope(node);
@@ -132,10 +132,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
node.thedef = node;
node.references = [];
}
if (node instanceof AST_SymbolLambda) {
defun.def_function(node, node.name == "arguments" ? undefined : defun);
}
else if (node instanceof AST_SymbolDefun) {
if (node instanceof AST_SymbolDefun || options.ie8 && node instanceof AST_SymbolLambda) {
// Careful here, the scope where this should be defined is
// the parent scope. The reason is that we enter a new
// scope when we encounter the AST_Defun node (which is
@@ -143,6 +140,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
// later.
(node.scope = defun.parent_scope).def_function(node, defun);
}
else if (node instanceof AST_SymbolLambda) {
defun.def_function(node, node.name == "arguments" ? undefined : defun);
}
else if (node instanceof AST_SymbolVar) {
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
if (defun !== scope) {
@@ -162,7 +162,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
// pass 2: find back references and eval
self.globals = new Dictionary();
var tw = new TreeWalker(function(node, descend){
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_LoopControl && node.label) {
node.label.thedef.references.push(node);
return true;
@@ -217,7 +217,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
}
});
AST_Toplevel.DEFMETHOD("def_global", function(node){
AST_Toplevel.DEFMETHOD("def_global", function(node) {
var globals = this.globals, name = node.name;
if (globals.has(name)) {
return globals.get(name);
@@ -230,7 +230,7 @@ AST_Toplevel.DEFMETHOD("def_global", function(node){
}
});
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
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
@@ -240,7 +240,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
this.cname = -1; // the current index for mangling functions/variables
});
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
AST_Lambda.DEFMETHOD("init_scope_vars", function() {
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
@@ -270,20 +270,20 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
this.mark_enclosed(options);
});
AST_Scope.DEFMETHOD("find_variable", function(name){
AST_Scope.DEFMETHOD("find_variable", function(name) {
if (name instanceof AST_Symbol) name = name.name;
return this.variables.get(name)
|| (this.parent_scope && this.parent_scope.find_variable(name));
});
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
var def = this.def_variable(symbol, init);
if (!def.init || def.init instanceof AST_Defun) def.init = init;
this.functions.set(symbol.name, def);
return def;
});
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
var def = this.variables.get(symbol.name);
if (def) {
def.orig.push(symbol);
@@ -349,13 +349,10 @@ function next_mangled_name(scope, options, def) {
holes.push(scope.cname);
}
scope.names_in_use[name] = true;
if (options.ie8 && def.orig[0] instanceof AST_SymbolLambda) {
names_in_use(scope.parent_scope, options)[name] = true;
}
return name;
}
AST_Symbol.DEFMETHOD("unmangleable", function(options){
AST_Symbol.DEFMETHOD("unmangleable", function(options) {
var def = this.definition();
return !def || def.unmangleable(options);
});
@@ -363,16 +360,15 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", return_false);
AST_Symbol.DEFMETHOD("unreferenced", function(){
return this.definition().references.length == 0
&& !(this.scope.uses_eval || this.scope.uses_with);
AST_Symbol.DEFMETHOD("unreferenced", function() {
return !this.definition().references.length && !this.scope.pinned();
});
AST_Symbol.DEFMETHOD("definition", function(){
AST_Symbol.DEFMETHOD("definition", function() {
return this.thedef;
});
AST_Symbol.DEFMETHOD("global", function(){
AST_Symbol.DEFMETHOD("global", function() {
return this.definition().global;
});
@@ -391,7 +387,7 @@ function _default_mangler_options(options) {
return options;
}
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
options = _default_mangler_options(options);
// We only need to mangle declaration nodes. Special logic wired
@@ -408,7 +404,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
}
var redefined = [];
var tw = new TreeWalker(function(node, descend){
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_LabeledStatement) {
// lname is incremented when we get to the AST_Label
var save_nesting = lname;
@@ -521,7 +517,7 @@ AST_Sequence.DEFMETHOD("tail_node", function() {
return this.expressions[this.expressions.length - 1];
});
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
options = _default_mangler_options(options);
base54.reset();
try {

View File

@@ -46,16 +46,15 @@
// a small wrapper around fitzgen's source-map library
function SourceMap(options) {
options = defaults(options, {
file : null,
root : null,
orig : null,
orig_line_diff : 0,
dest_line_diff : 0,
});
file: null,
root: null,
orig: null,
orig_line_diff: 0,
dest_line_diff: 0,
}, true);
var generator = new MOZ_SourceMap.SourceMapGenerator({
file : options.file,
sourceRoot : options.root
file: options.file,
sourceRoot: options.root
});
var maps = options.orig && Object.create(null);
if (maps) for (var source in options.orig) {
@@ -68,30 +67,38 @@ function SourceMap(options) {
}
maps[source] = map;
}
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
var map = maps && maps[source];
if (map) {
var info = map.originalPositionFor({
line: orig_line,
column: orig_col
});
if (info.source === null) return;
source = info.source;
orig_line = info.line;
orig_col = info.column;
name = info.name || name;
}
generator.addMapping({
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
original : { line: orig_line + options.orig_line_diff, column: orig_col },
source : source,
name : name
});
};
return {
add : add,
get : function() { return generator },
toString : function() { return JSON.stringify(generator.toJSON()); }
add: function(source, gen_line, gen_col, orig_line, orig_col, name) {
var map = maps && maps[source];
if (map) {
var info = map.originalPositionFor({
line: orig_line,
column: orig_col
});
if (info.source === null) return;
source = info.source;
orig_line = info.line;
orig_col = info.column;
name = info.name || name;
}
generator.addMapping({
name: name,
source: source,
generated: {
line: gen_line + options.dest_line_diff,
column: gen_col
},
original: {
line: orig_line + options.orig_line_diff,
column: orig_col
}
});
},
get: function() {
return generator;
},
toString: function() {
return JSON.stringify(generator.toJSON());
}
};
};
}

View File

@@ -43,8 +43,6 @@
"use strict";
// Tree transformer helpers.
function TreeTransformer(before, after) {
TreeWalker.call(this);
this.before = before;
@@ -52,168 +50,136 @@ function TreeTransformer(before, after) {
}
TreeTransformer.prototype = new TreeWalker;
(function(undefined){
function _(node, descend) {
node.DEFMETHOD("transform", function(tw, in_list){
var x, y;
tw.push(this);
if (tw.before) x = tw.before(this, descend, in_list);
if (x === undefined) {
x = this;
descend(x, tw);
if (tw.after) {
y = tw.after(x, in_list);
if (y !== undefined) x = y;
}
}
tw.pop();
return x;
});
};
(function(DEF) {
function do_list(list, tw) {
return MAP(list, function(node){
return MAP(list, function(node) {
return node.transform(tw, true);
});
};
}
_(AST_Node, noop);
_(AST_LabeledStatement, function(self, tw){
DEF(AST_Node, noop);
DEF(AST_LabeledStatement, function(self, tw) {
self.label = self.label.transform(tw);
self.body = self.body.transform(tw);
});
_(AST_SimpleStatement, function(self, tw){
DEF(AST_SimpleStatement, function(self, tw) {
self.body = self.body.transform(tw);
});
_(AST_Block, function(self, tw){
DEF(AST_Block, function(self, tw) {
self.body = do_list(self.body, tw);
});
_(AST_Do, function(self, tw){
DEF(AST_Do, function(self, tw) {
self.body = self.body.transform(tw);
self.condition = self.condition.transform(tw);
});
_(AST_While, function(self, tw){
DEF(AST_While, function(self, tw) {
self.condition = self.condition.transform(tw);
self.body = self.body.transform(tw);
});
_(AST_For, function(self, tw){
DEF(AST_For, function(self, tw) {
if (self.init) self.init = self.init.transform(tw);
if (self.condition) self.condition = self.condition.transform(tw);
if (self.step) self.step = self.step.transform(tw);
self.body = self.body.transform(tw);
});
_(AST_ForIn, function(self, tw){
DEF(AST_ForIn, function(self, tw) {
self.init = self.init.transform(tw);
self.object = self.object.transform(tw);
self.body = self.body.transform(tw);
});
_(AST_With, function(self, tw){
DEF(AST_With, function(self, tw) {
self.expression = self.expression.transform(tw);
self.body = self.body.transform(tw);
});
_(AST_Exit, function(self, tw){
DEF(AST_Exit, function(self, tw) {
if (self.value) self.value = self.value.transform(tw);
});
_(AST_LoopControl, function(self, tw){
DEF(AST_LoopControl, function(self, tw) {
if (self.label) self.label = self.label.transform(tw);
});
_(AST_If, function(self, tw){
DEF(AST_If, function(self, tw) {
self.condition = self.condition.transform(tw);
self.body = self.body.transform(tw);
if (self.alternative) self.alternative = self.alternative.transform(tw);
});
_(AST_Switch, function(self, tw){
DEF(AST_Switch, function(self, tw) {
self.expression = self.expression.transform(tw);
self.body = do_list(self.body, tw);
});
_(AST_Case, function(self, tw){
DEF(AST_Case, function(self, tw) {
self.expression = self.expression.transform(tw);
self.body = do_list(self.body, tw);
});
_(AST_Try, function(self, tw){
DEF(AST_Try, function(self, tw) {
self.body = do_list(self.body, tw);
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
});
_(AST_Catch, function(self, tw){
DEF(AST_Catch, function(self, tw) {
self.argname = self.argname.transform(tw);
self.body = do_list(self.body, tw);
});
_(AST_Definitions, function(self, tw){
DEF(AST_Definitions, function(self, tw) {
self.definitions = do_list(self.definitions, tw);
});
_(AST_VarDef, function(self, tw){
DEF(AST_VarDef, function(self, tw) {
self.name = self.name.transform(tw);
if (self.value) self.value = self.value.transform(tw);
});
_(AST_Lambda, function(self, tw){
DEF(AST_Lambda, function(self, tw) {
if (self.name) self.name = self.name.transform(tw);
self.argnames = do_list(self.argnames, tw);
self.body = do_list(self.body, tw);
});
_(AST_Call, function(self, tw){
DEF(AST_Call, function(self, tw) {
self.expression = self.expression.transform(tw);
self.args = do_list(self.args, tw);
});
_(AST_Sequence, function(self, tw){
DEF(AST_Sequence, function(self, tw) {
self.expressions = do_list(self.expressions, tw);
});
_(AST_Dot, function(self, tw){
DEF(AST_Dot, function(self, tw) {
self.expression = self.expression.transform(tw);
});
_(AST_Sub, function(self, tw){
DEF(AST_Sub, function(self, tw) {
self.expression = self.expression.transform(tw);
self.property = self.property.transform(tw);
});
_(AST_Unary, function(self, tw){
DEF(AST_Unary, function(self, tw) {
self.expression = self.expression.transform(tw);
});
_(AST_Binary, function(self, tw){
DEF(AST_Binary, function(self, tw) {
self.left = self.left.transform(tw);
self.right = self.right.transform(tw);
});
_(AST_Conditional, function(self, tw){
DEF(AST_Conditional, function(self, tw) {
self.condition = self.condition.transform(tw);
self.consequent = self.consequent.transform(tw);
self.alternative = self.alternative.transform(tw);
});
_(AST_Array, function(self, tw){
DEF(AST_Array, function(self, tw) {
self.elements = do_list(self.elements, tw);
});
_(AST_Object, function(self, tw){
DEF(AST_Object, function(self, tw) {
self.properties = do_list(self.properties, tw);
});
_(AST_ObjectProperty, function(self, tw){
DEF(AST_ObjectProperty, function(self, tw) {
self.value = self.value.transform(tw);
});
})();
})(function(node, descend) {
node.DEFMETHOD("transform", function(tw, in_list) {
var x, y;
tw.push(this);
if (tw.before) x = tw.before(this, descend, in_list);
if (typeof x === "undefined") {
x = this;
descend(x, tw);
if (tw.after) {
y = tw.after(x, in_list);
if (typeof y !== "undefined") x = y;
}
}
tw.pop();
return x;
});
});

View File

@@ -52,9 +52,7 @@ function member(name, array) {
}
function find_if(func, array) {
for (var i = 0, n = array.length; i < n; ++i) {
if (func(array[i])) return array[i];
}
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
}
function repeat_string(str, i) {
@@ -115,7 +113,7 @@ function return_true() { return true; }
function return_this() { return this; }
function return_null() { return null; }
var MAP = (function(){
var MAP = (function() {
function MAP(a, f, backwards) {
var ret = [], top = [], i;
function doit() {
@@ -138,7 +136,7 @@ var MAP = (function(){
}
}
return is_last;
};
}
if (Array.isArray(a)) {
if (backwards) {
for (i = a.length; --i >= 0;) if (doit()) break;
@@ -152,14 +150,14 @@ var MAP = (function(){
for (i in a) if (HOP(a, i)) if (doit()) break;
}
return top.concat(ret);
};
}
MAP.at_top = function(val) { return new AtTop(val) };
MAP.splice = function(val) { return new Splice(val) };
MAP.last = function(val) { return new Last(val) };
var skip = MAP.skip = {};
function AtTop(val) { this.v = val };
function Splice(val) { this.v = val };
function Last(val) { this.v = val };
function AtTop(val) { this.v = val }
function Splice(val) { this.v = val }
function Last(val) { this.v = val }
return MAP;
})();
@@ -169,7 +167,7 @@ function push_uniq(array, el) {
}
function string_template(text, props) {
return text.replace(/\{(.+?)\}/g, function(str, p){
return text.replace(/\{(.+?)\}/g, function(str, p) {
return props && props[p];
});
}

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.3.24",
"version": "3.4.3",
"engines": {
"node": ">=0.8.0"
},
@@ -23,12 +23,11 @@
"LICENSE"
],
"dependencies": {
"commander": "~2.15.0",
"commander": "~2.16.0",
"source-map": "~0.6.1"
},
"devDependencies": {
"acorn": "~5.5.3",
"mocha": "~3.5.1",
"acorn": "~5.7.1",
"semver": "~5.5.0"
},
"scripts": {

View File

@@ -5,7 +5,8 @@ replace_index: {
properties: true,
}
input: {
console.log(arguments && arguments[0]);
var arguments = [];
console.log(arguments[0]);
(function() {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
@@ -21,7 +22,8 @@ replace_index: {
})("bar", 42);
}
expect: {
console.log(arguments && arguments[0]);
var arguments = [];
console.log(arguments[0]);
(function() {
console.log(arguments[1], arguments[1], arguments.foo);
})("bar", 42);
@@ -45,6 +47,37 @@ replace_index: {
]
}
replace_index_strict: {
options = {
arguments: true,
evaluate: true,
properties: true,
reduce_vars: true,
}
input: {
"use strict";
(function() {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
(function(a, b) {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
}
expect: {
"use strict";
(function() {
console.log(arguments[1], arguments[1], arguments.foo);
})("bar", 42);
(function(a, b) {
console.log(b, b, arguments.foo);
})("bar", 42);
}
expect_stdout: [
"42 42 undefined",
"42 42 undefined",
]
}
replace_index_keep_fargs: {
options = {
arguments: true,
@@ -53,7 +86,8 @@ replace_index_keep_fargs: {
properties: true,
}
input: {
console.log(arguments && arguments[0]);
var arguments = [];
console.log(arguments[0]);
(function() {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
@@ -69,7 +103,8 @@ replace_index_keep_fargs: {
})("bar", 42);
}
expect: {
console.log(arguments && arguments[0]);
var arguments = [];
console.log(arguments[0]);
(function(argument_0, argument_1) {
console.log(argument_1, argument_1, arguments.foo);
})("bar", 42);
@@ -93,6 +128,38 @@ replace_index_keep_fargs: {
]
}
replace_index_keep_fargs_strict: {
options = {
arguments: true,
evaluate: true,
keep_fargs: false,
properties: true,
reduce_vars: true,
}
input: {
"use strict";
(function() {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
(function(a, b) {
console.log(arguments[1], arguments["1"], arguments["foo"]);
})("bar", 42);
}
expect: {
"use strict";
(function(argument_0, argument_1) {
console.log(argument_1, argument_1, arguments.foo);
})("bar", 42);
(function(a, b) {
console.log(b, b, arguments.foo);
})("bar", 42);
}
expect_stdout: [
"42 42 undefined",
"42 42 undefined",
]
}
modified: {
options = {
arguments: true,
@@ -101,8 +168,10 @@ modified: {
(function(a, b) {
var c = arguments[0];
var d = arguments[1];
a = "foo";
var a = "foo";
b++;
arguments[0] = "moo";
arguments[1] *= 2;
console.log(a, b, c, d, arguments[0], arguments[1]);
})("bar", 42);
}
@@ -110,10 +179,61 @@ modified: {
(function(a, b) {
var c = a;
var d = b;
a = "foo";
var a = "foo";
b++;
a = "moo";
b *= 2;
console.log(a, b, c, d, a, b);
})("bar", 42);
}
expect_stdout: "foo 43 bar 42 foo 43"
expect_stdout: "moo 86 bar 42 moo 86"
}
modified_strict: {
options = {
arguments: true,
reduce_vars: true,
}
input: {
"use strict";
(function(a, b) {
var c = arguments[0];
var d = arguments[1];
var a = "foo";
b++;
arguments[0] = "moo";
arguments[1] *= 2;
console.log(a, b, c, d, arguments[0], arguments[1]);
})("bar", 42);
}
expect: {
"use strict";
(function(a, b) {
var c = arguments[0];
var d = arguments[1];
var a = "foo";
b++;
arguments[0] = "moo";
arguments[1] *= 2;
console.log(a, b, c, d, arguments[0], arguments[1]);
})("bar", 42);
}
expect_stdout: "foo 43 bar 42 moo 84"
}
duplicate_argname: {
options = {
arguments: true,
}
input: {
(function(a, b, a) {
console.log(a, b, arguments[0], arguments[1], arguments[2]);
})("foo", 42, "bar");
}
expect: {
(function(a, b, a) {
console.log(a, b, arguments[0], b, a);
})("foo", 42, "bar");
}
expect_stdout: "bar 42 foo 42 bar"
}

View File

@@ -15,9 +15,9 @@ holes_and_undefined: {
constant_join: {
options = {
unsafe : true,
evaluate : true
};
evaluate: true,
unsafe: true,
}
input: {
var a = [ "foo", "bar", "baz" ].join("");
var a1 = [ "foo", "bar", "baz" ].join();
@@ -64,9 +64,9 @@ constant_join: {
constant_join_2: {
options = {
unsafe : true,
evaluate : true
};
evaluate: true,
unsafe: true,
}
input: {
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
@@ -93,9 +93,9 @@ constant_join_2: {
constant_join_3: {
options = {
unsafe: true,
evaluate: true,
};
unsafe: true,
}
input: {
var a = [ null ].join();
var b = [ , ].join();
@@ -133,7 +133,7 @@ for_loop: {
reduce_vars: true,
unsafe: true,
unused: true,
};
}
input: {
function f0() {
var a = [1, 2, 3];

View File

@@ -1,24 +1,24 @@
asm_mixed: {
options = {
sequences : true,
properties : true,
dead_code : true,
drop_debugger : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
loops : true,
unused : true,
hoist_funs : true,
keep_fargs : true,
keep_fnames : false,
hoist_vars : true,
if_return : true,
join_vars : true,
side_effects : true,
negate_iife : true
};
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
drop_debugger: true,
evaluate: true,
hoist_funs: true,
hoist_vars: true,
if_return: true,
join_vars: true,
keep_fargs: true,
keep_fnames: false,
loops: true,
negate_iife: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
// adapted from http://asmjs.org/spec/latest/
function asm_GeometricMean(stdlib, foreign, buffer) {

View File

@@ -1,9 +1,22 @@
collapse_vars_side_effects_1: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -76,9 +89,21 @@ collapse_vars_side_effects_1: {
collapse_vars_side_effects_2: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function fn(x) { return console.log(x), x; }
@@ -144,42 +169,56 @@ collapse_vars_side_effects_2: {
collapse_vars_issue_721: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true, passes:2
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
passes: 2,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
define(["require", "exports", 'handlebars'], function (require, exports, hb) {
define(["require", "exports", 'handlebars'], function(require, exports, hb) {
var win = window;
var _hb = win.Handlebars = hb;
return _hb;
});
def(function (hb) {
def(function(hb) {
var win = window;
var prop = 'Handlebars';
var _hb = win[prop] = hb;
return _hb;
});
def(function (hb) {
def(function(hb) {
var prop = 'Handlebars';
var win = window;
var _hb = win[prop] = hb;
return _hb;
});
def(function (hb) {
def(function(hb) {
var prop = 'Handlebars';
var win = g();
var _hb = win[prop] = hb;
return _hb;
});
def(function (hb) {
def(function(hb) {
var prop = g1();
var win = g2();
var _hb = win[prop] = hb;
return _hb;
});
def(function (hb) {
def(function(hb) {
var win = g2();
var prop = g1();
var _hb = win[prop] = hb;
@@ -196,14 +235,14 @@ collapse_vars_issue_721: {
def(function(hb) {
return window.Handlebars = hb;
}),
def(function (hb) {
def(function(hb) {
return g().Handlebars = hb;
}),
def(function (hb) {
def(function(hb) {
var prop = g1();
return g2()[prop] = hb;
}),
def(function (hb) {
def(function(hb) {
return g2()[g1()] = hb;
});
}
@@ -211,10 +250,23 @@ collapse_vars_issue_721: {
collapse_vars_properties: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1(obj) {
@@ -239,10 +291,23 @@ collapse_vars_properties: {
collapse_vars_if: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -290,10 +355,23 @@ collapse_vars_if: {
collapse_vars_while: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:false, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: false,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1(y) {
@@ -339,10 +417,21 @@ collapse_vars_while: {
collapse_vars_do_while: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:false, loops:false, unused:"keep_assign",
hoist_funs:true, keep_fargs:true, if_return:true, join_vars:true,
side_effects:true
booleans: false,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: false,
properties: true,
sequences: true,
side_effects: true,
unused: "keep_assign",
}
input: {
function f1(y) {
@@ -415,9 +504,21 @@ collapse_vars_do_while: {
collapse_vars_do_while_drop_assign: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:false, loops:false, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: false,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: false,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1(y) {
@@ -490,9 +591,21 @@ collapse_vars_do_while_drop_assign: {
collapse_vars_seq: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
var f1 = function(x, y) {
@@ -514,9 +627,21 @@ collapse_vars_seq: {
collapse_vars_throw: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
var f1 = function(x, y) {
@@ -546,9 +671,21 @@ collapse_vars_throw: {
collapse_vars_switch: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -586,9 +723,20 @@ collapse_vars_switch: {
collapse_vars_assignment: {
options = {
collapse_vars:true, sequences:true, properties:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function log(x) { return console.log(x), x; }
@@ -659,10 +807,20 @@ collapse_vars_assignment: {
collapse_vars_lvalues: {
options = {
collapse_vars:true, sequences:true, properties:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:"keep_assign",
hoist_funs:true, keep_fargs:true, if_return:true, join_vars:true,
side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: "keep_assign",
}
input: {
function f0(x) { var i = ++x; return x += i; }
@@ -692,9 +850,21 @@ collapse_vars_lvalues: {
collapse_vars_lvalues_drop_assign: {
options = {
collapse_vars:true, sequences:true, properties:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true, passes:3
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
passes: 3,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f0(x) { var i = ++x; return x += i; }
@@ -724,10 +894,22 @@ collapse_vars_lvalues_drop_assign: {
collapse_vars_misc1: {
options = {
collapse_vars:true, sequences:true, properties:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f0(o, a, h) {
@@ -771,10 +953,21 @@ collapse_vars_misc1: {
collapse_vars_self_reference: {
options = {
collapse_vars:true, unused:false,
sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: false,
}
input: {
// avoid bug in self-referential declaration.
@@ -802,10 +995,23 @@ collapse_vars_self_reference: {
collapse_vars_repeated: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -845,10 +1051,23 @@ collapse_vars_repeated: {
collapse_vars_closures: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function constant_vars_can_be_replaced_in_any_scope() {
@@ -873,9 +1092,21 @@ collapse_vars_closures: {
collapse_vars_unary: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f0(o, p) {
@@ -936,10 +1167,23 @@ collapse_vars_unary: {
collapse_vars_try: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -992,9 +1236,21 @@ collapse_vars_try: {
collapse_vars_array: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1(x, y) {
@@ -1026,9 +1282,21 @@ collapse_vars_array: {
collapse_vars_object: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f0(x, y) {
@@ -1094,9 +1362,21 @@ collapse_vars_object: {
collapse_vars_eval_and_with: {
options = {
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: false,
side_effects: true,
unused: true,
}
input: {
// Don't attempt to collapse vars in presence of eval() or with statement.
@@ -1134,10 +1414,23 @@ collapse_vars_eval_and_with: {
collapse_vars_constants: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1(x) {
@@ -1172,10 +1465,24 @@ collapse_vars_constants: {
collapse_vars_arguments: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true,
toplevel:true, reduce_funcs: true, reduce_vars:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var outer = function() {
@@ -1195,9 +1502,21 @@ collapse_vars_arguments: {
collapse_vars_short_circuit: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f0(x) { var a = foo(), b = bar(); return b || x; }
@@ -1237,20 +1556,20 @@ collapse_vars_short_circuit: {
collapse_vars_short_circuited_conditions: {
options = {
booleans: true,
collapse_vars: true,
sequences: false,
dead_code: true,
conditionals: false,
comparisons: false,
evaluate: true,
booleans: true,
loops: true,
unused: true,
hoist_funs: true,
keep_fargs: true,
if_return: false,
join_vars: true,
side_effects: true,
comparisons: false,
conditionals: false,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: false,
join_vars: true,
keep_fargs: true,
loops: true,
sequences: false,
side_effects: true,
unused: true,
}
input: {
function c1(x) { var a = foo(), b = bar(), c = baz(); return a ? b : c; }
@@ -1286,21 +1605,21 @@ collapse_vars_short_circuited_conditions: {
collapse_vars_regexp: {
options = {
booleans: true,
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
hoist_funs: true,
keep_fargs: true,
loops: false,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: false,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -1692,9 +2011,21 @@ iife_2: {
var_defs: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
var f1 = function(x, y) {
@@ -2825,8 +3156,8 @@ issue_2364_5: {
options = {
collapse_vars: true,
evaluate: true,
pure_getters: true,
properties: true,
pure_getters: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -3133,8 +3464,8 @@ issue_2437_1: {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -3150,7 +3481,7 @@ issue_2437_1: {
return result;
} else {
var req = new XMLHttpRequest();
var detectFunc = function () {};
var detectFunc = function(){};
req.onreadystatechange = detectFunc;
var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
req.onreadystatechange = null;
@@ -3166,7 +3497,7 @@ issue_2437_1: {
return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
result;
}
var req, detectFunc = function() {};
var req, detectFunc = function(){};
(req = new XMLHttpRequest()).onreadystatechange = detectFunc;
result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
return req.onreadystatechange = null, result;
@@ -3183,8 +3514,8 @@ issue_2437_2: {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
sequences: true,
side_effects: true,
toplevel: true,
unused: true,
}
@@ -3200,7 +3531,7 @@ issue_2437_2: {
return result;
} else {
var req = new XMLHttpRequest();
var detectFunc = function () {};
var detectFunc = function(){};
req.onreadystatechange = detectFunc;
var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
req.onreadystatechange = null;
@@ -3417,8 +3748,8 @@ issue_2436_6: {
pure_getters: "strict",
reduce_vars: true,
toplevel: true,
unused: true,
unsafe: true,
unused: true,
}
input: {
var o = {
@@ -4513,7 +4844,7 @@ issue_2878: {
}
input: {
var c = 0;
(function (a, b) {
(function(a, b) {
function f2() {
if (a) c++;
}
@@ -4526,7 +4857,7 @@ issue_2878: {
}
expect: {
var c = 0;
(function (a, b) {
(function(a, b) {
function f2() {
if (a) c++;
}
@@ -4931,6 +5262,27 @@ collapse_rhs_lhs_2: {
expect_stdout: "PASS"
}
collapse_rhs_loop: {
options = {
collapse_vars: true,
}
input: {
var s;
s = "<tpl>PASS</tpl>";
for (var m, r = /<tpl>(.*)<\/tpl>/; m = s.match(r);)
s = s.replace(m[0], m[1]);
console.log(s);
}
expect: {
var s;
s = "<tpl>PASS</tpl>";
for (var m, r = /<tpl>(.*)<\/tpl>/; m = s.match(r);)
s = s.replace(m[0], m[1]);
console.log(s);
}
expect_stdout: "PASS"
}
collapse_rhs_side_effects: {
options = {
collapse_vars: true,

View File

@@ -295,3 +295,31 @@ issue_2857_6: {
}
expect_stdout: "true"
}
is_boolean_unsafe: {
options = {
comparisons: true,
unsafe: true,
}
input: {
console.log(/foo/.test("bar") === [].isPrototypeOf({}));
}
expect: {
console.log(/foo/.test("bar") == [].isPrototypeOf({}));
}
expect_stdout: "true"
}
is_number_unsafe: {
options = {
comparisons: true,
unsafe: true,
}
input: {
console.log(Math.acos(42) !== "foo".charCodeAt(4));
}
expect: {
console.log(Math.acos(42) != "foo".charCodeAt(4));
}
expect_stdout: "true"
}

View File

@@ -1,7 +1,7 @@
concat_1: {
options = {
evaluate: true
};
evaluate: true,
}
input: {
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
var b = "foo" + 1 + x() + 2 + "boo";
@@ -26,7 +26,7 @@ concat_1: {
}
concat_2: {
options = {};
options = {}
input: {
console.log(
1 + (2 + 3),
@@ -55,7 +55,7 @@ concat_2: {
}
concat_3: {
options = {};
options = {}
input: {
console.log(
1 + 2 + (3 + 4 + 5),
@@ -84,7 +84,7 @@ concat_3: {
}
concat_4: {
options = {};
options = {}
input: {
console.log(
1 + "2" + (3 + 4 + 5),
@@ -113,7 +113,7 @@ concat_4: {
}
concat_5: {
options = {};
options = {}
input: {
console.log(
"1" + 2 + (3 + 4 + 5),
@@ -142,7 +142,7 @@ concat_5: {
}
concat_6: {
options = {};
options = {}
input: {
console.log(
"1" + "2" + (3 + 4 + 5),

View File

@@ -1,7 +1,7 @@
ifs_1: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
if (foo) bar();
if (!foo); else bar();
@@ -18,8 +18,8 @@ ifs_1: {
ifs_2: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
if (foo) {
x();
@@ -47,12 +47,12 @@ ifs_2: {
ifs_3_should_warn: {
options = {
conditionals : true,
dead_code : true,
evaluate : true,
booleans : true,
side_effects : true,
};
booleans: true,
conditionals: true,
dead_code: true,
evaluate: true,
side_effects: true,
}
input: {
var x, y;
if (x && !(x + "1") && y) { // 1
@@ -78,8 +78,8 @@ ifs_3_should_warn: {
ifs_4: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
if (foo && bar) {
x(foo)[10].bar.baz = something();
@@ -95,10 +95,10 @@ ifs_4: {
ifs_5: {
options = {
if_return: true,
conditionals: true,
comparisons: true,
};
conditionals: true,
if_return: true,
}
input: {
function f() {
if (foo) return;
@@ -132,9 +132,9 @@ ifs_5: {
ifs_6: {
options = {
comparisons: true,
conditionals: true,
comparisons: true
};
}
input: {
var x, y;
if (!foo && !bar && !baz && !boo) {
@@ -163,8 +163,8 @@ ifs_6: {
cond_1: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
function foo(do_something, some_condition) {
if (some_condition) {
@@ -189,8 +189,8 @@ cond_1: {
cond_2: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
function foo(x, FooBar, some_condition) {
if (some_condition) {
@@ -209,8 +209,8 @@ cond_2: {
cond_3: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
var FooBar;
if (some_condition()) {
@@ -227,8 +227,8 @@ cond_3: {
cond_4: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
var do_something;
if (some_condition()) {
@@ -251,8 +251,8 @@ cond_4: {
cond_5: {
options = {
conditionals: true
};
conditionals: true,
}
input: {
if (some_condition()) {
if (some_other_condition()) {
@@ -279,9 +279,9 @@ cond_5: {
cond_7: {
options = {
conditionals: true,
evaluate : true,
evaluate: true,
side_effects: true,
};
}
input: {
var x, y, z, a, b;
// compress these
@@ -342,8 +342,8 @@ cond_7: {
cond_7_1: {
options = {
conditionals: true,
evaluate : true
};
evaluate: true,
}
input: {
var x;
// access to global should be assumed to have side effects
@@ -361,10 +361,10 @@ cond_7_1: {
cond_8: {
options = {
booleans: false,
conditionals: true,
evaluate : true,
booleans : false
};
evaluate: true,
}
input: {
var a;
// compress these
@@ -445,10 +445,10 @@ cond_8: {
cond_8b: {
options = {
booleans: true,
conditionals: true,
evaluate : true,
booleans : true
};
evaluate: true,
}
input: {
var a;
// compress these
@@ -528,10 +528,10 @@ cond_8b: {
cond_8c: {
options = {
booleans: false,
conditionals: true,
evaluate : false,
booleans : false
};
evaluate: false,
}
input: {
var a;
// compress these
@@ -647,9 +647,21 @@ cond_9: {
ternary_boolean_consequent: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() { return a == b ? true : x; }
@@ -675,9 +687,21 @@ ternary_boolean_consequent: {
ternary_boolean_alternative: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() { return a == b ? x : true; }
@@ -778,11 +802,11 @@ trivial_boolean_ternary_expressions : {
issue_1154: {
options = {
booleans: true,
conditionals: true,
evaluate : true,
booleans : true,
evaluate: true,
side_effects: true,
};
}
input: {
function f1(x) { return x ? -1 : -1; }
function f2(x) { return x ? +2 : +2; }
@@ -818,7 +842,7 @@ issue_1154: {
no_evaluate: {
options = {
conditionals: true,
evaluate : false,
evaluate: false,
side_effects: true,
}
input: {

View File

@@ -1,7 +1,7 @@
dead_code_1: {
options = {
dead_code: true
};
dead_code: true,
}
input: {
function f() {
a();
@@ -25,8 +25,8 @@ dead_code_1: {
dead_code_2_should_warn: {
options = {
dead_code: true
};
dead_code: true,
}
input: {
function f() {
g();
@@ -64,13 +64,13 @@ dead_code_2_should_warn: {
dead_code_constant_boolean_should_warn_more: {
options = {
dead_code : true,
loops : true,
booleans : true,
conditionals : true,
evaluate : true,
side_effects : true,
};
booleans: true,
conditionals: true,
dead_code: true,
evaluate: true,
loops: true,
side_effects: true,
}
input: {
while (!((foo && bar) || (x + "0"))) {
console.log("unreachable");

View File

@@ -1,7 +1,7 @@
keep_debugger: {
options = {
drop_debugger: false
};
drop_debugger: false,
}
input: {
debugger;
}
@@ -12,8 +12,8 @@ keep_debugger: {
drop_debugger: {
options = {
drop_debugger: true
};
drop_debugger: true,
}
input: {
debugger;
if (foo) debugger;

View File

@@ -1,5 +1,5 @@
drop_console_1: {
options = {};
options = {}
input: {
console.log('foo');
console.log.apply(console, arguments);
@@ -11,7 +11,9 @@ drop_console_1: {
}
drop_console_2: {
options = { drop_console: true };
options = {
drop_console: true,
}
input: {
console.log('foo');
console.log.apply(console, arguments);

View File

@@ -1,5 +1,8 @@
unused_funarg_1: {
options = { unused: true, keep_fargs: false };
options = {
keep_fargs: false,
unused: true,
}
input: {
function f(a, b, c, d, e) {
return a + b;
@@ -13,7 +16,10 @@ unused_funarg_1: {
}
unused_funarg_2: {
options = { unused: true, keep_fargs: false };
options = {
keep_fargs: false,
unused: true,
}
input: {
function f(a, b, c, d, e) {
return a + c;
@@ -27,7 +33,9 @@ unused_funarg_2: {
}
unused_nested_function: {
options = { unused: true };
options = {
unused: true,
}
input: {
function f(x, y) {
function g() {
@@ -44,7 +52,9 @@ unused_nested_function: {
}
unused_circular_references_1: {
options = { unused: true };
options = {
unused: true,
}
input: {
function f(x, y) {
// circular reference
@@ -65,7 +75,9 @@ unused_circular_references_1: {
}
unused_circular_references_2: {
options = { unused: true };
options = {
unused: true,
}
input: {
function f(x, y) {
var foo = 1, bar = baz, baz = foo + bar, qwe = moo();
@@ -81,7 +93,9 @@ unused_circular_references_2: {
}
unused_circular_references_3: {
options = { unused: true };
options = {
unused: true,
}
input: {
function f(x, y) {
var g = function() { return h() };
@@ -97,7 +111,9 @@ unused_circular_references_3: {
}
unused_keep_setter_arg: {
options = { unused: true };
options = {
unused: true,
}
input: {
var x = {
_foo: null,
@@ -121,7 +137,9 @@ unused_keep_setter_arg: {
}
unused_var_in_catch: {
options = { unused: true };
options = {
unused: true,
}
input: {
function foo() {
try {
@@ -141,7 +159,9 @@ unused_var_in_catch: {
}
used_var_in_catch: {
options = { unused: true };
options = {
unused: true,
}
input: {
function foo() {
try {
@@ -165,7 +185,11 @@ used_var_in_catch: {
}
keep_fnames: {
options = { unused: true, keep_fnames: true, unsafe: true };
options = {
keep_fnames: true,
unsafe: true,
unused: true,
}
input: {
function foo() {
return function bar(baz) {};
@@ -367,7 +391,7 @@ drop_toplevel_vars_fargs: {
drop_toplevel_all: {
options = {
toplevel: true,
unused: true
unused: true,
}
input: {
var a, b = 1, c = g;
@@ -418,7 +442,11 @@ drop_toplevel_retain: {
drop_toplevel_retain_array: {
options = {
top_retain: [ "f", "a", "o" ],
top_retain: [
"f",
"a",
"o"
],
unused: true,
}
input: {
@@ -476,8 +504,8 @@ drop_toplevel_retain_regex: {
drop_toplevel_all_retain: {
options = {
toplevel: true,
top_retain: "f,a,o",
toplevel: true,
unused: true,
}
input: {
@@ -506,8 +534,8 @@ drop_toplevel_all_retain: {
drop_toplevel_funcs_retain: {
options = {
toplevel: "funcs",
top_retain: "f,a,o",
toplevel: "funcs",
unused: true,
}
input: {
@@ -537,8 +565,8 @@ drop_toplevel_funcs_retain: {
drop_toplevel_vars_retain: {
options = {
toplevel: "vars",
top_retain: "f,a,o",
toplevel: "vars",
unused: true,
}
input: {
@@ -1377,9 +1405,9 @@ issue_2516_1: {
issue_2516_2: {
options = {
collapse_vars: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
passes: 2,
unused: true,
}
input: {
@@ -1814,3 +1842,143 @@ issue_2995: {
}
expect_stdout: "PASS"
}
issue_3146_1: {
options = {
collapse_vars: true,
unused: true,
}
input: {
(function(f) {
f("g()");
})(function(a) {
eval(a);
function g(b) {
if (!b) b = "PASS";
console.log(b);
}
});
}
expect: {
(function(f) {
f("g()");
})(function(a) {
eval(a);
function g(b) {
if (!b) b = "PASS";
console.log(b);
}
});
}
expect_stdout: "PASS"
}
issue_3146_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function(f) {
f("g()");
})(function(a) {
eval(a);
function g(b) {
if (!b) b = "PASS";
console.log(b);
}
});
}
expect: {
(function(f) {
f("g()");
})(function(a) {
eval(a);
function g(b) {
if (!b) b = "PASS";
console.log(b);
}
});
}
expect_stdout: "PASS"
}
issue_3146_3: {
options = {
collapse_vars: true,
unused: true,
}
input: {
var g = "PASS";
(function(f) {
var g = "FAIL";
f("console.log(g)", g[g]);
})(function(a) {
eval(a);
});
}
expect: {
var g = "PASS";
(function(f) {
var g = "FAIL";
f("console.log(g)", g[g]);
})(function(a) {
eval(a);
});
}
expect_stdout: "PASS"
}
issue_3146_4: {
options = {
reduce_vars: true,
unused: true,
}
input: {
var g = "PASS";
(function(f) {
var g = "FAIL";
f("console.log(g)", g[g]);
})(function(a) {
eval(a);
});
}
expect: {
var g = "PASS";
(function(f) {
var g = "FAIL";
f("console.log(g)", g[g]);
})(function(a) {
eval(a);
});
}
expect_stdout: "PASS"
}
issue_3192: {
options = {
unused: true,
}
input: {
(function(a) {
console.log(a = "foo", arguments[0]);
})("bar");
(function(a) {
"use strict";
console.log(a = "foo", arguments[0]);
})("bar");
}
expect: {
(function(a) {
console.log(a = "foo", arguments[0]);
})("bar");
(function(a) {
"use strict";
console.log("foo", arguments[0]);
})("bar");
}
expect_stdout: [
"foo foo",
"foo bar",
]
}

View File

@@ -186,7 +186,9 @@ unary_prefix: {
}
negative_zero: {
options = { evaluate: true }
options = {
evaluate: true,
}
input: {
console.log(
-"",
@@ -207,7 +209,9 @@ negative_zero: {
}
positive_zero: {
options = { evaluate: true }
options = {
evaluate: true,
}
input: {
console.log(
+"",
@@ -229,8 +233,8 @@ positive_zero: {
unsafe_constant: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -421,8 +425,8 @@ prop_function: {
unsafe_integer_key: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -449,8 +453,8 @@ unsafe_integer_key: {
unsafe_integer_key_complex: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -477,8 +481,8 @@ unsafe_integer_key_complex: {
unsafe_float_key: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -505,8 +509,8 @@ unsafe_float_key: {
unsafe_float_key_complex: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -533,8 +537,8 @@ unsafe_float_key_complex: {
unsafe_array: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -569,8 +573,8 @@ unsafe_array: {
unsafe_string: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -597,8 +601,8 @@ unsafe_string: {
unsafe_array_bad_index: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -619,8 +623,8 @@ unsafe_array_bad_index: {
unsafe_string_bad_index: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -754,8 +758,8 @@ in_boolean_context: {
unsafe_charAt: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -782,8 +786,8 @@ unsafe_charAt: {
unsafe_charAt_bad_index: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -804,8 +808,8 @@ unsafe_charAt_bad_index: {
unsafe_charAt_noop: {
options = {
evaluate : true,
unsafe : true
evaluate: true,
unsafe: true,
}
input: {
console.log(
@@ -1195,7 +1199,7 @@ issue_2231_1: {
}
expect_stdout: true
expect_warnings: [
"WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1191,20]",
"WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1195,20]",
]
}
@@ -1212,7 +1216,7 @@ issue_2231_2: {
}
expect_stdout: true
expect_warnings: [
"WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1208,20]",
"WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1212,20]",
]
}
@@ -1350,14 +1354,14 @@ issue_2535_3: {
}
expect_stdout: true
expect_warnings: [
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1336,20]",
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1337,20]",
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1338,20]",
"WARN: Condition left of && always false [test/compress/evaluate.js:1338,20]",
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1339,20]",
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1340,20]",
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1341,20]",
"WARN: Condition left of || always true [test/compress/evaluate.js:1341,20]",
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1340,20]",
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1341,20]",
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1342,20]",
"WARN: Condition left of && always false [test/compress/evaluate.js:1342,20]",
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1343,20]",
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1344,20]",
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1345,20]",
"WARN: Condition left of || always true [test/compress/evaluate.js:1345,20]",
]
}

View File

@@ -9,20 +9,20 @@ non_ascii_function_identifier_name: {
iifes_returning_constants_keep_fargs_true: {
options = {
keep_fargs : true,
side_effects : true,
evaluate : true,
unused : true,
dead_code : true,
conditionals : true,
comparisons : true,
booleans : true,
if_return : true,
join_vars : true,
reduce_funcs : true,
reduce_vars : true,
collapse_vars : true,
inline : true,
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
inline: true,
join_vars: true,
keep_fargs: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function(){ return -1.23; }());
@@ -46,20 +46,20 @@ iifes_returning_constants_keep_fargs_true: {
iifes_returning_constants_keep_fargs_false: {
options = {
keep_fargs : false,
side_effects : true,
evaluate : true,
unused : true,
dead_code : true,
conditionals : true,
comparisons : true,
booleans : true,
if_return : true,
join_vars : true,
reduce_funcs : true,
reduce_vars : true,
collapse_vars : true,
inline : true,
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
inline: true,
join_vars: true,
keep_fargs: false,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function(){ return -1.23; }());
@@ -1175,8 +1175,8 @@ issue_2620_3: {
issue_2620_4: {
rename = true,
options = {
evaluate: true,
dead_code: true,
evaluate: true,
inline: true,
passes: 2,
reduce_vars: true,
@@ -1533,7 +1533,7 @@ issue_2663_3: {
unused: true,
}
input: {
(function () {
(function() {
var outputs = [
{ type: 0, target: null, eventName: "ngSubmit", propName: null },
{ type: 0, target: null, eventName: "submit", propName: null },
@@ -1550,11 +1550,11 @@ issue_2663_3: {
return handlers;
}
function renderEventHandlerClosure(eventName) {
return function () {
return function() {
return console.log(eventName);
};
}
listenToElementOutputs(outputs).forEach(function (handler) {
listenToElementOutputs(outputs).forEach(function(handler) {
return handler()
});
})();
@@ -1634,7 +1634,7 @@ loop_init_arg: {
}
input: {
var a = "PASS";
for (var k in "12") (function (b) {
for (var k in "12") (function(b) {
(b >>= 1) && (a = "FAIL"), b = 2;
})();
console.log(a);
@@ -2025,6 +2025,7 @@ deduplicate_parenthesis: {
drop_lone_use_strict: {
options = {
directives: true,
side_effects: true,
}
input: {
@@ -2052,6 +2053,27 @@ drop_lone_use_strict: {
}
}
issue_3166: {
options = {
directives: true,
}
input: {
"foo";
"use strict";
function f() {
"use strict";
"bar";
"use asm";
}
}
expect: {
"use strict";
function f() {
"use asm";
}
}
}
issue_3016_1: {
options = {
inline: true,

View File

@@ -2,7 +2,7 @@ must_replace: {
options = {
global_defs: {
D: "foo bar",
}
},
}
input: {
console.log(D);
@@ -141,9 +141,9 @@ mixed: {
console.log(CONFIG);
}
expect_warnings: [
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:128,22]',
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:130,8]',
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]",
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:128,22]",
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:130,8]",
]
}

View File

@@ -1,8 +1,8 @@
issue_2377_1: {
options = {
evaluate: true,
inline: true,
hoist_props: true,
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -33,8 +33,8 @@ issue_2377_1: {
issue_2377_2: {
options = {
evaluate: true,
inline: true,
hoist_props: true,
inline: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -64,8 +64,8 @@ issue_2377_2: {
issue_2377_3: {
options = {
evaluate: true,
inline: true,
hoist_props: true,
inline: true,
passes: 4,
reduce_funcs: true,
reduce_vars: true,
@@ -416,7 +416,10 @@ issue_2473_1: {
options = {
hoist_props: false,
reduce_vars: true,
top_retain: [ "x", "y" ],
top_retain: [
"x",
"y"
],
toplevel: true,
unused: true,
}
@@ -435,7 +438,10 @@ issue_2473_2: {
options = {
hoist_props: true,
reduce_vars: true,
top_retain: [ "x", "y" ],
top_retain: [
"x",
"y"
],
toplevel: true,
unused: true,
}
@@ -746,9 +752,9 @@ issue_3046: {
issue_3071_1: {
options = {
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
hoist_props: true,
passes: 3,
reduce_vars: true,
sequences: true,
@@ -773,9 +779,9 @@ issue_3071_1: {
issue_3071_2: {
options = {
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
hoist_props: true,
passes: 3,
reduce_vars: true,
sequences: true,
@@ -800,9 +806,9 @@ issue_3071_2: {
issue_3071_2_toplevel: {
options = {
evaluate: true,
hoist_props: true,
inline: true,
join_vars: true,
hoist_props: true,
passes: 3,
reduce_vars: true,
sequences: true,

View File

@@ -187,9 +187,9 @@ dont_screw_try_catch_undefined: {
reduce_vars: {
options = {
evaluate: true,
ie8: true,
reduce_funcs: true,
reduce_vars: true,
ie8: true,
unused: true,
}
mangle = {
@@ -420,8 +420,8 @@ issue_24_2: {
})();
}
expect: {
(function(n) {
console.log(typeof function o(){} === typeof n ? "FAIL" : "PASS");
(function(o) {
console.log(typeof function n(){} === typeof o ? "FAIL" : "PASS");
})();
}
expect_stdout: "PASS"
@@ -457,9 +457,29 @@ issue_2976_2: {
}());
}
expect: {
console.log(function n() {
var o;
return o === n ? "FAIL" : "PASS";
console.log(function f() {
var n;
return n === f ? "FAIL" : "PASS";
}());
}
expect_stdout: "PASS"
}
issue_2976_3: {
mangle = {
ie8: true,
toplevel: true,
}
input: {
console.log(function f() {
var a;
return a === f ? "FAIL" : "PASS";
}());
}
expect: {
console.log(function o() {
var n;
return n === o ? "FAIL" : "PASS";
}());
}
expect_stdout: "PASS"
@@ -538,3 +558,111 @@ issue_3035_ie8: {
}
expect_stdout: "PASS"
}
issue_3197_1: {
options = {
ie8: false,
inline: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
mangle = {
ie8: false,
}
input: {
var window = {};
!function() {
function Foo() {
console.log(this instanceof Foo);
}
window.Foo = Foo;
}();
new window.Foo();
}
expect: {
var window = {};
window.Foo = function o() {
console.log(this instanceof o);
};
new window.Foo();
}
expect_stdout: "true"
}
issue_3197_1_ie8: {
options = {
ie8: true,
inline: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
mangle = {
ie8: true,
}
input: {
var window = {};
!function() {
function Foo() {
console.log(this instanceof Foo);
}
window.Foo = Foo;
}();
new window.Foo();
}
expect: {
var window = {};
window.Foo = function Foo() {
console.log(this instanceof Foo);
};
new window.Foo();
}
expect_stdout: "true"
}
issue_3197_2: {
mangle = {
ie8: false,
}
input: {
(function(a) {
var f = function f() {
console.log(this instanceof f);
};
new f(a);
})();
}
expect: {
(function(n) {
var o = function n() {
console.log(this instanceof n);
};
new o(n);
})();
}
expect_stdout: "true"
}
issue_3197_2_ie8: {
mangle = {
ie8: true,
}
input: {
(function(a) {
var f = function f() {
console.log(this instanceof f);
};
new f(a);
})();
}
expect: {
(function(n) {
var o = function o() {
console.log(this instanceof o);
};
new o(n);
})();
}
expect_stdout: "true"
}

View File

@@ -1,14 +1,14 @@
if_return_1: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f(x) {
@@ -24,15 +24,15 @@ if_return_1: {
if_return_2: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f(x, y) {
@@ -49,15 +49,15 @@ if_return_2: {
if_return_3: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f(x) {
@@ -75,15 +75,15 @@ if_return_3: {
if_return_4: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f(x, y) {
@@ -100,15 +100,15 @@ if_return_4: {
if_return_5: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f() {
@@ -126,15 +126,15 @@ if_return_5: {
if_return_6: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f(x) {
@@ -150,15 +150,15 @@ if_return_6: {
if_return_7: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f(x) {
@@ -176,10 +176,10 @@ if_return_7: {
if_return_8: {
options = {
if_return: true,
sequences: true,
conditionals: true,
side_effects : true,
conditionals: true,
if_return: true,
sequences: true,
side_effects: true,
}
input: {
function f(e) {
@@ -220,15 +220,15 @@ if_return_8: {
issue_1089: {
options = {
if_return : true,
sequences : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
unused : true,
side_effects : true,
dead_code : true,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
if_return: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function x() {
@@ -251,9 +251,9 @@ issue_1089: {
issue_1437: {
options = {
if_return : true,
sequences : true,
conditionals : false
conditionals: false,
if_return: true,
sequences: true,
}
input: {
function x() {
@@ -281,9 +281,9 @@ issue_1437: {
issue_1437_conditionals: {
options = {
conditionals : true,
if_return : true,
sequences : true
conditionals: true,
if_return: true,
sequences: true,
}
input: {
function x() {

View File

@@ -1,8 +1,17 @@
non_hoisted_function_after_return: {
options = {
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, side_effects: true
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
function foo(x) {
@@ -27,19 +36,30 @@ non_hoisted_function_after_return: {
}
}
expect_warnings: [
'WARN: Dropping unreachable code [test/compress/issue-1034.js:11,16]',
"WARN: Dropping unreachable code [test/compress/issue-1034.js:14,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:17,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:18,21]"
"WARN: Dropping unreachable code [test/compress/issue-1034.js:20,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:23,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:26,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:27,21]"
]
}
non_hoisted_function_after_return_2a: {
options = {
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, side_effects: true,
collapse_vars: false, passes: 2, warnings: "verbose"
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
passes: 2,
side_effects: true,
unused: true,
warnings: "verbose",
}
input: {
function foo(x) {
@@ -65,28 +85,37 @@ non_hoisted_function_after_return_2a: {
}
}
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:48,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:48,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:51,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:68,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:68,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:71,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:71,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:68,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:75,21]",
"WARN: pass 0: last_count: Infinity, count: 37",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:73,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:73,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:76,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:71,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:73,16]",
"WARN: pass 1: last_count: 37, count: 18",
]
}
non_hoisted_function_after_return_2b: {
options = {
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, side_effects: true,
collapse_vars: false
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
function foo(x) {
@@ -111,19 +140,28 @@ non_hoisted_function_after_return_2b: {
}
expect_warnings: [
// duplicate warnings no longer emitted
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:99,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:99,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:103,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:126,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:126,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:128,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:128,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:132,12]",
]
}
non_hoisted_function_after_return_strict: {
options = {
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, side_effects: true
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
"use strict";
@@ -153,19 +191,30 @@ non_hoisted_function_after_return_strict: {
}
expect_stdout: "8 7"
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:133,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:136,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:139,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:140,21]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:171,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:174,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:177,12]",
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:178,21]",
]
}
non_hoisted_function_after_return_2a_strict: {
options = {
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, side_effects: true,
collapse_vars: false, passes: 2, warnings: "verbose"
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
passes: 2,
side_effects: true,
unused: true,
warnings: "verbose",
}
input: {
"use strict";
@@ -196,28 +245,37 @@ non_hoisted_function_after_return_2a_strict: {
}
expect_stdout: "5 6"
expect_warnings: [
"WARN: Dropping unreachable code [test/compress/issue-1034.js:175,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:175,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:175,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:182,21]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:224,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:224,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:227,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:227,16]",
"WARN: Dropping unused variable a [test/compress/issue-1034.js:224,20]",
"WARN: Dropping unused function nope [test/compress/issue-1034.js:231,21]",
"WARN: pass 0: last_count: Infinity, count: 48",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:180,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:180,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:183,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:178,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:180,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:229,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:229,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:232,12]",
"WARN: Dropping unused variable b [test/compress/issue-1034.js:227,20]",
"WARN: Dropping unused variable c [test/compress/issue-1034.js:229,16]",
"WARN: pass 1: last_count: 48, count: 29",
]
}
non_hoisted_function_after_return_2b_strict: {
options = {
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
if_return: true, join_vars: true, side_effects: true,
collapse_vars: false
booleans: true,
collapse_vars: false,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: false,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
"use strict";
@@ -247,10 +305,10 @@ non_hoisted_function_after_return_2b_strict: {
expect_stdout: "5 6"
expect_warnings: [
// duplicate warnings no longer emitted
"WARN: Dropping unreachable code [test/compress/issue-1034.js:229,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:229,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:231,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:235,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:287,16]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:287,16]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:289,12]",
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:289,12]",
"WARN: Dropping unreachable code [test/compress/issue-1034.js:293,12]",
]
}

View File

@@ -3,7 +3,7 @@ const_pragma: {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
};
}
input: {
/** @const */ var goog = goog || {};
@@ -19,7 +19,7 @@ not_const: {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
};
}
input: {
var goog = goog || {};

View File

@@ -1,6 +1,6 @@
with_in_global_scope: {
options = {
unused: true
unused: true,
}
input: {
var o = 42;
@@ -18,7 +18,7 @@ with_in_global_scope: {
}
with_in_function_scope: {
options = {
unused: true
unused: true,
}
input: {
function foo() {
@@ -40,7 +40,7 @@ with_in_function_scope: {
}
compress_with_with_in_other_scope: {
options = {
unused: true
unused: true,
}
input: {
function foo() {
@@ -69,7 +69,7 @@ compress_with_with_in_other_scope: {
}
with_using_existing_variable_outside_scope: {
options = {
unused: true
unused: true,
}
input: {
function f() {
@@ -99,7 +99,7 @@ with_using_existing_variable_outside_scope: {
}
check_drop_unused_in_peer_function: {
options = {
unused: true
unused: true,
}
input: {
function outer() {
@@ -148,7 +148,7 @@ check_drop_unused_in_peer_function: {
Infinity_not_in_with_scope: {
options = {
unused: true
unused: true,
}
input: {
var o = { Infinity: 'oInfinity' };
@@ -164,7 +164,7 @@ Infinity_not_in_with_scope: {
Infinity_in_with_scope: {
options = {
unused: true
unused: true,
}
input: {
var o = { Infinity: 'oInfinity' };
@@ -180,19 +180,19 @@ Infinity_in_with_scope: {
assorted_Infinity_NaN_undefined_in_with_scope: {
options = {
unused: true,
evaluate: true,
dead_code: true,
conditionals: true,
comparisons: true,
booleans: true,
hoist_funs: true,
keep_fargs: true,
if_return: true,
join_vars: true,
side_effects: true,
sequences: false,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
keep_infinity: false,
sequences: false,
side_effects: true,
unused: true,
}
input: {
var f = console.log;
@@ -242,19 +242,19 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
options = {
unused: true,
evaluate: true,
dead_code: true,
conditionals: true,
comparisons: true,
booleans: true,
hoist_funs: true,
keep_fargs: true,
if_return: true,
join_vars: true,
side_effects: true,
sequences: false,
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
keep_infinity: true,
sequences: false,
side_effects: true,
unused: true,
}
input: {
var f = console.log;

View File

@@ -1,11 +1,15 @@
keep_name_of_getter: {
options = { unused: true };
options = {
unused: true,
}
input: { a = { get foo () {} } }
expect: { a = { get foo () {} } }
}
keep_name_of_setter: {
options = { unused: true };
options = {
unused: true,
}
input: { a = { set foo () {} } }
expect: { a = { set foo () {} } }
}

View File

@@ -1,7 +1,7 @@
mangle_keep_fnames_false: {
options = {
keep_fnames : true,
keep_fargs : true,
keep_fargs: true,
keep_fnames: true,
}
mangle = {
keep_fnames : false,
@@ -26,8 +26,8 @@ mangle_keep_fnames_false: {
mangle_keep_fnames_true: {
options = {
keep_fnames : true,
keep_fargs : true,
keep_fargs: true,
keep_fnames: true,
}
mangle = {
keep_fnames : true,

View File

@@ -1,14 +1,14 @@
pure_function_calls: {
options = {
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
negate_iife : true,
booleans: true,
comparisons: true,
conditionals: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: true,
side_effects: true,
unused: true,
}
input: {
// pure top-level IIFE will be dropped
@@ -60,16 +60,16 @@ pure_function_calls: {
pure_function_calls_toplevel: {
options = {
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
negate_iife : true,
toplevel : true,
booleans: true,
comparisons: true,
conditionals: true,
evaluate: true,
if_return: true,
join_vars: true,
negate_iife: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
// pure top-level IIFE will be dropped

View File

@@ -1,16 +1,16 @@
string_plus_optimization: {
options = {
side_effects : true,
evaluate : true,
conditionals : true,
comparisons : true,
dead_code : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
hoist_funs : true,
};
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
side_effects: true,
unused: true,
}
input: {
function foo(anything) {
function throwing_function() {

View File

@@ -15,7 +15,7 @@
tranformation_sort_order_equal: {
options = {
comparisons: true,
};
}
input: { (a = parseInt('100')) == a }
expect: { (a = parseInt('100')) == a }
@@ -24,7 +24,7 @@ tranformation_sort_order_equal: {
tranformation_sort_order_unequal: {
options = {
comparisons: true,
};
}
input: { (a = parseInt('100')) != a }
expect: { (a = parseInt('100')) != a }
@@ -33,7 +33,7 @@ tranformation_sort_order_unequal: {
tranformation_sort_order_lesser_or_equal: {
options = {
comparisons: true,
};
}
input: { (a = parseInt('100')) <= a }
expect: { (a = parseInt('100')) <= a }
@@ -41,7 +41,7 @@ tranformation_sort_order_lesser_or_equal: {
tranformation_sort_order_greater_or_equal: {
options = {
comparisons: true,
};
}
input: { (a = parseInt('100')) >= a }
expect: { (a = parseInt('100')) >= a }

View File

@@ -1,6 +1,6 @@
level_zero: {
options = {
keep_fnames: true
keep_fnames: true,
}
mangle = {
keep_fnames: true
@@ -29,7 +29,7 @@ level_zero: {
level_one: {
options = {
keep_fnames: true
keep_fnames: true,
}
mangle = {
keep_fnames: true
@@ -58,7 +58,7 @@ level_one: {
level_two: {
options = {
keep_fnames: true
keep_fnames: true,
}
mangle = {
keep_fnames: true
@@ -97,7 +97,7 @@ level_two: {
level_three: {
options = {
keep_fnames: true
keep_fnames: true,
}
mangle = {
keep_fnames: true

View File

@@ -22,17 +22,17 @@ else_with_empty_statement: {
conditional_false_stray_else_in_loop: {
options = {
evaluate : true,
comparisons : true,
booleans : true,
unused : true,
loops : true,
side_effects : true,
dead_code : true,
hoist_vars : true,
join_vars : true,
if_return : true,
conditionals : false,
booleans: true,
comparisons: true,
conditionals: false,
dead_code: true,
evaluate: true,
hoist_vars: true,
if_return: true,
join_vars: true,
loops: true,
side_effects: true,
unused: true,
}
input: {
for (var i = 1; i <= 4; ++i) {

View File

@@ -125,8 +125,8 @@ label_do: {
label_while: {
options = {
evaluate: true,
dead_code: true,
evaluate: true,
loops: true,
}
input: {

View File

@@ -1,6 +1,8 @@
do_not_update_lhs: {
options = {
global_defs: { DEBUG: 0 }
global_defs: {
DEBUG: 0,
},
}
input: {
DEBUG++;
@@ -16,7 +18,9 @@ do_not_update_lhs: {
do_update_rhs: {
options = {
global_defs: { DEBUG: 0 }
global_defs: {
DEBUG: 0,
},
}
input: {
MY_DEBUG = DEBUG;
@@ -35,7 +39,7 @@ mixed: {
DEBUG: 0,
ENV: 1,
FOO: 2,
}
},
}
input: {
var ENV = 3;
@@ -60,11 +64,11 @@ mixed: {
x = 0;
}
expect_warnings: [
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:46,8]',
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:47,8]',
"WARN: global_defs ENV redefined [test/compress/issue-208.js:45,12]",
"WARN: global_defs FOO redefined [test/compress/issue-208.js:46,12]",
"WARN: global_defs FOO redefined [test/compress/issue-208.js:48,10]",
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:49,8]",
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:50,8]",
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:51,8]",
]
}

View File

@@ -1,5 +1,7 @@
return_with_no_value_in_if_body: {
options = { conditionals: true };
options = {
conditionals: true,
}
input: {
function foo(bar) {
if (bar) {

View File

@@ -1,5 +1,7 @@
issue_267: {
options = { comparisons: true };
options = {
comparisons: true,
}
input: {
x = a % b / b * c * 2;
x = a % b * 2

View File

@@ -1,5 +1,7 @@
issue_269_1: {
options = {unsafe: true};
options = {
unsafe: true,
}
input: {
f(
String(x),
@@ -20,7 +22,9 @@ issue_269_1: {
}
issue_269_dangers: {
options = {unsafe: true};
options = {
unsafe: true,
}
input: {
f(
String(x, x),
@@ -34,7 +38,9 @@ issue_269_dangers: {
}
issue_269_in_scope: {
options = {unsafe: true};
options = {
unsafe: true,
}
input: {
var String, Number, Boolean;
f(
@@ -50,7 +56,9 @@ issue_269_in_scope: {
}
strings_concat: {
options = {unsafe: true};
options = {
unsafe: true,
}
input: {
f(
String(x + 'str'),
@@ -67,9 +75,9 @@ strings_concat: {
regexp: {
options = {
evaluate: true,
unsafe: true,
}
evaluate: true,
unsafe: true,
}
input: {
RegExp("foo");
RegExp("bar", "ig");
@@ -85,6 +93,6 @@ regexp: {
RegExp("should", "fail");
}
expect_warnings: [
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:78,2]',
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:86,2]',
]
}

View File

@@ -186,7 +186,7 @@ negate_iife_5_off: {
inline: true,
negate_iife: false,
sequences: true,
};
}
input: {
if ((function(){ return t })()) {
foo(true);
@@ -245,7 +245,7 @@ negate_iife_issue_1073: {
reduce_vars: true,
sequences: true,
unused: true,
};
}
input: {
new (function(a) {
return function Foo() {
@@ -273,7 +273,7 @@ issue_1288_side_effects: {
reduce_vars: true,
side_effects: true,
unused: true,
};
}
input: {
if (w) ;
else {
@@ -399,7 +399,7 @@ wrap_iife_in_expression: {
wrap_iife: true,
}
input: {
foo = (function () {
foo = (function() {
return bar();
})();
}

View File

@@ -1,5 +1,7 @@
issue_44_valid_ast_1: {
options = { unused: true };
options = {
unused: true,
}
input: {
function a(b) {
for (var i = 0, e = b.qoo(); ; i++) {}
@@ -14,7 +16,9 @@ issue_44_valid_ast_1: {
}
issue_44_valid_ast_2: {
options = { unused: true };
options = {
unused: true,
}
input: {
function a(b) {
if (foo) for (var i = 0, e = b.qoo(); ; i++) {}

View File

@@ -1,8 +1,8 @@
keep_continue: {
options = {
dead_code: true,
evaluate: true
};
evaluate: true,
}
input: {
while (a) {
if (b) {

View File

@@ -1,5 +1,5 @@
NaN_and_Infinity_must_have_parens: {
options = {};
options = {}
input: {
Infinity.toString();
NaN.toString();
@@ -11,7 +11,7 @@ NaN_and_Infinity_must_have_parens: {
}
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
options = {};
options = {}
input: {
var Infinity, NaN;
Infinity.toString();

View File

@@ -1,8 +1,8 @@
issue_611: {
options = {
sequences: true,
side_effects: true
};
sequences: true,
side_effects: true,
}
input: {
define(function() {
function fn() {}

View File

@@ -1,9 +1,9 @@
wrongly_optimized: {
options = {
conditionals: true,
booleans: true,
evaluate: true
};
conditionals: true,
evaluate: true,
}
input: {
function func() {
foo();

View File

@@ -28,12 +28,12 @@ cond_5: {
dead_code_const_annotation_regex: {
options = {
booleans : true,
conditionals : true,
dead_code : true,
evaluate : true,
expression : true,
loops : true,
booleans: true,
conditionals: true,
dead_code: true,
evaluate: true,
expression: true,
loops: true,
}
input: {
var unused;
@@ -82,8 +82,8 @@ drop_value: {
wrongly_optimized: {
options = {
conditionals: true,
booleans: true,
conditionals: true,
evaluate: true,
expression: true,
}
@@ -195,7 +195,7 @@ negate_iife_5_off: {
expression: true,
negate_iife: false,
sequences: true,
};
}
input: {
if ((function(){ return t })()) {
foo(true);
@@ -248,7 +248,9 @@ issue_1254_negate_iife_nested: {
conditional: {
options = {
expression: true,
pure_funcs: [ "pure" ],
pure_funcs: [
"pure"
],
side_effects: true,
}
input: {

View File

@@ -1,7 +1,7 @@
negate_booleans_1: {
options = {
comparisons: true
};
comparisons: true,
}
input: {
var a = !a || !b || !c || !d || !e || !f;
}
@@ -12,8 +12,8 @@ negate_booleans_1: {
negate_booleans_2: {
options = {
comparisons: true
};
comparisons: true,
}
input: {
var match = !x && // should not touch this one
(!z || c) &&

View File

@@ -1,11 +1,31 @@
remove_redundant_sequence_items: {
options = { side_effects: true };
remove_sequence: {
options = {
side_effects: true,
}
input: {
(0, 1, eval)();
(0, 1, logThis)();
(0, 1, _decorators.logThis)();
}
expect: {
eval();
logThis();
(0, _decorators.logThis)();
}
}
remove_redundant_sequence_items: {
options = {
side_effects: true,
}
input: {
"use strict";
(0, 1, eval)();
(0, 1, logThis)();
(0, 1, _decorators.logThis)();
}
expect: {
"use strict";
(0, eval)();
logThis();
(0, _decorators.logThis)();
@@ -13,13 +33,17 @@ remove_redundant_sequence_items: {
}
dont_remove_this_binding_sequence: {
options = { side_effects: true };
options = {
side_effects: true,
}
input: {
"use strict";
(0, eval)();
(0, logThis)();
(0, _decorators.logThis)();
}
expect: {
"use strict";
(0, eval)();
logThis();
(0, _decorators.logThis)();

View File

@@ -2,25 +2,25 @@ dont_mangle_arguments: {
mangle = {
};
options = {
sequences : true,
properties : true,
dead_code : true,
drop_debugger : true,
conditionals : true,
comparisons : true,
evaluate : true,
booleans : true,
loops : true,
unused : true,
hoist_funs : true,
keep_fargs : true,
keep_fnames : false,
hoist_vars : true,
if_return : true,
join_vars : true,
side_effects : true,
negate_iife : false
};
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
drop_debugger: true,
evaluate: true,
hoist_funs: true,
hoist_vars: true,
if_return: true,
join_vars: true,
keep_fargs: true,
keep_fnames: false,
loops: true,
negate_iife: false,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
(function(){
var arguments = arguments, not_arguments = 9;

View File

@@ -1,8 +1,8 @@
keep_var_for_in: {
options = {
hoist_vars: true,
unused: true
};
unused: true,
}
input: {
(function(obj){
var foo = 5;

View File

@@ -3,8 +3,9 @@ this_binding_conditionals: {
conditionals: true,
evaluate: true,
side_effects: true,
};
}
input: {
"use strict";
(1 && a)();
(0 || a)();
(0 || 1 && a)();
@@ -26,6 +27,7 @@ this_binding_conditionals: {
(1 ? eval : 0)();
}
expect: {
"use strict";
a();
a();
a();
@@ -53,13 +55,15 @@ this_binding_collapse_vars: {
collapse_vars: true,
toplevel: true,
unused: true,
};
}
input: {
"use strict";
var c = a; c();
var d = a.b; d();
var e = eval; e();
}
expect: {
"use strict";
a();
(0, a.b)();
(0, eval)();
@@ -68,32 +72,89 @@ this_binding_collapse_vars: {
this_binding_side_effects: {
options = {
side_effects : true
};
side_effects: true,
}
input: {
(function (foo) {
(function(foo) {
(0, foo)();
(0, foo.bar)();
(0, eval)('console.log(foo);');
(0, eval)("console.log(foo);");
}());
(function (foo) {
(function(foo) {
"use strict";
(0, foo)();
(0, foo.bar)();
(0, eval)("console.log(foo);");
}());
(function(foo) {
var eval = console;
(0, foo)();
(0, foo.bar)();
(0, eval)('console.log(foo);');
(0, eval)("console.log(foo);");
}());
}
expect: {
(function (foo) {
(function(foo) {
foo();
(0, foo.bar)();
(0, eval)('console.log(foo);');
eval("console.log(foo);");
}());
(function (foo) {
(function(foo) {
"use strict";
foo();
(0, foo.bar)();
(0, eval)("console.log(foo);");
}());
(function(foo) {
var eval = console;
foo();
(0, foo.bar)();
(0, eval)('console.log(foo);');
eval("console.log(foo);");
}());
}
}
}
this_binding_sequences: {
options = {
sequences: true,
side_effects: true,
}
input: {
console.log(typeof function() {
return eval("this");
}());
console.log(typeof function() {
"use strict";
return eval("this");
}());
console.log(typeof function() {
return (0, eval)("this");
}());
console.log(typeof function() {
"use strict";
return (0, eval)("this");
}());
}
expect: {
console.log(typeof function() {
return eval("this");
}()),
console.log(typeof function() {
"use strict";
return eval("this");
}()),
console.log(typeof function() {
return eval("this");
}()),
console.log(typeof function() {
"use strict";
return (0, eval)("this");
}());
}
expect_stdout: [
"object",
"undefined",
"object",
"object",
]
}

View File

@@ -1,9 +1,21 @@
eval_collapse_vars: {
options = {
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
};
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: false,
side_effects: true,
unused: true,
}
input: {
function f1() {
var e = 7;
@@ -46,7 +58,10 @@ eval_collapse_vars: {
}
eval_unused: {
options = { unused: true, keep_fargs: false };
options = {
keep_fargs: false,
unused: true,
}
input: {
function f1(a, eval, c, d, e) {
return a('c') + eval;

View File

@@ -1,8 +1,19 @@
issue979_reported: {
options = {
sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
@@ -30,9 +41,20 @@ issue979_reported: {
issue979_test_negated_is_best: {
options = {
sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: true,
properties: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f3() {

View File

@@ -1,5 +1,9 @@
labels_1: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
out: {
if (foo) break out;
@@ -13,7 +17,11 @@ labels_1: {
}
labels_2: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
out: {
if (foo) print("stuff");
@@ -30,7 +38,11 @@ labels_2: {
}
labels_3: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
for (var i = 0; i < 5; ++i) {
if (i < 3) continue;
@@ -45,7 +57,11 @@ labels_3: {
}
labels_4: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
out: for (var i = 0; i < 5; ++i) {
if (i < 3) continue out;
@@ -60,7 +76,11 @@ labels_4: {
}
labels_5: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
// should keep the break-s in the following
input: {
while (foo) {
@@ -92,7 +112,11 @@ labels_6: {
}
labels_7: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
while (foo) {
x();
@@ -109,7 +133,11 @@ labels_7: {
}
labels_8: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
while (foo) {
x();
@@ -127,7 +155,11 @@ labels_8: {
}
labels_9: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
out: while (foo) {
x();
@@ -146,7 +178,11 @@ labels_9: {
}
labels_10: {
options = { if_return: true, conditionals: true, dead_code: true };
options = {
conditionals: true,
dead_code: true,
if_return: true,
}
input: {
out: while (foo) {
x();

View File

@@ -1,5 +1,7 @@
while_becomes_for: {
options = { loops: true };
options = {
loops: true,
}
input: {
while (foo()) bar();
}
@@ -9,7 +11,9 @@ while_becomes_for: {
}
drop_if_break_1: {
options = { loops: true };
options = {
loops: true,
}
input: {
for (;;)
if (foo()) break;
@@ -20,7 +24,9 @@ drop_if_break_1: {
}
drop_if_break_2: {
options = { loops: true };
options = {
loops: true,
}
input: {
for (;bar();)
if (foo()) break;
@@ -31,7 +37,9 @@ drop_if_break_2: {
}
drop_if_break_3: {
options = { loops: true };
options = {
loops: true,
}
input: {
for (;bar();) {
if (foo()) break;
@@ -48,7 +56,10 @@ drop_if_break_3: {
}
drop_if_break_4: {
options = { loops: true, sequences: true };
options = {
loops: true,
sequences: true,
}
input: {
for (;bar();) {
x();
@@ -64,7 +75,9 @@ drop_if_break_4: {
}
drop_if_else_break_1: {
options = { loops: true };
options = {
loops: true,
}
input: {
for (;;) if (foo()) bar(); else break;
}
@@ -74,7 +87,9 @@ drop_if_else_break_1: {
}
drop_if_else_break_2: {
options = { loops: true };
options = {
loops: true,
}
input: {
for (;bar();) {
if (foo()) baz();
@@ -87,7 +102,9 @@ drop_if_else_break_2: {
}
drop_if_else_break_3: {
options = { loops: true };
options = {
loops: true,
}
input: {
for (;bar();) {
if (foo()) baz();
@@ -106,7 +123,10 @@ drop_if_else_break_3: {
}
drop_if_else_break_4: {
options = { loops: true, sequences: true };
options = {
loops: true,
sequences: true,
}
input: {
for (;bar();) {
x();
@@ -123,7 +143,9 @@ drop_if_else_break_4: {
}
parse_do_while_with_semicolon: {
options = { loops: false };
options = {
loops: false,
}
input: {
do {
x();
@@ -135,7 +157,9 @@ parse_do_while_with_semicolon: {
}
parse_do_while_without_semicolon: {
options = { loops: false };
options = {
loops: false,
}
input: {
do {
x();
@@ -153,7 +177,7 @@ evaluate: {
loops: true,
passes: 2,
side_effects: true,
};
}
input: {
while (true) {
a();
@@ -457,7 +481,7 @@ init_side_effects: {
options = {
loops: true,
side_effects: true,
};
}
input: {
for (function() {}(), i = 0; i < 5; i++) console.log(i);
for (function() {}(); i < 10; i++) console.log(i);

View File

@@ -1,7 +1,7 @@
negate_iife_1: {
options = {
negate_iife: true
};
negate_iife: true,
}
input: {
(function(){ stuff() })();
}
@@ -13,7 +13,7 @@ negate_iife_1: {
negate_iife_1_off: {
options = {
negate_iife: false,
};
}
input: {
(function(){ stuff() })();
}
@@ -24,7 +24,7 @@ negate_iife_2: {
options = {
inline: true,
negate_iife: true,
};
}
input: {
(function(){ return {} })().x = 10;
}
@@ -45,9 +45,9 @@ negate_iife_2_side_effects: {
negate_iife_3: {
options = {
conditionals: true,
negate_iife: true,
conditionals: true
};
}
input: {
(function(){ return t })() ? console.log(true) : console.log(false);
}
@@ -88,9 +88,9 @@ negate_iife_3_side_effects: {
negate_iife_3_off: {
options = {
negate_iife: false,
conditionals: true,
};
negate_iife: false,
}
input: {
(function(){ return t })() ? console.log(true) : console.log(false);
}
@@ -117,10 +117,10 @@ negate_iife_3_off_evaluate: {
negate_iife_4: {
options = {
negate_iife: true,
conditionals: true,
sequences: true
};
negate_iife: true,
sequences: true,
}
input: {
(function(){ return t })() ? console.log(true) : console.log(false);
(function(){
@@ -136,11 +136,11 @@ negate_iife_4: {
sequence_off: {
options = {
negate_iife: false,
conditionals: true,
sequences: true,
negate_iife: false,
passes: 2,
};
sequences: true,
}
input: {
function f() {
(function(){ return t })() ? console.log(true) : console.log(false);
@@ -171,10 +171,10 @@ sequence_off: {
negate_iife_5: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
conditionals: true,
};
}
input: {
if ((function(){ return t })()) {
foo(true);
@@ -194,10 +194,10 @@ negate_iife_5: {
negate_iife_5_off: {
options = {
conditionals: true,
negate_iife: false,
sequences: true,
conditionals: true,
};
}
input: {
if ((function(){ return t })()) {
foo(true);
@@ -217,10 +217,10 @@ negate_iife_5_off: {
negate_iife_nested: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
conditionals: true,
};
}
input: {
function Foo(f) {
this.f = f;
@@ -250,10 +250,10 @@ negate_iife_nested: {
negate_iife_nested_off: {
options = {
conditionals: true,
negate_iife: false,
sequences: true,
conditionals: true,
};
}
input: {
function Foo(f) {
this.f = f;
@@ -283,10 +283,10 @@ negate_iife_nested_off: {
negate_iife_issue_1073: {
options = {
conditionals: true,
negate_iife: true,
sequences: true,
conditionals: true,
};
}
input: {
new (function(a) {
return function Foo() {
@@ -356,7 +356,7 @@ issue_1288: {
conditionals: true,
negate_iife: true,
side_effects: false,
};
}
input: {
if (w) ;
else {

View File

@@ -36,7 +36,9 @@ new_statements_3: {
}
new_with_rewritten_true_value: {
options = { booleans: true }
options = {
booleans: true,
}
input: {
new true;
}

View File

@@ -1729,3 +1729,106 @@ issue_869_2: {
}
expect_stdout: "PASS"
}
issue_3188_1: {
options = {
collapse_vars: true,
inline: true,
properties: true,
reduce_vars: true,
side_effects: true,
}
input: {
(function() {
function f() {
console.log(this.p);
}
(function() {
var o = {
p: "PASS",
f: f
};
o.f();
})();
})();
}
expect: {
(function() {
function f() {
console.log(this.p);
}
({
p: "PASS",
f: f
}).f();
var o;
})();
}
expect_stdout: "PASS"
}
issue_3188_2: {
options = {
collapse_vars: true,
inline: true,
properties: true,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
(function() {
var f = function() {
console.log(this.p);
};
function g() {
var o = {
p: "PASS",
f: f
};
o.f();
}
g();
})();
}
expect: {
({
p: "PASS",
f: function() {
console.log(this.p);
}
}).f();
}
expect_stdout: "PASS"
}
issue_3188_3: {
options = {
collapse_vars: true,
inline: true,
properties: true,
reduce_vars: true,
side_effects: true,
}
input: {
(function() {
function f() {
console.log(this[0]);
}
(function() {
var o = ["PASS", f];
o[1]();
})();
})();
}
expect: {
(function() {
function f() {
console.log(this[0]);
}
["PASS", f][1]();
var o;
})();
}
expect_stdout: "PASS"
}

View File

@@ -187,10 +187,10 @@ issue_2110_1: {
options = {
collapse_vars: true,
pure_getters: "strict",
sequences: true,
side_effects: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {

View File

@@ -1,15 +1,15 @@
reduce_vars: {
options = {
conditionals : true,
evaluate : true,
inline : true,
global_defs : {
C : 0
conditionals: true,
evaluate: true,
global_defs: {
C: 0,
},
reduce_funcs : true,
reduce_vars : true,
toplevel : true,
unused : true
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var A = 1;
@@ -63,11 +63,11 @@ reduce_vars: {
modified: {
options = {
conditionals : true,
evaluate : true,
reduce_funcs : true,
reduce_vars : true,
unused : true,
conditionals: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
function f0() {
@@ -184,12 +184,12 @@ modified: {
unsafe_evaluate: {
options = {
evaluate : true,
reduce_funcs : true,
reduce_vars : true,
side_effects : true,
unsafe : true,
unused : true
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unsafe: true,
unused: true,
}
input: {
function f0(){
@@ -344,10 +344,10 @@ unsafe_evaluate_unknown: {
unsafe_evaluate_object_1: {
options = {
evaluate : true,
reduce_funcs : true,
reduce_vars : true,
unsafe : true
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unsafe: true,
}
input: {
function f0(){
@@ -463,10 +463,10 @@ unsafe_evaluate_object_3: {
unsafe_evaluate_array_1: {
options = {
evaluate : true,
reduce_funcs : true,
reduce_vars : true,
unsafe : true
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unsafe: true,
}
input: {
function f0(){
@@ -642,11 +642,11 @@ unsafe_evaluate_array_5: {
unsafe_evaluate_equality_1: {
options = {
evaluate : true,
reduce_funcs : true,
reduce_vars : true,
unsafe : true,
unused : true
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unsafe: true,
unused: true,
}
input: {
function f0() {
@@ -674,12 +674,12 @@ unsafe_evaluate_equality_1: {
unsafe_evaluate_equality_2: {
options = {
collapse_vars: true,
evaluate : true,
passes : 2,
reduce_funcs : true,
reduce_vars : true,
unsafe : true,
unused : true
evaluate: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unsafe: true,
unused: true,
}
input: {
function f2() {
@@ -1130,7 +1130,7 @@ toplevel_on: {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:true,
toplevel: true,
unused: true,
}
input: {
@@ -1148,7 +1148,7 @@ toplevel_off: {
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:false,
toplevel: false,
unused: true,
}
input: {
@@ -1168,7 +1168,7 @@ toplevel_on_loops_1: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:true,
toplevel: true,
unused: true,
}
input: {
@@ -1196,7 +1196,7 @@ toplevel_off_loops_1: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:false,
toplevel: false,
unused: true,
}
input: {
@@ -1225,7 +1225,7 @@ toplevel_on_loops_2: {
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel:true,
toplevel: true,
unused: true,
}
input: {
@@ -1251,7 +1251,7 @@ toplevel_off_loops_2: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:false,
toplevel: false,
unused: true,
}
input: {
@@ -1278,7 +1278,7 @@ toplevel_on_loops_3: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:true,
toplevel: true,
unused: true,
}
input: {
@@ -1296,7 +1296,7 @@ toplevel_off_loops_3: {
loops: true,
reduce_funcs: true,
reduce_vars: true,
toplevel:false,
toplevel: false,
unused: true,
}
input: {
@@ -1560,6 +1560,32 @@ func_modified: {
expect_stdout: "7"
}
unused_modified: {
options = {
reduce_vars: true,
unused: true,
}
input: {
console.log(function() {
var b = 1, c = "FAIL";
if (0 || b--)
c = "PASS";
b = 1;
return c;
}());
}
expect: {
console.log(function() {
var b = 1, c = "FAIL";
if (0 || b--)
c = "PASS";
b = 1;
return c;
}());
}
expect_stdout: "PASS"
}
defun_label: {
options = {
passes: 2,
@@ -1868,8 +1894,8 @@ issue_1670_1: {
options = {
comparisons: true,
conditionals: true,
evaluate: true,
dead_code: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
@@ -1901,8 +1927,8 @@ issue_1670_1: {
issue_1670_2: {
options = {
conditionals: true,
evaluate: true,
dead_code: true,
evaluate: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -1934,8 +1960,8 @@ issue_1670_3: {
options = {
comparisons: true,
conditionals: true,
evaluate: true,
dead_code: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
@@ -1967,8 +1993,8 @@ issue_1670_3: {
issue_1670_4: {
options = {
conditionals: true,
evaluate: true,
dead_code: true,
evaluate: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
@@ -4887,7 +4913,7 @@ inverted_var: {
}(), function(c) {
c = 4;
return c;
}(), function (c) {
}(), function(c) {
c = 5;
return c;
var c;
@@ -6059,6 +6085,38 @@ conditional_nested_2: {
expect_stdout: "1"
}
conditional_nested_3: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var n = 2, c = 0;
(function f(a) {
0 < n-- && g(a = 1);
function g() {
a && c++;
}
g();
0 < n-- && f();
})();
console.log(c);
}
expect: {
var n = 2, c = 0;
(function f(a) {
0 < n-- && g(a = 1);
function g() {
a && c++;
}
g();
0 < n-- && f();
})();
console.log(c);
}
expect_stdout: "2"
}
issue_2436: {
options = {
evaluate: true,
@@ -6146,3 +6204,228 @@ issue_3125: {
}
expect_stdout: "7"
}
issue_3140_1: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a;
function f() {
}
f.g = function g() {
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
this();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect: {
(function() {
var a;
function f() {
}
f.g = function g() {
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
this();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect_stdout: "PASS"
}
issue_3140_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a;
function f() {
}
f.g = function g() {
var self = this;
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
self();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect: {
(function() {
var a;
function f() {
}
f.g = function g() {
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
this();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect_stdout: "PASS"
}
issue_3140_3: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a;
function f() {
}
f.g = function g() {
var self = this;
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
(function() {
return self;
})()();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect: {
(function() {
var a;
function f() {
}
f.g = function g() {
var self = this;
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
(function() {
return self;
})()();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect_stdout: "PASS"
}
issue_3140_4: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a;
function f() {
}
f.g = function g() {
var o = {
p: this
};
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
o.p();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect: {
(function() {
var a;
function f() {
}
f.g = function g() {
var o = {
p: this
};
function h() {
console.log(a ? "PASS" : "FAIL");
}
a = true;
o.p();
a = false;
h.g = g;
return h;
};
return f;
})().g().g();
}
expect_stdout: "PASS"
}
issue_3140_5: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var n = 1, c = 0;
(function(a) {
var b = function() {
this;
n-- && h();
}();
function h() {
b && c++;
}
h(b = 1);
})();
console.log(c);
}
expect: {
var n = 1, c = 0;
(function(a) {
var b = function() {
this;
n-- && h();
}();
function h() {
b && c++;
}
h(b = 1);
})();
console.log(c);
}
expect_stdout: "1"
}

37
test/compress/regexp.js Normal file
View File

@@ -0,0 +1,37 @@
regexp_simple: {
input: {
/rx/ig
}
expect_exact: "/rx/gi;"
}
regexp_slashes: {
input: {
/\\\/rx\/\\/ig
}
expect_exact: "/\\\\\\/rx\\/\\\\/gi;"
}
regexp_1: {
input: {
console.log(JSON.stringify("COMPASS? Overpass.".match(/([Sap]+)/ig)));
}
expect: {
console.log(JSON.stringify("COMPASS? Overpass.".match(/([Sap]+)/gi)));
}
expect_stdout: '["PASS","pass"]'
}
regexp_2: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log(JSON.stringify("COMPASS? Overpass.".match(new RegExp("([Sap]+)", "ig"))));
}
expect: {
console.log(JSON.stringify("COMPASS? Overpass.".match(/([Sap]+)/gi)));
}
expect_stdout: '["PASS","pass"]'
}

View File

@@ -1,24 +1,24 @@
return_undefined: {
options = {
sequences : false,
if_return : true,
evaluate : true,
dead_code : true,
conditionals : true,
comparisons : true,
booleans : true,
unused : true,
side_effects : true,
properties : true,
drop_debugger : true,
loops : true,
hoist_funs : true,
keep_fargs : true,
keep_fnames : false,
hoist_vars : true,
join_vars : true,
negate_iife : true
};
booleans: true,
comparisons: true,
conditionals: true,
dead_code: true,
drop_debugger: true,
evaluate: true,
hoist_funs: true,
hoist_vars: true,
if_return: true,
join_vars: true,
keep_fargs: true,
keep_fnames: false,
loops: true,
negate_iife: true,
properties: true,
sequences: false,
side_effects: true,
unused: true,
}
input: {
function f0() {
}

View File

@@ -1,7 +1,7 @@
make_sequences_1: {
options = {
sequences: true
};
sequences: true,
}
input: {
foo();
bar();
@@ -14,8 +14,8 @@ make_sequences_1: {
make_sequences_2: {
options = {
sequences: true
};
sequences: true,
}
input: {
if (boo) {
foo();
@@ -35,8 +35,8 @@ make_sequences_2: {
make_sequences_3: {
options = {
sequences: true
};
sequences: true,
}
input: {
function f() {
foo();
@@ -61,8 +61,8 @@ make_sequences_3: {
make_sequences_4: {
options = {
sequences: true
};
sequences: true,
}
input: {
x = 5;
if (y) z();
@@ -90,7 +90,9 @@ make_sequences_4: {
}
lift_sequences_1: {
options = { sequences: true };
options = {
sequences: true,
}
input: {
var foo, x, y, bar;
foo = !(x(), y(), bar());
@@ -102,7 +104,10 @@ lift_sequences_1: {
}
lift_sequences_2: {
options = { sequences: true, evaluate: true };
options = {
evaluate: true,
sequences: true,
}
input: {
var foo = 1, bar;
foo.x = (foo = {}, 10);
@@ -119,7 +124,10 @@ lift_sequences_2: {
}
lift_sequences_3: {
options = { sequences: true, conditionals: true };
options = {
conditionals: true,
sequences: true,
}
input: {
var x, foo, bar, baz;
x = (foo(), bar(), baz()) ? 10 : 20;
@@ -131,7 +139,9 @@ lift_sequences_3: {
}
lift_sequences_4: {
options = { side_effects: true };
options = {
side_effects: true,
}
input: {
var x, foo, bar, baz;
x = (foo, bar, baz);
@@ -160,7 +170,9 @@ lift_sequences_5: {
}
for_sequences: {
options = { sequences: true };
options = {
sequences: true,
}
input: {
// 1
foo();
@@ -203,7 +215,7 @@ for_sequences: {
limit_1: {
options = {
sequences: 3,
};
}
input: {
a;
b;
@@ -228,7 +240,7 @@ limit_1: {
limit_2: {
options = {
sequences: 3,
};
}
input: {
a, b;
c, d;
@@ -246,9 +258,9 @@ limit_2: {
negate_iife_for: {
options = {
sequences: true,
negate_iife: true,
};
sequences: true,
}
input: {
(function() {})();
for (i = 0; i < 5; i++) console.log(i);
@@ -265,7 +277,7 @@ negate_iife_for: {
iife: {
options = {
sequences: true,
};
}
input: {
x = 42;
(function a() {})();

View File

@@ -14,6 +14,13 @@ issue_1929: {
function f(s) {
return s.split(/[\\/]/);
}
console.log(JSON.stringify(f("A/B\\C\\D/E\\F")));
}
expect_exact: "function f(s){return s.split(/[\\\\/]/)}"
expect: {
function f(s) {
return s.split(/[\\/]/);
}
console.log(JSON.stringify(f("A/B\\C\\D/E\\F")));
}
expect_stdout: '["A","B","C","D","E","F"]'
}

View File

@@ -820,8 +820,8 @@ issue_1758: {
issue_2535: {
options = {
evaluate: true,
dead_code: true,
evaluate: true,
switches: true,
}
input: {

View File

@@ -2,7 +2,7 @@ typeof_evaluation: {
options = {
evaluate: true,
typeofs: true,
};
}
input: {
a = typeof 1;
b = typeof 'test';
@@ -27,11 +27,11 @@ typeof_evaluation: {
typeof_in_boolean_context: {
options = {
booleans : true,
evaluate : true,
conditionals : true,
side_effects : true,
};
booleans: true,
conditionals: true,
evaluate: true,
side_effects: true,
}
input: {
function f1(x) { return typeof x ? "yes" : "no"; }
function f2() { return typeof g()? "Yes" : "No"; }

View File

@@ -1,5 +1,5 @@
unicode_parse_variables: {
options = {};
options = {}
input: {
var a = {};
a.你好 = 456;

View File

@@ -23,7 +23,7 @@ wrap_iife_in_expression: {
wrap_iife: true,
}
input: {
foo = (function () {
foo = (function() {
return bar();
})();
}

View File

@@ -1,4 +1,5 @@
var fs = require("fs");
var parse = require("url").parse;
var path = require("path");
try {
@@ -19,7 +20,9 @@ module.exports = function(url, callback) {
var result = read(url);
result.on("error", function(e) {
if (e.code != "ENOENT") return callback(e);
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
var options = parse(url);
options.rejectUnauthorized = false;
require(options.protocol.slice(0, -1)).get(options, function(res) {
if (res.statusCode !== 200) return callback(res);
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
callback(null, read(url));

View File

@@ -0,0 +1,4 @@
function enclose() {
console.log("test enclose");
}
enclose();

View File

@@ -1,4 +1,4 @@
var bar = (function () {
var bar = (function() {
function foo (bar) {
return bar;
}

View File

@@ -3,7 +3,7 @@
"use strict";
var site = "http://browserbench.org/JetStream";
var site = "https://browserbench.org/JetStream";
if (typeof phantom == "undefined") {
require("../tools/exit");
var args = process.argv.slice(2);

View File

@@ -1,24 +1,114 @@
var fs = require("fs");
var Mocha = require("mocha");
var path = require("path");
// Instantiate a Mocha instance
var mocha = new Mocha({
timeout: 5000
});
var testDir = __dirname + "/mocha/";
var config = {
limit: 5000,
timeout: function(limit) {
this.limit = limit;
}
};
var tasks = [];
var titles = [];
describe = function(title, fn) {
config = Object.create(config);
titles.push(title);
fn.call(config);
titles.pop();
config = Object.getPrototypeOf(config);
};
it = function(title, fn) {
fn.limit = config.limit;
fn.titles = titles.slice();
fn.titles.push(title);
tasks.push(fn);
};
// Add each .js file to the Mocha instance
fs.readdirSync(testDir).filter(function(file) {
fs.readdirSync("test/mocha").filter(function(file) {
return /\.js$/.test(file);
}).forEach(function(file) {
mocha.addFile(path.join(testDir, file));
require("./mocha/" + file);
});
module.exports = function() {
mocha.run(function(failures) {
if (failures) process.on("exit", function() {
process.exit(failures);
function log_titles(log, current, marker) {
var indent = "";
var writing = false;
for (var i = 0; i < current.length; i++, indent += " ") {
if (titles[i] != current[i]) writing = true;
if (writing) log(indent + (i == current.length - 1 && marker || "") + current[i]);
}
titles = current;
}
function red(text) {
return "\u001B[31m" + text + "\u001B[39m";
}
function green(text) {
return "\u001B[32m" + text + "\u001B[39m";
}
var errors = [];
var total = tasks.length;
titles = [];
process.nextTick(function run() {
var task = tasks.shift();
if (task) try {
var elapsed = Date.now();
var timer;
var done = function() {
reset();
elapsed = Date.now() - elapsed;
if (elapsed > task.limit) {
throw new Error("Timed out: " + elapsed + "ms > " + task.limit + "ms");
}
log_titles(console.log, task.titles, green('\u221A '));
process.nextTick(run);
};
if (task.length) {
task.timeout = function(limit) {
clearTimeout(timer);
task.limit = limit;
timer = setTimeout(function() {
raise(new Error("Timed out: exceeds " + limit + "ms"));
}, limit);
};
task.timeout(task.limit);
process.on("uncaughtException", raise);
task.call(task, done);
} else {
task.timeout = config.timeout;
task.call(task);
done();
}
} catch (err) {
raise(err);
} else if (errors.length) {
console.error();
console.log(red(errors.length + " test(s) failed!"));
titles = [];
errors.forEach(function(titles, index) {
console.error();
log_titles(console.error, titles, (index + 1) + ") ");
var lines = titles.error.stack.split('\n');
console.error(red(lines[0]));
console.error(lines.slice(1).join("\n"));
});
});
};
process.exit(1);
} else {
console.log();
console.log(green(total + " test(s) passed."));
}
function raise(err) {
reset();
task.titles.error = err;
errors.push(task.titles);
log_titles(console.log, task.titles, red('\u00D7 '));
process.nextTick(run);
}
function reset() {
clearTimeout(timer);
done = function() {};
process.removeListener("uncaughtException", raise);
}
});

View File

@@ -1,17 +1,14 @@
var UglifyJS = require("../node");
var assert = require("assert");
var UglifyJS = require("../..");
describe("arguments", function() {
it("Should known that arguments in functions are local scoped", function() {
var ast = UglifyJS.parse("var arguments; var f = function() {arguments.length}");
ast.figure_out_scope();
// Test scope of `var arguments`
assert.strictEqual(ast.find_variable("arguments").global, true);
// Select arguments symbol in function
var symbol = ast.body[1].definitions[0].value.find_variable("arguments");
assert.strictEqual(symbol.global, false);
assert.strictEqual(symbol.scope, ast. // From ast
body[1]. // Select 2nd statement (equals to `var f ...`)
@@ -27,4 +24,4 @@ describe("arguments", function() {
assert.strictEqual(ast.body[0].body[0].uses_arguments, true);
assert.strictEqual(ast.body[0].body[0].body[0].uses_arguments, false);
});
});
});

View File

@@ -6,60 +6,48 @@ function read(path) {
return fs.readFileSync(path, "utf8");
}
describe("bin/uglifyjs", function () {
describe("bin/uglifyjs", function() {
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
it("should produce a functional build when using --self", function (done) {
it("Should produce a functional build when using --self", function(done) {
this.timeout(30000);
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
eval(stdout);
assert.strictEqual(typeof WrappedUglifyJS, 'object');
assert.strictEqual(typeof WrappedUglifyJS, "object");
var result = WrappedUglifyJS.minify("foo([true,,2+3]);");
assert.strictEqual(result.error, undefined);
assert.strictEqual(result.code, "foo([!0,,5]);");
done();
});
});
it("Should be able to filter comments correctly with `--comments all`", function (done) {
it("Should be able to filter comments correctly with `--comments all`", function(done) {
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
done();
});
});
it("Should be able to filter comments correctly with `--comment <RegExp>`", function (done) {
it("Should be able to filter comments correctly with `--comment <RegExp>`", function(done) {
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
done();
});
});
it("Should be able to filter comments correctly with just `--comment`", function (done) {
it("Should be able to filter comments correctly with just `--comment`", function(done) {
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "/*@preserve*/\n\n");
done();
});
});
it("Should give sensible error against invalid input source map", function(done) {
var command = uglifyjscmd + " test/mocha.js --source-map content=blah,url=inline";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.deepEqual(stderr.split(/\n/).slice(0, 2), [
"INFO: Using input source map: blah",
@@ -68,38 +56,35 @@ describe("bin/uglifyjs", function () {
done();
});
});
it("Should append source map to output when using --source-map url=inline", function (done) {
it("Should append source map to output when using --source-map url=inline", function(done) {
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==\n");
assert.strictEqual(stdout, [
"var bar=function(){function foo(bar){return bar}return foo}();",
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
"",
].join("\n"));
done();
});
});
it("should not append source map to output when not using --source-map url=inline", function (done) {
it("Should not append source map to output when not using --source-map url=inline", function(done) {
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
done();
});
});
it("should not consider source map file content as source map file name (issue #2082)", function (done) {
it("Should not consider source map file content as source map file name (issue #2082)", function(done) {
var command = [
uglifyjscmd,
"test/input/issue-2082/sample.js",
"--source-map", "content=test/input/issue-2082/sample.js.map",
"--source-map", "url=inline",
].join(" ");
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
if (err) throw err;
var stderrLines = stderr.split("\n");
assert.strictEqual(stderrLines[0], "INFO: Using input source map: test/input/issue-2082/sample.js.map");
assert.notStrictEqual(stderrLines[1], 'INFO: Using input source map: {"version": 3,"sources": ["index.js"],"mappings": ";"}');
@@ -136,82 +121,66 @@ describe("bin/uglifyjs", function () {
child.stdin.end(read("test/input/pr-3040/input.js"));
}, 1000);
});
it("Should work with --keep-fnames (mangle only)", function (done) {
it("Should work with --keep-fnames (mangle only)", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
done();
});
});
it("Should work with --keep-fnames (mangle & compress)", function (done) {
it("Should work with --keep-fnames (mangle & compress)", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
done();
});
});
it("Should work with keep_fnames under mangler options", function (done) {
it("Should work with keep_fnames under mangler options", function(done) {
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
done();
});
});
it("Should work with --define (simple)", function (done) {
it("Should work with --define (simple)", function(done) {
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "console.log(5);\n");
done();
});
});
it("Should work with --define (nested)", function (done) {
it("Should work with --define (nested)", function(done) {
var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "console.log(3,5);\n");
done();
});
});
it("Should work with --define (AST_Node)", function (done) {
it("Should work with --define (AST_Node)", function(done) {
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "stdout.println(D);\n");
done();
});
});
it("Should work with `--beautify`", function (done) {
it("Should work with `--beautify`", function(done) {
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
done();
});
});
it("Should work with `--beautify braces`", function (done) {
it("Should work with `--beautify braces`", function(done) {
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b braces';
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, read("test/input/issue-1482/braces.js"));
done();
});
@@ -225,20 +194,16 @@ describe("bin/uglifyjs", function () {
"--source-map", "includeSources=true",
"--source-map", "url=inline",
].join(" ");
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, read("test/input/issue-520/output.js"));
done();
});
});
it("Should warn for missing inline source map", function(done) {
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, [
"var bar=function(){function foo(bar){return bar}return foo}();",
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
@@ -256,10 +221,8 @@ describe("bin/uglifyjs", function () {
"test/input/issue-1323/sample.js",
"--source-map", "content=inline,url=inline",
].join(" ");
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, [
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUFBLE1BQWdCQyxRQUFRQyxJQUFJLEVBQUUsSUFBTyxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
@@ -272,8 +235,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with acorn and inline source map", function(done) {
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p acorn";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
done();
@@ -281,8 +243,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with SpiderMonkey and inline source map", function(done) {
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p spidermonkey";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
done();
@@ -290,8 +251,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with invalid syntax", function(done) {
var command = uglifyjscmd + ' test/input/invalid/simple.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
@@ -303,8 +263,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with correct marking of tabs", function(done) {
var command = uglifyjscmd + ' test/input/invalid/tab.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
@@ -316,8 +275,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with correct marking at start of line", function(done) {
var command = uglifyjscmd + ' test/input/invalid/eof.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
@@ -329,8 +287,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with a missing loop body", function(done) {
var command = uglifyjscmd + ' test/input/invalid/loop-no-body.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
@@ -342,8 +299,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (5--)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -357,8 +313,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (Math.random() /= 2)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -372,8 +327,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (++this)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -387,8 +341,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (++null)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -402,8 +355,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (a.=)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -417,8 +369,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (%.a)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -432,8 +383,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (a./();)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -447,8 +397,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error ({%: 1})", function(done) {
var command = uglifyjscmd + ' test/input/invalid/object.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -462,8 +411,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (delete x)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/delete.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -477,8 +425,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (function g(arguments))", function(done) {
var command = uglifyjscmd + ' test/input/invalid/function_1.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -492,8 +439,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (function eval())", function(done) {
var command = uglifyjscmd + ' test/input/invalid/function_2.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -507,8 +453,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (iife arguments())", function(done) {
var command = uglifyjscmd + ' test/input/invalid/function_3.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -522,8 +467,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (catch(eval))", function(done) {
var command = uglifyjscmd + ' test/input/invalid/try.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -537,8 +481,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (var eval)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/var.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -552,8 +495,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (else)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/else.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -567,8 +509,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (return)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/return.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -582,8 +523,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (for-in init)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/for-in_1.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -597,8 +537,7 @@ describe("bin/uglifyjs", function () {
});
it("Should throw syntax error (for-in var)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/for-in_2.js';
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
@@ -617,10 +556,8 @@ describe("bin/uglifyjs", function () {
"--source-map",
'content="' + read_map() + '",url=inline'
].join(" ");
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, [
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
@@ -642,10 +579,8 @@ describe("bin/uglifyjs", function () {
"-c",
"--source-map", "url=inline",
].join(" ");
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, [
'function foo(){return function(){console.log("PASS")}}foo()();',
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
@@ -656,9 +591,8 @@ describe("bin/uglifyjs", function () {
});
it("Should dump AST as JSON", function(done) {
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
var ast = JSON.parse(stdout);
assert.strictEqual(ast._class, "AST_Toplevel");
assert.ok(Array.isArray(ast.body));
@@ -667,7 +601,7 @@ describe("bin/uglifyjs", function () {
});
it("Should print supported options on invalid option syntax", function(done) {
var command = uglifyjscmd + " test/input/comments/filter.js -b ascii-only";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.ok(/^Supported options:\n[\s\S]*?\nERROR: `ascii-only` is not a supported option/.test(stderr), stderr);
@@ -676,27 +610,23 @@ describe("bin/uglifyjs", function () {
});
it("Should work with --mangle reserved=[]", function(done) {
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=[callback]";
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, 'function test(callback){"aaaaaaaaaaaaaaaa";callback(err,data);callback(err,data)}\n');
done();
});
});
it("Should work with --mangle reserved=false", function(done) {
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=false";
exec(command, function (err, stdout) {
exec(command, function(err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, 'function test(a){"aaaaaaaaaaaaaaaa";a(err,data);a(err,data)}\n');
done();
});
});
it("Should fail with --mangle-props reserved=[in]", function(done) {
var command = uglifyjscmd + " test/input/issue-505/input.js --mangle-props reserved=[in]";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.ok(/^Supported options:\n[\s\S]*?\nERROR: `reserved=\[in]` is not a supported option/.test(stderr), stderr);
@@ -705,7 +635,7 @@ describe("bin/uglifyjs", function () {
});
it("Should fail with --define a-b", function(done) {
var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
exec(command, function (err, stdout, stderr) {
exec(command, function(err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr, "Error parsing arguments for 'define': a-b\n");
@@ -744,4 +674,36 @@ describe("bin/uglifyjs", function () {
done();
});
});
it("Should work with --enclose", function(done) {
var command = uglifyjscmd + " test/input/enclose/input.js --enclose";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, '(function(){function enclose(){console.log("test enclose")}enclose()})();\n');
done();
});
});
it("Should work with --enclose arg", function(done) {
var command = uglifyjscmd + " test/input/enclose/input.js --enclose undefined";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, '(function(undefined){function enclose(){console.log("test enclose")}enclose()})();\n');
done();
});
});
it("Should work with --enclose arg:value", function(done) {
var command = uglifyjscmd + " test/input/enclose/input.js --enclose window,undefined:window";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, '(function(window,undefined){function enclose(){console.log("test enclose")}enclose()})(window);\n');
done();
});
});
it("Should work with --enclose & --wrap", function(done) {
var command = uglifyjscmd + " test/input/enclose/input.js --enclose window,undefined:window --wrap exports";
exec(command, function(err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, '(function(window,undefined){(function(exports){function enclose(){console.log("test enclose")}enclose()})(typeof exports=="undefined"?exports={}:exports)})(window);\n');
done();
});
});
});

View File

@@ -1,89 +0,0 @@
var UglifyJS = require("../node");
var assert = require("assert");
describe("comment filters", function() {
it("Should be able to filter comments by passing regexp", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
});
it("Should be able to filter comments with the 'all' option", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
});
it("Should be able to filter commments with the 'some' option", function() {
var ast = UglifyJS.parse("// foo\n/*@preserve*/\n// bar\n/*@license*/\n//@license with the wrong comment type\n/*@cc_on something*/");
assert.strictEqual(ast.print_to_string({comments: "some"}), "/*@preserve*/\n/*@license*/\n/*@cc_on something*/");
});
it("Should be able to filter comments by passing a function", function() {
var ast = UglifyJS.parse("/*TEST 123*/\n//An other comment\n//8 chars.");
var f = function(node, comment) {
return comment.value.length === 8;
};
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
});
it("Should be able to filter comments by passing regex in string format", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
});
it("Should be able to get the comment and comment type when using a function", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
var f = function(node, comment) {
return comment.type == "comment1" || comment.type == "comment3";
};
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
});
it("Should be able to filter comments by passing a boolean", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
assert.strictEqual(ast.print_to_string({comments: false}), "");
});
it("Should never be able to filter comment5 (shebangs)", function() {
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
var f = function(node, comment) {
assert.strictEqual(comment.type === "comment5", false);
return true;
};
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
});
it("Should never be able to filter comment5 when using 'some' as filter", function() {
var ast = UglifyJS.parse("#!foo\n//foo\n/*@preserve*/\n/* please hide me */");
assert.strictEqual(ast.print_to_string({comments: "some"}), "#!foo\n/*@preserve*/");
});
it("Should have no problem on multiple calls", function() {
const options = {
comments: /ok/
};
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
});
it("Should handle shebang and preamble correctly", function() {
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
output: { preamble: "/* Build */" }
}).code;
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
});
it("Should handle preamble without shebang correctly", function() {
var code = UglifyJS.minify("var x = 10;", {
output: { preamble: "/* Build */" }
}).code;
assert.strictEqual(code, "/* Build */\nvar x=10;");
});
});

View File

@@ -1,262 +0,0 @@
var assert = require("assert");
var uglify = require("../node");
describe("Comment", function() {
it("Should recognize eol of single line comments", function() {
var tests = [
"//Some comment 1\n>",
"//Some comment 2\r>",
"//Some comment 3\r\n>",
"//Some comment 4\u2028>",
"//Some comment 5\u2029>"
];
var fail = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "Unexpected token: operator (>)" &&
e.line === 2 &&
e.col === 0;
}
for (var i = 0; i < tests.length; i++) {
assert.throws(function() {
uglify.parse(tests[i]);
}, fail, tests[i]);
}
});
it("Should update the position of a multiline comment correctly", function() {
var tests = [
"/*Some comment 1\n\n\n*/\n>\n\n\n\n\n\n",
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n"
];
var fail = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "Unexpected token: operator (>)" &&
e.line === 5 &&
e.col === 0;
}
for (var i = 0; i < tests.length; i++) {
assert.throws(function() {
uglify.parse(tests[i]);
}, fail, tests[i]);
}
});
it("Should handle comment within return correctly", function() {
var result = uglify.minify([
"function unequal(x, y) {",
" return (",
" // Either one",
" x < y",
" ||",
" y < x",
" );",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function unequal(x, y) {",
" // Either one",
" return x < y || y < x;",
"}",
].join("\n"));
});
it("Should handle comment folded into return correctly", function() {
var result = uglify.minify([
"function f() {",
" /* boo */ x();",
" return y();",
"}",
].join("\n"), {
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function f() {",
" /* boo */",
" return x(), y();",
"}",
].join("\n"));
});
it("Should not drop comments after first OutputStream", function() {
var code = "/* boo */\nx();";
var ast = uglify.parse(code);
var out1 = uglify.OutputStream({
beautify: true,
comments: "all",
});
ast.print(out1);
var out2 = uglify.OutputStream({
beautify: true,
comments: "all",
});
ast.print(out2);
assert.strictEqual(out1.get(), code);
assert.strictEqual(out2.get(), out1.get());
});
it("Should retain trailing comments", function() {
var code = [
"if (foo /* lost comment */ && bar /* lost comment */) {",
" // this one is kept",
" {/* lost comment */}",
" !function() {",
" // lost comment",
" }();",
" function baz() {/* lost comment */}",
" // lost comment",
"}",
"// comments right before EOF are lost as well",
].join("\n");
var result = uglify.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should retain comments within braces", function() {
var code = [
"{/* foo */}",
"a({/* foo */});",
"while (a) {/* foo */}",
"switch (a) {/* foo */}",
"if (a) {/* foo */} else {/* bar */}",
].join("\n\n");
var result = uglify.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should correctly preserve new lines around comments", function() {
var tests = [
[
"// foo",
"// bar",
"x();",
].join("\n"),
[
"// foo",
"/* bar */",
"x();",
].join("\n"),
[
"// foo",
"/* bar */ x();",
].join("\n"),
[
"/* foo */",
"// bar",
"x();",
].join("\n"),
[
"/* foo */ // bar",
"x();",
].join("\n"),
[
"/* foo */",
"/* bar */",
"x();",
].join("\n"),
[
"/* foo */",
"/* bar */ x();",
].join("\n"),
[
"/* foo */ /* bar */",
"x();",
].join("\n"),
"/* foo */ /* bar */ x();",
].forEach(function(code) {
var result = uglify.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
});
it("Should preserve new line before comment without beautify", function() {
var code = [
"function f(){",
"/* foo */bar()}",
].join("\n");
var result = uglify.minify(code, {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should preserve comments around IIFE", function() {
var result = uglify.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
});
it("Should output line comments after statements", function() {
var result = uglify.minify([
"x()//foo",
"{y()//bar",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"x();//foo",
"{y();//bar",
"}",
].join("\n"));
});
});

View File

@@ -1,22 +0,0 @@
var Uglify = require('../../');
var assert = require("assert");
describe("comment before constant", function() {
var js = 'function f() { /*c1*/ var /*c2*/ foo = /*c3*/ false; return foo; }';
it("Should test comment before constant is retained and output after mangle.", function() {
var result = Uglify.minify(js, {
compress: { collapse_vars: false, reduce_vars: false },
output: { comments: true },
});
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
});
it("Should test code works when comments disabled.", function() {
var result = Uglify.minify(js, {
compress: { collapse_vars: false, reduce_vars: false },
output: { comments: false },
});
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
});
});

380
test/mocha/comments.js Normal file
View File

@@ -0,0 +1,380 @@
var assert = require("assert");
var UglifyJS = require("../node");
describe("comments", function() {
it("Should recognize eol of single line comments", function() {
var tests = [
"//Some comment 1\n>",
"//Some comment 2\r>",
"//Some comment 3\r\n>",
"//Some comment 4\u2028>",
"//Some comment 5\u2029>"
];
var fail = function(e) {
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Unexpected token: operator (>)"
&& e.line === 2
&& e.col === 0;
}
for (var i = 0; i < tests.length; i++) {
assert.throws(function() {
UglifyJS.parse(tests[i]);
}, fail, tests[i]);
}
});
it("Should update the position of a multiline comment correctly", function() {
var tests = [
"/*Some comment 1\n\n\n*/\n>\n\n\n\n\n\n",
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n"
];
var fail = function(e) {
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Unexpected token: operator (>)"
&& e.line === 5
&& e.col === 0;
}
for (var i = 0; i < tests.length; i++) {
assert.throws(function() {
UglifyJS.parse(tests[i]);
}, fail, tests[i]);
}
});
it("Should handle comment within return correctly", function() {
var result = UglifyJS.minify([
"function unequal(x, y) {",
" return (",
" // Either one",
" x < y",
" ||",
" y < x",
" );",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function unequal(x, y) {",
" // Either one",
" return x < y || y < x;",
"}",
].join("\n"));
});
it("Should handle comment folded into return correctly", function() {
var result = UglifyJS.minify([
"function f() {",
" /* boo */ x();",
" return y();",
"}",
].join("\n"), {
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"function f() {",
" /* boo */",
" return x(), y();",
"}",
].join("\n"));
});
it("Should not drop comments after first OutputStream", function() {
var code = "/* boo */\nx();";
var ast = UglifyJS.parse(code);
var out1 = UglifyJS.OutputStream({
beautify: true,
comments: "all",
});
ast.print(out1);
var out2 = UglifyJS.OutputStream({
beautify: true,
comments: "all",
});
ast.print(out2);
assert.strictEqual(out1.get(), code);
assert.strictEqual(out2.get(), out1.get());
});
it("Should retain trailing comments", function() {
var code = [
"if (foo /* lost comment */ && bar /* lost comment */) {",
" // this one is kept",
" {/* lost comment */}",
" !function() {",
" // lost comment",
" }();",
" function baz() {/* lost comment */}",
" // lost comment",
"}",
"// comments right before EOF are lost as well",
].join("\n");
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should retain comments within braces", function() {
var code = [
"{/* foo */}",
"a({/* foo */});",
"while (a) {/* foo */}",
"switch (a) {/* foo */}",
"if (a) {/* foo */} else {/* bar */}",
].join("\n\n");
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should correctly preserve new lines around comments", function() {
var tests = [
[
"// foo",
"// bar",
"x();",
].join("\n"),
[
"// foo",
"/* bar */",
"x();",
].join("\n"),
[
"// foo",
"/* bar */ x();",
].join("\n"),
[
"/* foo */",
"// bar",
"x();",
].join("\n"),
[
"/* foo */ // bar",
"x();",
].join("\n"),
[
"/* foo */",
"/* bar */",
"x();",
].join("\n"),
[
"/* foo */",
"/* bar */ x();",
].join("\n"),
[
"/* foo */ /* bar */",
"x();",
].join("\n"),
"/* foo */ /* bar */ x();",
].forEach(function(code) {
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
beautify: true,
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
});
it("Should preserve new line before comment without beautify", function() {
var code = [
"function f(){",
"/* foo */bar()}",
].join("\n");
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, code);
});
it("Should preserve comments around IIFE", function() {
var result = UglifyJS.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
});
it("Should output line comments after statements", function() {
var result = UglifyJS.minify([
"x()//foo",
"{y()//bar",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"x();//foo",
"{y();//bar",
"}",
].join("\n"));
});
describe("comment before constant", function() {
var js = 'function f() { /*c1*/ var /*c2*/ foo = /*c3*/ false; return foo; }';
it("Should test comment before constant is retained and output after mangle.", function() {
var result = UglifyJS.minify(js, {
compress: { collapse_vars: false, reduce_vars: false },
output: { comments: true },
});
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
});
it("Should test code works when comments disabled.", function() {
var result = UglifyJS.minify(js, {
compress: { collapse_vars: false, reduce_vars: false },
output: { comments: false },
});
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
});
});
describe("comment filters", function() {
it("Should be able to filter comments by passing regexp", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
});
it("Should be able to filter comments with the 'all' option", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
});
it("Should be able to filter commments with the 'some' option", function() {
var ast = UglifyJS.parse("// foo\n/*@preserve*/\n// bar\n/*@license*/\n//@license with the wrong comment type\n/*@cc_on something*/");
assert.strictEqual(ast.print_to_string({comments: "some"}), "/*@preserve*/\n/*@license*/\n/*@cc_on something*/");
});
it("Should be able to filter comments by passing a function", function() {
var ast = UglifyJS.parse("/*TEST 123*/\n//An other comment\n//8 chars.");
var f = function(node, comment) {
return comment.value.length === 8;
};
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
});
it("Should be able to filter comments by passing regex in string format", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
});
it("Should be able to get the comment and comment type when using a function", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
var f = function(node, comment) {
return comment.type == "comment1" || comment.type == "comment3";
};
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
});
it("Should be able to filter comments by passing a boolean", function() {
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
assert.strictEqual(ast.print_to_string({comments: false}), "");
});
it("Should never be able to filter comment5 (shebangs)", function() {
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
var f = function(node, comment) {
assert.strictEqual(comment.type === "comment5", false);
return true;
};
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
});
it("Should never be able to filter comment5 when using 'some' as filter", function() {
var ast = UglifyJS.parse("#!foo\n//foo\n/*@preserve*/\n/* please hide me */");
assert.strictEqual(ast.print_to_string({comments: "some"}), "#!foo\n/*@preserve*/");
});
it("Should have no problem on multiple calls", function() {
const options = {
comments: /ok/
};
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
});
it("Should handle shebang and preamble correctly", function() {
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
output: { preamble: "/* Build */" }
}).code;
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
});
it("Should handle preamble without shebang correctly", function() {
var code = UglifyJS.minify("var x = 10;", {
output: { preamble: "/* Build */" }
}).code;
assert.strictEqual(code, "/* Build */\nvar x=10;");
});
});
describe("Huge number of comments.", function() {
it("Should parse and compress code with thousands of consecutive comments", function() {
var js = "function lots_of_comments(x) { return 7 -";
for (var i = 1; i <= 5000; ++i) js += "// " + i + "\n";
for (; i <= 10000; ++i) js += "/* " + i + " */ /**/";
js += "x; }";
var result = UglifyJS.minify(js, { mangle: false });
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
});
});
});

View File

@@ -1,15 +1,13 @@
var assert = require("assert");
var uglify = require("../node");
var UglifyJS = require("../node");
describe("Directives", function() {
it ("Should allow tokenizer to store directives state", function() {
var tokenizer = uglify.tokenizer("", "foo.js");
it("Should allow tokenizer to store directives state", function() {
var tokenizer = UglifyJS.tokenizer("", "foo.js");
// Stack level 0
assert.strictEqual(tokenizer.has_directive("use strict"), false);
assert.strictEqual(tokenizer.has_directive("use asm"), false);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
// Stack level 2
tokenizer.push_directives_stack();
tokenizer.push_directives_stack();
@@ -17,7 +15,6 @@ describe("Directives", function() {
assert.strictEqual(tokenizer.has_directive("use strict"), true);
assert.strictEqual(tokenizer.has_directive("use asm"), false);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
// Stack level 3
tokenizer.push_directives_stack();
tokenizer.add_directive("use strict");
@@ -25,13 +22,11 @@ describe("Directives", function() {
assert.strictEqual(tokenizer.has_directive("use strict"), true);
assert.strictEqual(tokenizer.has_directive("use asm"), true);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
// Stack level 2
tokenizer.pop_directives_stack();
assert.strictEqual(tokenizer.has_directive("use strict"), true);
assert.strictEqual(tokenizer.has_directive("use asm"), false);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
// Stack level 3
tokenizer.push_directives_stack();
tokenizer.add_directive("use thing");
@@ -39,172 +34,172 @@ describe("Directives", function() {
assert.strictEqual(tokenizer.has_directive("use strict"), true);
assert.strictEqual(tokenizer.has_directive("use asm"), false); // Directives are strict!
assert.strictEqual(tokenizer.has_directive("use thing"), true);
// Stack level 2
tokenizer.pop_directives_stack();
assert.strictEqual(tokenizer.has_directive("use strict"), true);
assert.strictEqual(tokenizer.has_directive("use asm"), false);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
// Stack level 1
tokenizer.pop_directives_stack();
assert.strictEqual(tokenizer.has_directive("use strict"), false);
assert.strictEqual(tokenizer.has_directive("use asm"), false);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
// Stack level 0
tokenizer.pop_directives_stack();
assert.strictEqual(tokenizer.has_directive("use strict"), false);
assert.strictEqual(tokenizer.has_directive("use asm"), false);
assert.strictEqual(tokenizer.has_directive("use thing"), false);
});
it("Should know which strings are directive and which ones are not", function() {
var test_directive = function(tokenizer, test) {
test.directives.map(function(directive) {
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test.input);
});
test.non_directives.map(function(fake_directive) {
assert.strictEqual(tokenizer.has_directive(fake_directive), false, fake_directive + " in " + test.input);
});
}
var tests = [
{
input: '"use strict"\n',
directives: ["use strict"],
non_directives: ["use asm"]
},
{
input: '"use\\\nstrict";',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: '"use strict"\n"use asm"\n"use bar"\n',
directives: ["use strict", "use asm", "use bar"],
non_directives: ["use foo", "use\\x20strict"]
},
{
input: '"use \\\nstrict";"use strict";',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: '"\\76";',
directives: [],
non_directives: [">", "\\76"]
},
{
input: '"use strict"', // no ; or newline
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: ';"use strict"',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
[
[
'"use strict"\n',
[ "use strict"],
[ "use asm"]
],
[
'"use\\\nstrict";',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
'"use strict"\n"use asm"\n"use bar"\n',
[ "use strict", "use asm", "use bar" ],
[ "use foo", "use\\x20strict" ]
],
[
'"use \\\nstrict";"use strict";',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
'"\\76";',
[],
[ ">", "\\76" ]
],
[
// no ; or newline
'"use strict"',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
';"use strict"',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
// Duplicate above code but put it in a function
{
input: 'function foo() {"use strict"\n',
directives: ["use strict"],
non_directives: ["use asm"]
},
{
input: 'function foo() {"use\\\nstrict";',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: 'function foo() {"use strict"\n"use asm"\n"use bar"\n',
directives: ["use strict", "use asm", "use bar"],
non_directives: ["use foo", "use\\x20strict"]
},
{
input: 'function foo() {"use \\\nstrict";"use strict";',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: 'var foo = function() {"\\76";',
directives: [],
non_directives: [">", "\\76"]
},
{
input: 'var foo = function() {"use strict"', // no ; or newline
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: 'var foo = function() {;"use strict"',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
[
'function foo() {"use strict"\n',
[ "use strict" ],
[ "use asm" ]
],
[
'function foo() {"use\\\nstrict";',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
'function foo() {"use strict"\n"use asm"\n"use bar"\n',
[ "use strict", "use asm", "use bar" ],
[ "use foo", "use\\x20strict" ]
],
[
'function foo() {"use \\\nstrict";"use strict";',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
'var foo = function() {"\\76";',
[],
[ ">", "\\76" ]
],
[
'var foo = function() {"use strict"', // no ; or newline
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
'var foo = function() {;"use strict"',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
// Special cases
{
input: '"1";"2";"3";"4";;"5"',
directives: ["1", "2", "3", "4"],
non_directives: ["5", "6", "use strict", "use asm"]
},
{
input: 'if(1){"use strict";',
directives: [],
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
},
{
input: '"use strict";try{"use asm";',
directives: ["use strict"],
non_directives: ["use\nstrict", "use \nstrict", "use asm"]
}
];
for (var i = 0; i < tests.length; i++) {
// Fail parser deliberately to get state at failure
var tokenizer = uglify.tokenizer(tests[i].input + "]", "foo.js");
try {
var parser = uglify.parse(tokenizer);
throw new Error("Expected parser to fail");
} catch (e) {
assert.strictEqual(e instanceof uglify.JS_Parse_Error, true);
assert.strictEqual(e.message, "Unexpected token: punc (])");
}
test_directive(tokenizer, tests[i]);
}
[
'"1";"2";"3";"4";;"5"',
[ "1", "2", "3", "4" ],
[ "5", "6", "use strict", "use asm" ]
],
[
'if(1){"use strict";',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
],
[
'"use strict";try{"use asm";',
[ "use strict" ],
[ "use\nstrict", "use \nstrict", "use asm" ]
],
].forEach(function(test) {
var tokenizer = UglifyJS.tokenizer(test[0] + "]", "foo.js");
assert.throws(function() {
UglifyJS.parse(tokenizer);
}, function(e) {
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Unexpected token: punc (])"
}, test[0]);
test[1].forEach(function(directive) {
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test[0]);
});
test[2].forEach(function(fake_directive) {
assert.strictEqual(tokenizer.has_directive(fake_directive), false, fake_directive + " in " + test[0]);
});
});
});
it("Should test EXPECT_DIRECTIVE RegExp", function() {
[
["", true],
["'test';", true],
["'test';;", true],
["'tests';\n", true],
["'tests'", false],
["'tests'; \n\t", true],
["'tests';\n\n", true],
["\n\n\"use strict\";\n\n", true]
[ "", true ],
[ "'test';", true ],
[ "'test';;", true ],
[ "'tests';\n", true ],
[ "'tests'", false ],
[ "'tests'; \n\t", true ],
[ "'tests';\n\n", true ],
[ "\n\n\"use strict\";\n\n", true ],
].forEach(function(test) {
var out = uglify.OutputStream();
var out = UglifyJS.OutputStream();
out.print(test[0]);
out.print_string("", null, true);
assert.strictEqual(out.get() === test[0] + ';""', test[1], test[0]);
});
});
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
assert.strictEqual(
uglify.minify(
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
{output: {beautify: true, quote_style: 3}, compress: false}
).code,
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
);
var result = UglifyJS.minify([
'"use strict";',
"'use strict';",
'"use strict";',
'"use strict";;',
"'use strict';",
"console.log('use strict');"
].join(""), {
compress: false,
output: {
beautify: true,
quote_style: 3
}
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
'"use strict";',
"'use strict';",
'"use strict";',
'"use strict";',
";'use strict';",
"console.log('use strict');"
].join("\n\n"));
});
it("Should not add double semicolons in non-scoped block statements to avoid strings becoming directives", function() {
var tests = [
[
[
'{"use\x20strict"}',
'{"use strict"}'
@@ -221,26 +216,27 @@ describe("Directives", function() {
'if(1){"use\x20strict"} else {"use strict"}',
'if(1){"use strict"}else{"use strict"}'
]
];
for (var i = 0; i < tests.length; i++) {
assert.strictEqual(
uglify.minify(tests[i][0], {compress: false, mangle: false}).code,
tests[i][1],
tests[i][0]
);
}
].forEach(function(test) {
var result = UglifyJS.minify(test[0], {
compress: false,
mangle: false
});
if (result.error) throw result.error;
assert.strictEqual(result.code, test[1], test[0]);
});
});
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
var code = uglify.minify('"use strict";"use\\x20strict";',
{output: {semicolons: false}, compress: false}
).code;
assert.strictEqual(code, '"use strict";;"use strict"\n');
var result = UglifyJS.minify('"use strict";"use\\x20strict";', {
compress: false,
output: {
semicolons: false
}
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '"use strict";;"use strict"\n');
});
it("Should check quote style of directives", function() {
var tests = [
[
// 0. Prefer double quotes, unless string contains more double quotes than single quotes
[
'"testing something";',
@@ -337,45 +333,53 @@ describe("Directives", function() {
3,
"'\"use strict\"';",
],
];
for (var i = 0; i < tests.length; i++) {
assert.strictEqual(
uglify.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
tests[i][2],
tests[i][0] + " using mode " + tests[i][1]
);
}
].forEach(function(test) {
var result = UglifyJS.minify(test[0], {
compress: false,
output: {
quote_style: test[1]
}
});
if (result.error) throw result.error;
assert.strictEqual(result.code, test[2], test[0] + " using mode " + test[1]);
});
});
it("Should be able to compress without side effects", function() {
// NOTE: the "use asm" directive disables any optimisation after being defined
var tests = [
[
[
'"use strict";"use strict";"use strict";"use foo";"use strict";;"use sloppy";doSomething("foo");',
'"use strict";"use foo";doSomething("foo");',
'function f(){ "use strict" }',
'function f(){ "use asm" }',
'function f(){ "use nondirective" }',
'function f(){ ;"use strict" }',
'function f(){ "use \n"; }',
'"use strict";doSomething("foo");'
],
[
// Nothing gets optimised in the compressor because "use asm" is the first statement
// Nothing gets optimised in the compressor because "use asm" is the first statement
'"use asm";"use\\x20strict";1+1;',
'"use asm";;"use strict";1+1;', // Yet, the parser noticed that "use strict" wasn't a directive
'function f(){"use strict"}',
'function f(){"use asm"}',
'function f(){"use nondirective"}',
'function f(){}',
'function f(){}',
]
];
for (var i = 0; i < tests.length; i++) {
assert.strictEqual(
uglify.minify(tests[i][0]).code,
tests[i][1],
tests[i][0]
);
}
// Yet, the parser noticed that "use strict" wasn't a directive
'"use asm";;"use strict";1+1;',
],
[
'function f(){ "use strict" }',
'function f(){}'
],
[
'function f(){ "use asm" }',
'function f(){"use asm"}'
],
[
'function f(){ "use nondirective" }',
'function f(){}'
],
[
'function f(){ ;"use strict" }',
'function f(){}'
],
[
'function f(){ "use \\n"; }',
'function f(){}'
],
].forEach(function(test) {
var result = UglifyJS.minify(test[0]);
if (result.error) throw result.error;
assert.strictEqual(result.code, test[1], test[0]);
});
});
});

View File

@@ -1,5 +1,5 @@
var UglifyJS = require("../node");
var assert = require("assert");
var UglifyJS = require("../node");
describe("Getters and setters", function() {
it("Should not accept operator symbols as getter/setter name", function() {
@@ -61,29 +61,24 @@ describe("Getters and setters", function() {
return results;
};
var testCase = function(data) {
return function() {
UglifyJS.parse(data.code);
};
};
var fail = function(data) {
return function (e) {
return e instanceof UglifyJS.JS_Parse_Error &&
e.message === "Unexpected token: operator (" + data.operator + ")";
return function(e) {
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Unexpected token: operator (" + data.operator + ")";
};
};
var errorMessage = function(data) {
return "Expected but didn't get a syntax error while parsing following line:\n" + data.code;
};
var tests = generator();
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
assert.throws(testCase(test), fail(test), errorMessage(test));
}
});
});

View File

@@ -35,7 +35,7 @@ describe("bin/uglifyjs with input file globs", function() {
done();
});
});
it("should throw with non-matching glob string", function(done) {
it("Should throw with non-matching glob string", function(done) {
var command = uglifyjscmd + ' "test/input/issue-1242/blah.*"';
exec(command, function(err, stdout, stderr) {
@@ -53,7 +53,7 @@ describe("bin/uglifyjs with input file globs", function() {
done();
});
});
it("should handle special characters in glob string", function(done) {
it("Should handle special characters in glob string", function(done) {
var command = uglifyjscmd + ' "test/input/issue-1632/^{*}[???](*)+$.??" -cm';
exec(command, function(err, stdout) {
@@ -63,7 +63,7 @@ describe("bin/uglifyjs with input file globs", function() {
done();
});
});
it("should handle array of glob strings - matching and otherwise", function(done) {
it("Should handle array of glob strings - matching and otherwise", function(done) {
var dir = "test/input/issue-1242";
var command = uglifyjscmd + ' "' + [
path.join(dir, "b*.es5"),

View File

@@ -1,14 +0,0 @@
var Uglify = require('../../');
var assert = require("assert");
describe("Huge number of comments.", function() {
it("Should parse and compress code with thousands of consecutive comments", function() {
var js = 'function lots_of_comments(x) { return 7 -';
var i;
for (i = 1; i <= 5000; ++i) { js += "// " + i + "\n"; }
for (; i <= 10000; ++i) { js += "/* " + i + " */ /**/"; }
js += "x; }";
var result = Uglify.minify(js, { mangle: false });
assert.strictEqual(result.code, "function lots_of_comments(x){return 7-x}");
});
});

21
test/mocha/ie8.js Normal file
View File

@@ -0,0 +1,21 @@
var assert = require("assert");
var UglifyJS = require("../..");
describe("ie8", function() {
it("Should be able to minify() with undefined as catch parameter in a try...catch statement", function() {
assert.strictEqual(
UglifyJS.minify([
"function a(b){",
" try {",
" throw 'Stuff';",
" } catch (undefined) {",
" console.log('caught: ' + undefined);",
" }",
" console.log('undefined is ' + undefined);",
" return b === undefined;",
"};",
].join("\n")).code,
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
);
});
});

View File

@@ -1,68 +0,0 @@
var assert = require("assert");
var Uglify = require("../../");
var SourceMapConsumer = require("source-map").SourceMapConsumer;
function getMap() {
return {
"version": 3,
"sources": ["index.js"],
"names": [],
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
"file": "bundle.js",
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
};
}
function prepareMap(sourceMap) {
var code = [
'"use strict";',
"",
"var foo = function foo(x) {",
' return "foo " + x;',
"};",
'console.log(foo("bar"));',
"",
"//# sourceMappingURL=bundle.js.map",
].join("\n");
var result = Uglify.minify(code, {
sourceMap: {
content: sourceMap,
includeSources: true,
}
});
if (result.error) throw result.error;
return new SourceMapConsumer(result.map);
}
describe("input sourcemaps", function() {
it("Should copy over original sourcesContent", function() {
var orig = getMap();
var map = prepareMap(orig);
assert.equal(map.sourceContentFor("index.js"), orig.sourcesContent[0]);
});
it("Should copy sourcesContent if sources are relative", function() {
var relativeMap = getMap();
relativeMap.sources = ['./index.js'];
var map = prepareMap(relativeMap);
assert.notEqual(map.sourcesContent, null);
assert.equal(map.sourcesContent.length, 1);
assert.equal(map.sourceContentFor("index.js"), relativeMap.sourcesContent[0]);
});
it("Should not have invalid mappings from inputSourceMap (issue #882)", function() {
var map = prepareMap(getMap());
// The original source has only 2 lines, check that mappings don't have more lines
var msg = "Mapping should not have higher line number than the original file had";
map.eachMapping(function(mapping) {
assert.ok(mapping.originalLine <= 2, msg);
});
map.allGeneratedPositionsFor({
source: "index.js",
line: 1,
column: 1
}).forEach(function(pos) {
assert.ok(pos.line <= 2, msg);
});
});
});

View File

@@ -1,5 +1,5 @@
var Uglify = require('../../');
var assert = require("assert");
var UglifyJS = require("../..");
describe("let", function() {
this.timeout(30000);
@@ -10,7 +10,7 @@ describe("let", function() {
s += "var v" + i + "=0;";
}
s += '}';
var result = Uglify.minify(s, {
var result = UglifyJS.minify(s, {
compress: false
}).code;
@@ -39,7 +39,7 @@ describe("let", function() {
for (var i = 0; i < 18000; i++) {
s += "v.b" + i + ";";
}
var result = Uglify.minify(s, {
var result = UglifyJS.minify(s, {
compress: false,
ie8: true,
mangle: {

View File

@@ -1,5 +1,5 @@
var Uglify = require("../node");
var assert = require("assert");
var UglifyJS = require("../node");
describe("line-endings", function() {
var options = {
@@ -14,19 +14,19 @@ describe("line-endings", function() {
it("Should parse LF line endings", function() {
var js = '/*!one\n2\n3*///comment\nfunction f(x) {\n if (x)\n//comment\n return 3;\n}\n';
var result = Uglify.minify(js, options);
var result = UglifyJS.minify(js, options);
assert.strictEqual(result.code, expected_code);
});
it("Should parse CR/LF line endings", function() {
var js = '/*!one\r\n2\r\n3*///comment\r\nfunction f(x) {\r\n if (x)\r\n//comment\r\n return 3;\r\n}\r\n';
var result = Uglify.minify(js, options);
var result = UglifyJS.minify(js, options);
assert.strictEqual(result.code, expected_code);
});
it("Should parse CR line endings", function() {
var js = '/*!one\r2\r3*///comment\rfunction f(x) {\r if (x)\r//comment\r return 3;\r}\r';
var result = Uglify.minify(js, options);
var result = UglifyJS.minify(js, options);
assert.strictEqual(result.code, expected_code);
});
@@ -44,16 +44,15 @@ describe("line-endings", function() {
]
var test = function(input) {
return function() {
Uglify.parse(input);
UglifyJS.parse(input);
}
}
var fail = function(e) {
return e instanceof Uglify.JS_Parse_Error &&
e.message === "Unexpected line terminator";
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Unexpected line terminator";
}
for (var i = 0; i < inputs.length; i++) {
assert.throws(test(inputs[i]), fail);
}
});
});

View File

@@ -1,22 +1,22 @@
var Uglify = require('../../');
var assert = require("assert");
var UglifyJS = require("../..");
describe("Input file as map", function() {
it("Should accept object", function() {
var jsMap = {
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
};
var result = Uglify.minify(jsMap, {sourceMap: true});
var result = UglifyJS.minify(jsMap, {sourceMap: true});
var map = JSON.parse(result.map);
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
assert.deepEqual(map.sources, ['/scripts/foo.js']);
assert.strictEqual(map.file, undefined);
result = Uglify.minify(jsMap);
result = UglifyJS.minify(jsMap);
assert.strictEqual(result.map, undefined);
result = Uglify.minify(jsMap, {sourceMap: {filename: 'out.js'}});
result = UglifyJS.minify(jsMap, {sourceMap: {filename: 'out.js'}});
map = JSON.parse(result.map);
assert.strictEqual(map.file, 'out.js');
});
@@ -26,7 +26,7 @@ describe("Input file as map", function() {
'var foo = {"x": 1, y: 2, \'z\': 3};',
'var bar = 15;'
];
var result = Uglify.minify(jsSeq, {sourceMap: true});
var result = UglifyJS.minify(jsSeq, {sourceMap: true});
var map = JSON.parse(result.map);
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
@@ -37,7 +37,7 @@ describe("Input file as map", function() {
var jsMap = {
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
};
var result = Uglify.minify(jsMap, {sourceMap: {includeSources: true}});
var result = UglifyJS.minify(jsMap, {sourceMap: {includeSources: true}});
var map = JSON.parse(result.map);
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');

View File

@@ -1,7 +1,7 @@
var Uglify = require('../../');
var assert = require("assert");
var readFileSync = require("fs").readFileSync;
var run_code = require("../sandbox").run_code;
var UglifyJS = require("../../");
function read(path) {
return readFileSync(path, "utf8");
@@ -10,14 +10,14 @@ function read(path) {
describe("minify", function() {
it("Should test basic sanity of minify with default options", function() {
var js = 'function foo(bar) { if (bar) return 3; else return 7; var u = not_called(); }';
var result = Uglify.minify(js);
var result = UglifyJS.minify(js);
assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
});
it("Should skip inherited keys from `files`", function() {
var files = Object.create({ skip: this });
files[0] = "alert(1 + 1)";
var result = Uglify.minify(files);
var result = UglifyJS.minify(files);
assert.strictEqual(result.code, "alert(2);");
});
@@ -32,7 +32,7 @@ describe("minify", function() {
"qux.js",
].forEach(function(file) {
var code = read("test/input/issue-1242/" + file);
var result = Uglify.minify(code, {
var result = UglifyJS.minify(code, {
mangle: {
cache: cache,
toplevel: true
@@ -65,7 +65,7 @@ describe("minify", function() {
"qux.js",
].forEach(function(file) {
var code = read("test/input/issue-1242/" + file);
var result = Uglify.minify(code, {
var result = UglifyJS.minify(code, {
mangle: {
toplevel: true
},
@@ -96,7 +96,7 @@ describe("minify", function() {
'"xxyyy";var j={t:2,u:3},k=4;',
'console.log(i.s,j.t,j.u,k);',
].forEach(function(code) {
var result = Uglify.minify(code, {
var result = UglifyJS.minify(code, {
compress: false,
mangle: {
properties: true,
@@ -117,15 +117,15 @@ describe("minify", function() {
});
it("Should not parse invalid use of reserved words", function() {
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
assert.strictEqual(Uglify.minify("function this(){}").error.message, "Unexpected token: name (this)");
assert.strictEqual(UglifyJS.minify("function enum(){}").error, undefined);
assert.strictEqual(UglifyJS.minify("function static(){}").error, undefined);
assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name (this)");
});
describe("keep_quoted_props", function() {
it("Should preserve quotes in object literals", function() {
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
var result = Uglify.minify(js, {
var result = UglifyJS.minify(js, {
output: {
keep_quoted_props: true
}});
@@ -134,7 +134,7 @@ describe("minify", function() {
it("Should preserve quote styles when quote_style is 3", function() {
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
var result = Uglify.minify(js, {
var result = UglifyJS.minify(js, {
output: {
keep_quoted_props: true,
quote_style: 3
@@ -144,7 +144,7 @@ describe("minify", function() {
it("Should not preserve quotes in object literals when disabled", function() {
var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
var result = Uglify.minify(js, {
var result = UglifyJS.minify(js, {
output: {
keep_quoted_props: false,
quote_style: 3
@@ -156,7 +156,7 @@ describe("minify", function() {
describe("mangleProperties", function() {
it("Shouldn't mangle quoted properties", function() {
var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
var result = Uglify.minify(js, {
var result = UglifyJS.minify(js, {
compress: {
properties: false
},
@@ -174,7 +174,7 @@ describe("minify", function() {
'a["foo"]="bar",a.a="red",x={"bar":10};');
});
it("Should not mangle quoted property within dead code", function() {
var result = Uglify.minify('({ "keep": 1 }); g.keep = g.change;', {
var result = UglifyJS.minify('({ "keep": 1 }); g.keep = g.change;', {
mangle: {
properties: {
keep_quoted: true
@@ -187,8 +187,8 @@ describe("minify", function() {
});
describe("#__PURE__", function() {
it("should drop #__PURE__ hint after use", function() {
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
it("Should drop #__PURE__ hint after use", function() {
var result = UglifyJS.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
output: {
comments: "all",
beautify: false,
@@ -197,8 +197,8 @@ describe("minify", function() {
var code = result.code;
assert.strictEqual(code, "// comment1 comment2\nbar();");
});
it("should drop #__PURE__ hint if function is retained", function() {
var result = Uglify.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
it("Should drop #__PURE__ hint if function is retained", function() {
var result = UglifyJS.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
output: {
comments: "all",
beautify: false,
@@ -210,8 +210,8 @@ describe("minify", function() {
});
describe("JS_Parse_Error", function() {
it("should return syntax error", function() {
var result = Uglify.minify("function f(a{}");
it("Should return syntax error", function() {
var result = UglifyJS.minify("function f(a{}");
var err = result.error;
assert.ok(err instanceof Error);
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
@@ -219,8 +219,8 @@ describe("minify", function() {
assert.strictEqual(err.line, 1);
assert.strictEqual(err.col, 12);
});
it("should reject duplicated label name", function() {
var result = Uglify.minify("L:{L:{}}");
it("Should reject duplicated label name", function() {
var result = UglifyJS.minify("L:{L:{}}");
var err = result.error;
assert.ok(err instanceof Error);
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Label L defined twice");
@@ -231,8 +231,8 @@ describe("minify", function() {
});
describe("global_defs", function() {
it("should throw for non-trivial expressions", function() {
var result = Uglify.minify("alert(42);", {
it("Should throw for non-trivial expressions", function() {
var result = UglifyJS.minify("alert(42);", {
compress: {
global_defs: {
"@alert": "debugger"
@@ -243,10 +243,10 @@ describe("minify", function() {
assert.ok(err instanceof Error);
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
});
it("should skip inherited properties", function() {
it("Should skip inherited properties", function() {
var foo = Object.create({ skip: this });
foo.bar = 42;
var result = Uglify.minify("alert(FOO);", {
var result = UglifyJS.minify("alert(FOO);", {
compress: {
global_defs: {
FOO: foo
@@ -266,7 +266,7 @@ describe("minify", function() {
"}",
"f();",
].join("\n");
var ast = Uglify.minify(code, {
var ast = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
@@ -279,7 +279,7 @@ describe("minify", function() {
assert.strictEqual(ast.body[0].body.length, 2);
assert.strictEqual(ast.body[0].body[0].TYPE, "SimpleStatement");
var stat = ast.body[0].body[0];
Uglify.minify(ast, {
UglifyJS.minify(ast, {
compress: {
sequences: false
},
@@ -294,7 +294,7 @@ describe("minify", function() {
it("Should be repeatable", function() {
var code = "!function(x){return x(x)}(y);";
for (var i = 0; i < 2; i++) {
assert.strictEqual(Uglify.minify(code, {
assert.strictEqual(UglifyJS.minify(code, {
compress: {
toplevel: true,
},
@@ -303,4 +303,45 @@ describe("minify", function() {
}
});
});
describe("enclose", function() {
var code = read("test/input/enclose/input.js");
it("Should work with true", function() {
var result = UglifyJS.minify(code, {
compress: false,
enclose: true,
mangle: false,
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '(function(){function enclose(){console.log("test enclose")}enclose()})();');
});
it("Should work with arg", function() {
var result = UglifyJS.minify(code, {
compress: false,
enclose: 'undefined',
mangle: false,
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '(function(undefined){function enclose(){console.log("test enclose")}enclose()})();');
});
it("Should work with arg:value", function() {
var result = UglifyJS.minify(code, {
compress: false,
enclose: 'window,undefined:window',
mangle: false,
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '(function(window,undefined){function enclose(){console.log("test enclose")}enclose()})(window);');
});
it("Should work alongside wrap", function() {
var result = UglifyJS.minify(code, {
compress: false,
enclose: 'window,undefined:window',
mangle: false,
wrap: 'exports',
});
if (result.error) throw result.error;
assert.strictEqual(result.code, '(function(window,undefined){(function(exports){function enclose(){console.log("test enclose")}enclose()})(typeof exports=="undefined"?exports={}:exports)})(window);');
});
});
});

View File

@@ -1,24 +1,23 @@
var assert = require("assert");
var uglify = require("../node");
var UglifyJS = require("../node");
describe("Number literals", function () {
describe("Number literals", function() {
it("Should not allow legacy octal literals in strict mode", function() {
var inputs = [
'"use strict";00;',
'"use strict"; var foo = 00;'
];
var test = function(input) {
return function() {
uglify.parse(input);
UglifyJS.parse(input);
}
}
};
var error = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "Legacy octal literals are not allowed in strict mode";
}
return e instanceof UglifyJS.JS_Parse_Error
&& e.message === "Legacy octal literals are not allowed in strict mode";
};
for (var i = 0; i < inputs.length; i++) {
assert.throws(test(inputs[i]), error, inputs[i]);
}
});
});
});

View File

@@ -1,5 +1,5 @@
var UglifyJS = require("../node");
var assert = require("assert");
var UglifyJS = require("../..");
describe("operator", function() {
it("Should handle mixing of ++/+/--/- correctly", function() {

View File

@@ -1,5 +1,5 @@
var assert = require("assert");
var uglify = require("../../");
var UglifyJS = require("../..");
describe("parentheses", function() {
it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
@@ -33,7 +33,7 @@ describe("parentheses", function() {
];
for (var i = 0; i < tests.length; i++) {
assert.strictEqual(
uglify.minify(tests[i], {
UglifyJS.minify(tests[i], {
output: {beautify: true},
compress: false,
mangle: false
@@ -74,7 +74,7 @@ describe("parentheses", function() {
];
for (var i = 0; i < tests.length; i++) {
assert.strictEqual(
uglify.minify(tests[i], {
UglifyJS.minify(tests[i], {
output: {beautify: false},
compress: false,
mangle: false
@@ -94,7 +94,7 @@ describe("parentheses", function() {
code = code.concat(code);
}
code = code.join("");
var result = uglify.minify(code, {
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
});

View File

@@ -1,21 +0,0 @@
var assert = require("assert");
var uglify = require("../../");
describe("screw-ie8", function () {
it("Should be able to minify() with undefined as catch parameter in a try...catch statement", function () {
assert.strictEqual(
uglify.minify(
"function a(b){\
try {\
throw 'Stuff';\
} catch (undefined) {\
console.log('caught: ' + undefined);\
}\
console.log('undefined is ' + undefined);\
return b === undefined;\
};"
).code,
'function a(o){try{throw"Stuff"}catch(o){console.log("caught: "+o)}return console.log("undefined is "+void 0),void 0===o}'
);
});
});

Some files were not shown because too many files have changed in this diff Show More