Compare commits

...

8 Commits

Author SHA1 Message Date
Alex Lam S.L
888a321417 Merge pull request #2042 from alexlamsl/harmony-v3.0.15
Merging from master for 3.0.15
2017-06-01 19:28:30 +08:00
alexlamsl
ee5c03f7f1 Merge branch 'master' into harmony-v3.0.15 2017-06-01 18:26:09 +08:00
Alex Lam S.L
4377e932ca v3.0.15 2017-06-01 18:12:38 +08:00
Alex Lam S.L
bac14ba881 fix non-identifier getter/setter name (#2041)
fixes #2040
2017-06-01 18:11:16 +08:00
Alex Lam S.L
ec095ed647 whitelist unsafe evaluate candidates (#2039)
- all arguments may accept constant values
- return constant value
- free of side effects
- available & identical across locales and runtime environments
2017-06-01 04:33:05 +08:00
Alex Lam S.L
17e73121fa enhance unsafe evaluate (#2037) 2017-06-01 00:56:28 +08:00
kzc
0cb75089f0 document safari10 mangle option (#2035) 2017-05-31 23:16:20 +08:00
kzc
f71e8fd948 reformat mangle options section of README (#2036) 2017-05-31 21:52:43 +08:00
6 changed files with 142 additions and 37 deletions

View File

@@ -677,17 +677,22 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
## Mangle options
- `reserved` - pass an array of identifiers that should be excluded from mangling
- `reserved` (default `[]`). Pass an array of identifiers that should be
excluded from mangling. Example: `["foo", "bar"]`.
- `toplevel` — mangle names declared in the top level scope (disabled by
default).
- `toplevel` (default `false`). Pass `true` to mangle names declared in the
top level scope.
- `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](#compress-options).
- `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](#compress-options).
- `eval` (default `false`). Pass `true` to mangle names visible in scopes
where `eval` or `with` are used.
- `safari10` (default `false`). Pass `true` to work around the Safari 10 loop
iterator [bug](https://bugs.webkit.org/show_bug.cgi?id=171041)
"Cannot declare a let variable twice".
Examples:

View File

@@ -1718,6 +1718,63 @@ merge(Compressor.prototype, {
}
throw def;
});
var object_fns = [
'constructor',
'toString',
'valueOf',
];
var native_fns = {
Array: makePredicate([
'indexOf',
'join',
'lastIndexOf',
'slice',
].concat(object_fns)),
Boolean: makePredicate(object_fns),
Number: makePredicate([
'toExponential',
'toFixed',
'toPrecision',
].concat(object_fns)),
RegExp: makePredicate([
'test',
].concat(object_fns)),
String: makePredicate([
'charAt',
'charCodeAt',
'concat',
'indexOf',
'italics',
'lastIndexOf',
'match',
'replace',
'search',
'slice',
'split',
'substr',
'substring',
'trim',
].concat(object_fns)),
};
def(AST_Call, function(compressor){
var exp = this.expression;
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
var key = exp.property;
if (key instanceof AST_Node) {
key = ev(key, compressor);
}
var val = ev(exp.expression, compressor);
if ((val && native_fns[val.constructor.name] || return_false)(key)) {
return val[key].apply(val, this.args.map(function(arg) {
return ev(arg, compressor);
}));
}
}
throw def;
});
def(AST_New, function(compressor){
throw def;
});
})(function(node, func){
node.DEFMETHOD("_eval", func);
});
@@ -3312,6 +3369,11 @@ merge(Compressor.prototype, {
&& is_iife_call(self)) {
return self.negate(compressor, true);
}
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
return self;
});

View File

@@ -1536,7 +1536,8 @@ function OutputStream(options) {
DEFPRINT(AST_NewTarget, function(self, output) {
output.print("new.target");
});
AST_ObjectProperty.DEFMETHOD("print_property_name", function(key, quote, output) {
function print_property_name(key, quote, output) {
if (output.option("quote_keys")) {
output.print_string(key + "");
} else if ((typeof key == "number"
@@ -1553,7 +1554,8 @@ function OutputStream(options) {
} else {
output.print_string(key, quote);
}
});
}
DEFPRINT(AST_ObjectKeyVal, function(self, output){
function get_name(self) {
var def = self.definition();
@@ -1566,7 +1568,7 @@ function OutputStream(options) {
is_identifier_string(self.key) &&
get_name(self.value) === self.key
) {
self.print_property_name(self.key, self.quote, output);
print_property_name(self.key, self.quote, output);
} else if (allowShortHand &&
self.value instanceof AST_DefaultAssign &&
@@ -1574,12 +1576,12 @@ function OutputStream(options) {
is_identifier_string(self.key) &&
get_name(self.value.left) === self.key
) {
self.print_property_name(self.key, self.quote, output);
print_property_name(self.key, self.quote, output);
output.print("=");
self.value.right.print(output);
} else {
if (!(self.key instanceof AST_Node)) {
self.print_property_name(self.key, self.quote, output);
print_property_name(self.key, self.quote, output);
} else {
output.with_square(function() {
self.key.print(output);
@@ -1589,15 +1591,18 @@ function OutputStream(options) {
self.value.print(output);
}
});
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, self, output) {
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) {
var self = this;
if (self.static) {
output.print("static");
output.space();
}
output.print(type);
output.space();
if (type) {
output.print(type);
output.space();
}
if (self.key instanceof AST_SymbolMethod) {
self.print_property_name(self.key.name, self.quote, output);
print_property_name(self.key.name, self.quote, output);
} else {
output.with_square(function() {
self.key.print(output);
@@ -1606,27 +1611,13 @@ function OutputStream(options) {
self.value._do_print(output, true);
});
DEFPRINT(AST_ObjectSetter, function(self, output){
self._print_getter_setter("set", self, output);
self._print_getter_setter("set", output);
});
DEFPRINT(AST_ObjectGetter, function(self, output){
self._print_getter_setter("get", self, output);
self._print_getter_setter("get", output);
});
DEFPRINT(AST_ConciseMethod, function(self, output){
if (self.static) {
output.print("static");
output.space();
}
if (self.is_generator) {
output.print("*");
}
if (self.key instanceof AST_SymbolMethod) {
self.print_property_name(self.key.name, self.quote, output);
} else {
output.with_square(function() {
self.key.print(output);
});
}
self.value._do_print(output, true);
self._print_getter_setter(self.is_generator && "*", output);
});
AST_Symbol.DEFMETHOD("_do_print", function(output){
var def = this.definition();

View File

@@ -4,7 +4,7 @@
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.0.14",
"version": "3.0.15",
"engines": {
"node": ">=0.8.0"
},

View File

@@ -873,13 +873,15 @@ unsafe_charAt_noop: {
input: {
console.log(
s.charAt(0),
"string".charAt(x)
"string".charAt(x),
(typeof x).charAt()
);
}
expect: {
console.log(
s.charAt(0),
"string".charAt(x)
"string".charAt(x),
(typeof x)[0]
);
}
}
@@ -1130,3 +1132,31 @@ issue_1964_2: {
}
expect_stdout: "b"
}
array_slice_index: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log([1,2,3].slice(1)[1]);
}
expect: {
console.log(3);
}
expect_stdout: "3"
}
string_charCodeAt: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log("foo".charCodeAt("bar".length));
}
expect: {
console.log(NaN);
}
expect_stdout: "NaN"
}

View File

@@ -557,3 +557,20 @@ native_prototype: {
"".indexOf.call(e, "bar");
}
}
issue_2040: {
input: {
var a = 1;
var b = {
get "a-b"() {
return a;
},
set "a-b"(c) {
a = c;
}
};
console.log(b["a-b"], b["a-b"] = 2, b["a-b"]);
}
expect_exact: 'var a=1;var b={get"a-b"(){return a},set"a-b"(c){a=c}};console.log(b["a-b"],b["a-b"]=2,b["a-b"]);'
expect_stdout: "1 2 2"
}