[Pkg-javascript-commits] [uglifyjs] 45/77: Add option to preserve/enforce string quote style
Jonas Smedegaard
dr at jones.dk
Tue May 19 00:02:31 UTC 2015
This is an automated email from the git hooks/post-receive script.
js pushed a commit to tag v2.4.18
in repository uglifyjs.
commit fbbaa42ee55a7f753f7cab9b1a905ccf73cf26d5
Author: Mihai Bazon <mihai.bazon at gmail.com>
Date: Tue Jan 27 22:26:27 2015 +0200
Add option to preserve/enforce string quote style
`-q 0` (default) use single or double quotes such as to minimize the number of
bytes (prefers double quotes when both will do); this is the previous
behavior.
`-q 1` -- always use single quotes
`-q 2` -- always use double quotes
`-q 3` or just `-q` -- always use the original quotes.
Related codegen option: `quote_style`.
Close #495
Close #460
Some `yargs` guru please tell me why `uglifyjs --help` doesn't display the
help string for `-q` / `--quotes`, and why it doesn't output the expected
argument types anymore, like good old `optimist` did.
---
README.md | 7 +++++++
bin/uglifyjs | 11 +++++++++--
lib/ast.js | 15 ++++++++++-----
lib/output.js | 34 +++++++++++++++++++++++++---------
lib/parse.js | 26 ++++++++++++++++++++------
5 files changed, 71 insertions(+), 22 deletions(-)
diff --git a/README.md b/README.md
index d2ec432..2bb2138 100644
--- a/README.md
+++ b/README.md
@@ -352,6 +352,13 @@ can pass additional arguments that control the code output:
it will be prepended to the output literally. The source map will
adjust for this text. Can be used to insert a comment containing
licensing information, for example.
+- `quote_style` (default `0`) -- preferred quote style for strings (affects
+ quoted property names and directives as well):
+ - `0` -- prefers double quotes, switches to single quotes when there are
+ more double quotes in the string itself.
+ - `1` -- always use single quotes
+ - `2` -- always use double quotes
+ - `3` -- always use the original quotes
### Keeping copyright notices or other comments
diff --git a/bin/uglifyjs b/bin/uglifyjs
index 11c3a01..c9f4c12 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -66,6 +66,7 @@ You need to pass an argument to this option to specify the name that your module
.describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.")
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
+ .describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
.alias("p", "prefix")
.alias("o", "output")
@@ -77,6 +78,7 @@ You need to pass an argument to this option to specify the name that your module
.alias("r", "reserved")
.alias("V", "version")
.alias("e", "enclose")
+ .alias("q", "quotes")
.string("source-map")
.string("source-map-root")
@@ -151,9 +153,14 @@ if (ARGS.r) {
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
}
+if (ARGS.quotes === true) {
+ ARGS.quotes = 3;
+}
+
var OUTPUT_OPTIONS = {
- beautify: BEAUTIFY ? true : false,
- preamble: ARGS.preamble || null,
+ beautify : BEAUTIFY ? true : false,
+ preamble : ARGS.preamble || null,
+ quote_style : ARGS.quotes != null ? ARGS.quotes : 0
};
if (ARGS.screw_ie8) {
diff --git a/lib/ast.js b/lib/ast.js
index 5aa1be3..2e539cf 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -120,11 +120,12 @@ var AST_Debugger = DEFNODE("Debugger", null, {
$documentation: "Represents a debugger statement",
}, AST_Statement);
-var AST_Directive = DEFNODE("Directive", "value scope", {
+var AST_Directive = DEFNODE("Directive", "value scope quote", {
$documentation: "Represents a directive, like \"use strict\";",
$propdoc: {
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
- scope: "[AST_Scope/S] The scope that this directive affects"
+ scope: "[AST_Scope/S] The scope that this directive affects",
+ quote: "[string] the original quote character"
},
}, AST_Statement);
@@ -766,8 +767,11 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
}
});
-var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, {
+var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", {
$documentation: "A key: value object property",
+ $propdoc: {
+ quote: "[string] the original quote character"
+ }
}, AST_ObjectProperty);
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
@@ -852,10 +856,11 @@ var AST_Constant = DEFNODE("Constant", null, {
}
});
-var AST_String = DEFNODE("String", "value", {
+var AST_String = DEFNODE("String", "value quote", {
$documentation: "A string literal",
$propdoc: {
- value: "[string] the contents of this string"
+ value: "[string] the contents of this string",
+ quote: "[string] the original quote character"
}
}, AST_Constant);
diff --git a/lib/output.js b/lib/output.js
index bfe6242..135636b 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -63,6 +63,7 @@ function OutputStream(options) {
preserve_line : false,
screw_ie8 : false,
preamble : null,
+ quote_style : 0
}, true);
var indentation = 0;
@@ -84,7 +85,7 @@ function OutputStream(options) {
});
};
- function make_string(str) {
+ function make_string(str, quote) {
var dq = 0, sq = 0;
str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0\ufeff]/g, function(s){
switch (s) {
@@ -102,13 +103,27 @@ function OutputStream(options) {
}
return s;
});
+ function quote_single() {
+ return "'" + str.replace(/\x27/g, "\\'") + "'";
+ }
+ function quote_double() {
+ return '"' + str.replace(/\x22/g, '\\"') + '"';
+ }
if (options.ascii_only) str = to_ascii(str);
- if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
- else return '"' + str.replace(/\x22/g, '\\"') + '"';
+ switch (options.quote_style) {
+ case 1:
+ return quote_single();
+ case 2:
+ return quote_double();
+ case 3:
+ return quote == "'" ? quote_single() : quote_double();
+ default:
+ return dq > sq ? quote_single() : quote_double();
+ }
};
- function encode_string(str) {
- var ret = make_string(str);
+ function encode_string(str, quote) {
+ var ret = make_string(str, quote);
if (options.inline_script)
ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1");
return ret;
@@ -324,7 +339,7 @@ function OutputStream(options) {
force_semicolon : force_semicolon,
to_ascii : to_ascii,
print_name : function(name) { print(make_name(name)) },
- print_string : function(str) { print(encode_string(str)) },
+ print_string : function(str, quote) { print(encode_string(str, quote)) },
next_indent : next_indent,
with_indent : with_indent,
with_block : with_block,
@@ -581,7 +596,7 @@ function OutputStream(options) {
/* -----[ PRINTERS ]----- */
DEFPRINT(AST_Directive, function(self, output){
- output.print_string(self.value);
+ output.print_string(self.value, self.quote);
output.semicolon();
});
DEFPRINT(AST_Debugger, function(self, output){
@@ -1077,6 +1092,7 @@ function OutputStream(options) {
});
DEFPRINT(AST_ObjectKeyVal, function(self, output){
var key = self.key;
+ var quote = self.quote;
if (output.option("quote_keys")) {
output.print_string(key + "");
} else if ((typeof key == "number"
@@ -1087,7 +1103,7 @@ function OutputStream(options) {
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
output.print_name(key);
} else {
- output.print_string(key);
+ output.print_string(key, quote);
}
output.colon();
self.value.print(output);
@@ -1125,7 +1141,7 @@ function OutputStream(options) {
output.print(self.getValue());
});
DEFPRINT(AST_String, function(self, output){
- output.print_string(self.getValue());
+ output.print_string(self.getValue(), self.quote);
});
DEFPRINT(AST_Number, function(self, output){
output.print(make_num(self.getValue()));
diff --git a/lib/parse.js b/lib/parse.js
index 35ce7ef..78c1dd4 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -367,7 +367,7 @@ function tokenizer($TEXT, filename, html5_comments) {
return num;
};
- var read_string = with_eof_error("Unterminated string constant", function(){
+ var read_string = with_eof_error("Unterminated string constant", function(quote_char){
var quote = next(), ret = "";
for (;;) {
var ch = next(true);
@@ -392,7 +392,9 @@ function tokenizer($TEXT, filename, html5_comments) {
else if (ch == quote) break;
ret += ch;
}
- return token("string", ret);
+ var tok = token("string", ret);
+ tok.quote = quote_char;
+ return tok;
});
function skip_line_comment(type) {
@@ -547,7 +549,7 @@ function tokenizer($TEXT, filename, html5_comments) {
if (!ch) return token("eof");
var code = ch.charCodeAt(0);
switch (code) {
- case 34: case 39: return read_string();
+ case 34: case 39: return read_string(ch);
case 46: return handle_dot();
case 47: return handle_slash();
}
@@ -737,8 +739,14 @@ function parse($TEXT, options) {
case "string":
var dir = S.in_directives, stat = simple_statement();
// XXXv2: decide how to fix directives
- if (dir && stat.body instanceof AST_String && !is("punc", ","))
- return new AST_Directive({ value: stat.body.value });
+ if (dir && stat.body instanceof AST_String && !is("punc", ",")) {
+ return new AST_Directive({
+ start : stat.body.start,
+ end : stat.body.end,
+ quote : stat.body.quote,
+ value : stat.body.value,
+ });
+ }
return stat;
case "num":
case "regexp":
@@ -1124,7 +1132,12 @@ function parse($TEXT, options) {
ret = new AST_Number({ start: tok, end: tok, value: tok.value });
break;
case "string":
- ret = new AST_String({ start: tok, end: tok, value: tok.value });
+ ret = new AST_String({
+ start : tok,
+ end : tok,
+ value : tok.value,
+ quote : tok.quote
+ });
break;
case "regexp":
ret = new AST_RegExp({ start: tok, end: tok, value: tok.value });
@@ -1237,6 +1250,7 @@ function parse($TEXT, options) {
expect(":");
a.push(new AST_ObjectKeyVal({
start : start,
+ quote : start.quote,
key : name,
value : expression(false),
end : prev()
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list