diff --git a/bin/uglifyjs b/bin/uglifyjs index 1b01aa177b..e6d5c20b9c 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -46,6 +46,7 @@ program.option("--config-file ", "Read minify() options from JSON file."); program.option("-d, --define [=value]", "Global definitions.", parse_js("define")); program.option("--ecma ", "Specify ECMAScript release: 5, 6, 7 or 8."); program.option("--ie8", "Support non-standard Internet Explorer 8."); +program.option("--keep-classnames", "Do not mangle/drop class names."); program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name."); program.option("--name-cache ", "File to hold mangled name mappings."); program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)"); @@ -95,6 +96,9 @@ if (program.define) { options.compress.global_defs[expr] = program.define[expr]; } } +if (program.keepClassnames) { + options.keep_classnames = true; +} if (program.keepFnames) { options.keep_fnames = true; } diff --git a/lib/compress.js b/lib/compress.js index ca74fed636..48816ff7a9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -69,6 +69,7 @@ function Compressor(options, false_by_default) { if_return : !false_by_default, inline : !false_by_default, join_vars : !false_by_default, + keep_classnames: false, keep_fargs : true, keep_fnames : false, keep_infinity : false, @@ -2610,8 +2611,9 @@ merge(Compressor.prototype, { // pass 3: we should drop declarations not in_use var tt = new TreeTransformer( function before(node, descend, in_list) { - if (!compressor.option("keep_fnames") - && node.name && (node instanceof AST_Function || node instanceof AST_ClassExpression)) { + if (node.name + && (!compressor.option("keep_classnames") && node instanceof AST_ClassExpression + || !compressor.option("keep_fnames") && node instanceof AST_Function)) { var def = node.name.definition(); // any declarations with same name will overshadow // name of this anonymous function and can therefore diff --git a/lib/minify.js b/lib/minify.js index d3db1edb07..2ac6afd642 100644 --- a/lib/minify.js +++ b/lib/minify.js @@ -51,6 +51,7 @@ function minify(files, options) { compress: {}, ecma: undefined, ie8: false, + keep_classnames: undefined, keep_fnames: false, mangle: {}, nameCache: null, @@ -65,8 +66,12 @@ function minify(files, options) { var timings = options.timings && { start: Date.now() }; + if (options.keep_classnames === undefined) { + options.keep_classnames = options.keep_fnames; + } set_shorthand("ecma", options, [ "parse", "compress", "output" ]); set_shorthand("ie8", options, [ "compress", "mangle", "output" ]); + set_shorthand("keep_classnames", options, [ "compress", "mangle" ]); set_shorthand("keep_fnames", options, [ "compress", "mangle" ]); set_shorthand("toplevel", options, [ "compress", "mangle" ]); set_shorthand("warnings", options, [ "compress" ]); diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 577e2b35a0..a86cccd3c5 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -1574,3 +1574,101 @@ issue_2288: { } } } + +issue_2418_1: { + options = { + unused: true, + } + input: { + class C {} + function F() {} + (class c {}); + (function f() {}); + } + expect: { + class C {} + function F() {} + (class {}); + (function() {}); + } +} + +issue_2418_2: { + options = { + keep_classnames: false, + keep_fnames: false, + unused: true, + } + input: { + class C {} + function F() {} + (class c {}); + (function f() {}); + } + expect: { + class C {} + function F() {} + (class {}); + (function() {}); + } +} + +issue_2418_3: { + options = { + keep_classnames: false, + keep_fnames: true, + unused: true, + } + input: { + class C {} + function F() {} + (class c {}); + (function f() {}); + } + expect: { + class C {} + function F() {} + (class {}); + (function f() {}); + } +} + +issue_2418_4: { + options = { + keep_classnames: true, + keep_fnames: false, + unused: true, + } + input: { + class C {} + function F() {} + (class c {}); + (function f() {}); + } + expect: { + class C {} + function F() {} + (class c {}); + (function() {}); + } +} + +issue_2418_5: { + options = { + keep_classnames: true, + keep_fnames: true, + unused: true, + } + input: { + class C {} + function F() {} + (class c {}); + (function f() {}); + } + expect: { + class C {} + function F() {} + (class c {}); + (function f() {}); + } +} diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js index 18d0936885..e5f129a472 100644 --- a/test/compress/hoist_props.js +++ b/test/compress/hoist_props.js @@ -389,6 +389,7 @@ hoist_class: { evaluate: true, hoist_props: true, inline: true, + keep_classnames: true, keep_fnames: true, passes: 2, reduce_funcs: true, @@ -432,6 +433,7 @@ hoist_class_with_new: { evaluate: true, hoist_props: true, inline: true, + keep_classnames: true, keep_fnames: true, passes: 2, reduce_funcs: true,