Skip to content

Commit

Permalink
implement annotations (#4763)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl committed Mar 12, 2021
1 parent c36c3cb commit 3b5d501
Show file tree
Hide file tree
Showing 15 changed files with 690 additions and 552 deletions.
243 changes: 129 additions & 114 deletions README.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions bin/uglifyjs
Expand Up @@ -95,6 +95,8 @@ function process_option(name, no_value) {
" -b, --beautify [options] Beautify output/specify output options.",
" -O, --output-opts <options> Output options (beautify disabled).",
" -o, --output <file> Output file (default STDOUT).",
" --annotations Process and preserve comment annotations.",
" --no-annotations Ignore and discard comment annotations.",
" --comments [filter] Preserve copyright comments in the output.",
" --config-file <file> Read minify() options from JSON file.",
" -d, --define <expr>[=value] Global definitions.",
Expand Down Expand Up @@ -142,13 +144,17 @@ function process_option(name, no_value) {
case "enclose":
options[name] = read_value();
break;
case "annotations":
case "ie8":
case "timings":
case "toplevel":
case "validate":
case "webkit":
options[name] = true;
break;
case "no-annotations":
options.annotations = false;
break;
case "keep-fnames":
options.keep_fnames = true;
break;
Expand Down
3 changes: 2 additions & 1 deletion lib/compress.js
Expand Up @@ -48,6 +48,7 @@ function Compressor(options, false_by_default) {
return new Compressor(options, false_by_default);
TreeTransformer.call(this, this.before, this.after);
this.options = defaults(options, {
annotations : !false_by_default,
arguments : !false_by_default,
arrows : !false_by_default,
assignments : !false_by_default,
Expand Down Expand Up @@ -4725,7 +4726,7 @@ merge(Compressor.prototype, {
|| expr.expression.name == "Math" && expr.property == "random");
}
}
return this.pure || !compressor.pure_funcs(this);
return compressor.option("annotations") && this.pure || !compressor.pure_funcs(this);
});
AST_Node.DEFMETHOD("is_call_pure", return_false);
AST_Call.DEFMETHOD("is_call_pure", function(compressor) {
Expand Down
34 changes: 15 additions & 19 deletions lib/minify.js
Expand Up @@ -47,14 +47,12 @@ function parse_source_map(content) {
}

function set_shorthand(name, options, keys) {
if (options[name]) {
keys.forEach(function(key) {
if (options[key]) {
if (typeof options[key] != "object") options[key] = {};
if (!(name in options[key])) options[key][name] = options[name];
}
});
}
keys.forEach(function(key) {
if (options[key]) {
if (typeof options[key] != "object") options[key] = {};
if (!(name in options[key])) options[key][name] = options[name];
}
});
}

function init_cache(cache) {
Expand All @@ -75,6 +73,7 @@ function to_json(cache) {
function minify(files, options) {
try {
options = defaults(options, {
annotations: undefined,
compress: {},
enclose: false,
ie8: false,
Expand All @@ -94,17 +93,14 @@ function minify(files, options) {
wrap: false,
}, true);
if (options.validate) AST_Node.enable_validation();
var timings = options.timings && {
start: Date.now()
};
if (options.rename === undefined) {
options.rename = options.compress && options.mangle;
}
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
set_shorthand("v8", options, [ "mangle", "output" ]);
set_shorthand("webkit", options, [ "mangle", "output" ]);
var timings = options.timings && { start: Date.now() };
if (options.rename === undefined) options.rename = options.compress && options.mangle;
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
if (options.ie8) set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle" ]);
if (options.v8) set_shorthand("v8", options, [ "mangle", "output" ]);
if (options.webkit) set_shorthand("webkit", options, [ "mangle", "output" ]);
var quoted_props;
if (options.mangle) {
options.mangle = defaults(options.mangle, {
Expand Down
31 changes: 25 additions & 6 deletions lib/output.js
Expand Up @@ -52,6 +52,7 @@ function OutputStream(options) {

var readonly = !options;
options = defaults(options, {
annotations : false,
ascii_only : false,
beautify : false,
braces : false,
Expand Down Expand Up @@ -500,12 +501,14 @@ function OutputStream(options) {
space();
}
}
var value = c.value.replace(/[@#]__PURE__/g, " ");
if (/^\s*$/.test(value)) return;
if (/comment[134]/.test(c.type)) {
print("//" + c.value.replace(/[@#]__PURE__/g, " ") + "\n");
print("//" + value + "\n");
indent();
last_nlb = true;
} else if (c.type == "comment2") {
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/");
print("/*" + value + "*/");
last_nlb = false;
}
});
Expand Down Expand Up @@ -558,11 +561,13 @@ function OutputStream(options) {
} else if (i > 0 || !tail) {
space();
}
var value = c.value.replace(/[@#]__PURE__/g, " ");
if (/^\s*$/.test(value)) return;
if (/comment[134]/.test(c.type)) {
print("//" + c.value.replace(/[@#]__PURE__/g, " "));
print("//" + value);
need_newline_indented = true;
} else if (c.type == "comment2") {
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/");
print("/*" + value + "*/");
need_space = true;
}
});
Expand Down Expand Up @@ -1436,6 +1441,17 @@ function OutputStream(options) {
});

/* -----[ other expressions ]----- */
function print_annotation(self, output) {
if (!output.option("annotations")) return;
if (!self.pure) return;
var level = 0, parent = self, node;
do {
node = parent;
parent = output.parent(level++);
if (parent instanceof AST_Call && parent.expression === node) return;
} while (parent instanceof AST_PropAccess && parent.expression === node);
output.print("/*" + self.pure + "*/");
}
function print_call_args(self, output) {
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
output.add_mapping(self.start);
Expand All @@ -1448,11 +1464,14 @@ function OutputStream(options) {
});
}
DEFPRINT(AST_Call, function(output) {
this.expression.print(output);
print_call_args(this, output);
var self = this;
print_annotation(self, output);
self.expression.print(output);
print_call_args(self, output);
});
DEFPRINT(AST_New, function(output) {
var self = this;
print_annotation(self, output);
output.print("new");
output.space();
self.expression.print(output);
Expand Down
28 changes: 12 additions & 16 deletions lib/parse.js
Expand Up @@ -1758,7 +1758,6 @@ function parse($TEXT, options) {
args : args,
end : prev()
});
mark_pure(call);
return subscripts(call, allow_calls);
};

Expand Down Expand Up @@ -1840,7 +1839,6 @@ function parse($TEXT, options) {
end.comments_after.length = 0;
end.comments_after = ex.end.comments_after;
ex.end = end;
if (ex instanceof AST_Call) mark_pure(ex);
if (is("punc", "=>")) return arrow(ex instanceof AST_Sequence ? ex.expressions : [ ex ], start);
return subscripts(ex, allow_calls);
case "[":
Expand Down Expand Up @@ -2217,19 +2215,6 @@ function parse($TEXT, options) {
});
}

function mark_pure(call) {
var start = call.start;
var comments = start.comments_before;
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
while (--i >= 0) {
var comment = comments[i];
if (/[@#]__PURE__/.test(comment.value)) {
call.pure = comment;
break;
}
}
}

function template(tag) {
var read = S.input.context().read_template;
var strings = [];
Expand Down Expand Up @@ -2277,7 +2262,6 @@ function parse($TEXT, options) {
args : expr_list(")", !options.strict),
end : prev()
});
mark_pure(call);
return subscripts(call, true);
}
if (is("punc", "`")) {
Expand All @@ -2286,6 +2270,18 @@ function parse($TEXT, options) {
tmpl.end = prev();
return subscripts(tmpl, allow_calls);
}
if (expr instanceof AST_Call && !expr.pure) {
var start = expr.start;
var comments = start.comments_before;
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
while (--i >= 0) {
var match = /[@#]__PURE__/.exec(comments[i].value);
if (match) {
expr.pure = match[0];
break;
}
}
}
return expr;
};

Expand Down
1 change: 1 addition & 0 deletions test/compress.js
Expand Up @@ -262,6 +262,7 @@ function test_case(test) {
var input = to_toplevel(test.input, test.mangle);
var input_code = make_code(input);
var input_formatted = make_code(test.input, {
annotations: true,
beautify: true,
comments: "all",
keep_quoted_props: true,
Expand Down

0 comments on commit 3b5d501

Please sign in to comment.