aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2021-05-22 03:12:37 +0100
committerGitHub <noreply@github.com>2021-05-22 10:12:37 +0800
commitd2a45ba441ed6975021b3524215c01a011dfb46a (patch)
treeff68f99235009ef8098b2c6c57a2f0ec50cc8a8e
parentde376c3d3316fc4a33a876793eb4d693422415a0 (diff)
downloadtracifyjs-d2a45ba441ed6975021b3524215c01a011dfb46a.tar.gz
tracifyjs-d2a45ba441ed6975021b3524215c01a011dfb46a.zip
fix corner case in parsing private field/method (#4952)
fixes #4951
-rw-r--r--lib/parse.js8
-rw-r--r--test/compress/classes.js31
-rw-r--r--test/sandbox.js2
3 files changed, 34 insertions, 7 deletions
diff --git a/lib/parse.js b/lib/parse.js
index 2930039a..463b2103 100644
--- a/lib/parse.js
+++ b/lib/parse.js
@@ -124,7 +124,7 @@ var PUNC_AFTER_EXPRESSION = PUNC_SEPARATORS + PUNC_CLOSERS;
var PUNC_BEFORE_EXPRESSION = PUNC_OPENERS + PUNC_SEPARATORS;
var PUNC_CHARS = PUNC_BEFORE_EXPRESSION + "`" + PUNC_CLOSERS;
var WHITESPACE_CHARS = NEWLINE_CHARS + " \u00a0\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\uFEFF";
-var NON_IDENTIFIER_CHARS = makePredicate(characters("./'\"" + OPERATOR_CHARS + PUNC_CHARS + WHITESPACE_CHARS));
+var NON_IDENTIFIER_CHARS = makePredicate(characters("./'\"#" + OPERATOR_CHARS + PUNC_CHARS + WHITESPACE_CHARS));
NEWLINE_CHARS = makePredicate(characters(NEWLINE_CHARS));
OPERATOR_CHARS = makePredicate(characters(OPERATOR_CHARS));
@@ -468,7 +468,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
});
function read_name() {
- var backslash = false, name = "", ch, escaped = false, hex;
+ var backslash = false, ch, escaped = false, name = peek() == "#" ? next() : "";
while (ch = peek()) {
if (!backslash) {
if (ch == "\\") escaped = backslash = true, next();
@@ -483,7 +483,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
}
}
if (KEYWORDS[name] && escaped) {
- hex = name.charCodeAt(0).toString(16).toUpperCase();
+ var hex = name.charCodeAt(0).toString(16).toUpperCase();
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
}
return name;
@@ -618,7 +618,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
if (PUNC_CHARS[ch]) return token("punc", next());
if (looking_at("=>")) return token("punc", next() + next());
if (OPERATOR_CHARS[ch]) return read_operator();
- if (code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word();
+ if (code == 35 || code == 92 || !NON_IDENTIFIER_CHARS[ch]) return read_word();
break;
}
parse_error("Unexpected character '" + ch + "'");
diff --git a/test/compress/classes.js b/test/compress/classes.js
index e201bd3d..69d7047e 100644
--- a/test/compress/classes.js
+++ b/test/compress/classes.js
@@ -72,7 +72,7 @@ fields: {
console.log(k, o[k]);
console.log(o.q);
}
- expect_exact: 'var o=new class A{"#p";static #p="PASS";async;get q(){return A.#p}[6*7]=console?"foo":"bar"};for(var k in o)console.log(k,o[k]);console.log(o.q);'
+ expect_exact: 'var o=new class A{"#p";static#p="PASS";async;get q(){return A.#p}[6*7]=console?"foo":"bar"};for(var k in o)console.log(k,o[k]);console.log(o.q);'
expect_stdout: [
"42 foo",
"#p undefined",
@@ -136,7 +136,7 @@ private_methods: {
}
}().q.then(console.log);
}
- expect_exact: "(new class A{static*#f(){yield 3*A.#p}async #g(){for(var a of A.#f())return a*await 2}static get #p(){return 7}get q(){return this.#g()}}).q.then(console.log);"
+ expect_exact: "(new class A{static*#f(){yield 3*A.#p}async#g(){for(var a of A.#f())return a*await 2}static get#p(){return 7}get q(){return this.#g()}}).q.then(console.log);"
expect_stdout: "42"
node_version: ">=14.6"
}
@@ -1563,3 +1563,30 @@ drop_unused_self_reference: {
expect_stdout: "PASS"
node_version: ">=4"
}
+
+issue_4951_1: {
+ input: {
+ class A {
+ static#p = console.log("PASS");
+ }
+ }
+ expect_exact: 'class A{static#p=console.log("PASS")}'
+ expect_stdout: "PASS"
+ node_version: ">=12"
+}
+
+issue_4951_2: {
+ input: {
+ new class {
+ constructor() {
+ this.#f().then(console.log);
+ }
+ async#f() {
+ return await "PASS";
+ }
+ }();
+ }
+ expect_exact: 'new class{constructor(){this.#f().then(console.log)}async#f(){return await"PASS"}};'
+ expect_stdout: "PASS"
+ node_version: ">=14.6"
+}
diff --git a/test/sandbox.js b/test/sandbox.js
index 59b2a231..edebcabe 100644
--- a/test/sandbox.js
+++ b/test/sandbox.js
@@ -28,7 +28,7 @@ exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, top
if ([
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
/\b(async[ \t]+function|setImmediate|setInterval|setTimeout)\b/,
- /\basync([ \t]+|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
+ /\basync([ \t]+|[ \t]*#|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
].some(function(pattern) {
return pattern.test(code);
})) {