Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
614db97cca | ||
|
|
d854523783 | ||
|
|
781f26eda1 | ||
|
|
37f4395cc0 | ||
|
|
de619ae5a6 | ||
|
|
86859f6d7e | ||
|
|
dcdcfe4d39 | ||
|
|
72306b9885 | ||
|
|
38756b1f26 | ||
|
|
85a09fc3b6 | ||
|
|
307b88d6cc | ||
|
|
fb049d3a81 | ||
|
|
67cca43358 | ||
|
|
642273c290 | ||
|
|
e8b23c7798 | ||
|
|
9edbe93df5 | ||
|
|
af37ecafe1 | ||
|
|
41a9329409 | ||
|
|
7eb52d2837 | ||
|
|
eb63fece2f | ||
|
|
2d8af8947e | ||
|
|
2650182f47 | ||
|
|
572b97b0bb | ||
|
|
698705a820 | ||
|
|
debc525fa1 | ||
|
|
5576e2737a | ||
|
|
b40d5de69c | ||
|
|
b7ef7840f3 | ||
|
|
85924bb32e | ||
|
|
a97690fc72 | ||
|
|
02c638209e | ||
|
|
030611b729 | ||
|
|
335b72df03 | ||
|
|
3a7d53f3cf |
79
README.md
79
README.md
@@ -65,9 +65,11 @@ The available options are:
|
||||
--in-source-map Input source map, useful if you're compressing
|
||||
JS that was generated from some other original
|
||||
code.
|
||||
--screw-ie8 Pass this flag if you don't care about full
|
||||
compliance with Internet Explorer 6-8 quirks
|
||||
(by default UglifyJS will try to be IE-proof).
|
||||
--screw-ie8 Use this flag if you don't wish to support
|
||||
Internet Explorer 6-8 quirks.
|
||||
By default UglifyJS will not try to be IE-proof.
|
||||
--support-ie8 Use this flag to support Internet Explorer 6-8 quirks.
|
||||
Note: may break standards compliant `catch` identifiers.
|
||||
--expr Parse a single expression, rather than a
|
||||
program (for parsing JSON)
|
||||
-p, --prefix Skip prefix for original filenames that appear
|
||||
@@ -133,11 +135,11 @@ The available options are:
|
||||
--reserved-file File containing reserved names
|
||||
--reserve-domprops Make (most?) DOM properties reserved for
|
||||
--mangle-props
|
||||
--mangle-props Mangle property names (default `0`). Set to
|
||||
--mangle-props Mangle property names (default `0`). Set to
|
||||
`true` or `1` to mangle all property names. Set
|
||||
to `unquoted` or `2` to only mangle unquoted
|
||||
to `unquoted` or `2` to only mangle unquoted
|
||||
property names. Mode `2` also enables the
|
||||
`keep_quoted_props` beautifier option to
|
||||
`keep_quoted_props` beautifier option to
|
||||
preserve the quotes around property names and
|
||||
disables the `properties` compressor option to
|
||||
prevent rewriting quoted properties with dot
|
||||
@@ -289,7 +291,14 @@ you can pass a comma-separated list of options. Options are in the form
|
||||
`foo=bar`, or just `foo` (the latter implies a boolean option that you want
|
||||
to set `true`; it's effectively a shortcut for `foo=true`).
|
||||
|
||||
- `sequences` -- join consecutive simple statements using the comma operator
|
||||
- `sequences` (default: true) -- join consecutive simple statements using the
|
||||
comma operator. May be set to a positive integer to specify the maximum number
|
||||
of consecutive comma sequences that will be generated. If this option is set to
|
||||
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
||||
to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
|
||||
is grandfathered to be equivalent to `true` and as such means `200`. On rare
|
||||
occasions the default sequences limit leads to very slow compress times in which
|
||||
case a value of `20` or less is recommended.
|
||||
|
||||
- `properties` -- rewrite property access using the dot notation, for
|
||||
example `foo["bar"] → foo.bar`
|
||||
@@ -369,8 +378,8 @@ to set `true`; it's effectively a shortcut for `foo=true`).
|
||||
for code which relies on `Function.length`.
|
||||
|
||||
- `keep_fnames` -- default `false`. Pass `true` to prevent the
|
||||
compressor from mangling/discarding function names. Useful for code relying on
|
||||
`Function.prototype.name`.
|
||||
compressor from discarding function names. Useful for code relying on
|
||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
||||
|
||||
- `passes` -- default `1`. Number of times to run compress. Use an
|
||||
integer argument larger than 1 to further reduce code size in some cases.
|
||||
@@ -619,6 +628,14 @@ console.log(result.code); // minified output
|
||||
console.log(result.map);
|
||||
```
|
||||
|
||||
To generate a source map with the fromString option, you can also use an object:
|
||||
```javascript
|
||||
var result = UglifyJS.minify({"file1.js": "var a = function () {};"}, {
|
||||
outSourceMap: "out.js.map",
|
||||
fromString: true
|
||||
});
|
||||
```
|
||||
|
||||
Note that the source map is not saved in a file, it's just returned in
|
||||
`result.map`. The value passed for `outSourceMap` is only used to set the
|
||||
`file` attribute in the source map (see [the spec][sm-spec]).
|
||||
@@ -654,6 +671,17 @@ var result = UglifyJS.minify("compiled.js", {
|
||||
The `inSourceMap` is only used if you also request `outSourceMap` (it makes
|
||||
no sense otherwise).
|
||||
|
||||
To set the source map url, use the `sourceMapUrl` option.
|
||||
If you're using the X-SourceMap header instead, you can just set the `sourceMapUrl` option to false.
|
||||
Defaults to outSourceMap:
|
||||
|
||||
```javascript
|
||||
var result = UglifyJS.minify([ "file1.js" ], {
|
||||
outSourceMap: "out.js.map",
|
||||
sourceMapUrl: "localhost/out.js.map"
|
||||
});
|
||||
```
|
||||
|
||||
Other options:
|
||||
|
||||
- `warnings` (default `false`) — pass `true` to display compressor warnings.
|
||||
@@ -661,7 +689,8 @@ Other options:
|
||||
- `fromString` (default `false`) — if you pass `true` then you can pass
|
||||
JavaScript source code, rather than file names.
|
||||
|
||||
- `mangle` — pass `false` to skip mangling names.
|
||||
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
|
||||
an object to specify mangling options (see below).
|
||||
|
||||
- `mangleProperties` (default `false`) — pass an object to specify custom
|
||||
mangle property options.
|
||||
@@ -680,6 +709,36 @@ Other options:
|
||||
|
||||
- `except` - pass an array of identifiers that should be excluded from mangling
|
||||
|
||||
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
||||
default).
|
||||
|
||||
- `eval` — mangle names visible in scopes where eval or with are used
|
||||
(disabled by default).
|
||||
|
||||
- `keep_fnames` -- default `false`. Pass `true` to not mangle
|
||||
function names. Useful for code relying on `Function.prototype.name`.
|
||||
See also: the `keep_fnames` [compress option](#compressor-options).
|
||||
|
||||
Examples:
|
||||
|
||||
```javascript
|
||||
//tst.js
|
||||
var globalVar;
|
||||
function funcName(firstLongName, anotherLongName)
|
||||
{
|
||||
var myVariable = firstLongName + anotherLongName;
|
||||
}
|
||||
|
||||
UglifyJS.minify("tst.js").code;
|
||||
// 'function funcName(a,n){}var globalVar;'
|
||||
|
||||
UglifyJS.minify("tst.js", { mangle: { except: ['firstLongName'] } }).code;
|
||||
// 'function funcName(firstLongName,a){}var globalVar;'
|
||||
|
||||
UglifyJS.minify("tst.js", { mangle: { toplevel: true } }).code;
|
||||
// 'function n(n,a){}var a;'
|
||||
```
|
||||
|
||||
##### mangleProperties options
|
||||
|
||||
- `regex` — Pass a RegExp to only mangle certain names (maps to the `--mangle-regex` CLI arguments option)
|
||||
|
||||
24
appveyor.yml
Normal file
24
appveyor.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4.0"
|
||||
- nodejs_version: "6.0"
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||
- npm install
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
|
||||
build: off
|
||||
23
bin/uglifyjs
23
bin/uglifyjs
@@ -10,6 +10,7 @@ var fs = require("fs");
|
||||
var path = require("path");
|
||||
var async = require("async");
|
||||
var acorn;
|
||||
var screw_ie8 = true;
|
||||
var ARGS = yargs
|
||||
.usage("$0 input1.js [input2.js ...] [options]\n\
|
||||
Use a single dash to read input from the standard input.\
|
||||
@@ -24,7 +25,8 @@ mangling you need to use `-c` and `-m`.\
|
||||
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||
.describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default UglifyJS will try to be IE-proof).")
|
||||
.describe("screw-ie8", "Do not support Internet Explorer 6-8 quirks. This flag is enabled by default.")
|
||||
.describe("support-ie8", "Support non-standard Internet Explorer 6-8 javascript. Note: may break standards compliant `catch` identifiers.")
|
||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
||||
@@ -105,12 +107,14 @@ You need to pass an argument to this option to specify the name that your module
|
||||
.string("p")
|
||||
.string("prefix")
|
||||
.string("name-cache")
|
||||
|
||||
.array("reserved-file")
|
||||
.array("pure-funcs")
|
||||
|
||||
.boolean("expr")
|
||||
.boolean("source-map-include-sources")
|
||||
.boolean("screw-ie8")
|
||||
.boolean("support-ie8")
|
||||
.boolean("export-all")
|
||||
.boolean("self")
|
||||
.boolean("v")
|
||||
@@ -230,12 +234,14 @@ if (ARGS.mangle_props == 2) {
|
||||
COMPRESS.properties = false;
|
||||
}
|
||||
|
||||
if (ARGS.screw_ie8) {
|
||||
if (COMPRESS) COMPRESS.screw_ie8 = true;
|
||||
if (MANGLE) MANGLE.screw_ie8 = true;
|
||||
OUTPUT_OPTIONS.screw_ie8 = true;
|
||||
if (ARGS.support_ie8 === true && ARGS.screw_ie8 !== true) {
|
||||
screw_ie8 = false;
|
||||
}
|
||||
|
||||
if (COMPRESS) COMPRESS.screw_ie8 = screw_ie8;
|
||||
if (MANGLE) MANGLE.screw_ie8 = screw_ie8;
|
||||
OUTPUT_OPTIONS.screw_ie8 = screw_ie8;
|
||||
|
||||
if (ARGS.keep_fnames) {
|
||||
if (COMPRESS) COMPRESS.keep_fnames = true;
|
||||
if (MANGLE) MANGLE.keep_fnames = true;
|
||||
@@ -267,6 +273,9 @@ if (ARGS.comments != null) {
|
||||
|
||||
var files = ARGS._.slice();
|
||||
|
||||
if (process.platform === "win32")
|
||||
files = UglifyJS.simple_glob(files);
|
||||
|
||||
if (ARGS.self) {
|
||||
if (files.length > 0) {
|
||||
print_error("WARN: Ignoring input files since --self was passed");
|
||||
@@ -426,7 +435,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
||||
|
||||
if (SCOPE_IS_NEEDED) {
|
||||
time_it("scope", function(){
|
||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
||||
TOPLEVEL.figure_out_scope({ screw_ie8: screw_ie8, cache: TL_CACHE });
|
||||
if (ARGS.lint) {
|
||||
TOPLEVEL.scope_warnings();
|
||||
}
|
||||
@@ -441,7 +450,7 @@ async.eachLimit(files, 1, function (file, cb) {
|
||||
|
||||
if (SCOPE_IS_NEEDED) {
|
||||
time_it("scope", function(){
|
||||
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8, cache: TL_CACHE });
|
||||
TOPLEVEL.figure_out_scope({ screw_ie8: screw_ie8, cache: TL_CACHE });
|
||||
if (MANGLE && !TL_CACHE) {
|
||||
TOPLEVEL.compute_char_frequency(MANGLE);
|
||||
}
|
||||
|
||||
@@ -72,13 +72,15 @@ function Compressor(options, false_by_default) {
|
||||
pure_getters : false,
|
||||
pure_funcs : null,
|
||||
negate_iife : !false_by_default,
|
||||
screw_ie8 : false,
|
||||
screw_ie8 : true,
|
||||
drop_console : false,
|
||||
angular : false,
|
||||
warnings : true,
|
||||
global_defs : {},
|
||||
passes : 1,
|
||||
}, true);
|
||||
var sequences = this.options["sequences"];
|
||||
this.sequences_limit = sequences == 1 ? 200 : sequences | 0;
|
||||
this.warnings_produced = {};
|
||||
};
|
||||
|
||||
@@ -190,7 +192,7 @@ merge(Compressor.prototype, {
|
||||
if ((1 / val) < 0) {
|
||||
return make_node(AST_UnaryPrefix, orig, {
|
||||
operator: "-",
|
||||
expression: make_node(AST_Number, null, { value: -val })
|
||||
expression: make_node(AST_Number, orig, { value: -val })
|
||||
});
|
||||
}
|
||||
|
||||
@@ -266,7 +268,7 @@ merge(Compressor.prototype, {
|
||||
if (compressor.option("if_return")) {
|
||||
statements = handle_if_return(statements, compressor);
|
||||
}
|
||||
if (compressor.option("sequences")) {
|
||||
if (compressor.sequences_limit > 0) {
|
||||
statements = sequencesize(statements, compressor);
|
||||
}
|
||||
if (compressor.option("join_vars")) {
|
||||
@@ -721,7 +723,7 @@ merge(Compressor.prototype, {
|
||||
seq = [];
|
||||
};
|
||||
statements.forEach(function(stat){
|
||||
if (stat instanceof AST_SimpleStatement && seqLength(seq) < 2000) {
|
||||
if (stat instanceof AST_SimpleStatement && seqLength(seq) < compressor.sequences_limit) {
|
||||
seq.push(stat.body);
|
||||
} else {
|
||||
push_seq();
|
||||
@@ -808,7 +810,7 @@ merge(Compressor.prototype, {
|
||||
CHANGED = true;
|
||||
}
|
||||
else if (stat instanceof AST_For
|
||||
&& prev instanceof AST_Definitions
|
||||
&& prev instanceof AST_Var
|
||||
&& (!stat.init || stat.init.TYPE == prev.TYPE)) {
|
||||
CHANGED = true;
|
||||
a.pop();
|
||||
|
||||
@@ -45,20 +45,55 @@
|
||||
|
||||
(function(){
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
ExpressionStatement: function(M) {
|
||||
var expr = M.expression;
|
||||
if (expr.type === "Literal" && typeof expr.value === "string") {
|
||||
return new AST_Directive({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
value: expr.value
|
||||
var normalize_directives = function(body) {
|
||||
var in_directive = true;
|
||||
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
||||
body[i] = new AST_Directive({
|
||||
start: body[i].start,
|
||||
end: body[i].end,
|
||||
value: body[i].body.value
|
||||
});
|
||||
} else if (in_directive && !(body[i] instanceof AST_Statement && body[i].body instanceof AST_String)) {
|
||||
in_directive = false;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
Program: function(M) {
|
||||
return new AST_Toplevel({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
body: normalize_directives(M.body.map(from_moz))
|
||||
});
|
||||
},
|
||||
FunctionDeclaration: function(M) {
|
||||
return new AST_Defun({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
name: from_moz(M.id),
|
||||
argnames: M.params.map(from_moz),
|
||||
body: normalize_directives(from_moz(M.body).body)
|
||||
});
|
||||
},
|
||||
FunctionExpression: function(M) {
|
||||
return new AST_Function({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
name: from_moz(M.id),
|
||||
argnames: M.params.map(from_moz),
|
||||
body: normalize_directives(from_moz(M.body).body)
|
||||
});
|
||||
},
|
||||
ExpressionStatement: function(M) {
|
||||
return new AST_SimpleStatement({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
body: from_moz(expr)
|
||||
body: from_moz(M.expression)
|
||||
});
|
||||
},
|
||||
TryStatement: function(M) {
|
||||
@@ -94,6 +129,15 @@
|
||||
return new AST_ObjectGetter(args);
|
||||
}
|
||||
},
|
||||
ArrayExpression: function(M) {
|
||||
return new AST_Array({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
elements : M.elements.map(function(elem){
|
||||
return elem === null ? new AST_Hole() : from_moz(elem);
|
||||
})
|
||||
});
|
||||
},
|
||||
ObjectExpression: function(M) {
|
||||
return new AST_Object({
|
||||
start : my_start_token(M),
|
||||
@@ -185,7 +229,6 @@
|
||||
});
|
||||
};
|
||||
|
||||
map("Program", AST_Toplevel, "body@body");
|
||||
map("EmptyStatement", AST_EmptyStatement);
|
||||
map("BlockStatement", AST_BlockStatement, "body@body");
|
||||
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
|
||||
@@ -201,13 +244,10 @@
|
||||
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
|
||||
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
|
||||
map("DebuggerStatement", AST_Debugger);
|
||||
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body");
|
||||
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
||||
map("CatchClause", AST_Catch, "param>argname, body%body");
|
||||
|
||||
map("ThisExpression", AST_This);
|
||||
map("ArrayExpression", AST_Array, "elements@elements");
|
||||
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body");
|
||||
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
||||
@@ -215,6 +255,31 @@
|
||||
map("NewExpression", AST_New, "callee>expression, arguments@args");
|
||||
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
||||
|
||||
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
|
||||
return {
|
||||
type: "Program",
|
||||
body: M.body.map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
|
||||
return {
|
||||
type: "FunctionDeclaration",
|
||||
id: to_moz(M.name),
|
||||
params: M.argnames.map(to_moz),
|
||||
body: to_moz_block(M)
|
||||
}
|
||||
});
|
||||
|
||||
def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) {
|
||||
return {
|
||||
type: "FunctionExpression",
|
||||
id: to_moz(M.name),
|
||||
params: M.argnames.map(to_moz),
|
||||
body: to_moz_block(M)
|
||||
}
|
||||
});
|
||||
|
||||
def_to_moz(AST_Directive, function To_Moz_Directive(M) {
|
||||
return {
|
||||
type: "ExpressionStatement",
|
||||
@@ -302,6 +367,13 @@
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) {
|
||||
return {
|
||||
type: "ArrayExpression",
|
||||
elements: M.elements.map(to_moz)
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) {
|
||||
return {
|
||||
type: "ObjectExpression",
|
||||
|
||||
@@ -64,7 +64,7 @@ function OutputStream(options) {
|
||||
comments : false,
|
||||
shebang : true,
|
||||
preserve_line : false,
|
||||
screw_ie8 : false,
|
||||
screw_ie8 : true,
|
||||
preamble : null,
|
||||
quote_style : 0,
|
||||
keep_quoted_props: false
|
||||
@@ -531,9 +531,11 @@ function OutputStream(options) {
|
||||
});
|
||||
|
||||
PARENS([ AST_Unary, AST_Undefined ], function(output){
|
||||
if (this.expression instanceof AST_Call)
|
||||
return false;
|
||||
var p = output.parent();
|
||||
return p instanceof AST_PropAccess && p.expression === this
|
||||
|| p instanceof AST_New;
|
||||
|| p instanceof AST_Call && p.expression === this;
|
||||
});
|
||||
|
||||
PARENS(AST_Seq, function(output){
|
||||
@@ -861,8 +863,8 @@ function OutputStream(options) {
|
||||
// adds the block brackets if needed.
|
||||
if (!self.body)
|
||||
return output.force_semicolon();
|
||||
if (self.body instanceof AST_Do
|
||||
&& !output.option("screw_ie8")) {
|
||||
if (self.body instanceof AST_Do) {
|
||||
// Unconditionally use the if/do-while workaround for all browsers.
|
||||
// https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
|
||||
// croaks with "syntax error" on code like this: if (foo)
|
||||
// do ... while(cond); else ... we need block brackets
|
||||
|
||||
92
lib/parse.js
92
lib/parse.js
@@ -107,7 +107,9 @@ var OPERATORS = makePredicate([
|
||||
"||"
|
||||
]);
|
||||
|
||||
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF"));
|
||||
var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF"));
|
||||
|
||||
var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029"));
|
||||
|
||||
var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,.;:"));
|
||||
|
||||
@@ -234,7 +236,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
var ch = S.text.charAt(S.pos++);
|
||||
if (signal_eof && !ch)
|
||||
throw EX_EOF;
|
||||
if ("\r\n\u2028\u2029".indexOf(ch) >= 0) {
|
||||
if (NEWLINE_CHARS(ch)) {
|
||||
S.newline_before = S.newline_before || !in_string;
|
||||
++S.line;
|
||||
S.col = 0;
|
||||
@@ -261,7 +263,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
var text = S.text;
|
||||
for (var i = S.pos, n = S.text.length; i < n; ++i) {
|
||||
var ch = text[i];
|
||||
if (ch == '\n' || ch == '\r')
|
||||
if (NEWLINE_CHARS(ch))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@@ -313,8 +315,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
};
|
||||
|
||||
function skip_whitespace() {
|
||||
var ch;
|
||||
while (WHITESPACE_CHARS(ch = peek()) || ch == "\u2028" || ch == "\u2029")
|
||||
while (WHITESPACE_CHARS(peek()))
|
||||
next();
|
||||
};
|
||||
|
||||
@@ -348,11 +349,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return is_alphanumeric_char(code);
|
||||
});
|
||||
if (prefix) num = prefix + num;
|
||||
if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) {
|
||||
parse_error("SyntaxError: Legacy octal literals are not allowed in strict mode");
|
||||
}
|
||||
var valid = parse_js_number(num);
|
||||
if (!isNaN(valid)) {
|
||||
return token("num", valid);
|
||||
} else {
|
||||
parse_error("Invalid syntax: " + num);
|
||||
parse_error("SyntaxError: Invalid syntax: " + num);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -365,7 +369,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
case 98 : return "\b";
|
||||
case 118 : return "\u000b"; // \v
|
||||
case 102 : return "\f";
|
||||
case 48 : return "\0";
|
||||
case 120 : return String.fromCharCode(hex_bytes(2)); // \x
|
||||
case 117 : return String.fromCharCode(hex_bytes(4)); // \u
|
||||
case 10 : return ""; // newline
|
||||
@@ -375,46 +378,44 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (ch >= "0" && ch <= "7")
|
||||
return read_octal_escape_sequence(ch);
|
||||
return ch;
|
||||
};
|
||||
|
||||
function read_octal_escape_sequence(ch) {
|
||||
// Read
|
||||
var p = peek();
|
||||
if (p >= "0" && p <= "7") {
|
||||
ch += next(true);
|
||||
if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7")
|
||||
ch += next(true);
|
||||
}
|
||||
|
||||
// Parse
|
||||
if (ch === "0") return "\0";
|
||||
if (ch.length > 0 && next_token.has_directive("use strict"))
|
||||
parse_error("SyntaxError: Legacy octal escape sequences are not allowed in strict mode");
|
||||
return String.fromCharCode(parseInt(ch, 8));
|
||||
}
|
||||
|
||||
function hex_bytes(n) {
|
||||
var num = 0;
|
||||
for (; n > 0; --n) {
|
||||
var digit = parseInt(next(true), 16);
|
||||
if (isNaN(digit))
|
||||
parse_error("Invalid hex-character pattern in string");
|
||||
parse_error("SyntaxError: Invalid hex-character pattern in string");
|
||||
num = (num << 4) | digit;
|
||||
}
|
||||
return num;
|
||||
};
|
||||
|
||||
var read_string = with_eof_error("Unterminated string constant", function(quote_char){
|
||||
var read_string = with_eof_error("SyntaxError: Unterminated string constant", function(quote_char){
|
||||
var quote = next(), ret = "";
|
||||
for (;;) {
|
||||
var ch = next(true, true);
|
||||
if (ch == "\\") {
|
||||
var octal_len = 0, first = null;
|
||||
ch = read_while(function(ch){
|
||||
if (ch >= "0" && ch <= "7") {
|
||||
if (!first) {
|
||||
first = ch;
|
||||
return ++octal_len;
|
||||
}
|
||||
else if (first <= "3" && octal_len <= 2) return ++octal_len;
|
||||
else if (first >= "4" && octal_len <= 1) return ++octal_len;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (octal_len > 0) {
|
||||
if (ch !== "0" && next_token.has_directive("use strict"))
|
||||
parse_error("Octal literals are not allowed in strict mode");
|
||||
ch = String.fromCharCode(parseInt(ch, 8));
|
||||
} else {
|
||||
ch = read_escaped_char(true);
|
||||
}
|
||||
}
|
||||
else if ("\r\n\u2028\u2029".indexOf(ch) >= 0) parse_error("Unterminated string constant");
|
||||
if (ch == "\\") ch = read_escaped_char(true);
|
||||
else if (NEWLINE_CHARS(ch)) parse_error("SyntaxError: Unterminated string constant");
|
||||
else if (ch == quote) break;
|
||||
ret += ch;
|
||||
}
|
||||
@@ -439,21 +440,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return next_token;
|
||||
};
|
||||
|
||||
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function(){
|
||||
var skip_multiline_comment = with_eof_error("SyntaxError: Unterminated multiline comment", function(){
|
||||
var regex_allowed = S.regex_allowed;
|
||||
var i = find("*/", true);
|
||||
var text = S.text.substring(S.pos, i).replace(/\r\n|\r/g, '\n');
|
||||
var a = text.split("\n"), n = a.length;
|
||||
var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, '\n');
|
||||
// update stream position
|
||||
S.pos = i + 2;
|
||||
S.line += n - 1;
|
||||
if (n > 1) S.col = a[n - 1].length;
|
||||
else S.col += a[n - 1].length;
|
||||
S.col += 2;
|
||||
var nlb = S.newline_before = S.newline_before || text.indexOf("\n") >= 0;
|
||||
forward(text.length /* doesn't count \r\n as 2 char while S.pos - i does */ + 2);
|
||||
S.comments_before.push(token("comment2", text, true));
|
||||
S.regex_allowed = regex_allowed;
|
||||
S.newline_before = nlb;
|
||||
return next_token;
|
||||
});
|
||||
|
||||
@@ -466,9 +460,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
else break;
|
||||
}
|
||||
else {
|
||||
if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
|
||||
if (ch != "u") parse_error("SyntaxError: Expecting UnicodeEscapeSequence -- uXXXX");
|
||||
ch = read_escaped_char();
|
||||
if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
|
||||
if (!is_identifier_char(ch)) parse_error("SyntaxError: Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
|
||||
name += ch;
|
||||
backslash = false;
|
||||
}
|
||||
@@ -480,9 +474,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return name;
|
||||
};
|
||||
|
||||
var read_regexp = with_eof_error("Unterminated regular expression", function(regexp){
|
||||
var read_regexp = with_eof_error("SyntaxError: Unterminated regular expression", function(regexp){
|
||||
var prev_backslash = false, ch, in_class = false;
|
||||
while ((ch = next(true))) if (prev_backslash) {
|
||||
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
||||
parse_error("SyntaxError: Unexpected line terminator");
|
||||
} else if (prev_backslash) {
|
||||
regexp += "\\" + ch;
|
||||
prev_backslash = false;
|
||||
} else if (ch == "[") {
|
||||
@@ -495,8 +491,6 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
break;
|
||||
} else if (ch == "\\") {
|
||||
prev_backslash = true;
|
||||
} else if ("\r\n\u2028\u2029".indexOf(ch) >= 0) {
|
||||
parse_error("Unexpected line terminator");
|
||||
} else {
|
||||
regexp += ch;
|
||||
}
|
||||
@@ -504,7 +498,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
try {
|
||||
return token("regexp", new RegExp(regexp, mods));
|
||||
} catch(e) {
|
||||
parse_error(e.message);
|
||||
parse_error("SyntaxError: " + e.message);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -605,7 +599,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
parse_error("Unexpected character '" + ch + "'");
|
||||
parse_error("SyntaxError: Unexpected character '" + ch + "'");
|
||||
};
|
||||
|
||||
next_token.context = function(nc) {
|
||||
|
||||
@@ -86,27 +86,22 @@ function mangle_properties(ast, options) {
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
var ignored = {};
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node){
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
if (!(ignore_quoted && node.quote))
|
||||
add(node.key);
|
||||
add(node.key, ignore_quoted && node.quote);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
add(node.key.name);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
if (this.parent() instanceof AST_Assign) {
|
||||
add(node.property);
|
||||
}
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
if (this.parent() instanceof AST_Assign) {
|
||||
if (!ignore_quoted)
|
||||
addStrings(node.property);
|
||||
}
|
||||
addStrings(node.property, ignore_quoted);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -154,13 +149,19 @@ function mangle_properties(ast, options) {
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (ignore_quoted && name in ignored) return false;
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
return cache.props.has(name)
|
||||
|| names_to_mangle.indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
function add(name, ignore) {
|
||||
if (ignore) {
|
||||
ignored[name] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (can_mangle(name))
|
||||
push_uniq(names_to_mangle, name);
|
||||
|
||||
@@ -184,7 +185,7 @@ function mangle_properties(ast, options) {
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function addStrings(node) {
|
||||
function addStrings(node, ignore) {
|
||||
var out = {};
|
||||
try {
|
||||
(function walk(node){
|
||||
@@ -194,7 +195,7 @@ function mangle_properties(ast, options) {
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_String) {
|
||||
add(node.value);
|
||||
add(node.value, ignore);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Conditional) {
|
||||
|
||||
10
lib/scope.js
10
lib/scope.js
@@ -88,7 +88,7 @@ SymbolDef.prototype = {
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
options = defaults(options, {
|
||||
screw_ie8: false,
|
||||
screw_ie8: true,
|
||||
cache: null
|
||||
});
|
||||
|
||||
@@ -314,9 +314,13 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
// a function expression's argument cannot shadow the function expression's name
|
||||
|
||||
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
|
||||
|
||||
// the function's mangled_name is null when keep_fnames is true
|
||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||
|
||||
while (true) {
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
if (!(tricky_def && tricky_def.mangled_name == name))
|
||||
if (!tricky_name || tricky_name != name)
|
||||
return name;
|
||||
}
|
||||
});
|
||||
@@ -377,7 +381,7 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||
eval : false,
|
||||
sort : false, // Ignored. Flag retained for backwards compatibility.
|
||||
toplevel : false,
|
||||
screw_ie8 : false,
|
||||
screw_ie8 : true,
|
||||
keep_fnames : false
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,6 +58,16 @@ function SourceMap(options) {
|
||||
sourceRoot : options.root
|
||||
});
|
||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||
|
||||
if (orig_map && Array.isArray(options.orig.sources)) {
|
||||
options.orig.sources.forEach(function(source) {
|
||||
var sourceContent = orig_map.sourceContentFor(source, true);
|
||||
if (sourceContent) {
|
||||
generator.setSourceContent(source, sourceContent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
if (orig_map) {
|
||||
var info = orig_map.originalPositionFor({
|
||||
|
||||
13
lib/utils.js
13
lib/utils.js
@@ -227,10 +227,19 @@ function makePredicate(words) {
|
||||
}
|
||||
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;
|
||||
});
|
||||
}
|
||||
function compareTo(arr) {
|
||||
if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";
|
||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
||||
f += "switch(str){";
|
||||
for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
|
||||
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
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "2.6.4",
|
||||
"version": "2.7.2",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ ascii_only_true: {
|
||||
options = {}
|
||||
beautify = {
|
||||
ascii_only : true,
|
||||
screw_ie8 : true,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
@@ -12,13 +13,14 @@ ascii_only_true: {
|
||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\x0B\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||
}
|
||||
|
||||
ascii_only_false: {
|
||||
options = {}
|
||||
beautify = {
|
||||
ascii_only : false,
|
||||
screw_ie8 : true,
|
||||
beautify : false,
|
||||
}
|
||||
input: {
|
||||
@@ -29,6 +31,6 @@ ascii_only_false: {
|
||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||
}
|
||||
}
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\x0B\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||
}
|
||||
|
||||
|
||||
52
test/compress/issue-1202.js
Normal file
52
test/compress/issue-1202.js
Normal file
@@ -0,0 +1,52 @@
|
||||
mangle_keep_fnames_false: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : false,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function n(a, b, c) {
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function t(n, r, u) {
|
||||
return n + r + u;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mangle_keep_fnames_true: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function n(a, b, c) {
|
||||
return a + b + c;
|
||||
};
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function total() {
|
||||
return function n(t, r, u) {
|
||||
return t + r + u;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,4 +144,46 @@ parse_do_while_without_semicolon: {
|
||||
expect: {
|
||||
do x(); while (false);y();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
keep_collapse_const_in_own_block_scope: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true
|
||||
}
|
||||
input: {
|
||||
var i=2;
|
||||
const c=5;
|
||||
while(i--)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var i=2;
|
||||
const c=5;
|
||||
for(;i--;)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
|
||||
keep_collapse_const_in_own_block_scope_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true
|
||||
}
|
||||
input: {
|
||||
const c=5;
|
||||
var i=2; // Moves to loop, while it did not in previous test
|
||||
while(i--)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
const c=5;
|
||||
for(var i=2;i--;)
|
||||
console.log(i);
|
||||
console.log(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,3 +130,31 @@ negate_iife_issue_1073: {
|
||||
}(7))();
|
||||
}
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_false: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return function() {
|
||||
console.log('test')
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '!function(){return function(){console.log("test")}}()();'
|
||||
}
|
||||
|
||||
@@ -50,3 +50,28 @@ new_with_many_parameters: {
|
||||
}
|
||||
expect_exact: 'new foo.bar("baz");new x(/123/,456);'
|
||||
}
|
||||
|
||||
new_constructor_with_unary_arguments: {
|
||||
input: {
|
||||
new x();
|
||||
new x(-1);
|
||||
new x(-1, -2);
|
||||
new x(void 1, +2, -3, ~4, !5, --a, ++b, c--, d++, typeof e, delete f);
|
||||
new (-1); // should parse despite being invalid at runtime.
|
||||
new (-1)(); // should parse despite being invalid at runtime.
|
||||
new (-1)(-2); // should parse despite being invalid at runtime.
|
||||
}
|
||||
expect_exact: "new x;new x(-1);new x(-1,-2);new x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);new(-1);new(-1);new(-1)(-2);"
|
||||
}
|
||||
|
||||
call_with_unary_arguments: {
|
||||
input: {
|
||||
x();
|
||||
x(-1);
|
||||
x(-1, -2);
|
||||
x(void 1, +2, -3, ~4, !5, --a, ++b, c--, d++, typeof e, delete f);
|
||||
(-1)(); // should parse despite being invalid at runtime.
|
||||
(-1)(-2); // should parse despite being invalid at runtime.
|
||||
}
|
||||
expect_exact: "x();x(-1);x(-1,-2);x(void 1,+2,-3,~4,!5,--a,++b,c--,d++,typeof e,delete f);(-1)();(-1)(-2);"
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ keep_properties: {
|
||||
|
||||
dot_properties: {
|
||||
options = {
|
||||
properties: true
|
||||
properties: true,
|
||||
screw_ie8: false
|
||||
};
|
||||
input: {
|
||||
a["foo"] = "bar";
|
||||
@@ -81,15 +82,22 @@ mangle_properties: {
|
||||
a["foo"] = "bar";
|
||||
a.color = "red";
|
||||
x = {"bar": 10};
|
||||
a.run(x.bar, a.foo);
|
||||
a['run']({color: "blue", foo: "baz"});
|
||||
}
|
||||
expect: {
|
||||
a["a"] = "bar";
|
||||
a.b = "red";
|
||||
x = {c: 10};
|
||||
a.d(x.c, a.a);
|
||||
a['d']({b: "blue", a: "baz"});
|
||||
}
|
||||
}
|
||||
|
||||
mangle_unquoted_properties: {
|
||||
options = {
|
||||
properties: false
|
||||
}
|
||||
mangle_props = {
|
||||
ignore_quoted: true
|
||||
}
|
||||
@@ -99,27 +107,294 @@ mangle_unquoted_properties: {
|
||||
keep_quoted_props: true,
|
||||
}
|
||||
input: {
|
||||
a.top = 1;
|
||||
function f1() {
|
||||
a["foo"] = "bar";
|
||||
a.color = "red";
|
||||
x = {"bar": 10};
|
||||
a.stuff = 2;
|
||||
x = {"bar": 10, size: 7};
|
||||
a.size = 9;
|
||||
}
|
||||
function f2() {
|
||||
a.foo = "bar";
|
||||
a['color'] = "red";
|
||||
x = {bar: 10};
|
||||
x = {bar: 10, size: 7};
|
||||
a.size = 9;
|
||||
a.stuff = 3;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
a.a = 1;
|
||||
function f1() {
|
||||
a["foo"] = "bar";
|
||||
a.a = "red";
|
||||
x = {"bar": 10};
|
||||
a.color = "red";
|
||||
a.b = 2;
|
||||
x = {"bar": 10, c: 7};
|
||||
a.c = 9;
|
||||
}
|
||||
function f2() {
|
||||
a.b = "bar";
|
||||
a.foo = "bar";
|
||||
a['color'] = "red";
|
||||
x = {c: 10};
|
||||
x = {bar: 10, c: 7};
|
||||
a.c = 9;
|
||||
a.b = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
first_256_chars_as_properties: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
// Note: some of these unicode character keys are not visible on github.com
|
||||
var o = {
|
||||
"\0":0,"":1,"":2,"":3,"":4,"":5,"":6,"":7,"\b":8,
|
||||
"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"":14,"":15,"":16,"":17,
|
||||
"":18,"":19,"":20,"":21,"":22,"":23,"":24,"":25,"":26,
|
||||
"":27,"":28,"":29,"":30,"":31," ":32,"!":33,'"':34,"#":35,
|
||||
$:36,"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,
|
||||
"-":45,".":46,"/":47,"0":48,"1":49,"2":50,"3":51,"4":52,"5":53,"6":54,"7":55,
|
||||
"8":56,"9":57,":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,
|
||||
B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,
|
||||
O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,
|
||||
"\\":92,"]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,
|
||||
f:102,g:103,h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,
|
||||
q:113,r:114,s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,
|
||||
"|":124,"}":125,"~":126,"":127,"":128,"":129,"":130,"":131,
|
||||
"":132,"
":133,"":134,"":135,"":136,"":137,"":138,"":139,
|
||||
"":140,"":141,"":142,"":143,"":144,"":145,"":146,"":147,
|
||||
"":148,"":149,"":150,"":151,"":152,"":153,"":154,"":155,
|
||||
"":156,"":157,"":158,"":159," ":160,"¡":161,"¢":162,"£":163,
|
||||
"¤":164,"¥":165,"¦":166,"§":167,"¨":168,"©":169,"ª":170,"«":171,
|
||||
"¬":172,"":173,"®":174,"¯":175,"°":176,"±":177,"²":178,"³":179,
|
||||
"´":180,"µ":181,"¶":182,"·":183,"¸":184,"¹":185,"º":186,"»":187,
|
||||
"¼":188,"½":189,"¾":190,"¿":191,"À":192,"Á":193,"Â":194,"Ã":195,
|
||||
"Ä":196,"Å":197,"Æ":198,"Ç":199,"È":200,"É":201,"Ê":202,"Ë":203,
|
||||
"Ì":204,"Í":205,"Î":206,"Ï":207,"Ð":208,"Ñ":209,"Ò":210,"Ó":211,
|
||||
"Ô":212,"Õ":213,"Ö":214,"×":215,"Ø":216,"Ù":217,"Ú":218,"Û":219,
|
||||
"Ü":220,"Ý":221,"Þ":222,"ß":223,"à":224,"á":225,"â":226,"ã":227,
|
||||
"ä":228,"å":229,"æ":230,"ç":231,"è":232,"é":233,"ê":234,"ë":235,
|
||||
"ì":236,"í":237,"î":238,"ï":239,"ð":240,"ñ":241,"ò":242,"ó":243,
|
||||
"ô":244,"õ":245,"ö":246,"÷":247,"ø":248,"ù":249,"ú":250,"û":251,
|
||||
"ü":252,"ý":253,"þ":254,"ÿ":255
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
"\0":0,"\x01":1,"\x02":2,"\x03":3,"\x04":4,"\x05":5,"\x06":6,
|
||||
"\x07":7,"\b":8,"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"\x0e":14,
|
||||
"\x0f":15,"\x10":16,"\x11":17,"\x12":18,"\x13":19,"\x14":20,"\x15":21,
|
||||
"\x16":22,"\x17":23,"\x18":24,"\x19":25,"\x1a":26,"\x1b":27,"\x1c":28,
|
||||
"\x1d":29,"\x1e":30,"\x1f":31," ":32,"!":33,'"':34,"#":35,$:36,
|
||||
"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,
|
||||
".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,
|
||||
":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,B:66,C:67,
|
||||
D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,
|
||||
Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,"\\":92,
|
||||
"]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,f:102,g:103,
|
||||
h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,q:113,r:114,
|
||||
s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,"|":124,
|
||||
"}":125,"~":126,"\x7f":127,"\x80":128,"\x81":129,"\x82":130,"\x83":131,
|
||||
"\x84":132,"\x85":133,"\x86":134,"\x87":135,"\x88":136,"\x89":137,
|
||||
"\x8a":138,"\x8b":139,"\x8c":140,"\x8d":141,"\x8e":142,"\x8f":143,
|
||||
"\x90":144,"\x91":145,"\x92":146,"\x93":147,"\x94":148,"\x95":149,
|
||||
"\x96":150,"\x97":151,"\x98":152,"\x99":153,"\x9a":154,"\x9b":155,
|
||||
"\x9c":156,"\x9d":157,"\x9e":158,"\x9f":159,"\xa0":160,"\xa1":161,
|
||||
"\xa2":162,"\xa3":163,"\xa4":164,"\xa5":165,"\xa6":166,"\xa7":167,
|
||||
"\xa8":168,"\xa9":169,"\xaa":170,"\xab":171,"\xac":172,"\xad":173,
|
||||
"\xae":174,"\xaf":175,"\xb0":176,"\xb1":177,"\xb2":178,"\xb3":179,
|
||||
"\xb4":180,"\xb5":181,"\xb6":182,"\xb7":183,"\xb8":184,"\xb9":185,
|
||||
"\xba":186,"\xbb":187,"\xbc":188,"\xbd":189,"\xbe":190,"\xbf":191,
|
||||
"\xc0":192,"\xc1":193,"\xc2":194,"\xc3":195,"\xc4":196,"\xc5":197,
|
||||
"\xc6":198,"\xc7":199,"\xc8":200,"\xc9":201,"\xca":202,"\xcb":203,
|
||||
"\xcc":204,"\xcd":205,"\xce":206,"\xcf":207,"\xd0":208,"\xd1":209,
|
||||
"\xd2":210,"\xd3":211,"\xd4":212,"\xd5":213,"\xd6":214,"\xd7":215,
|
||||
"\xd8":216,"\xd9":217,"\xda":218,"\xdb":219,"\xdc":220,"\xdd":221,
|
||||
"\xde":222,"\xdf":223,"\xe0":224,"\xe1":225,"\xe2":226,"\xe3":227,
|
||||
"\xe4":228,"\xe5":229,"\xe6":230,"\xe7":231,"\xe8":232,"\xe9":233,
|
||||
"\xea":234,"\xeb":235,"\xec":236,"\xed":237,"\xee":238,"\xef":239,
|
||||
"\xf0":240,"\xf1":241,"\xf2":242,"\xf3":243,"\xf4":244,"\xf5":245,
|
||||
"\xf6":246,"\xf7":247,"\xf8":248,"\xf9":249,"\xfa":250,"\xfb":251,
|
||||
"\xfc":252,"\xfd":253,"\xfe":254,"\xff":255
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
first_256_unicode_chars_as_properties: {
|
||||
input: {
|
||||
var o = {
|
||||
"\u0000": 0, "\u0001": 1, "\u0002": 2, "\u0003": 3, "\u0004": 4, "\u0005": 5,
|
||||
"\u0006": 6, "\u0007": 7, "\u0008": 8, "\u0009": 9, "\u000A": 10, "\u000B": 11,
|
||||
"\u000C": 12, "\u000D": 13, "\u000E": 14, "\u000F": 15, "\u0010": 16, "\u0011": 17,
|
||||
"\u0012": 18, "\u0013": 19, "\u0014": 20, "\u0015": 21, "\u0016": 22, "\u0017": 23,
|
||||
"\u0018": 24, "\u0019": 25, "\u001A": 26, "\u001B": 27, "\u001C": 28, "\u001D": 29,
|
||||
"\u001E": 30, "\u001F": 31, "\u0020": 32, "\u0021": 33, "\u0022": 34, "\u0023": 35,
|
||||
"\u0024": 36, "\u0025": 37, "\u0026": 38, "\u0027": 39, "\u0028": 40, "\u0029": 41,
|
||||
"\u002A": 42, "\u002B": 43, "\u002C": 44, "\u002D": 45, "\u002E": 46, "\u002F": 47,
|
||||
"\u0030": 48, "\u0031": 49, "\u0032": 50, "\u0033": 51, "\u0034": 52, "\u0035": 53,
|
||||
"\u0036": 54, "\u0037": 55, "\u0038": 56, "\u0039": 57, "\u003A": 58, "\u003B": 59,
|
||||
"\u003C": 60, "\u003D": 61, "\u003E": 62, "\u003F": 63, "\u0040": 64, "\u0041": 65,
|
||||
"\u0042": 66, "\u0043": 67, "\u0044": 68, "\u0045": 69, "\u0046": 70, "\u0047": 71,
|
||||
"\u0048": 72, "\u0049": 73, "\u004A": 74, "\u004B": 75, "\u004C": 76, "\u004D": 77,
|
||||
"\u004E": 78, "\u004F": 79, "\u0050": 80, "\u0051": 81, "\u0052": 82, "\u0053": 83,
|
||||
"\u0054": 84, "\u0055": 85, "\u0056": 86, "\u0057": 87, "\u0058": 88, "\u0059": 89,
|
||||
"\u005A": 90, "\u005B": 91, "\u005C": 92, "\u005D": 93, "\u005E": 94, "\u005F": 95,
|
||||
"\u0060": 96, "\u0061": 97, "\u0062": 98, "\u0063": 99, "\u0064": 100, "\u0065": 101,
|
||||
"\u0066": 102, "\u0067": 103, "\u0068": 104, "\u0069": 105, "\u006A": 106, "\u006B": 107,
|
||||
"\u006C": 108, "\u006D": 109, "\u006E": 110, "\u006F": 111, "\u0070": 112, "\u0071": 113,
|
||||
"\u0072": 114, "\u0073": 115, "\u0074": 116, "\u0075": 117, "\u0076": 118, "\u0077": 119,
|
||||
"\u0078": 120, "\u0079": 121, "\u007A": 122, "\u007B": 123, "\u007C": 124, "\u007D": 125,
|
||||
"\u007E": 126, "\u007F": 127, "\u0080": 128, "\u0081": 129, "\u0082": 130, "\u0083": 131,
|
||||
"\u0084": 132, "\u0085": 133, "\u0086": 134, "\u0087": 135, "\u0088": 136, "\u0089": 137,
|
||||
"\u008A": 138, "\u008B": 139, "\u008C": 140, "\u008D": 141, "\u008E": 142, "\u008F": 143,
|
||||
"\u0090": 144, "\u0091": 145, "\u0092": 146, "\u0093": 147, "\u0094": 148, "\u0095": 149,
|
||||
"\u0096": 150, "\u0097": 151, "\u0098": 152, "\u0099": 153, "\u009A": 154, "\u009B": 155,
|
||||
"\u009C": 156, "\u009D": 157, "\u009E": 158, "\u009F": 159, "\u00A0": 160, "\u00A1": 161,
|
||||
"\u00A2": 162, "\u00A3": 163, "\u00A4": 164, "\u00A5": 165, "\u00A6": 166, "\u00A7": 167,
|
||||
"\u00A8": 168, "\u00A9": 169, "\u00AA": 170, "\u00AB": 171, "\u00AC": 172, "\u00AD": 173,
|
||||
"\u00AE": 174, "\u00AF": 175, "\u00B0": 176, "\u00B1": 177, "\u00B2": 178, "\u00B3": 179,
|
||||
"\u00B4": 180, "\u00B5": 181, "\u00B6": 182, "\u00B7": 183, "\u00B8": 184, "\u00B9": 185,
|
||||
"\u00BA": 186, "\u00BB": 187, "\u00BC": 188, "\u00BD": 189, "\u00BE": 190, "\u00BF": 191,
|
||||
"\u00C0": 192, "\u00C1": 193, "\u00C2": 194, "\u00C3": 195, "\u00C4": 196, "\u00C5": 197,
|
||||
"\u00C6": 198, "\u00C7": 199, "\u00C8": 200, "\u00C9": 201, "\u00CA": 202, "\u00CB": 203,
|
||||
"\u00CC": 204, "\u00CD": 205, "\u00CE": 206, "\u00CF": 207, "\u00D0": 208, "\u00D1": 209,
|
||||
"\u00D2": 210, "\u00D3": 211, "\u00D4": 212, "\u00D5": 213, "\u00D6": 214, "\u00D7": 215,
|
||||
"\u00D8": 216, "\u00D9": 217, "\u00DA": 218, "\u00DB": 219, "\u00DC": 220, "\u00DD": 221,
|
||||
"\u00DE": 222, "\u00DF": 223, "\u00E0": 224, "\u00E1": 225, "\u00E2": 226, "\u00E3": 227,
|
||||
"\u00E4": 228, "\u00E5": 229, "\u00E6": 230, "\u00E7": 231, "\u00E8": 232, "\u00E9": 233,
|
||||
"\u00EA": 234, "\u00EB": 235, "\u00EC": 236, "\u00ED": 237, "\u00EE": 238, "\u00EF": 239,
|
||||
"\u00F0": 240, "\u00F1": 241, "\u00F2": 242, "\u00F3": 243, "\u00F4": 244, "\u00F5": 245,
|
||||
"\u00F6": 246, "\u00F7": 247, "\u00F8": 248, "\u00F9": 249, "\u00FA": 250, "\u00FB": 251,
|
||||
"\u00FC": 252, "\u00FD": 253, "\u00FE": 254, "\u00FF": 255
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
"\0":0,"\x01":1,"\x02":2,"\x03":3,"\x04":4,"\x05":5,"\x06":6,
|
||||
"\x07":7,"\b":8,"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"\x0e":14,
|
||||
"\x0f":15,"\x10":16,"\x11":17,"\x12":18,"\x13":19,"\x14":20,"\x15":21,
|
||||
"\x16":22,"\x17":23,"\x18":24,"\x19":25,"\x1a":26,"\x1b":27,"\x1c":28,
|
||||
"\x1d":29,"\x1e":30,"\x1f":31," ":32,"!":33,'"':34,"#":35,$:36,
|
||||
"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,
|
||||
".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,
|
||||
":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,B:66,C:67,
|
||||
D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,
|
||||
Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,"\\":92,
|
||||
"]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,f:102,g:103,
|
||||
h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,q:113,r:114,
|
||||
s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,"|":124,
|
||||
"}":125,"~":126,"\x7f":127,"\x80":128,"\x81":129,"\x82":130,"\x83":131,
|
||||
"\x84":132,"\x85":133,"\x86":134,"\x87":135,"\x88":136,"\x89":137,
|
||||
"\x8a":138,"\x8b":139,"\x8c":140,"\x8d":141,"\x8e":142,"\x8f":143,
|
||||
"\x90":144,"\x91":145,"\x92":146,"\x93":147,"\x94":148,"\x95":149,
|
||||
"\x96":150,"\x97":151,"\x98":152,"\x99":153,"\x9a":154,"\x9b":155,
|
||||
"\x9c":156,"\x9d":157,"\x9e":158,"\x9f":159,"\xa0":160,"\xa1":161,
|
||||
"\xa2":162,"\xa3":163,"\xa4":164,"\xa5":165,"\xa6":166,"\xa7":167,
|
||||
"\xa8":168,"\xa9":169,"\xaa":170,"\xab":171,"\xac":172,"\xad":173,
|
||||
"\xae":174,"\xaf":175,"\xb0":176,"\xb1":177,"\xb2":178,"\xb3":179,
|
||||
"\xb4":180,"\xb5":181,"\xb6":182,"\xb7":183,"\xb8":184,"\xb9":185,
|
||||
"\xba":186,"\xbb":187,"\xbc":188,"\xbd":189,"\xbe":190,"\xbf":191,
|
||||
"\xc0":192,"\xc1":193,"\xc2":194,"\xc3":195,"\xc4":196,"\xc5":197,
|
||||
"\xc6":198,"\xc7":199,"\xc8":200,"\xc9":201,"\xca":202,"\xcb":203,
|
||||
"\xcc":204,"\xcd":205,"\xce":206,"\xcf":207,"\xd0":208,"\xd1":209,
|
||||
"\xd2":210,"\xd3":211,"\xd4":212,"\xd5":213,"\xd6":214,"\xd7":215,
|
||||
"\xd8":216,"\xd9":217,"\xda":218,"\xdb":219,"\xdc":220,"\xdd":221,
|
||||
"\xde":222,"\xdf":223,"\xe0":224,"\xe1":225,"\xe2":226,"\xe3":227,
|
||||
"\xe4":228,"\xe5":229,"\xe6":230,"\xe7":231,"\xe8":232,"\xe9":233,
|
||||
"\xea":234,"\xeb":235,"\xec":236,"\xed":237,"\xee":238,"\xef":239,
|
||||
"\xf0":240,"\xf1":241,"\xf2":242,"\xf3":243,"\xf4":244,"\xf5":245,
|
||||
"\xf6":246,"\xf7":247,"\xf8":248,"\xf9":249,"\xfa":250,"\xfb":251,
|
||||
"\xfc":252,"\xfd":253,"\xfe":254,"\xff":255
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
first_256_hex_chars_as_properties: {
|
||||
input: {
|
||||
var o = {
|
||||
"\x00": 0, "\x01": 1, "\x02": 2, "\x03": 3, "\x04": 4, "\x05": 5,
|
||||
"\x06": 6, "\x07": 7, "\x08": 8, "\x09": 9, "\x0A": 10, "\x0B": 11,
|
||||
"\x0C": 12, "\x0D": 13, "\x0E": 14, "\x0F": 15, "\x10": 16, "\x11": 17,
|
||||
"\x12": 18, "\x13": 19, "\x14": 20, "\x15": 21, "\x16": 22, "\x17": 23,
|
||||
"\x18": 24, "\x19": 25, "\x1A": 26, "\x1B": 27, "\x1C": 28, "\x1D": 29,
|
||||
"\x1E": 30, "\x1F": 31, "\x20": 32, "\x21": 33, "\x22": 34, "\x23": 35,
|
||||
"\x24": 36, "\x25": 37, "\x26": 38, "\x27": 39, "\x28": 40, "\x29": 41,
|
||||
"\x2A": 42, "\x2B": 43, "\x2C": 44, "\x2D": 45, "\x2E": 46, "\x2F": 47,
|
||||
"\x30": 48, "\x31": 49, "\x32": 50, "\x33": 51, "\x34": 52, "\x35": 53,
|
||||
"\x36": 54, "\x37": 55, "\x38": 56, "\x39": 57, "\x3A": 58, "\x3B": 59,
|
||||
"\x3C": 60, "\x3D": 61, "\x3E": 62, "\x3F": 63, "\x40": 64, "\x41": 65,
|
||||
"\x42": 66, "\x43": 67, "\x44": 68, "\x45": 69, "\x46": 70, "\x47": 71,
|
||||
"\x48": 72, "\x49": 73, "\x4A": 74, "\x4B": 75, "\x4C": 76, "\x4D": 77,
|
||||
"\x4E": 78, "\x4F": 79, "\x50": 80, "\x51": 81, "\x52": 82, "\x53": 83,
|
||||
"\x54": 84, "\x55": 85, "\x56": 86, "\x57": 87, "\x58": 88, "\x59": 89,
|
||||
"\x5A": 90, "\x5B": 91, "\x5C": 92, "\x5D": 93, "\x5E": 94, "\x5F": 95,
|
||||
"\x60": 96, "\x61": 97, "\x62": 98, "\x63": 99, "\x64": 100, "\x65": 101,
|
||||
"\x66": 102, "\x67": 103, "\x68": 104, "\x69": 105, "\x6A": 106, "\x6B": 107,
|
||||
"\x6C": 108, "\x6D": 109, "\x6E": 110, "\x6F": 111, "\x70": 112, "\x71": 113,
|
||||
"\x72": 114, "\x73": 115, "\x74": 116, "\x75": 117, "\x76": 118, "\x77": 119,
|
||||
"\x78": 120, "\x79": 121, "\x7A": 122, "\x7B": 123, "\x7C": 124, "\x7D": 125,
|
||||
"\x7E": 126, "\x7F": 127, "\x80": 128, "\x81": 129, "\x82": 130, "\x83": 131,
|
||||
"\x84": 132, "\x85": 133, "\x86": 134, "\x87": 135, "\x88": 136, "\x89": 137,
|
||||
"\x8A": 138, "\x8B": 139, "\x8C": 140, "\x8D": 141, "\x8E": 142, "\x8F": 143,
|
||||
"\x90": 144, "\x91": 145, "\x92": 146, "\x93": 147, "\x94": 148, "\x95": 149,
|
||||
"\x96": 150, "\x97": 151, "\x98": 152, "\x99": 153, "\x9A": 154, "\x9B": 155,
|
||||
"\x9C": 156, "\x9D": 157, "\x9E": 158, "\x9F": 159, "\xA0": 160, "\xA1": 161,
|
||||
"\xA2": 162, "\xA3": 163, "\xA4": 164, "\xA5": 165, "\xA6": 166, "\xA7": 167,
|
||||
"\xA8": 168, "\xA9": 169, "\xAA": 170, "\xAB": 171, "\xAC": 172, "\xAD": 173,
|
||||
"\xAE": 174, "\xAF": 175, "\xB0": 176, "\xB1": 177, "\xB2": 178, "\xB3": 179,
|
||||
"\xB4": 180, "\xB5": 181, "\xB6": 182, "\xB7": 183, "\xB8": 184, "\xB9": 185,
|
||||
"\xBA": 186, "\xBB": 187, "\xBC": 188, "\xBD": 189, "\xBE": 190, "\xBF": 191,
|
||||
"\xC0": 192, "\xC1": 193, "\xC2": 194, "\xC3": 195, "\xC4": 196, "\xC5": 197,
|
||||
"\xC6": 198, "\xC7": 199, "\xC8": 200, "\xC9": 201, "\xCA": 202, "\xCB": 203,
|
||||
"\xCC": 204, "\xCD": 205, "\xCE": 206, "\xCF": 207, "\xD0": 208, "\xD1": 209,
|
||||
"\xD2": 210, "\xD3": 211, "\xD4": 212, "\xD5": 213, "\xD6": 214, "\xD7": 215,
|
||||
"\xD8": 216, "\xD9": 217, "\xDA": 218, "\xDB": 219, "\xDC": 220, "\xDD": 221,
|
||||
"\xDE": 222, "\xDF": 223, "\xE0": 224, "\xE1": 225, "\xE2": 226, "\xE3": 227,
|
||||
"\xE4": 228, "\xE5": 229, "\xE6": 230, "\xE7": 231, "\xE8": 232, "\xE9": 233,
|
||||
"\xEA": 234, "\xEB": 235, "\xEC": 236, "\xED": 237, "\xEE": 238, "\xEF": 239,
|
||||
"\xF0": 240, "\xF1": 241, "\xF2": 242, "\xF3": 243, "\xF4": 244, "\xF5": 245,
|
||||
"\xF6": 246, "\xF7": 247, "\xF8": 248, "\xF9": 249, "\xFA": 250, "\xFB": 251,
|
||||
"\xFC": 252, "\xFD": 253, "\xFE": 254, "\xFF": 255
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
"\0":0,"\x01":1,"\x02":2,"\x03":3,"\x04":4,"\x05":5,"\x06":6,
|
||||
"\x07":7,"\b":8,"\t":9,"\n":10,"\v":11,"\f":12,"\r":13,"\x0e":14,
|
||||
"\x0f":15,"\x10":16,"\x11":17,"\x12":18,"\x13":19,"\x14":20,"\x15":21,
|
||||
"\x16":22,"\x17":23,"\x18":24,"\x19":25,"\x1a":26,"\x1b":27,"\x1c":28,
|
||||
"\x1d":29,"\x1e":30,"\x1f":31," ":32,"!":33,'"':34,"#":35,$:36,
|
||||
"%":37,"&":38,"'":39,"(":40,")":41,"*":42,"+":43,",":44,"-":45,
|
||||
".":46,"/":47,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,
|
||||
":":58,";":59,"<":60,"=":61,">":62,"?":63,"@":64,A:65,B:66,C:67,
|
||||
D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,
|
||||
Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"[":91,"\\":92,
|
||||
"]":93,"^":94,_:95,"`":96,a:97,b:98,c:99,d:100,e:101,f:102,g:103,
|
||||
h:104,i:105,j:106,k:107,l:108,m:109,n:110,o:111,p:112,q:113,r:114,
|
||||
s:115,t:116,u:117,v:118,w:119,x:120,y:121,z:122,"{":123,"|":124,
|
||||
"}":125,"~":126,"\x7f":127,"\x80":128,"\x81":129,"\x82":130,"\x83":131,
|
||||
"\x84":132,"\x85":133,"\x86":134,"\x87":135,"\x88":136,"\x89":137,
|
||||
"\x8a":138,"\x8b":139,"\x8c":140,"\x8d":141,"\x8e":142,"\x8f":143,
|
||||
"\x90":144,"\x91":145,"\x92":146,"\x93":147,"\x94":148,"\x95":149,
|
||||
"\x96":150,"\x97":151,"\x98":152,"\x99":153,"\x9a":154,"\x9b":155,
|
||||
"\x9c":156,"\x9d":157,"\x9e":158,"\x9f":159,"\xa0":160,"\xa1":161,
|
||||
"\xa2":162,"\xa3":163,"\xa4":164,"\xa5":165,"\xa6":166,"\xa7":167,
|
||||
"\xa8":168,"\xa9":169,"\xaa":170,"\xab":171,"\xac":172,"\xad":173,
|
||||
"\xae":174,"\xaf":175,"\xb0":176,"\xb1":177,"\xb2":178,"\xb3":179,
|
||||
"\xb4":180,"\xb5":181,"\xb6":182,"\xb7":183,"\xb8":184,"\xb9":185,
|
||||
"\xba":186,"\xbb":187,"\xbc":188,"\xbd":189,"\xbe":190,"\xbf":191,
|
||||
"\xc0":192,"\xc1":193,"\xc2":194,"\xc3":195,"\xc4":196,"\xc5":197,
|
||||
"\xc6":198,"\xc7":199,"\xc8":200,"\xc9":201,"\xca":202,"\xcb":203,
|
||||
"\xcc":204,"\xcd":205,"\xce":206,"\xcf":207,"\xd0":208,"\xd1":209,
|
||||
"\xd2":210,"\xd3":211,"\xd4":212,"\xd5":213,"\xd6":214,"\xd7":215,
|
||||
"\xd8":216,"\xd9":217,"\xda":218,"\xdb":219,"\xdc":220,"\xdd":221,
|
||||
"\xde":222,"\xdf":223,"\xe0":224,"\xe1":225,"\xe2":226,"\xe3":227,
|
||||
"\xe4":228,"\xe5":229,"\xe6":230,"\xe7":231,"\xe8":232,"\xe9":233,
|
||||
"\xea":234,"\xeb":235,"\xec":236,"\xed":237,"\xee":238,"\xef":239,
|
||||
"\xf0":240,"\xf1":241,"\xf2":242,"\xf3":243,"\xf4":244,"\xf5":245,
|
||||
"\xf6":246,"\xf7":247,"\xf8":248,"\xf9":249,"\xfa":250,"\xfb":251,
|
||||
"\xfc":252,"\xfd":253,"\xfe":254,"\xff":255
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
10
test/compress/string-literal.js
Normal file
10
test/compress/string-literal.js
Normal file
@@ -0,0 +1,10 @@
|
||||
octal_escape_sequence: {
|
||||
input: {
|
||||
var boundaries = "\0\7\00\07\70\77\000\077\300\377";
|
||||
var border_check = "\400\700\0000\3000";
|
||||
}
|
||||
expect: {
|
||||
var boundaries = "\x00\x07\x00\x07\x38\x3f\x00\x3f\xc0\xff";
|
||||
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
||||
}
|
||||
}
|
||||
8
test/input/issue-1236/simple.js
Normal file
8
test/input/issue-1236/simple.js
Normal file
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var foo = function foo(x) {
|
||||
return "foo " + x;
|
||||
};
|
||||
console.log(foo("bar"));
|
||||
|
||||
//# sourceMappingURL=simple.js.map
|
||||
8
test/input/issue-1236/simple.js.map
Normal file
8
test/input/issue-1236/simple.js.map
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["index.js"],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
||||
"file": "simple.js",
|
||||
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
|
||||
}
|
||||
4
test/input/issue-1242/bar.es5
Normal file
4
test/input/issue-1242/bar.es5
Normal file
@@ -0,0 +1,4 @@
|
||||
function bar(x) {
|
||||
var triple = x * (2 + 1);
|
||||
return triple;
|
||||
}
|
||||
4
test/input/issue-1242/baz.es5
Normal file
4
test/input/issue-1242/baz.es5
Normal file
@@ -0,0 +1,4 @@
|
||||
function baz(x) {
|
||||
var half = x / 2;
|
||||
return half;
|
||||
}
|
||||
5
test/input/issue-1242/foo.es5
Normal file
5
test/input/issue-1242/foo.es5
Normal file
@@ -0,0 +1,5 @@
|
||||
var print = console.log.bind(console);
|
||||
function foo(x) {
|
||||
var twice = x * 2;
|
||||
print('Foo:', twice);
|
||||
}
|
||||
4
test/input/issue-1242/qux.js
Normal file
4
test/input/issue-1242/qux.js
Normal file
@@ -0,0 +1,4 @@
|
||||
var a = bar(1+2);
|
||||
var b = baz(3+9);
|
||||
print('q' + 'u' + 'x', a, b);
|
||||
foo(5+6);
|
||||
22
test/mocha/cli.js
Normal file
22
test/mocha/cli.js
Normal file
@@ -0,0 +1,22 @@
|
||||
var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
|
||||
describe("bin/uglifyjs", function () {
|
||||
it("should produce a functional build when using --self", function (done) {
|
||||
this.timeout(5000);
|
||||
|
||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
var command = uglifyjs + ' --self -cm --wrap WrappedUglifyJS';
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
eval(stdout);
|
||||
|
||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
||||
assert.strictEqual(true, WrappedUglifyJS.parse('foo;') instanceof WrappedUglifyJS.AST_Node);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
50
test/mocha/comment.js
Normal file
50
test/mocha/comment.js
Normal file
@@ -0,0 +1,50 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Comment", function() {
|
||||
it("Should recognize eol of single line comments", function() {
|
||||
var tests = [
|
||||
"//Some comment 1\n>",
|
||||
"//Some comment 2\r>",
|
||||
"//Some comment 3\r\n>",
|
||||
"//Some comment 4\u2028>",
|
||||
"//Some comment 5\u2029>"
|
||||
];
|
||||
|
||||
var fail = function(e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Unexpected token: operator (>)" &&
|
||||
e.line === 2 &&
|
||||
e.col === 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(function() {
|
||||
uglify.parse(tests[i], {fromString: true})
|
||||
}, fail, tests[i]);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should update the position of a multiline comment correctly", function() {
|
||||
var tests = [
|
||||
"/*Some comment 1\n\n\n*/\n>\n\n\n\n\n\n",
|
||||
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
|
||||
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
|
||||
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
|
||||
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n"
|
||||
];
|
||||
|
||||
var fail = function(e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Unexpected token: operator (>)" &&
|
||||
e.line === 5 &&
|
||||
e.col === 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(function() {
|
||||
uglify.parse(tests[i], {fromString: true})
|
||||
}, fail, tests[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
28
test/mocha/glob.js
Normal file
28
test/mocha/glob.js
Normal file
@@ -0,0 +1,28 @@
|
||||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("minify() with input file globs", function() {
|
||||
it("minify() with one input file glob string.", function() {
|
||||
var result = Uglify.minify("test/input/issue-1242/foo.*", {
|
||||
compress: { collapse_vars: true }
|
||||
});
|
||||
assert.strictEqual(result.code, 'function foo(o){print("Foo:",2*o)}var print=console.log.bind(console);');
|
||||
});
|
||||
it("minify() with an array of one input file glob.", function() {
|
||||
var result = Uglify.minify([
|
||||
"test/input/issue-1242/b*.es5",
|
||||
], {
|
||||
compress: { collapse_vars: true }
|
||||
});
|
||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}');
|
||||
});
|
||||
it("minify() with an array of multiple input file globs.", function() {
|
||||
var result = Uglify.minify([
|
||||
"test/input/issue-1242/???.es5",
|
||||
"test/input/issue-1242/*.js",
|
||||
], {
|
||||
compress: { collapse_vars: true }
|
||||
});
|
||||
assert.strictEqual(result.code, 'function bar(n){return 3*n}function baz(n){return n/2}function foo(n){print("Foo:",2*n)}var print=console.log.bind(console);print("qux",bar(3),baz(12)),foo(11);');
|
||||
});
|
||||
});
|
||||
43
test/mocha/input-sourcemaps.js
Normal file
43
test/mocha/input-sourcemaps.js
Normal file
@@ -0,0 +1,43 @@
|
||||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
var SourceMapConsumer = require("source-map").SourceMapConsumer;
|
||||
|
||||
describe("input sourcemaps", function() {
|
||||
var transpiled = '"use strict";\n\n' +
|
||||
'var foo = function foo(x) {\n return "foo " + x;\n};\n' +
|
||||
'console.log(foo("bar"));\n\n' +
|
||||
'//# sourceMappingURL=bundle.js.map';
|
||||
|
||||
var transpilemap = {
|
||||
"version": 3,
|
||||
"sources": ["index.js"],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,IAAI,MAAM,SAAN,GAAM;AAAA,SAAK,SAAS,CAAd;AAAA,CAAV;AACA,QAAQ,GAAR,CAAY,IAAI,KAAJ,CAAZ",
|
||||
"file": "bundle.js",
|
||||
"sourcesContent": ["let foo = x => \"foo \" + x;\nconsole.log(foo(\"bar\"));"]
|
||||
};
|
||||
|
||||
var result = Uglify.minify(transpiled, {
|
||||
fromString: true,
|
||||
inSourceMap: transpilemap,
|
||||
outSourceMap: true
|
||||
});
|
||||
var map = new SourceMapConsumer(result.map);
|
||||
|
||||
it("Should copy over original sourcesContent", function() {
|
||||
assert.equal(map.sourceContentFor("index.js"), transpilemap.sourcesContent[0]);
|
||||
});
|
||||
|
||||
it("Final sourcemap should not have invalid mappings from inputSourceMap (issue #882) ", function() {
|
||||
// The original source has only 2 lines, check that mappings don't have more lines
|
||||
|
||||
var msg = "Mapping should not have higher line number than the original file had";
|
||||
map.eachMapping(function(mapping) {
|
||||
assert.ok(mapping.originalLine <= 2, msg)
|
||||
});
|
||||
|
||||
map.allGeneratedPositionsFor({source: "index.js", line: 1, column: 1}).forEach(function(pos) {
|
||||
assert.ok(pos.line <= 2, msg);
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -37,6 +37,10 @@ describe("line-endings", function() {
|
||||
"/\r/",
|
||||
"/\u2028/",
|
||||
"/\u2029/",
|
||||
"/\\\n/",
|
||||
"/\\\r/",
|
||||
"/\\\u2028/",
|
||||
"/\\\u2029/",
|
||||
"/someRandomTextLike[]()*AndThen\n/"
|
||||
]
|
||||
var test = function(input) {
|
||||
@@ -46,7 +50,7 @@ describe("line-endings", function() {
|
||||
}
|
||||
var fail = function(e) {
|
||||
return e instanceof Uglify.JS_Parse_Error &&
|
||||
e.message === "Unexpected line terminator";
|
||||
e.message === "SyntaxError: Unexpected line terminator";
|
||||
}
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
assert.throws(test(inputs[i]), fail);
|
||||
|
||||
40
test/mocha/minify-file-map.js
Normal file
40
test/mocha/minify-file-map.js
Normal file
@@ -0,0 +1,40 @@
|
||||
var Uglify = require('../../');
|
||||
var assert = require("assert");
|
||||
|
||||
describe("Input file as map", function() {
|
||||
it("Should accept object", function() {
|
||||
var jsMap = {
|
||||
'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'
|
||||
};
|
||||
var result = Uglify.minify(jsMap, {fromString: true, outSourceMap: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
|
||||
assert.deepEqual(map.sources, ['/scripts/foo.js']);
|
||||
});
|
||||
|
||||
it("Should accept array of objects and strings", function() {
|
||||
var jsSeq = [
|
||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
||||
'var bar = 15;'
|
||||
];
|
||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||
assert.strictEqual(map.sources[0], '/scripts/foo.js');
|
||||
});
|
||||
|
||||
it("Should correctly include source", function() {
|
||||
var jsSeq = [
|
||||
{'/scripts/foo.js': 'var foo = {"x": 1, y: 2, \'z\': 3};'},
|
||||
'var bar = 15;'
|
||||
];
|
||||
var result = Uglify.minify(jsSeq, {fromString: true, outSourceMap: true, sourceMapIncludeSources: true});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3},bar=15;');
|
||||
assert.deepEqual(map.sourcesContent, ['var foo = {"x": 1, y: 2, \'z\': 3};', 'var bar = 15;']);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -59,4 +59,20 @@ describe("minify", function() {
|
||||
'a["foo"]="bar",a.a="red",x={"bar":10};');
|
||||
});
|
||||
});
|
||||
|
||||
describe("inSourceMap", function() {
|
||||
it("Should read the given string filename correctly when sourceMapIncludeSources is enabled (#1236)", function() {
|
||||
var result = Uglify.minify('./test/input/issue-1236/simple.js', {
|
||||
outSourceMap: "simple.js.min.map",
|
||||
inSourceMap: "./test/input/issue-1236/simple.js.map",
|
||||
sourceMapIncludeSources: true
|
||||
});
|
||||
|
||||
var map = JSON.parse(result.map);
|
||||
|
||||
assert.equal(map.sourcesContent.length, 1);
|
||||
assert.equal(map.sourcesContent[0],
|
||||
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
24
test/mocha/number-literal.js
Normal file
24
test/mocha/number-literal.js
Normal file
@@ -0,0 +1,24 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Number literals", function () {
|
||||
it("Should not allow legacy octal literals in strict mode", function() {
|
||||
var inputs = [
|
||||
'"use strict";00;',
|
||||
'"use strict"; var foo = 00;'
|
||||
];
|
||||
|
||||
var test = function(input) {
|
||||
return function() {
|
||||
uglify.parse(input);
|
||||
}
|
||||
}
|
||||
var error = function(e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Legacy octal literals are not allowed in strict mode";
|
||||
}
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
assert.throws(test(inputs[i]), error, inputs[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
124
test/mocha/spidermonkey.js
Normal file
124
test/mocha/spidermonkey.js
Normal file
@@ -0,0 +1,124 @@
|
||||
var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("spidermonkey export/import sanity test", function() {
|
||||
it("should produce a functional build when using --self with spidermonkey", function (done) {
|
||||
this.timeout(20000);
|
||||
|
||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
var command = uglifyjs + " --self -cm --wrap SpiderUglify --dump-spidermonkey-ast | " +
|
||||
uglifyjs + " --spidermonkey -cm";
|
||||
|
||||
exec(command, function (err, stdout) {
|
||||
if (err) throw err;
|
||||
|
||||
eval(stdout);
|
||||
assert.strictEqual(typeof SpiderUglify, "object");
|
||||
|
||||
var ast = SpiderUglify.parse("foo([true,,2+3]);");
|
||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
||||
|
||||
ast.figure_out_scope();
|
||||
ast = SpiderUglify.Compressor({}).compress(ast);
|
||||
assert.strictEqual(true, ast instanceof SpiderUglify.AST_Node);
|
||||
|
||||
var stream = SpiderUglify.OutputStream({});
|
||||
ast.print(stream);
|
||||
var code = stream.toString();
|
||||
assert.strictEqual(code, "foo([!0,,5]);");
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should judge between directives and strings correctly on import", function() {
|
||||
var tests = [
|
||||
{
|
||||
input: '"use strict";;"use sloppy"',
|
||||
directives: 1,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: ';"use strict"',
|
||||
directives: 0,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: '"use strict"; "use something else";',
|
||||
directives: 2,
|
||||
strings: 0
|
||||
},
|
||||
{
|
||||
input: 'function foo() {"use strict";;"use sloppy" }',
|
||||
directives: 1,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: 'function foo() {;"use strict" }',
|
||||
directives: 0,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: 'function foo() {"use strict"; "use something else"; }',
|
||||
directives: 2,
|
||||
strings: 0
|
||||
},
|
||||
{
|
||||
input: 'var foo = function() {"use strict";;"use sloppy" }',
|
||||
directives: 1,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: 'var foo = function() {;"use strict" }',
|
||||
directives: 0,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: 'var foo = function() {"use strict"; "use something else"; }',
|
||||
directives: 2,
|
||||
strings: 0
|
||||
},
|
||||
{
|
||||
input: '{"use strict";;"use sloppy" }',
|
||||
directives: 0,
|
||||
strings: 2
|
||||
},
|
||||
{
|
||||
input: '{;"use strict" }',
|
||||
directives: 0,
|
||||
strings: 1
|
||||
},
|
||||
{
|
||||
input: '{"use strict"; "use something else"; }',
|
||||
directives: 0,
|
||||
strings: 2
|
||||
}
|
||||
];
|
||||
|
||||
var counter_directives;
|
||||
var counter_strings;
|
||||
|
||||
var checkWalker = new uglify.TreeWalker(function(node, descend) {
|
||||
if (node instanceof uglify.AST_String) {
|
||||
counter_strings++;
|
||||
} else if (node instanceof uglify.AST_Directive) {
|
||||
counter_directives++;
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
counter_directives = 0;
|
||||
counter_strings = 0;
|
||||
|
||||
var ast = uglify.parse(tests[i].input);
|
||||
var moz_ast = ast.to_mozilla_ast();
|
||||
var from_moz_ast = uglify.AST_Node.from_mozilla_ast(moz_ast);
|
||||
|
||||
from_moz_ast.walk(checkWalker);
|
||||
|
||||
assert.strictEqual(counter_directives, tests[i].directives, "Directives count mismatch for test " + tests[i].input);
|
||||
assert.strictEqual(counter_strings, tests[i].strings, "String count mismatch for test " + tests[i].input);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -19,7 +19,7 @@ describe("String literals", function() {
|
||||
|
||||
var error = function(e) {
|
||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
||||
e.message === "Unterminated string constant";
|
||||
e.message === "SyntaxError: Unterminated string constant";
|
||||
};
|
||||
|
||||
for (var input in inputs) {
|
||||
@@ -49,7 +49,7 @@ describe("String literals", function() {
|
||||
|
||||
var error = function(e) {
|
||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
||||
e.message === "Octal literals are not allowed in strict mode";
|
||||
e.message === "SyntaxError: Legacy octal escape sequences are not allowed in strict mode";
|
||||
}
|
||||
|
||||
for (var input in inputs) {
|
||||
|
||||
@@ -2,7 +2,7 @@ var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("With", function() {
|
||||
it ("Should throw syntaxError when using with statement in strict mode", function() {
|
||||
it("Should throw syntaxError when using with statement in strict mode", function() {
|
||||
var code = '"use strict";\nthrow NotEarlyError;\nwith ({}) { }';
|
||||
var test = function() {
|
||||
uglify.parse(code);
|
||||
@@ -13,4 +13,11 @@ describe("With", function() {
|
||||
}
|
||||
assert.throws(test, error);
|
||||
});
|
||||
});
|
||||
it("Should set uses_with for scopes involving With statements", function() {
|
||||
var ast = uglify.parse("with(e) {f(1, 2)}");
|
||||
ast.figure_out_scope();
|
||||
assert.equal(ast.uses_with, true);
|
||||
assert.equal(ast.body[0].expression.scope.uses_with, true);
|
||||
assert.equal(ast.body[0].body.body[0].body.expression.scope.uses_with, true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -132,25 +132,39 @@ function run_compress_tests() {
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
else if (test.expect_warnings) {
|
||||
U.AST_Node.warn_function = original_warn_function;
|
||||
var expected_warnings = make_code(test.expect_warnings, {
|
||||
beautify: false,
|
||||
quote_style: 2, // force double quote to match JSON
|
||||
});
|
||||
warnings_emitted = warnings_emitted.map(function(input) {
|
||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||
});
|
||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||
if (expected_warnings != actual_warnings) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
||||
else {
|
||||
// expect == output
|
||||
try {
|
||||
var reparsed_ast = U.parse(output);
|
||||
} catch (ex) {
|
||||
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
|
||||
input: input_code,
|
||||
expected_warnings: expected_warnings,
|
||||
actual_warnings: actual_warnings,
|
||||
output: output,
|
||||
error: ex.toString(),
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
if (test.expect_warnings) {
|
||||
U.AST_Node.warn_function = original_warn_function;
|
||||
var expected_warnings = make_code(test.expect_warnings, {
|
||||
beautify: false,
|
||||
quote_style: 2, // force double quote to match JSON
|
||||
});
|
||||
warnings_emitted = warnings_emitted.map(function(input) {
|
||||
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
|
||||
});
|
||||
var actual_warnings = JSON.stringify(warnings_emitted);
|
||||
if (expected_warnings != actual_warnings) {
|
||||
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
|
||||
input: input_code,
|
||||
expected_warnings: expected_warnings,
|
||||
actual_warnings: actual_warnings,
|
||||
});
|
||||
failures++;
|
||||
failed_files[file] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var tests = parse_test(path.resolve(dir, file));
|
||||
|
||||
@@ -43,6 +43,7 @@ exports.minify = function(files, options) {
|
||||
outSourceMap : null,
|
||||
sourceRoot : null,
|
||||
inSourceMap : null,
|
||||
sourceMapUrl : null,
|
||||
fromString : false,
|
||||
warnings : false,
|
||||
mangle : {},
|
||||
@@ -61,18 +62,26 @@ exports.minify = function(files, options) {
|
||||
if (options.spidermonkey) {
|
||||
toplevel = UglifyJS.AST_Node.from_mozilla_ast(files);
|
||||
} else {
|
||||
if (typeof files == "string")
|
||||
files = [ files ];
|
||||
files.forEach(function(file, i){
|
||||
function addFile(file, fileUrl) {
|
||||
var code = options.fromString
|
||||
? file
|
||||
: fs.readFileSync(file, "utf8");
|
||||
sourcesContent[file] = code;
|
||||
sourcesContent[fileUrl] = code;
|
||||
toplevel = UglifyJS.parse(code, {
|
||||
filename: options.fromString ? i : file,
|
||||
filename: fileUrl,
|
||||
toplevel: toplevel,
|
||||
bare_returns: options.parse ? options.parse.bare_returns : undefined
|
||||
});
|
||||
}
|
||||
if (!options.fromString) files = UglifyJS.simple_glob(files);
|
||||
[].concat(files).forEach(function (files, i) {
|
||||
if (typeof files === 'string') {
|
||||
addFile(files, options.fromString ? i : files);
|
||||
} else {
|
||||
for (var fileUrl in files) {
|
||||
addFile(files[fileUrl], fileUrl);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (options.wrap) {
|
||||
@@ -106,7 +115,7 @@ exports.minify = function(files, options) {
|
||||
var inMap = options.inSourceMap;
|
||||
var output = {};
|
||||
if (typeof options.inSourceMap == "string") {
|
||||
inMap = fs.readFileSync(options.inSourceMap, "utf8");
|
||||
inMap = JSON.parse(fs.readFileSync(options.inSourceMap, "utf8"));
|
||||
}
|
||||
if (options.outSourceMap) {
|
||||
output.source_map = UglifyJS.SourceMap({
|
||||
@@ -129,8 +138,9 @@ exports.minify = function(files, options) {
|
||||
var stream = UglifyJS.OutputStream(output);
|
||||
toplevel.print(stream);
|
||||
|
||||
if (options.outSourceMap && "string" === typeof options.outSourceMap) {
|
||||
stream += "\n//# sourceMappingURL=" + options.outSourceMap;
|
||||
var mappingUrlPrefix = "\n//# sourceMappingURL=";
|
||||
if (options.outSourceMap && typeof options.outSourceMap === "string" && options.sourceMapUrl !== false) {
|
||||
stream += mappingUrlPrefix + (typeof options.sourceMapUrl === "string" ? options.sourceMapUrl : options.outSourceMap);
|
||||
}
|
||||
|
||||
var source_map = output.source_map;
|
||||
@@ -252,3 +262,47 @@ exports.writeNameCache = function(filename, key, cache) {
|
||||
fs.writeFileSync(filename, JSON.stringify(data, null, 2), "utf8");
|
||||
}
|
||||
};
|
||||
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
// Example: "foo/bar/*baz??.*.js"
|
||||
// Argument `glob` may be a string or an array of strings.
|
||||
// Returns an array of strings. Garbage in, garbage out.
|
||||
exports.simple_glob = function simple_glob(glob) {
|
||||
var results = [];
|
||||
if (Array.isArray(glob)) {
|
||||
glob.forEach(function(elem) {
|
||||
results = results.concat(simple_glob(elem));
|
||||
});
|
||||
return results;
|
||||
}
|
||||
if (glob.match(/\*|\?/)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir);
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + (path.basename(glob)
|
||||
.replace(/\(/g, "\\(")
|
||||
.replace(/\)/g, "\\)")
|
||||
.replace(/\{/g, "\\{")
|
||||
.replace(/\}/g, "\\}")
|
||||
.replace(/\[/g, "\\[")
|
||||
.replace(/\]/g, "\\]")
|
||||
.replace(/\+/g, "\\+")
|
||||
.replace(/\^/g, "\\^")
|
||||
.replace(/\$/g, "\\$")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\./g, "\\.")
|
||||
.replace(/\?/g, ".")) + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
for (var i in entries) {
|
||||
if (rx.test(entries[i]))
|
||||
results.push(dir + "/" + entries[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (results.length === 0)
|
||||
results = [ glob ];
|
||||
return results;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user