Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bce7ee5f6a | ||
|
|
b39043f3ab | ||
|
|
caf96acb08 | ||
|
|
c76749084b | ||
|
|
5843494ee2 | ||
|
|
efa21ae3e6 | ||
|
|
24d9633a35 | ||
|
|
7963b96681 | ||
|
|
8c62d854ce | ||
|
|
69931574e1 | ||
|
|
b5af8a1914 | ||
|
|
c14d09ba84 | ||
|
|
4fc39d8dad | ||
|
|
0b7c70f726 | ||
|
|
f72d3029dd | ||
|
|
1a0d6edc81 | ||
|
|
7b59b2f5b2 | ||
|
|
7bc7704edf | ||
|
|
14e712ee80 | ||
|
|
f83adcc995 | ||
|
|
df8a99439a | ||
|
|
6b91d12ec3 | ||
|
|
f37b91879f | ||
|
|
d835c72c80 | ||
|
|
c4cebb4b01 | ||
|
|
d51a00a450 | ||
|
|
fc0f168a0c | ||
|
|
a0ca595c2c | ||
|
|
1a314e9f60 | ||
|
|
6fcbd5e217 | ||
|
|
22cea023d1 | ||
|
|
70d4477e05 | ||
|
|
838f837379 | ||
|
|
82a8b6f612 | ||
|
|
69fc7ca8da | ||
|
|
0a79496e0a | ||
|
|
9e87edfc2e | ||
|
|
27211cf2d5 | ||
|
|
b5ce199711 | ||
|
|
c71ed91e63 | ||
|
|
f7545d0f1c | ||
|
|
59eecb6bf5 | ||
|
|
d83c6490ab | ||
|
|
7362f57966 | ||
|
|
eaa2c1f6af | ||
|
|
6a916523d4 | ||
|
|
ba7069d52b | ||
|
|
4dd7d0e39b | ||
|
|
90199d0a96 | ||
|
|
b82fd0ad41 | ||
|
|
183da16896 | ||
|
|
87857b0f1b | ||
|
|
e5f6a88233 | ||
|
|
8d0b00317e | ||
|
|
db49daf365 | ||
|
|
923deeff35 | ||
|
|
0b62a28b47 | ||
|
|
44116c6d2b | ||
|
|
b5bab254ce | ||
|
|
81603ecd15 | ||
|
|
e67553fa55 |
8
.github/ISSUE_TEMPLATE.md
vendored
8
.github/ISSUE_TEMPLATE.md
vendored
@@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
<!-- Note: sub-optimal but correct code is not a bug -->
|
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||||
|
|
||||||
**ES5 or ES6+ input?**
|
|
||||||
|
|
||||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
|
||||||
|
|
||||||
**Uglify version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input**
|
**JavaScript input**
|
||||||
@@ -24,6 +20,6 @@
|
|||||||
**JavaScript output or error produced.**
|
**JavaScript output or error produced.**
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Note: `uglify-js` only supports ES5.
|
Note: `uglify-js` only supports JavaScript.
|
||||||
Those wishing to minify ES6 should use `uglify-es`.
|
Those wishing to minify ES6+ should transpile first.
|
||||||
-->
|
-->
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -104,6 +104,8 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
sequences.
|
sequences.
|
||||||
--config-file <file> Read `minify()` options from JSON file.
|
--config-file <file> Read `minify()` options from JSON file.
|
||||||
-d, --define <expr>[=value] Global definitions.
|
-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.
|
--ie8 Support non-standard Internet Explorer 8.
|
||||||
Equivalent to setting `ie8: true` in `minify()`
|
Equivalent to setting `ie8: true` in `minify()`
|
||||||
for `compress`, `mangle` and `output` options.
|
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
|
JS that was generated from some other original
|
||||||
code. Specify "inline" if the source map is
|
code. Specify "inline" if the source map is
|
||||||
included within the sources.
|
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
|
`includeSources` Pass this flag if you want to include
|
||||||
the content of source files in the
|
the content of source files in the
|
||||||
source map as sourcesContent property.
|
source map as sourcesContent property.
|
||||||
@@ -149,7 +152,9 @@ debugging your compressed JavaScript. To get a source map, pass
|
|||||||
|
|
||||||
Additional options:
|
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.
|
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
|
||||||
|
|
||||||
@@ -685,7 +690,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
|
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
|
||||||
function won't produce any side effect, in which case the whole
|
function won't produce any side effect, in which case the whole
|
||||||
statement would get discarded. The current implementation adds some
|
statement would get discarded. The current implementation adds some
|
||||||
overhead (compression will be slower).
|
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||||
|
are also under `mangle.reserved` to avoid mangling.
|
||||||
|
|
||||||
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
||||||
this, UglifyJS will assume that object property access
|
this, UglifyJS will assume that object property access
|
||||||
@@ -1040,8 +1046,9 @@ var result = UglifyJS.minify(ast, {
|
|||||||
### Working with Uglify AST
|
### Working with Uglify AST
|
||||||
|
|
||||||
Transversal and transformation of the native AST can be performed through
|
Transversal and transformation of the native AST can be performed through
|
||||||
[`TreeWalker`](http://lisperator.net/uglifyjs/walk) and
|
[`TreeWalker`](https://github.com/mishoo/UglifyJS2/blob/master/lib/ast.js) and
|
||||||
[`TreeTransformer`](http://lisperator.net/uglifyjs/transform) respectively.
|
[`TreeTransformer`](https://github.com/mishoo/UglifyJS2/blob/master/lib/transform.js)
|
||||||
|
respectively.
|
||||||
|
|
||||||
### ESTree / SpiderMonkey AST
|
### ESTree / SpiderMonkey AST
|
||||||
|
|
||||||
|
|||||||
@@ -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("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
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("--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("--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.");
|
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("--no-rename", "Disable symbol expansion.");
|
||||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
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("--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("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||||
program.option("--verbose", "Print diagnostic messages.");
|
program.option("--verbose", "Print diagnostic messages.");
|
||||||
program.option("--warn", "Print warning messages.");
|
program.option("--warn", "Print warning messages.");
|
||||||
@@ -61,6 +62,7 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|||||||
}
|
}
|
||||||
[
|
[
|
||||||
"compress",
|
"compress",
|
||||||
|
"enclose",
|
||||||
"ie8",
|
"ie8",
|
||||||
"mangle",
|
"mangle",
|
||||||
"sourceMap",
|
"sourceMap",
|
||||||
|
|||||||
27
lib/ast.js
27
lib/ast.js
@@ -314,6 +314,9 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
|||||||
if (this.functions) node.functions = this.functions.clone();
|
if (this.functions) node.functions = this.functions.clone();
|
||||||
if (this.enclosed) node.enclosed = this.enclosed.slice();
|
if (this.enclosed) node.enclosed = this.enclosed.slice();
|
||||||
return node;
|
return node;
|
||||||
|
},
|
||||||
|
pinned: function() {
|
||||||
|
return this.uses_eval || this.uses_with;
|
||||||
}
|
}
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
@@ -332,6 +335,23 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return wrapped_tl;
|
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);
|
}, AST_Scope);
|
||||||
|
|
||||||
@@ -544,11 +564,10 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
|||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function() {
|
return visitor._visit(this, function() {
|
||||||
var args = this.args;
|
|
||||||
for (var i = 0, len = args.length; i < len; i++) {
|
|
||||||
args[i]._walk(visitor);
|
|
||||||
}
|
|
||||||
this.expression._walk(visitor);
|
this.expression._walk(visitor);
|
||||||
|
this.args.forEach(function(node) {
|
||||||
|
node._walk(visitor);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
694
lib/compress.js
694
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -7,15 +7,23 @@ var to_base64 = typeof btoa == "undefined" ? function(str) {
|
|||||||
return new Buffer(str).toString("base64");
|
return new Buffer(str).toString("base64");
|
||||||
} : btoa;
|
} : btoa;
|
||||||
|
|
||||||
function read_source_map(code) {
|
function read_source_map(name, code) {
|
||||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
AST_Node.warn("inline source map not found");
|
AST_Node.warn("inline source map not found: " + name);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return to_ascii(match[2]);
|
return to_ascii(match[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_source_map(content) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(content);
|
||||||
|
} catch (ex) {
|
||||||
|
throw new Error("invalid input source map: " + content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function set_shorthand(name, options, keys) {
|
function set_shorthand(name, options, keys) {
|
||||||
if (options[name]) {
|
if (options[name]) {
|
||||||
keys.forEach(function(key) {
|
keys.forEach(function(key) {
|
||||||
@@ -47,6 +55,7 @@ function minify(files, options) {
|
|||||||
try {
|
try {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
compress: {},
|
compress: {},
|
||||||
|
enclose: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
@@ -113,7 +122,7 @@ function minify(files, options) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (timings) timings.parse = Date.now();
|
if (timings) timings.parse = Date.now();
|
||||||
var toplevel;
|
var source_maps, toplevel;
|
||||||
if (files instanceof AST_Toplevel) {
|
if (files instanceof AST_Toplevel) {
|
||||||
toplevel = files;
|
toplevel = files;
|
||||||
} else {
|
} else {
|
||||||
@@ -122,13 +131,23 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
options.parse = options.parse || {};
|
options.parse = options.parse || {};
|
||||||
options.parse.toplevel = null;
|
options.parse.toplevel = null;
|
||||||
|
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||||
|
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||||
|
source_map_content = parse_source_map(source_map_content);
|
||||||
|
}
|
||||||
|
source_maps = source_map_content && Object.create(null);
|
||||||
for (var name in files) if (HOP(files, name)) {
|
for (var name in files) if (HOP(files, name)) {
|
||||||
options.parse.filename = name;
|
options.parse.filename = name;
|
||||||
options.parse.toplevel = parse(files[name], options.parse);
|
options.parse.toplevel = parse(files[name], options.parse);
|
||||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
if (source_maps) {
|
||||||
if (Object.keys(files).length > 1)
|
if (source_map_content == "inline") {
|
||||||
throw new Error("inline source map only works with singular input");
|
var inlined_content = read_source_map(name, files[name]);
|
||||||
options.sourceMap.content = read_source_map(files[name]);
|
if (inlined_content) {
|
||||||
|
source_maps[name] = parse_source_map(inlined_content);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
source_maps[name] = source_map_content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toplevel = options.parse.toplevel;
|
toplevel = options.parse.toplevel;
|
||||||
@@ -139,6 +158,9 @@ function minify(files, options) {
|
|||||||
if (options.wrap) {
|
if (options.wrap) {
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
}
|
}
|
||||||
|
if (options.enclose) {
|
||||||
|
toplevel = toplevel.wrap_enclose(options.enclose);
|
||||||
|
}
|
||||||
if (timings) timings.rename = Date.now();
|
if (timings) timings.rename = Date.now();
|
||||||
if (options.rename) {
|
if (options.rename) {
|
||||||
toplevel.figure_out_scope(options.mangle);
|
toplevel.figure_out_scope(options.mangle);
|
||||||
@@ -164,16 +186,9 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
if (!HOP(options.output, "code") || options.output.code) {
|
if (!HOP(options.output, "code") || options.output.code) {
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
if (typeof options.sourceMap.content == "string") {
|
|
||||||
try {
|
|
||||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
|
||||||
} catch (ex) {
|
|
||||||
throw new Error("invalid input source map: " + options.sourceMap.content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
options.output.source_map = SourceMap({
|
options.output.source_map = SourceMap({
|
||||||
file: options.sourceMap.filename,
|
file: options.sourceMap.filename,
|
||||||
orig: options.sourceMap.content,
|
orig: source_maps,
|
||||||
root: options.sourceMap.root
|
root: options.sourceMap.root
|
||||||
});
|
});
|
||||||
if (options.sourceMap.includeSources) {
|
if (options.sourceMap.includeSources) {
|
||||||
@@ -182,6 +197,8 @@ function minify(files, options) {
|
|||||||
} else for (var name in files) if (HOP(files, name)) {
|
} else for (var name in files) if (HOP(files, name)) {
|
||||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
options.output.source_map.get()._sourcesContents = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete options.output.ast;
|
delete options.output.ast;
|
||||||
|
|||||||
105
lib/output.js
105
lib/output.js
@@ -173,7 +173,7 @@ function OutputStream(options) {
|
|||||||
default:
|
default:
|
||||||
return dq > sq ? quote_single() : quote_double();
|
return dq > sq ? quote_single() : quote_double();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function encode_string(str, quote) {
|
function encode_string(str, quote) {
|
||||||
var ret = make_string(str, quote);
|
var ret = make_string(str, quote);
|
||||||
@@ -183,20 +183,21 @@ function OutputStream(options) {
|
|||||||
ret = ret.replace(/--\x3e/g, "--\\x3e");
|
ret = ret.replace(/--\x3e/g, "--\\x3e");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
function make_name(name) {
|
function make_name(name) {
|
||||||
name = name.toString();
|
name = name.toString();
|
||||||
name = to_utf8(name, true);
|
name = to_utf8(name, true);
|
||||||
return name;
|
return name;
|
||||||
};
|
}
|
||||||
|
|
||||||
function make_indent(back) {
|
function make_indent(back) {
|
||||||
return repeat_string(" ", options.indent_start + indentation - back * options.indent_level);
|
return repeat_string(" ", options.indent_start + indentation - back * options.indent_level);
|
||||||
};
|
}
|
||||||
|
|
||||||
/* -----[ beautification/minification ]----- */
|
/* -----[ beautification/minification ]----- */
|
||||||
|
|
||||||
|
var has_parens = false;
|
||||||
var might_need_space = false;
|
var might_need_space = false;
|
||||||
var might_need_semicolon = false;
|
var might_need_semicolon = false;
|
||||||
var might_add_newline = 0;
|
var might_add_newline = 0;
|
||||||
@@ -280,7 +281,7 @@ function OutputStream(options) {
|
|||||||
might_need_semicolon = false;
|
might_need_semicolon = false;
|
||||||
|
|
||||||
if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
|
if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
|
||||||
if (options.semicolons || requireSemicolonChars(ch)) {
|
if (options.semicolons || requireSemicolonChars[ch]) {
|
||||||
OUTPUT += ";";
|
OUTPUT += ";";
|
||||||
current_col++;
|
current_col++;
|
||||||
current_pos++;
|
current_pos++;
|
||||||
@@ -340,6 +341,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OUTPUT += str;
|
OUTPUT += str;
|
||||||
|
has_parens = str[str.length - 1] == "(";
|
||||||
current_pos += str.length;
|
current_pos += str.length;
|
||||||
var a = str.split(/\r?\n/), n = a.length - 1;
|
var a = str.split(/\r?\n/), n = a.length - 1;
|
||||||
current_line += n;
|
current_line += n;
|
||||||
@@ -349,7 +351,7 @@ function OutputStream(options) {
|
|||||||
current_col = a[n].length;
|
current_col = a[n].length;
|
||||||
}
|
}
|
||||||
last = str;
|
last = str;
|
||||||
};
|
}
|
||||||
|
|
||||||
var space = options.beautify ? function() {
|
var space = options.beautify ? function() {
|
||||||
print(" ");
|
print(" ");
|
||||||
@@ -372,6 +374,11 @@ function OutputStream(options) {
|
|||||||
return ret;
|
return ret;
|
||||||
} : function(col, cont) { return cont() };
|
} : function(col, cont) { return cont() };
|
||||||
|
|
||||||
|
var may_add_newline = options.max_line_len ? function() {
|
||||||
|
ensure_line_len();
|
||||||
|
might_add_newline = OUTPUT.length;
|
||||||
|
} : noop;
|
||||||
|
|
||||||
var newline = options.beautify ? function() {
|
var newline = options.beautify ? function() {
|
||||||
if (newline_insert < 0) return print("\n");
|
if (newline_insert < 0) return print("\n");
|
||||||
if (OUTPUT[newline_insert] != "\n") {
|
if (OUTPUT[newline_insert] != "\n") {
|
||||||
@@ -380,10 +387,7 @@ function OutputStream(options) {
|
|||||||
current_line++;
|
current_line++;
|
||||||
}
|
}
|
||||||
newline_insert++;
|
newline_insert++;
|
||||||
} : options.max_line_len ? function() {
|
} : may_add_newline;
|
||||||
ensure_line_len();
|
|
||||||
might_add_newline = OUTPUT.length;
|
|
||||||
} : noop;
|
|
||||||
|
|
||||||
var semicolon = options.beautify ? function() {
|
var semicolon = options.beautify ? function() {
|
||||||
print(";");
|
print(";");
|
||||||
@@ -394,11 +398,11 @@ function OutputStream(options) {
|
|||||||
function force_semicolon() {
|
function force_semicolon() {
|
||||||
might_need_semicolon = false;
|
might_need_semicolon = false;
|
||||||
print(";");
|
print(";");
|
||||||
};
|
}
|
||||||
|
|
||||||
function next_indent() {
|
function next_indent() {
|
||||||
return indentation + options.indent_level;
|
return indentation + options.indent_level;
|
||||||
};
|
}
|
||||||
|
|
||||||
function with_block(cont) {
|
function with_block(cont) {
|
||||||
var ret;
|
var ret;
|
||||||
@@ -410,34 +414,40 @@ function OutputStream(options) {
|
|||||||
indent();
|
indent();
|
||||||
print("}");
|
print("}");
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
function with_parens(cont) {
|
function with_parens(cont) {
|
||||||
print("(");
|
print("(");
|
||||||
|
may_add_newline();
|
||||||
//XXX: still nice to have that for argument lists
|
//XXX: still nice to have that for argument lists
|
||||||
//var ret = with_indent(current_col, cont);
|
//var ret = with_indent(current_col, cont);
|
||||||
var ret = cont();
|
var ret = cont();
|
||||||
|
may_add_newline();
|
||||||
print(")");
|
print(")");
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
function with_square(cont) {
|
function with_square(cont) {
|
||||||
print("[");
|
print("[");
|
||||||
|
may_add_newline();
|
||||||
//var ret = with_indent(current_col, cont);
|
//var ret = with_indent(current_col, cont);
|
||||||
var ret = cont();
|
var ret = cont();
|
||||||
|
may_add_newline();
|
||||||
print("]");
|
print("]");
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
function comma() {
|
function comma() {
|
||||||
|
may_add_newline();
|
||||||
print(",");
|
print(",");
|
||||||
|
may_add_newline();
|
||||||
space();
|
space();
|
||||||
};
|
}
|
||||||
|
|
||||||
function colon() {
|
function colon() {
|
||||||
print(":");
|
print(":");
|
||||||
space();
|
space();
|
||||||
};
|
}
|
||||||
|
|
||||||
var add_mapping = mappings ? function(token, name) {
|
var add_mapping = mappings ? function(token, name) {
|
||||||
mapping_token = token;
|
mapping_token = token;
|
||||||
@@ -449,7 +459,7 @@ function OutputStream(options) {
|
|||||||
ensure_line_len();
|
ensure_line_len();
|
||||||
}
|
}
|
||||||
return OUTPUT;
|
return OUTPUT;
|
||||||
};
|
}
|
||||||
|
|
||||||
function has_nlb() {
|
function has_nlb() {
|
||||||
var index = OUTPUT.lastIndexOf("\n");
|
var index = OUTPUT.lastIndexOf("\n");
|
||||||
@@ -576,7 +586,7 @@ function OutputStream(options) {
|
|||||||
indentation : function() { return indentation },
|
indentation : function() { return indentation },
|
||||||
current_width : function() { return current_col - indentation },
|
current_width : function() { return current_col - indentation },
|
||||||
should_break : function() { return options.width && this.current_width() >= options.width },
|
should_break : function() { return options.width && this.current_width() >= options.width },
|
||||||
has_parens : function() { return OUTPUT[OUTPUT.length - 1] == "(" },
|
has_parens : function() { return has_parens },
|
||||||
newline : newline,
|
newline : newline,
|
||||||
print : print,
|
print : print,
|
||||||
space : space,
|
space : space,
|
||||||
@@ -617,8 +627,7 @@ function OutputStream(options) {
|
|||||||
return stack[stack.length - 2 - (n || 0)];
|
return stack[stack.length - 2 - (n || 0)];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/* -----[ code generators ]----- */
|
/* -----[ code generators ]----- */
|
||||||
|
|
||||||
@@ -628,7 +637,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function DEFPRINT(nodetype, generator) {
|
function DEFPRINT(nodetype, generator) {
|
||||||
nodetype.DEFMETHOD("_codegen", generator);
|
nodetype.DEFMETHOD("_codegen", generator);
|
||||||
};
|
}
|
||||||
|
|
||||||
var in_directive = false;
|
var in_directive = false;
|
||||||
var active_scope = null;
|
var active_scope = null;
|
||||||
@@ -677,7 +686,7 @@ function OutputStream(options) {
|
|||||||
} else {
|
} else {
|
||||||
nodetype.DEFMETHOD("needs_parens", func);
|
nodetype.DEFMETHOD("needs_parens", func);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
PARENS(AST_Node, return_false);
|
PARENS(AST_Node, return_false);
|
||||||
|
|
||||||
@@ -863,7 +872,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
in_directive = false;
|
in_directive = false;
|
||||||
};
|
}
|
||||||
|
|
||||||
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
|
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
|
||||||
force_statement(this.body, output);
|
force_statement(this.body, output);
|
||||||
@@ -899,7 +908,7 @@ function OutputStream(options) {
|
|||||||
display_body(self.body, false, output, allow_directives);
|
display_body(self.body, false, output, allow_directives);
|
||||||
});
|
});
|
||||||
} else print_braced_empty(self, output);
|
} else print_braced_empty(self, output);
|
||||||
};
|
}
|
||||||
DEFPRINT(AST_BlockStatement, function(self, output){
|
DEFPRINT(AST_BlockStatement, function(self, output){
|
||||||
print_braced(self, output);
|
print_braced(self, output);
|
||||||
});
|
});
|
||||||
@@ -1062,7 +1071,7 @@ function OutputStream(options) {
|
|||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
force_statement(self.body, output);
|
force_statement(self.body, output);
|
||||||
};
|
}
|
||||||
DEFPRINT(AST_If, function(self, output){
|
DEFPRINT(AST_If, function(self, output){
|
||||||
output.print("if");
|
output.print("if");
|
||||||
output.space();
|
output.space();
|
||||||
@@ -1182,7 +1191,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
node.print(output, parens);
|
node.print(output, parens);
|
||||||
};
|
}
|
||||||
|
|
||||||
DEFPRINT(AST_VarDef, function(self, output){
|
DEFPRINT(AST_VarDef, function(self, output){
|
||||||
self.name.print(output);
|
self.name.print(output);
|
||||||
@@ -1244,7 +1253,7 @@ function OutputStream(options) {
|
|||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
expr.print(output);
|
expr.print(output);
|
||||||
var prop = self.property;
|
var prop = self.property;
|
||||||
if (output.option("ie8") && RESERVED_WORDS(prop)) {
|
if (output.option("ie8") && RESERVED_WORDS[prop]) {
|
||||||
output.print("[");
|
output.print("[");
|
||||||
output.add_mapping(self.end);
|
output.add_mapping(self.end);
|
||||||
output.print_string(prop);
|
output.print_string(prop);
|
||||||
@@ -1356,7 +1365,7 @@ function OutputStream(options) {
|
|||||||
output.print_string(key);
|
output.print_string(key);
|
||||||
} else if ("" + +key == key && key >= 0) {
|
} else if ("" + +key == key && key >= 0) {
|
||||||
output.print(make_num(key));
|
output.print(make_num(key));
|
||||||
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
} else if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) {
|
||||||
if (quote && output.option("keep_quoted_props")) {
|
if (quote && output.option("keep_quoted_props")) {
|
||||||
output.print_string(key, quote);
|
output.print_string(key, quote);
|
||||||
} else {
|
} else {
|
||||||
@@ -1428,7 +1437,7 @@ function OutputStream(options) {
|
|||||||
else
|
else
|
||||||
stat.print(output);
|
stat.print(output);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// self should be AST_New. decide if we want to show parens or not.
|
// self should be AST_New. decide if we want to show parens or not.
|
||||||
function need_constructor_parens(self, output) {
|
function need_constructor_parens(self, output) {
|
||||||
@@ -1436,7 +1445,7 @@ function OutputStream(options) {
|
|||||||
if (self.args.length > 0) return true;
|
if (self.args.length > 0) return true;
|
||||||
|
|
||||||
return output.option("beautify");
|
return output.option("beautify");
|
||||||
};
|
}
|
||||||
|
|
||||||
function best_of(a) {
|
function best_of(a) {
|
||||||
var best = a[0], len = best.length;
|
var best = a[0], len = best.length;
|
||||||
@@ -1447,27 +1456,31 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return best;
|
return best;
|
||||||
};
|
}
|
||||||
|
|
||||||
function make_num(num) {
|
function make_num(num) {
|
||||||
var str = num.toString(10), a = [ str.replace(/^0\./, ".").replace('e+', 'e') ], m;
|
var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e");
|
||||||
|
var candidates = [ str ];
|
||||||
if (Math.floor(num) === num) {
|
if (Math.floor(num) === num) {
|
||||||
if (num >= 0) {
|
if (num < 0) {
|
||||||
a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
|
candidates.push("-0x" + (-num).toString(16).toLowerCase());
|
||||||
"0" + num.toString(8)); // same.
|
|
||||||
} else {
|
} else {
|
||||||
a.push("-0x" + (-num).toString(16).toLowerCase(), // probably pointless
|
candidates.push("0x" + num.toString(16).toLowerCase());
|
||||||
"-0" + (-num).toString(8)); // same.
|
|
||||||
}
|
}
|
||||||
if ((m = /^(.*?)(0+)$/.exec(num))) {
|
|
||||||
a.push(m[1] + "e" + m[2].length);
|
|
||||||
}
|
}
|
||||||
} else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
|
var match, len, digits;
|
||||||
a.push(m[2] + "e-" + (m[1].length + m[2].length),
|
if (match = /^\.0+/.exec(str)) {
|
||||||
str.substr(str.indexOf(".")));
|
len = match[0].length;
|
||||||
|
digits = str.slice(len);
|
||||||
|
candidates.push(digits + "e-" + (digits.length + len - 1));
|
||||||
|
} else if (match = /0+$/.exec(str)) {
|
||||||
|
len = match[0].length;
|
||||||
|
candidates.push(str.slice(0, -len) + "e" + len);
|
||||||
|
} else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
|
||||||
|
candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
|
||||||
|
}
|
||||||
|
return best_of(candidates);
|
||||||
}
|
}
|
||||||
return best_of(a);
|
|
||||||
};
|
|
||||||
|
|
||||||
function make_block(stmt, output) {
|
function make_block(stmt, output) {
|
||||||
if (!stmt || stmt instanceof AST_EmptyStatement)
|
if (!stmt || stmt instanceof AST_EmptyStatement)
|
||||||
@@ -1479,7 +1492,7 @@ function OutputStream(options) {
|
|||||||
stmt.print(output);
|
stmt.print(output);
|
||||||
output.newline();
|
output.newline();
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/* -----[ source map generators ]----- */
|
/* -----[ source map generators ]----- */
|
||||||
|
|
||||||
|
|||||||
42
lib/parse.js
42
lib/parse.js
@@ -165,7 +165,7 @@ function is_unicode_connector_punctuation(ch) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function is_identifier(name) {
|
function is_identifier(name) {
|
||||||
return !RESERVED_WORDS(name) && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
function is_identifier_start(code) {
|
function is_identifier_start(code) {
|
||||||
@@ -245,7 +245,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
var ch = S.text.charAt(S.pos++);
|
var ch = S.text.charAt(S.pos++);
|
||||||
if (signal_eof && !ch)
|
if (signal_eof && !ch)
|
||||||
throw EX_EOF;
|
throw EX_EOF;
|
||||||
if (NEWLINE_CHARS(ch)) {
|
if (NEWLINE_CHARS[ch]) {
|
||||||
S.newline_before = S.newline_before || !in_string;
|
S.newline_before = S.newline_before || !in_string;
|
||||||
++S.line;
|
++S.line;
|
||||||
S.col = 0;
|
S.col = 0;
|
||||||
@@ -272,7 +272,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
var text = S.text;
|
var text = S.text;
|
||||||
for (var i = S.pos, n = S.text.length; i < n; ++i) {
|
for (var i = S.pos, n = S.text.length; i < n; ++i) {
|
||||||
var ch = text[i];
|
var ch = text[i];
|
||||||
if (NEWLINE_CHARS(ch))
|
if (NEWLINE_CHARS[ch])
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -292,9 +292,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
var prev_was_dot = false;
|
var prev_was_dot = false;
|
||||||
function token(type, value, is_comment) {
|
function token(type, value, is_comment) {
|
||||||
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
|
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX[value]) ||
|
||||||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
|
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value]) ||
|
||||||
(type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
|
(type == "punc" && PUNC_BEFORE_EXPRESSION[value]));
|
||||||
if (type == "punc" && value == ".") {
|
if (type == "punc" && value == ".") {
|
||||||
prev_was_dot = true;
|
prev_was_dot = true;
|
||||||
} else if (!is_comment) {
|
} else if (!is_comment) {
|
||||||
@@ -324,7 +324,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function skip_whitespace() {
|
function skip_whitespace() {
|
||||||
while (WHITESPACE_CHARS(peek()))
|
while (WHITESPACE_CHARS[peek()])
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -424,7 +424,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
var ch = next(true, true);
|
var ch = next(true, true);
|
||||||
if (ch == "\\") ch = read_escaped_char(true);
|
if (ch == "\\") ch = read_escaped_char(true);
|
||||||
else if (NEWLINE_CHARS(ch)) parse_error("Unterminated string constant");
|
else if (NEWLINE_CHARS[ch]) parse_error("Unterminated string constant");
|
||||||
else if (ch == quote) break;
|
else if (ch == quote) break;
|
||||||
ret += ch;
|
ret += ch;
|
||||||
}
|
}
|
||||||
@@ -476,7 +476,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
backslash = false;
|
backslash = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (KEYWORDS(name) && escaped) {
|
if (KEYWORDS[name] && escaped) {
|
||||||
hex = name.charCodeAt(0).toString(16).toUpperCase();
|
hex = name.charCodeAt(0).toString(16).toUpperCase();
|
||||||
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
|
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
|
||||||
}
|
}
|
||||||
@@ -485,7 +485,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
|
|
||||||
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
||||||
var prev_backslash = false, ch, in_class = false;
|
var prev_backslash = false, ch, in_class = false;
|
||||||
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
while ((ch = next(true))) if (NEWLINE_CHARS[ch]) {
|
||||||
parse_error("Unexpected line terminator");
|
parse_error("Unexpected line terminator");
|
||||||
} else if (prev_backslash) {
|
} else if (prev_backslash) {
|
||||||
source += "\\" + ch;
|
source += "\\" + ch;
|
||||||
@@ -517,7 +517,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
function grow(op) {
|
function grow(op) {
|
||||||
if (!peek()) return op;
|
if (!peek()) return op;
|
||||||
var bigger = op + peek();
|
var bigger = op + peek();
|
||||||
if (OPERATORS(bigger)) {
|
if (OPERATORS[bigger]) {
|
||||||
next();
|
next();
|
||||||
return grow(bigger);
|
return grow(bigger);
|
||||||
} else {
|
} else {
|
||||||
@@ -550,9 +550,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
function read_word() {
|
function read_word() {
|
||||||
var word = read_name();
|
var word = read_name();
|
||||||
if (prev_was_dot) return token("name", word);
|
if (prev_was_dot) return token("name", word);
|
||||||
return KEYWORDS_ATOM(word) ? token("atom", word)
|
return KEYWORDS_ATOM[word] ? token("atom", word)
|
||||||
: !KEYWORDS(word) ? token("name", word)
|
: !KEYWORDS[word] ? token("name", word)
|
||||||
: OPERATORS(word) ? token("operator", word)
|
: OPERATORS[word] ? token("operator", word)
|
||||||
: token("keyword", word);
|
: token("keyword", word);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -603,8 +603,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_digit(code)) return read_num();
|
if (is_digit(code)) return read_num();
|
||||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
if (PUNC_CHARS[ch]) return token("punc", next());
|
||||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
if (OPERATOR_CHARS[ch]) return read_operator();
|
||||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1321,7 +1321,7 @@ function parse($TEXT, options) {
|
|||||||
func.end = prev();
|
func.end = prev();
|
||||||
return subscripts(func, allow_calls);
|
return subscripts(func, allow_calls);
|
||||||
}
|
}
|
||||||
if (ATOMIC_START_TOKEN(S.token.type)) {
|
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||||
return subscripts(as_atom_node(), allow_calls);
|
return subscripts(as_atom_node(), allow_calls);
|
||||||
}
|
}
|
||||||
unexpected();
|
unexpected();
|
||||||
@@ -1406,7 +1406,7 @@ function parse($TEXT, options) {
|
|||||||
var tmp = S.token;
|
var tmp = S.token;
|
||||||
switch (tmp.type) {
|
switch (tmp.type) {
|
||||||
case "operator":
|
case "operator":
|
||||||
if (!KEYWORDS(tmp.value)) unexpected();
|
if (!KEYWORDS[tmp.value]) unexpected();
|
||||||
case "num":
|
case "num":
|
||||||
case "string":
|
case "string":
|
||||||
case "name":
|
case "name":
|
||||||
@@ -1504,7 +1504,7 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
var maybe_unary = function(allow_calls) {
|
var maybe_unary = function(allow_calls) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
if (is("operator") && UNARY_PREFIX(start.value)) {
|
if (is("operator") && UNARY_PREFIX[start.value]) {
|
||||||
next();
|
next();
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
|
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
|
||||||
@@ -1513,7 +1513,7 @@ function parse($TEXT, options) {
|
|||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
var val = expr_atom(allow_calls);
|
var val = expr_atom(allow_calls);
|
||||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !has_newline_before(S.token)) {
|
while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) {
|
||||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||||
val.start = start;
|
val.start = start;
|
||||||
val.end = S.token;
|
val.end = S.token;
|
||||||
@@ -1585,7 +1585,7 @@ function parse($TEXT, options) {
|
|||||||
var maybe_assign = function(no_in) {
|
var maybe_assign = function(no_in) {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var left = maybe_conditional(no_in), val = S.token.value;
|
var left = maybe_conditional(no_in), val = S.token.value;
|
||||||
if (is("operator") && ASSIGNMENT(val)) {
|
if (is("operator") && ASSIGNMENT[val]) {
|
||||||
if (is_assignable(left)) {
|
if (is_assignable(left)) {
|
||||||
next();
|
next();
|
||||||
return new AST_Assign({
|
return new AST_Assign({
|
||||||
|
|||||||
@@ -150,6 +150,10 @@ function mangle_properties(ast, options) {
|
|||||||
else if (node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
addStrings(node.property, add);
|
addStrings(node.property, add);
|
||||||
}
|
}
|
||||||
|
else if (node instanceof AST_Call
|
||||||
|
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||||
|
addStrings(node.args[1], add);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// step 2: transform the tree, renaming properties
|
// step 2: transform the tree, renaming properties
|
||||||
@@ -167,6 +171,10 @@ function mangle_properties(ast, options) {
|
|||||||
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||||
node.property = mangleStrings(node.property);
|
node.property = mangleStrings(node.property);
|
||||||
}
|
}
|
||||||
|
else if (node instanceof AST_Call
|
||||||
|
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||||
|
node.args[1] = mangleStrings(node.args[1]);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
|
|||||||
47
lib/scope.js
47
lib/scope.js
@@ -55,7 +55,7 @@ function SymbolDef(scope, orig, init) {
|
|||||||
this.mangled_name = null;
|
this.mangled_name = null;
|
||||||
this.undeclared = false;
|
this.undeclared = false;
|
||||||
this.id = SymbolDef.next_id++;
|
this.id = SymbolDef.next_id++;
|
||||||
};
|
}
|
||||||
|
|
||||||
SymbolDef.next_id = 1;
|
SymbolDef.next_id = 1;
|
||||||
|
|
||||||
@@ -63,12 +63,12 @@ SymbolDef.prototype = {
|
|||||||
unmangleable: function(options) {
|
unmangleable: function(options) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
return (this.global && !options.toplevel)
|
return this.global && !options.toplevel
|
||||||
|| this.undeclared
|
|| this.undeclared
|
||||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
|| !options.eval && this.scope.pinned()
|
||||||
|| (options.keep_fnames
|
|| options.keep_fnames
|
||||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
|| this.orig[0] instanceof AST_SymbolDefun);
|
||||||
},
|
},
|
||||||
mangle: function(options) {
|
mangle: function(options) {
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
@@ -344,7 +344,7 @@ function next_mangled_name(scope, options, def) {
|
|||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
name = base54(++scope.cname);
|
name = base54(++scope.cname);
|
||||||
if (in_use[name] || !is_identifier(name) || member(name, options.reserved)) continue;
|
if (in_use[name] || !is_identifier(name) || options.reserved.has[name]) continue;
|
||||||
if (!names[name]) break;
|
if (!names[name]) break;
|
||||||
holes.push(scope.cname);
|
holes.push(scope.cname);
|
||||||
}
|
}
|
||||||
@@ -364,8 +364,7 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
|||||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unreferenced", function() {
|
AST_Symbol.DEFMETHOD("unreferenced", function() {
|
||||||
return this.definition().references.length == 0
|
return !this.definition().references.length && !this.scope.pinned();
|
||||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("definition", function() {
|
AST_Symbol.DEFMETHOD("definition", function() {
|
||||||
@@ -387,6 +386,7 @@ function _default_mangler_options(options) {
|
|||||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||||
// Never mangle arguments
|
// Never mangle arguments
|
||||||
push_uniq(options.reserved, "arguments");
|
push_uniq(options.reserved, "arguments");
|
||||||
|
options.reserved.has = makePredicate(options.reserved);
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,10 +452,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
redefined.forEach(mangle);
|
redefined.forEach(mangle);
|
||||||
|
|
||||||
function mangle(def) {
|
function mangle(def) {
|
||||||
if (!member(def.name, options.reserved)) {
|
if (options.reserved.has[def.name]) return;
|
||||||
def.mangle(options);
|
def.mangle(options);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
@@ -504,7 +503,7 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
|||||||
function rename(def) {
|
function rename(def) {
|
||||||
if (def.global && options.cache) return;
|
if (def.global && options.cache) return;
|
||||||
if (def.unmangleable(options)) return;
|
if (def.unmangleable(options)) return;
|
||||||
if (member(def.name, options.reserved)) return;
|
if (options.reserved.has[def.name]) return;
|
||||||
var d = def.redefined();
|
var d = def.redefined();
|
||||||
def.name = d ? d.name : next_name();
|
def.name = d ? d.name : next_name();
|
||||||
def.orig.forEach(function(sym) {
|
def.orig.forEach(function(sym) {
|
||||||
@@ -556,17 +555,21 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
|||||||
});
|
});
|
||||||
|
|
||||||
var base54 = (function() {
|
var base54 = (function() {
|
||||||
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
var freq = Object.create(null);
|
||||||
var digits = "0123456789".split("");
|
function init(chars) {
|
||||||
|
var array = [];
|
||||||
|
for (var i = 0, len = chars.length; i < len; i++) {
|
||||||
|
var ch = chars[i];
|
||||||
|
array.push(ch);
|
||||||
|
freq[ch] = -1e-2 * i;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
var digits = init("0123456789");
|
||||||
|
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
|
||||||
var chars, frequency;
|
var chars, frequency;
|
||||||
function reset() {
|
function reset() {
|
||||||
frequency = Object.create(null);
|
frequency = Object.create(freq);
|
||||||
leading.forEach(function(ch) {
|
|
||||||
frequency[ch] = 0;
|
|
||||||
});
|
|
||||||
digits.forEach(function(ch) {
|
|
||||||
frequency[ch] = 0;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
base54.consider = function(str, delta) {
|
base54.consider = function(str, delta) {
|
||||||
for (var i = str.length; --i >= 0;) {
|
for (var i = str.length; --i >= 0;) {
|
||||||
@@ -577,7 +580,7 @@ var base54 = (function() {
|
|||||||
return frequency[b] - frequency[a];
|
return frequency[b] - frequency[a];
|
||||||
}
|
}
|
||||||
base54.sort = function() {
|
base54.sort = function() {
|
||||||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
chars = leading.sort(compare).concat(digits.sort(compare));
|
||||||
};
|
};
|
||||||
base54.reset = reset;
|
base54.reset = reset;
|
||||||
reset();
|
reset();
|
||||||
@@ -591,6 +594,6 @@ var base54 = (function() {
|
|||||||
base = 64;
|
base = 64;
|
||||||
} while (num > 0);
|
} while (num > 0);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
return base54;
|
return base54;
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -57,26 +57,26 @@ function SourceMap(options) {
|
|||||||
file : options.file,
|
file : options.file,
|
||||||
sourceRoot : options.root
|
sourceRoot : options.root
|
||||||
});
|
});
|
||||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
var maps = options.orig && Object.create(null);
|
||||||
|
if (maps) for (var source in options.orig) {
|
||||||
if (orig_map && Array.isArray(options.orig.sources)) {
|
var map = new MOZ_SourceMap.SourceMapConsumer(options.orig[source]);
|
||||||
orig_map._sources.toArray().forEach(function(source) {
|
if (Array.isArray(options.orig[source].sources)) {
|
||||||
var sourceContent = orig_map.sourceContentFor(source, true);
|
map._sources.toArray().forEach(function(source) {
|
||||||
if (sourceContent) {
|
var sourceContent = map.sourceContentFor(source, true);
|
||||||
generator.setSourceContent(source, sourceContent);
|
if (sourceContent) generator.setSourceContent(source, sourceContent);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
maps[source] = map;
|
||||||
|
}
|
||||||
|
|
||||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||||
if (orig_map) {
|
var map = maps && maps[source];
|
||||||
var info = orig_map.originalPositionFor({
|
if (map) {
|
||||||
|
var info = map.originalPositionFor({
|
||||||
line: orig_line,
|
line: orig_line,
|
||||||
column: orig_col
|
column: orig_col
|
||||||
});
|
});
|
||||||
if (info.source === null) {
|
if (info.source === null) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
source = info.source;
|
source = info.source;
|
||||||
orig_line = info.line;
|
orig_line = info.line;
|
||||||
orig_col = info.column;
|
orig_col = info.column;
|
||||||
|
|||||||
@@ -93,7 +93,12 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
self.body = do_list(self.body, tw);
|
self.body = do_list(self.body, tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
_(AST_DWLoop, function(self, tw){
|
_(AST_Do, function(self, tw){
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_While, function(self, tw){
|
||||||
self.condition = self.condition.transform(tw);
|
self.condition = self.condition.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
|
|||||||
143
lib/utils.js
143
lib/utils.js
@@ -45,27 +45,25 @@
|
|||||||
|
|
||||||
function characters(str) {
|
function characters(str) {
|
||||||
return str.split("");
|
return str.split("");
|
||||||
};
|
}
|
||||||
|
|
||||||
function member(name, array) {
|
function member(name, array) {
|
||||||
return array.indexOf(name) >= 0;
|
return array.indexOf(name) >= 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
function find_if(func, array) {
|
function find_if(func, array) {
|
||||||
for (var i = 0, n = array.length; i < n; ++i) {
|
for (var i = 0, n = array.length; i < n; ++i) {
|
||||||
if (func(array[i]))
|
if (func(array[i])) return array[i];
|
||||||
return array[i];
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function repeat_string(str, i) {
|
function repeat_string(str, i) {
|
||||||
if (i <= 0) return "";
|
if (i <= 0) return "";
|
||||||
if (i == 1) return str;
|
if (i == 1) return str;
|
||||||
var d = repeat_string(str, i >> 1);
|
var d = repeat_string(str, i >> 1);
|
||||||
d += d;
|
d += d;
|
||||||
if (i & 1) d += str;
|
return i & 1 ? d + str : d;
|
||||||
return d;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function configure_error_stack(fn) {
|
function configure_error_stack(fn) {
|
||||||
Object.defineProperty(fn.prototype, "stack", {
|
Object.defineProperty(fn.prototype, "stack", {
|
||||||
@@ -84,27 +82,23 @@ function configure_error_stack(fn) {
|
|||||||
function DefaultsError(msg, defs) {
|
function DefaultsError(msg, defs) {
|
||||||
this.message = msg;
|
this.message = msg;
|
||||||
this.defs = defs;
|
this.defs = defs;
|
||||||
};
|
}
|
||||||
DefaultsError.prototype = Object.create(Error.prototype);
|
DefaultsError.prototype = Object.create(Error.prototype);
|
||||||
DefaultsError.prototype.constructor = DefaultsError;
|
DefaultsError.prototype.constructor = DefaultsError;
|
||||||
DefaultsError.prototype.name = "DefaultsError";
|
DefaultsError.prototype.name = "DefaultsError";
|
||||||
configure_error_stack(DefaultsError);
|
configure_error_stack(DefaultsError);
|
||||||
|
|
||||||
DefaultsError.croak = function(msg, defs) {
|
|
||||||
throw new DefaultsError(msg, defs);
|
|
||||||
};
|
|
||||||
|
|
||||||
function defaults(args, defs, croak) {
|
function defaults(args, defs, croak) {
|
||||||
if (args === true)
|
if (args === true) args = {};
|
||||||
args = {};
|
|
||||||
var ret = args || {};
|
var ret = args || {};
|
||||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
|
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
|
||||||
DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||||
|
}
|
||||||
for (var i in defs) if (HOP(defs, i)) {
|
for (var i in defs) if (HOP(defs, i)) {
|
||||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}
|
||||||
|
|
||||||
function merge(obj, ext) {
|
function merge(obj, ext) {
|
||||||
var count = 0;
|
var count = 0;
|
||||||
@@ -113,7 +107,7 @@ function merge(obj, ext) {
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
};
|
}
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
function return_false() { return false; }
|
function return_false() { return false; }
|
||||||
@@ -145,7 +139,7 @@ var MAP = (function(){
|
|||||||
}
|
}
|
||||||
return is_last;
|
return is_last;
|
||||||
};
|
};
|
||||||
if (a instanceof Array) {
|
if (Array.isArray(a)) {
|
||||||
if (backwards) {
|
if (backwards) {
|
||||||
for (i = a.length; --i >= 0;) if (doit()) break;
|
for (i = a.length; --i >= 0;) if (doit()) break;
|
||||||
ret.reverse();
|
ret.reverse();
|
||||||
@@ -172,101 +166,40 @@ var MAP = (function(){
|
|||||||
function push_uniq(array, el) {
|
function push_uniq(array, el) {
|
||||||
if (array.indexOf(el) < 0)
|
if (array.indexOf(el) < 0)
|
||||||
array.push(el);
|
array.push(el);
|
||||||
};
|
}
|
||||||
|
|
||||||
function string_template(text, props) {
|
function string_template(text, props) {
|
||||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||||
return props && props[p];
|
return props && props[p];
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
function remove(array, el) {
|
function remove(array, el) {
|
||||||
for (var i = array.length; --i >= 0;) {
|
for (var i = array.length; --i >= 0;) {
|
||||||
if (array[i] === el) array.splice(i, 1);
|
if (array[i] === el) array.splice(i, 1);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function mergeSort(array, cmp) {
|
|
||||||
if (array.length < 2) return array.slice();
|
|
||||||
function merge(a, b) {
|
|
||||||
var r = [], ai = 0, bi = 0, i = 0;
|
|
||||||
while (ai < a.length && bi < b.length) {
|
|
||||||
cmp(a[ai], b[bi]) <= 0
|
|
||||||
? r[i++] = a[ai++]
|
|
||||||
: r[i++] = b[bi++];
|
|
||||||
}
|
}
|
||||||
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
|
||||||
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
|
||||||
return r;
|
|
||||||
};
|
|
||||||
function _ms(a) {
|
|
||||||
if (a.length <= 1)
|
|
||||||
return a;
|
|
||||||
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
|
||||||
left = _ms(left);
|
|
||||||
right = _ms(right);
|
|
||||||
return merge(left, right);
|
|
||||||
};
|
|
||||||
return _ms(array);
|
|
||||||
};
|
|
||||||
|
|
||||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
|
||||||
// [1] https://github.com/marijnh/acorn
|
|
||||||
function makePredicate(words) {
|
function makePredicate(words) {
|
||||||
if (!(words instanceof Array)) words = words.split(" ");
|
if (!Array.isArray(words)) words = words.split(" ");
|
||||||
var f = "", cats = [];
|
var map = Object.create(null);
|
||||||
out: for (var i = 0; i < words.length; ++i) {
|
words.forEach(function(word) {
|
||||||
for (var j = 0; j < cats.length; ++j)
|
map[word] = true;
|
||||||
if (cats[j][0].length == words[i].length) {
|
|
||||||
cats[j].push(words[i]);
|
|
||||||
continue out;
|
|
||||||
}
|
|
||||||
cats.push([words[i]]);
|
|
||||||
}
|
|
||||||
function quote(word) {
|
|
||||||
return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) {
|
|
||||||
switch (s) {
|
|
||||||
case "\u2028": return "\\u2028";
|
|
||||||
case "\u2029": return "\\u2029";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
});
|
});
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
function compareTo(arr) {
|
|
||||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
|
||||||
f += "switch(str){";
|
|
||||||
for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":";
|
|
||||||
f += "return true}return false;";
|
|
||||||
}
|
|
||||||
// When there are more than three length categories, an outer
|
|
||||||
// switch first dispatches on the lengths, to save on comparisons.
|
|
||||||
if (cats.length > 3) {
|
|
||||||
cats.sort(function(a, b) {return b.length - a.length;});
|
|
||||||
f += "switch(str.length){";
|
|
||||||
for (var i = 0; i < cats.length; ++i) {
|
|
||||||
var cat = cats[i];
|
|
||||||
f += "case " + cat[0].length + ":";
|
|
||||||
compareTo(cat);
|
|
||||||
}
|
|
||||||
f += "}";
|
|
||||||
// Otherwise, simply generate a flat `switch` statement.
|
|
||||||
} else {
|
|
||||||
compareTo(words);
|
|
||||||
}
|
|
||||||
return new Function("str", f);
|
|
||||||
};
|
|
||||||
|
|
||||||
function all(array, predicate) {
|
function all(array, predicate) {
|
||||||
for (var i = array.length; --i >= 0;)
|
for (var i = array.length; --i >= 0;)
|
||||||
if (!predicate(array[i]))
|
if (!predicate(array[i]))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
function Dictionary() {
|
function Dictionary() {
|
||||||
this._values = Object.create(null);
|
this._values = Object.create(null);
|
||||||
this._size = 0;
|
this._size = 0;
|
||||||
};
|
}
|
||||||
Dictionary.prototype = {
|
Dictionary.prototype = {
|
||||||
set: function(key, val) {
|
set: function(key, val) {
|
||||||
if (!this.has(key)) ++this._size;
|
if (!this.has(key)) ++this._size;
|
||||||
@@ -327,20 +260,22 @@ function HOP(obj, prop) {
|
|||||||
// a statement.
|
// a statement.
|
||||||
function first_in_statement(stack) {
|
function first_in_statement(stack) {
|
||||||
var node = stack.parent(-1);
|
var node = stack.parent(-1);
|
||||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
||||||
if (p instanceof AST_Statement && p.body === node)
|
if (p.TYPE == "Call") {
|
||||||
return true;
|
if (p.expression === node) continue;
|
||||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
} else if (p instanceof AST_Binary) {
|
||||||
(p.TYPE == "Call" && p.expression === node ) ||
|
if (p.left === node) continue;
|
||||||
(p instanceof AST_Dot && p.expression === node ) ||
|
} else if (p instanceof AST_Conditional) {
|
||||||
(p instanceof AST_Sub && p.expression === node ) ||
|
if (p.condition === node) continue;
|
||||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
} else if (p instanceof AST_PropAccess) {
|
||||||
(p instanceof AST_Binary && p.left === node ) ||
|
if (p.expression === node) continue;
|
||||||
(p instanceof AST_UnaryPostfix && p.expression === node ))
|
} else if (p instanceof AST_Sequence) {
|
||||||
{
|
if (p.expressions[0] === node) continue;
|
||||||
node = p;
|
} else if (p instanceof AST_Statement) {
|
||||||
} else {
|
return p.body === node;
|
||||||
|
} else if (p instanceof AST_UnaryPostfix) {
|
||||||
|
if (p.expression === node) continue;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.3.18",
|
"version": "3.4.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -28,7 +28,6 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.5.3",
|
"acorn": "~5.5.3",
|
||||||
"mocha": "~3.5.1",
|
|
||||||
"semver": "~5.5.0"
|
"semver": "~5.5.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -4056,6 +4056,36 @@ replace_all_var: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replace_all_var_scope: {
|
||||||
|
rename = true;
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var a = 100, b = 10;
|
||||||
|
(function(r, a) {
|
||||||
|
switch (~a) {
|
||||||
|
case (b += a):
|
||||||
|
case a++:
|
||||||
|
}
|
||||||
|
})(--b, a);
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 100, b = 10;
|
||||||
|
(function(c, o) {
|
||||||
|
switch (~a) {
|
||||||
|
case (b += a):
|
||||||
|
case o++:
|
||||||
|
}
|
||||||
|
})(--b, a);
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "100 109"
|
||||||
|
}
|
||||||
|
|
||||||
cascade_statement: {
|
cascade_statement: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -4901,6 +4931,27 @@ collapse_rhs_lhs_2: {
|
|||||||
expect_stdout: "PASS"
|
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: {
|
collapse_rhs_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -5327,3 +5378,24 @@ issue_3032: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3096: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var ar = ["a", "b"];
|
||||||
|
var first = ar.pop();
|
||||||
|
return ar + "" + first;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var ar = ["a", "b"];
|
||||||
|
var first = ar.pop();
|
||||||
|
return ar + "" + first;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "ab"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1814,3 +1814,115 @@ issue_2995: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
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"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2237,3 +2237,85 @@ issue_3018: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3054: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: 1,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
return { a: true };
|
||||||
|
}
|
||||||
|
console.log(function(b) {
|
||||||
|
b = false;
|
||||||
|
return f();
|
||||||
|
}().a, f.call().a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
return { a: !0 };
|
||||||
|
}
|
||||||
|
console.log(function(b) {
|
||||||
|
return { a: !(b = !1) };
|
||||||
|
}().a, f.call().a);
|
||||||
|
}
|
||||||
|
expect_stdout: "true true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3076: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "PASS";
|
||||||
|
(function(b) {
|
||||||
|
var n = 2;
|
||||||
|
while (--b + function() {
|
||||||
|
e && (c = "FAIL");
|
||||||
|
e = 5;
|
||||||
|
return 1;
|
||||||
|
try {
|
||||||
|
var a = 5;
|
||||||
|
} catch (e) {
|
||||||
|
var e;
|
||||||
|
}
|
||||||
|
}().toString() && --n > 0);
|
||||||
|
})(2);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "PASS";
|
||||||
|
(function(b) {
|
||||||
|
var n = 2;
|
||||||
|
while (--b + (e = void 0, e && (c = "FAIL"), e = 5, 1).toString() && --n > 0);
|
||||||
|
var e;
|
||||||
|
})(2),
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3125: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
return "PASS";
|
||||||
|
}.call());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -716,3 +716,143 @@ issue_3021: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "2 2"
|
expect_stdout: "2 2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3046: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
do {
|
||||||
|
var b = {
|
||||||
|
c: a++
|
||||||
|
};
|
||||||
|
} while (b.c && a);
|
||||||
|
return a;
|
||||||
|
}(0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
do {
|
||||||
|
var b_c = a++;
|
||||||
|
} while (b_c && a);
|
||||||
|
return a;
|
||||||
|
}(0));
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3071_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var obj = {};
|
||||||
|
obj.one = 1;
|
||||||
|
obj.two = 2;
|
||||||
|
console.log(obj.one);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3071_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
obj = {};
|
||||||
|
obj.one = 1;
|
||||||
|
obj.two = 2;
|
||||||
|
console.log(obj.one);
|
||||||
|
var obj;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3071_2_toplevel: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
join_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
obj = {};
|
||||||
|
obj.one = 1;
|
||||||
|
obj.two = 2;
|
||||||
|
console.log(obj.one);
|
||||||
|
var obj;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3071_3: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function(a, b) {
|
||||||
|
(function f(o) {
|
||||||
|
var n = 2;
|
||||||
|
while (--b + (o = {
|
||||||
|
p: c++,
|
||||||
|
}) && --n > 0);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function(a, b) {
|
||||||
|
(function f(o) {
|
||||||
|
var n = 2;
|
||||||
|
while (--b + (o = {
|
||||||
|
p: c++,
|
||||||
|
}) && --n > 0);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,31 @@
|
|||||||
remove_redundant_sequence_items: {
|
remove_sequence: {
|
||||||
options = { side_effects: true };
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
(0, 1, eval)();
|
(0, 1, eval)();
|
||||||
(0, 1, logThis)();
|
(0, 1, logThis)();
|
||||||
(0, 1, _decorators.logThis)();
|
(0, 1, _decorators.logThis)();
|
||||||
}
|
}
|
||||||
expect: {
|
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)();
|
(0, eval)();
|
||||||
logThis();
|
logThis();
|
||||||
(0, _decorators.logThis)();
|
(0, _decorators.logThis)();
|
||||||
@@ -13,13 +33,17 @@ remove_redundant_sequence_items: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_remove_this_binding_sequence: {
|
dont_remove_this_binding_sequence: {
|
||||||
options = { side_effects: true };
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"use strict";
|
||||||
(0, eval)();
|
(0, eval)();
|
||||||
(0, logThis)();
|
(0, logThis)();
|
||||||
(0, _decorators.logThis)();
|
(0, _decorators.logThis)();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"use strict";
|
||||||
(0, eval)();
|
(0, eval)();
|
||||||
logThis();
|
logThis();
|
||||||
(0, _decorators.logThis)();
|
(0, _decorators.logThis)();
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ this_binding_conditionals: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"use strict";
|
||||||
(1 && a)();
|
(1 && a)();
|
||||||
(0 || a)();
|
(0 || a)();
|
||||||
(0 || 1 && a)();
|
(0 || 1 && a)();
|
||||||
@@ -26,6 +27,7 @@ this_binding_conditionals: {
|
|||||||
(1 ? eval : 0)();
|
(1 ? eval : 0)();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"use strict";
|
||||||
a();
|
a();
|
||||||
a();
|
a();
|
||||||
a();
|
a();
|
||||||
@@ -53,13 +55,15 @@ this_binding_collapse_vars: {
|
|||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"use strict";
|
||||||
var c = a; c();
|
var c = a; c();
|
||||||
var d = a.b; d();
|
var d = a.b; d();
|
||||||
var e = eval; e();
|
var e = eval; e();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"use strict";
|
||||||
a();
|
a();
|
||||||
(0, a.b)();
|
(0, a.b)();
|
||||||
(0, eval)();
|
(0, eval)();
|
||||||
@@ -69,31 +73,88 @@ this_binding_collapse_vars: {
|
|||||||
this_binding_side_effects: {
|
this_binding_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
side_effects : true
|
side_effects : true
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(foo) {
|
(function(foo) {
|
||||||
(0, foo)();
|
(0, foo)();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
(0, eval)("console.log(foo);");
|
||||||
|
}());
|
||||||
|
(function(foo) {
|
||||||
|
"use strict";
|
||||||
|
(0, foo)();
|
||||||
|
(0, foo.bar)();
|
||||||
|
(0, eval)("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
(function(foo) {
|
(function(foo) {
|
||||||
var eval = console;
|
var eval = console;
|
||||||
(0, foo)();
|
(0, foo)();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
(0, eval)("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function(foo) {
|
(function(foo) {
|
||||||
foo();
|
foo();
|
||||||
(0, foo.bar)();
|
(0, foo.bar)();
|
||||||
(0, eval)('console.log(foo);');
|
eval("console.log(foo);");
|
||||||
|
}());
|
||||||
|
(function(foo) {
|
||||||
|
"use strict";
|
||||||
|
foo();
|
||||||
|
(0, foo.bar)();
|
||||||
|
(0, eval)("console.log(foo);");
|
||||||
}());
|
}());
|
||||||
(function(foo) {
|
(function(foo) {
|
||||||
var eval = console;
|
var eval = console;
|
||||||
foo();
|
foo();
|
||||||
(0, foo.bar)();
|
(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",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ too_short: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: [
|
expect_exact: [
|
||||||
'function f(a){',
|
"function f(",
|
||||||
'return{',
|
"a){return{",
|
||||||
'c:42,',
|
"c:42,d:a(",
|
||||||
'd:a(),',
|
'),e:"foo"}',
|
||||||
'e:"foo"}}',
|
"}",
|
||||||
]
|
]
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Output exceeds 10 characters"
|
"WARN: Output exceeds 10 characters",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,11 +29,25 @@ just_enough: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: [
|
expect_exact: [
|
||||||
'function f(a){',
|
"function f(a){",
|
||||||
'return{c:42,',
|
"return{c:42,",
|
||||||
'd:a(),e:"foo"}',
|
'd:a(),e:"foo"}',
|
||||||
'}',
|
"}",
|
||||||
]
|
|
||||||
expect_warnings: [
|
|
||||||
]
|
]
|
||||||
|
expect_warnings: []
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_304: {
|
||||||
|
beautify = {
|
||||||
|
max_line_len: 10,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0, c = 0, d = 0, e = 0;
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"var a=0,",
|
||||||
|
"b=0,c=0,",
|
||||||
|
"d=0,e=0;",
|
||||||
|
]
|
||||||
|
expect_warnings: []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
hex_numbers_in_parentheses_for_prototype_functions: {
|
hex_numbers_in_parentheses_for_prototype_functions: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
function f() {
|
||||||
(-2);
|
(-2);
|
||||||
(-2).toFixed(0);
|
(-2).toFixed(0);
|
||||||
|
|
||||||
@@ -9,13 +13,37 @@ hex_numbers_in_parentheses_for_prototype_functions: {
|
|||||||
(0.2);
|
(0.2);
|
||||||
(0.2).toFixed(0);
|
(0.2).toFixed(0);
|
||||||
|
|
||||||
|
(2.34e20);
|
||||||
|
(2.34e20).toFixed(0);
|
||||||
|
|
||||||
(0.00000002);
|
(0.00000002);
|
||||||
(0.00000002).toFixed(0);
|
(0.00000002).toFixed(0);
|
||||||
|
|
||||||
(1000000000000000128);
|
(1000000000000000128);
|
||||||
(1000000000000000128).toFixed(0);
|
(1000000000000000128).toFixed(0);
|
||||||
|
|
||||||
|
(-1000000000000000128);
|
||||||
|
(-1000000000000000128).toFixed(0);
|
||||||
}
|
}
|
||||||
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"function f() {",
|
||||||
|
" -2;",
|
||||||
|
" (-2).toFixed(0);",
|
||||||
|
" 2;",
|
||||||
|
" 2..toFixed(0);",
|
||||||
|
" .2;",
|
||||||
|
" .2.toFixed(0);",
|
||||||
|
" 234e18;",
|
||||||
|
" 234e18.toFixed(0);",
|
||||||
|
" 2e-8;",
|
||||||
|
" 2e-8.toFixed(0);",
|
||||||
|
" 0xde0b6b3a7640080;",
|
||||||
|
" (0xde0b6b3a7640080).toFixed(0);",
|
||||||
|
" -0xde0b6b3a7640080;",
|
||||||
|
" (-0xde0b6b3a7640080).toFixed(0);",
|
||||||
|
"}",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
comparisons: {
|
comparisons: {
|
||||||
|
|||||||
@@ -1208,6 +1208,37 @@ join_object_assignments_3: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
join_object_assignments_4: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o;
|
||||||
|
console.log(o);
|
||||||
|
o = {};
|
||||||
|
o.a = "foo";
|
||||||
|
console.log(o.b);
|
||||||
|
o.b = "bar";
|
||||||
|
console.log(o.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o;
|
||||||
|
console.log(o),
|
||||||
|
o = {
|
||||||
|
a: "foo",
|
||||||
|
},
|
||||||
|
console.log(o.b),
|
||||||
|
o.b = "bar",
|
||||||
|
console.log(o.a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"undefined",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
join_object_assignments_return_1: {
|
join_object_assignments_return_1: {
|
||||||
options = {
|
options = {
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -1640,3 +1671,61 @@ issue_2893_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_869_1: {
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
reserved: [ "get" ]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { p: "FAIL" };
|
||||||
|
Object.defineProperty(o, "p", {
|
||||||
|
get: function() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { o: "FAIL" };
|
||||||
|
Object.defineProperty(o, "o", {
|
||||||
|
get: function() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(o.o);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_869_2: {
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
reserved: [ "get" ]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { p: "FAIL" };
|
||||||
|
Object.defineProperties(o, {
|
||||||
|
p: {
|
||||||
|
get: function() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { o: "FAIL" };
|
||||||
|
Object.defineProperties(o, {
|
||||||
|
o: {
|
||||||
|
get: function() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(o.o);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -535,3 +535,110 @@ issue_2705_6: {
|
|||||||
"/* */new(/* */a()||b())(c(),d());",
|
"/* */new(/* */a()||b())(c(),d());",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3065_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
pure_funcs: [ "pureFunc" ],
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function modifyWrapper(a, f, wrapper) {
|
||||||
|
wrapper.a = a;
|
||||||
|
wrapper.f = f;
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
function pureFunc(fun) {
|
||||||
|
return modifyWrapper(1, fun, function(a) {
|
||||||
|
return fun(a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var unused = pureFunc(function(x) {
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3065_2: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
pure_funcs: [ "pureFunc" ],
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
reserved: [ "pureFunc" ],
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function modifyWrapper(a, f, wrapper) {
|
||||||
|
wrapper.a = a;
|
||||||
|
wrapper.f = f;
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
function pureFunc(fun) {
|
||||||
|
return modifyWrapper(1, fun, function(a) {
|
||||||
|
return fun(a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var unused = pureFunc(function(x) {
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3065_3: {
|
||||||
|
options = {
|
||||||
|
pure_funcs: [ "debug" ],
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function debug(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
debug(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
return "FAIL";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3065_4: {
|
||||||
|
options = {
|
||||||
|
pure_funcs: [ "debug" ],
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var debug = function(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
};
|
||||||
|
debug(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
return "FAIL";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1476,18 +1476,18 @@ defun_redefine: {
|
|||||||
};
|
};
|
||||||
return g() + h();
|
return g() + h();
|
||||||
}
|
}
|
||||||
|
console.log(f());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
function g() {
|
(function() {
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
g = function() {
|
|
||||||
return 3;
|
return 3;
|
||||||
};
|
});
|
||||||
return g() + 2;
|
return 3 + 2;
|
||||||
}
|
}
|
||||||
|
console.log(f());
|
||||||
}
|
}
|
||||||
|
expect_stdout: "5"
|
||||||
}
|
}
|
||||||
|
|
||||||
func_inline: {
|
func_inline: {
|
||||||
@@ -1527,23 +1527,37 @@ func_modified: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(a) {
|
function f(a) {
|
||||||
function a() { return 1; }
|
function a() {
|
||||||
function b() { return 2; }
|
return 1;
|
||||||
function c() { return 3; }
|
}
|
||||||
|
function b() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
function c() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
b.inject = [];
|
b.inject = [];
|
||||||
c = function() { return 4; };
|
c = function() {
|
||||||
|
return 4;
|
||||||
|
};
|
||||||
return a() + b() + c();
|
return a() + b() + c();
|
||||||
}
|
}
|
||||||
|
console.log(f());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a) {
|
function f(a) {
|
||||||
function b() { return 2; }
|
function b() {
|
||||||
function c() { return 3; }
|
return 2;
|
||||||
|
}
|
||||||
b.inject = [];
|
b.inject = [];
|
||||||
c = function() { return 4; };
|
(function() {
|
||||||
return 1 + 2 + c();
|
return 4;
|
||||||
|
});
|
||||||
|
return 1 + 2 + 4;
|
||||||
}
|
}
|
||||||
|
console.log(f());
|
||||||
}
|
}
|
||||||
|
expect_stdout: "7"
|
||||||
}
|
}
|
||||||
|
|
||||||
defun_label: {
|
defun_label: {
|
||||||
@@ -5054,9 +5068,7 @@ defun_var_1: {
|
|||||||
console.log(typeof a, typeof b);
|
console.log(typeof a, typeof b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 42;
|
console.log("number", "function");
|
||||||
function a() {}
|
|
||||||
console.log(typeof a, "function");
|
|
||||||
}
|
}
|
||||||
expect_stdout: "number function"
|
expect_stdout: "number function"
|
||||||
}
|
}
|
||||||
@@ -5076,9 +5088,7 @@ defun_var_2: {
|
|||||||
console.log(typeof a, typeof b);
|
console.log(typeof a, typeof b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a() {}
|
console.log("number", "function");
|
||||||
var a = 42;
|
|
||||||
console.log(typeof a, "function");
|
|
||||||
}
|
}
|
||||||
expect_stdout: "number function"
|
expect_stdout: "number function"
|
||||||
}
|
}
|
||||||
@@ -5654,3 +5664,742 @@ issue_3042_2: {
|
|||||||
"true",
|
"true",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3068_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
continue;
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
continue;
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3068_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
while ("" == typeof a);
|
||||||
|
} finally {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
while ("" == typeof a);
|
||||||
|
} finally {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var b = "defined";
|
||||||
|
} while (b && b.c);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3110_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 3,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function foo() {
|
||||||
|
return isDev ? "foo" : "bar";
|
||||||
|
}
|
||||||
|
var isDev = true;
|
||||||
|
var obj = {
|
||||||
|
foo: foo
|
||||||
|
};
|
||||||
|
console.log(foo());
|
||||||
|
console.log(obj.foo());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("foo"),
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3110_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 4,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function foo() {
|
||||||
|
return isDev ? "foo" : "bar";
|
||||||
|
}
|
||||||
|
var isDev = true;
|
||||||
|
console.log(foo());
|
||||||
|
var obj = {
|
||||||
|
foo: foo
|
||||||
|
};
|
||||||
|
console.log(obj.foo());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("foo"),
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3110_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function foo() {
|
||||||
|
return isDev ? "foo" : "bar";
|
||||||
|
}
|
||||||
|
console.log(foo());
|
||||||
|
var isDev = true;
|
||||||
|
var obj = {
|
||||||
|
foo: foo
|
||||||
|
};
|
||||||
|
console.log(obj.foo());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function foo() {
|
||||||
|
return isDev ? "foo" : "bar";
|
||||||
|
}
|
||||||
|
console.log(foo());
|
||||||
|
var isDev = true;
|
||||||
|
var obj = {
|
||||||
|
foo: foo
|
||||||
|
};
|
||||||
|
console.log(obj.foo());
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3113_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
while (g());
|
||||||
|
}
|
||||||
|
var a = f();
|
||||||
|
function g() {
|
||||||
|
a && a[c++];
|
||||||
|
}
|
||||||
|
g(a = 1);
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
while (g());
|
||||||
|
}
|
||||||
|
var a = f();
|
||||||
|
function g() {
|
||||||
|
a && a[c++];
|
||||||
|
}
|
||||||
|
g(a = 1);
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3113_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
while (g());
|
||||||
|
}
|
||||||
|
var a = f();
|
||||||
|
function g() {
|
||||||
|
a && a[c++];
|
||||||
|
}
|
||||||
|
a = 1;
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
while (g());
|
||||||
|
}
|
||||||
|
var a = f();
|
||||||
|
function g() {
|
||||||
|
a && a[c++];
|
||||||
|
}
|
||||||
|
a = 1;
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3113_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
while (g());
|
||||||
|
}
|
||||||
|
var a;
|
||||||
|
function g() {
|
||||||
|
a && a[c++];
|
||||||
|
}
|
||||||
|
g(a = 1);
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
c++;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3113_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
function f() {
|
||||||
|
b += a;
|
||||||
|
}
|
||||||
|
f(f(), ++a);
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
function f() {
|
||||||
|
b += a;
|
||||||
|
}
|
||||||
|
f(f(), ++a);
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3113_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
while (g());
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
while (g());
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"1",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_nested_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, b = 0;
|
||||||
|
(function f(c) {
|
||||||
|
function g() {
|
||||||
|
c && (c.a = 0);
|
||||||
|
c && (c.a = 0);
|
||||||
|
c && (c[b++] *= 0);
|
||||||
|
}
|
||||||
|
g(a-- && f(g(c = 42)));
|
||||||
|
})();
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1, b = 0;
|
||||||
|
(function f(c) {
|
||||||
|
function g() {
|
||||||
|
c && (c.a = 0);
|
||||||
|
c && (c.a = 0);
|
||||||
|
c && (c[b++] *= 0);
|
||||||
|
}
|
||||||
|
g(a-- && f(g(c = 42)));
|
||||||
|
})();
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_nested_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function(a) {
|
||||||
|
function f() {
|
||||||
|
a && c++;
|
||||||
|
}
|
||||||
|
f(!c && f(), a = 1);
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function(a) {
|
||||||
|
function f() {
|
||||||
|
a && c++;
|
||||||
|
}
|
||||||
|
f(!c && f(), a = 1);
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c;
|
||||||
|
console.log(((c = {
|
||||||
|
a: 1,
|
||||||
|
b: 2
|
||||||
|
}).a = 3, {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c;
|
||||||
|
console.log(((c = {
|
||||||
|
a: 1,
|
||||||
|
b: 2
|
||||||
|
}).a = 3, {
|
||||||
|
x: c.a,
|
||||||
|
y: c.b
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2916: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = "FAIL";
|
||||||
|
(function(b) {
|
||||||
|
(function(d) {
|
||||||
|
d[0] = 1;
|
||||||
|
})(b);
|
||||||
|
+b && (c = "PASS");
|
||||||
|
})([]);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = "FAIL";
|
||||||
|
(function(b) {
|
||||||
|
b[0] = 1;
|
||||||
|
+b && (c = "PASS");
|
||||||
|
})([]);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3125: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o;
|
||||||
|
console.log((function() {
|
||||||
|
this.p++;
|
||||||
|
}.call(o = {
|
||||||
|
p: 6
|
||||||
|
}), o.p));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o;
|
||||||
|
console.log((function() {
|
||||||
|
this.p++;
|
||||||
|
}.call(o = {
|
||||||
|
p: 6
|
||||||
|
}), o.p));
|
||||||
|
}
|
||||||
|
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
37
test/compress/regexp.js
Normal 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"]'
|
||||||
|
}
|
||||||
@@ -876,3 +876,59 @@ forin: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
call: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
function b() {
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
b.c = function() {
|
||||||
|
console.log(this === b ? "bar" : "baz");
|
||||||
|
};
|
||||||
|
(a, b)();
|
||||||
|
(a, b.c)();
|
||||||
|
(a, function() {
|
||||||
|
console.log(this === a);
|
||||||
|
})();
|
||||||
|
new (a, b)();
|
||||||
|
new (a, b.c)();
|
||||||
|
new (a, function() {
|
||||||
|
console.log(this === a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function() {
|
||||||
|
return this;
|
||||||
|
}();
|
||||||
|
function b() {
|
||||||
|
console.log("foo");
|
||||||
|
}
|
||||||
|
b.c = function() {
|
||||||
|
console.log(this === b ? "bar" : "baz");
|
||||||
|
},
|
||||||
|
a, b(),
|
||||||
|
(a, b.c)(),
|
||||||
|
a, function() {
|
||||||
|
console.log(this === a);
|
||||||
|
}(),
|
||||||
|
a, new b(),
|
||||||
|
a, new b.c(),
|
||||||
|
a, new function() {
|
||||||
|
console.log(this === a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"true",
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
"false",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ issue_1929: {
|
|||||||
function f(s) {
|
function f(s) {
|
||||||
return s.split(/[\\/]/);
|
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"]'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,17 +90,11 @@ typeof_defun_1: {
|
|||||||
"function" == typeof h && h();
|
"function" == typeof h && h();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function g() {
|
|
||||||
h = 42;
|
|
||||||
console.log("NOPE");
|
|
||||||
}
|
|
||||||
function h() {
|
function h() {
|
||||||
console.log("YUP");
|
console.log("YUP");
|
||||||
}
|
}
|
||||||
g = 42;
|
|
||||||
console.log("YES");
|
console.log("YES");
|
||||||
"function" == typeof g && g();
|
h();
|
||||||
"function" == typeof h && h();
|
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"YES",
|
"YES",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
var parse = require("url").parse;
|
||||||
var path = require("path");
|
var path = require("path");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -19,7 +20,9 @@ module.exports = function(url, callback) {
|
|||||||
var result = read(url);
|
var result = read(url);
|
||||||
result.on("error", function(e) {
|
result.on("error", function(e) {
|
||||||
if (e.code != "ENOENT") return callback(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);
|
if (res.statusCode !== 200) return callback(res);
|
||||||
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
||||||
callback(null, read(url));
|
callback(null, read(url));
|
||||||
|
|||||||
4
test/input/enclose/input.js
Normal file
4
test/input/enclose/input.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
function enclose() {
|
||||||
|
console.log("test enclose");
|
||||||
|
}
|
||||||
|
enclose();
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
function test(a){
|
function test(a){
|
||||||
"aaaaaaaaaaaaaaaa"
|
"aaaaaaaaaaaaaaaa"
|
||||||
;a(err,data),a(err,data)
|
;a(err,data),a(err,
|
||||||
}
|
data)}
|
||||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBS0M7QUFDVjtDQUNBQSxFQUFTQyxJQUFLQyxNQUNkRixFQUFTQyxJQUFLQyJ9
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBS0M7QUFDVjtDQUNBQSxFQUFTQyxJQUFLQyxNQUNkRixFQUFTQztBQUFLQyJ9
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var site = "http://browserbench.org/JetStream";
|
var site = "https://browserbench.org/JetStream";
|
||||||
if (typeof phantom == "undefined") {
|
if (typeof phantom == "undefined") {
|
||||||
require("../tools/exit");
|
require("../tools/exit");
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
|
|||||||
122
test/mocha.js
122
test/mocha.js
@@ -1,24 +1,114 @@
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var Mocha = require("mocha");
|
|
||||||
var path = require("path");
|
|
||||||
|
|
||||||
// Instantiate a Mocha instance
|
var config = {
|
||||||
var mocha = new Mocha({
|
limit: 5000,
|
||||||
timeout: 5000
|
timeout: function(limit) {
|
||||||
});
|
this.limit = limit;
|
||||||
var testDir = __dirname + "/mocha/";
|
}
|
||||||
|
};
|
||||||
|
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("test/mocha").filter(function(file) {
|
||||||
fs.readdirSync(testDir).filter(function(file) {
|
|
||||||
return /\.js$/.test(file);
|
return /\.js$/.test(file);
|
||||||
}).forEach(function(file) {
|
}).forEach(function(file) {
|
||||||
mocha.addFile(path.join(testDir, file));
|
require("./mocha/" + file);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = function() {
|
function log_titles(log, current, marker) {
|
||||||
mocha.run(function(failures) {
|
var indent = "";
|
||||||
if (failures) process.on("exit", function() {
|
var writing = false;
|
||||||
process.exit(failures);
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ describe("bin/uglifyjs", function () {
|
|||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
var stderrLines = stderr.split('\n');
|
var stderrLines = stderr.split("\n");
|
||||||
assert.strictEqual(stderrLines[0], 'INFO: Using input source map: test/input/issue-2082/sample.js.map');
|
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": ";"}');
|
assert.notStrictEqual(stderrLines[1], 'INFO: Using input source map: {"version": 3,"sources": ["index.js"],"mappings": ";"}');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -121,7 +121,8 @@ describe("bin/uglifyjs", function () {
|
|||||||
var command = [
|
var command = [
|
||||||
uglifyjscmd,
|
uglifyjscmd,
|
||||||
"--source-map", "content=" + mapFile,
|
"--source-map", "content=" + mapFile,
|
||||||
"--source-map", "url=inline"
|
"--source-map", "includeSources=true",
|
||||||
|
"--source-map", "url=inline",
|
||||||
].join(" ");
|
].join(" ");
|
||||||
|
|
||||||
var child = exec(command, function(err, stdout) {
|
var child = exec(command, function(err, stdout) {
|
||||||
@@ -216,7 +217,14 @@ describe("bin/uglifyjs", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should process inline source map", function(done) {
|
it("Should process inline source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-520/input.js -mc toplevel --source-map content=inline,url=inline";
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-520/input.js",
|
||||||
|
"-mc", "toplevel",
|
||||||
|
"--source-map", "content=inline",
|
||||||
|
"--source-map", "includeSources=true",
|
||||||
|
"--source-map", "url=inline",
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -236,16 +244,29 @@ describe("bin/uglifyjs", function () {
|
|||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||||
"",
|
"",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
var stderrLines = stderr.split("\n");
|
||||||
|
assert.strictEqual(stderrLines[0], "WARN: inline source map not found: test/input/issue-1323/sample.js");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with multiple input and inline source map", function(done) {
|
it("Should handle multiple input and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-520/input.js test/input/issue-520/output.js --source-map content=inline,url=inline";
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-520/input.js",
|
||||||
|
"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) {
|
||||||
assert.ok(err);
|
if (err) throw err;
|
||||||
assert.strictEqual(stderr.split(/\n/)[0], "ERROR: inline source map only works with singular input");
|
|
||||||
|
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==",
|
||||||
|
"",
|
||||||
|
].join("\n"));
|
||||||
|
var stderrLines = stderr.split("\n");
|
||||||
|
assert.strictEqual(stderrLines[0], "WARN: inline source map not found: test/input/issue-1323/sample.js");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -723,4 +744,36 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
var Uglify = require('../../');
|
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
var Uglify = require("../../");
|
||||||
var SourceMapConsumer = require("source-map").SourceMapConsumer;
|
var SourceMapConsumer = require("source-map").SourceMapConsumer;
|
||||||
|
|
||||||
describe("input sourcemaps", function() {
|
|
||||||
var transpilemap, map;
|
|
||||||
|
|
||||||
function getMap() {
|
function getMap() {
|
||||||
return {
|
return {
|
||||||
"version": 3,
|
"version": 3,
|
||||||
@@ -17,50 +14,55 @@ describe("input sourcemaps", function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function prepareMap(sourceMap) {
|
function prepareMap(sourceMap) {
|
||||||
var transpiled = '"use strict";\n\n' +
|
var code = [
|
||||||
'var foo = function foo(x) {\n return "foo " + x;\n};\n' +
|
'"use strict";',
|
||||||
'console.log(foo("bar"));\n\n' +
|
"",
|
||||||
'//# sourceMappingURL=bundle.js.map';
|
"var foo = function foo(x) {",
|
||||||
|
' return "foo " + x;',
|
||||||
transpilemap = sourceMap || getMap();
|
"};",
|
||||||
|
'console.log(foo("bar"));',
|
||||||
var result = Uglify.minify(transpiled, {
|
"",
|
||||||
|
"//# sourceMappingURL=bundle.js.map",
|
||||||
|
].join("\n");
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: transpilemap
|
content: sourceMap,
|
||||||
|
includeSources: true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
map = new SourceMapConsumer(result.map);
|
return new SourceMapConsumer(result.map);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(function () {
|
describe("input sourcemaps", function() {
|
||||||
prepareMap();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should copy over original sourcesContent", function() {
|
it("Should copy over original sourcesContent", function() {
|
||||||
assert.equal(map.sourceContentFor("index.js"), transpilemap.sourcesContent[0]);
|
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() {
|
it("Should copy sourcesContent if sources are relative", function() {
|
||||||
var relativeMap = getMap();
|
var relativeMap = getMap();
|
||||||
relativeMap.sources = ['./index.js'];
|
relativeMap.sources = ['./index.js'];
|
||||||
|
var map = prepareMap(relativeMap);
|
||||||
prepareMap(relativeMap);
|
|
||||||
assert.notEqual(map.sourcesContent, null);
|
assert.notEqual(map.sourcesContent, null);
|
||||||
assert.equal(map.sourcesContent.length, 1);
|
assert.equal(map.sourcesContent.length, 1);
|
||||||
assert.equal(map.sourceContentFor("index.js"), transpilemap.sourcesContent[0]);
|
assert.equal(map.sourceContentFor("index.js"), relativeMap.sourcesContent[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Final sourcemap should not have invalid mappings from inputSourceMap (issue #882)", function() {
|
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
|
// 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";
|
var msg = "Mapping should not have higher line number than the original file had";
|
||||||
map.eachMapping(function(mapping) {
|
map.eachMapping(function(mapping) {
|
||||||
assert.ok(mapping.originalLine <= 2, msg)
|
assert.ok(mapping.originalLine <= 2, msg);
|
||||||
});
|
});
|
||||||
|
map.allGeneratedPositionsFor({
|
||||||
map.allGeneratedPositionsFor({source: "index.js", line: 1, column: 1}).forEach(function(pos) {
|
source: "index.js",
|
||||||
|
line: 1,
|
||||||
|
column: 1
|
||||||
|
}).forEach(function(pos) {
|
||||||
assert.ok(pos.line <= 2, msg);
|
assert.ok(pos.line <= 2, msg);
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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 = Uglify.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 = Uglify.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 = Uglify.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 = Uglify.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);');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../../");
|
||||||
|
|
||||||
describe("New", function() {
|
describe("parentheses", function() {
|
||||||
it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
|
it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
|
||||||
var tests = [
|
var tests = [
|
||||||
"new x(1);",
|
"new x(1);",
|
||||||
@@ -83,4 +83,23 @@ describe("New", function() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should compress leading parenthesis with reasonable performance", function() {
|
||||||
|
this.timeout(30000);
|
||||||
|
var code = [
|
||||||
|
"({}?0:1)&&x();",
|
||||||
|
"(function(){}).name;",
|
||||||
|
];
|
||||||
|
for (var i = 16; --i >= 0;) {
|
||||||
|
code = code.concat(code);
|
||||||
|
}
|
||||||
|
code = code.join("");
|
||||||
|
var result = uglify.minify(code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
// Dismal performance for `assert.strictEqual()` in Node.js 6
|
||||||
|
assert.ok(result.code === code);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -57,23 +57,23 @@ describe("sourcemaps", function() {
|
|||||||
includeSources: true
|
includeSources: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
var map = JSON.parse(result.map);
|
var map = JSON.parse(result.map);
|
||||||
|
assert.equal(map.file, "simple.min.js");
|
||||||
assert.equal(map.file, 'simple.min.js');
|
|
||||||
assert.equal(map.sourcesContent.length, 1);
|
assert.equal(map.sourcesContent.length, 1);
|
||||||
assert.equal(map.sourcesContent[0],
|
assert.equal(map.sourcesContent[0], 'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||||
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
|
||||||
});
|
});
|
||||||
it("Should process inline source map", function() {
|
it("Should process inline source map", function() {
|
||||||
var code = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
var result = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
||||||
compress: { toplevel: true },
|
compress: { toplevel: true },
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline",
|
content: "inline",
|
||||||
|
includeSources: true,
|
||||||
url: "inline"
|
url: "inline"
|
||||||
}
|
}
|
||||||
}).code + "\n";
|
});
|
||||||
assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code + "\n", readFileSync("test/input/issue-520/output.js", "utf8"));
|
||||||
});
|
});
|
||||||
it("Should warn for missing inline source map", function() {
|
it("Should warn for missing inline source map", function() {
|
||||||
var warn_function = Uglify.AST_Node.warn_function;
|
var warn_function = Uglify.AST_Node.warn_function;
|
||||||
@@ -90,44 +90,82 @@ describe("sourcemaps", function() {
|
|||||||
});
|
});
|
||||||
assert.strictEqual(result.code, "var bar=function(bar){return bar};");
|
assert.strictEqual(result.code, "var bar=function(bar){return bar};");
|
||||||
assert.strictEqual(warnings.length, 1);
|
assert.strictEqual(warnings.length, 1);
|
||||||
assert.strictEqual(warnings[0], "inline source map not found");
|
assert.strictEqual(warnings[0], "inline source map not found: 0");
|
||||||
} finally {
|
} finally {
|
||||||
Uglify.AST_Node.warn_function = warn_function;
|
Uglify.AST_Node.warn_function = warn_function;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should fail with multiple input and inline source map", function() {
|
it("Should handle multiple input and inline source map", function() {
|
||||||
|
var warn_function = Uglify.AST_Node.warn_function;
|
||||||
|
var warnings = [];
|
||||||
|
Uglify.AST_Node.warn_function = function(txt) {
|
||||||
|
warnings.push(txt);
|
||||||
|
};
|
||||||
|
try {
|
||||||
var result = Uglify.minify([
|
var result = Uglify.minify([
|
||||||
read("./test/input/issue-520/input.js"),
|
read("./test/input/issue-520/input.js"),
|
||||||
read("./test/input/issue-520/output.js")
|
read("./test/input/issue-1323/sample.js"),
|
||||||
], {
|
], {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
content: "inline",
|
content: "inline",
|
||||||
url: "inline"
|
url: "inline",
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var err = result.error;
|
if (result.error) throw result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.strictEqual(result.code, [
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "Error: inline source map only works with singular input");
|
"var Foo=function(){console.log(3)};new Foo;var bar=function(o){return o};",
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwiMSJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFdBQWdCQyxRQUFRQyxJQUFJLElBQVMsSUFBSUYsSUNBbkQsSUFBSUcsSUFDQSxTQUFjQSxHQUNWLE9BQU9BIn0=",
|
||||||
|
].join("\n"));
|
||||||
|
assert.strictEqual(warnings.length, 1);
|
||||||
|
assert.strictEqual(warnings[0], "inline source map not found: 1");
|
||||||
|
} finally {
|
||||||
|
Uglify.AST_Node.warn_function = warn_function;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should drop source contents for includeSources=false", function() {
|
||||||
|
var result = Uglify.minify(read("./test/input/issue-520/input.js"), {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
sourceMap: {
|
||||||
|
content: "inline",
|
||||||
|
includeSources: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
var map = JSON.parse(result.map);
|
||||||
|
assert.strictEqual(map.sourcesContent.length, 1);
|
||||||
|
result = Uglify.minify(result.code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
sourceMap: {
|
||||||
|
content: result.map,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
map = JSON.parse(result.map);
|
||||||
|
assert.ok(!("sourcesContent" in map));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("sourceMapInline", function() {
|
describe("sourceMapInline", function() {
|
||||||
it("should append source map to output js when sourceMapInline is enabled", function() {
|
it("Should append source map to output js when sourceMapInline is enabled", function() {
|
||||||
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
var result = Uglify.minify('var a = function(foo) { return foo; };', {
|
||||||
sourceMap: {
|
sourceMap: {
|
||||||
url: "inline"
|
url: "inline"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
assert.strictEqual(code, "var a=function(n){return n};\n" +
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsiYSIsImZvbyJdLCJtYXBwaW5ncyI6IkFBQUEsSUFBSUEsRUFBSSxTQUFTQyxHQUFPLE9BQU9BIn0=");
|
||||||
});
|
});
|
||||||
it("should not append source map to output js when sourceMapInline is not enabled", function() {
|
it("Should not append source map to output js when sourceMapInline is not enabled", function() {
|
||||||
var result = Uglify.minify('var a = function(foo) { return foo; };');
|
var result = Uglify.minify('var a = function(foo) { return foo; };');
|
||||||
|
if (result.error) throw result.error;
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=function(n){return n};");
|
assert.strictEqual(code, "var a=function(n){return n};");
|
||||||
});
|
});
|
||||||
it("should work with max_line_len", function() {
|
it("Should work with max_line_len", function() {
|
||||||
var result = Uglify.minify(read("./test/input/issue-505/input.js"), {
|
var result = Uglify.minify(read("./test/input/issue-505/input.js"), {
|
||||||
output: {
|
output: {
|
||||||
max_line_len: 20
|
max_line_len: 20
|
||||||
@@ -136,8 +174,39 @@ describe("sourcemaps", function() {
|
|||||||
url: "inline"
|
url: "inline"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.error, undefined);
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, read("./test/input/issue-505/output.js"));
|
assert.strictEqual(result.code, read("./test/input/issue-505/output.js"));
|
||||||
});
|
});
|
||||||
|
it("Should work with unicode characters", function() {
|
||||||
|
var code = [
|
||||||
|
"var tëst = '→unicøde←';",
|
||||||
|
"alert(tëst);",
|
||||||
|
].join("\n");
|
||||||
|
var result = Uglify.minify(code, {
|
||||||
|
sourceMap: {
|
||||||
|
includeSources: true,
|
||||||
|
url: "inline",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
var map = JSON.parse(result.map);
|
||||||
|
assert.strictEqual(map.sourcesContent.length, 1);
|
||||||
|
assert.strictEqual(map.sourcesContent[0], code);
|
||||||
|
var encoded = result.code.slice(result.code.lastIndexOf(",") + 1);
|
||||||
|
map = JSON.parse(new Buffer(encoded, "base64").toString());
|
||||||
|
assert.strictEqual(map.sourcesContent.length, 1);
|
||||||
|
assert.strictEqual(map.sourcesContent[0], code);
|
||||||
|
result = Uglify.minify(result.code, {
|
||||||
|
sourceMap: {
|
||||||
|
content: "inline",
|
||||||
|
includeSources: true,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
map = JSON.parse(result.map);
|
||||||
|
assert.strictEqual(map.names.length, 2);
|
||||||
|
assert.strictEqual(map.names[0], "tëst");
|
||||||
|
assert.strictEqual(map.names[1], "alert");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ if (failures) {
|
|||||||
console.error("!!! " + Object.keys(failed_files).join(", "));
|
console.error("!!! " + Object.keys(failed_files).join(", "));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
console.log();
|
||||||
var mocha_tests = require("./mocha.js");
|
require("./mocha.js");
|
||||||
mocha_tests();
|
|
||||||
|
|
||||||
/* -----[ utils ]----- */
|
/* -----[ utils ]----- */
|
||||||
|
|
||||||
@@ -172,7 +171,7 @@ function run_compress_tests() {
|
|||||||
}
|
}
|
||||||
if (test.expect_stdout
|
if (test.expect_stdout
|
||||||
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||||
var stdout = sandbox.run_code(input_code, true);
|
var stdout = run_code(input_code);
|
||||||
if (test.expect_stdout === true) {
|
if (test.expect_stdout === true) {
|
||||||
test.expect_stdout = stdout;
|
test.expect_stdout = stdout;
|
||||||
}
|
}
|
||||||
@@ -186,7 +185,7 @@ function run_compress_tests() {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stdout = sandbox.run_code(output, true);
|
stdout = run_code(output);
|
||||||
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
|
||||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
|
||||||
input: input_formatted,
|
input: input_formatted,
|
||||||
@@ -344,6 +343,11 @@ function evaluate(code) {
|
|||||||
return new Function("return(" + code + ")")();
|
return new Function("return(" + code + ")")();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function run_code(code) {
|
||||||
|
var result = sandbox.run_code(code, true);
|
||||||
|
return typeof result == "string" ? result.replace(/\u001b\[\d+m/g, "") : result;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to reminify original input with standard options
|
// Try to reminify original input with standard options
|
||||||
// to see if it matches expect_stdout.
|
// to see if it matches expect_stdout.
|
||||||
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
||||||
@@ -367,7 +371,7 @@ function reminify(orig_options, input_code, input_formatted, expect_stdout) {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
var stdout = sandbox.run_code(result.code, true);
|
var stdout = run_code(result.code);
|
||||||
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
|
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
|
||||||
stdout = expect_stdout;
|
stdout = expect_stdout;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,9 @@ var semver = require("semver");
|
|||||||
var vm = require("vm");
|
var vm = require("vm");
|
||||||
|
|
||||||
function createContext() {
|
function createContext() {
|
||||||
var context = Object.create(null);
|
return vm.createContext(Object.defineProperty({}, "console", {
|
||||||
Object.defineProperty(context, "console", {
|
value: {
|
||||||
value: function() {
|
log: function(msg) {
|
||||||
var con = Object.create(null);
|
|
||||||
Object.defineProperty(con, "log", {
|
|
||||||
value: function(msg) {
|
|
||||||
if (arguments.length == 1 && typeof msg == "string") {
|
if (arguments.length == 1 && typeof msg == "string") {
|
||||||
return console.log("%s", msg);
|
return console.log("%s", msg);
|
||||||
}
|
}
|
||||||
@@ -15,11 +12,8 @@ function createContext() {
|
|||||||
return safe_log(arg, 3);
|
return safe_log(arg, 3);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return con;
|
}));
|
||||||
}()
|
|
||||||
});
|
|
||||||
return vm.createContext(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function safe_log(arg, level) {
|
function safe_log(arg, level) {
|
||||||
@@ -40,7 +34,7 @@ function safe_log(arg, level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function strip_func_ids(text) {
|
function strip_func_ids(text) {
|
||||||
return text.toString().replace(/F[0-9]{6}N/g, "<F<>N>");
|
return ("" + text).replace(/F[0-9]{6}N/g, "<F<>N>");
|
||||||
}
|
}
|
||||||
|
|
||||||
var context;
|
var context;
|
||||||
|
|||||||
@@ -18,6 +18,13 @@
|
|||||||
{
|
{
|
||||||
"toplevel": true
|
"toplevel": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"compress": {
|
||||||
|
"passes": 1e6,
|
||||||
|
"unsafe": true
|
||||||
|
},
|
||||||
|
"toplevel": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"compress": {
|
"compress": {
|
||||||
"keep_fargs": false,
|
"keep_fargs": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user