diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-05-22 03:12:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-22 10:12:37 +0800 |
commit | d2a45ba441ed6975021b3524215c01a011dfb46a (patch) | |
tree | ff68f99235009ef8098b2c6c57a2f0ec50cc8a8e | |
parent | de376c3d3316fc4a33a876793eb4d693422415a0 (diff) | |
download | tracifyjs-d2a45ba441ed6975021b3524215c01a011dfb46a.tar.gz tracifyjs-d2a45ba441ed6975021b3524215c01a011dfb46a.zip |
fix corner case in parsing private field/method (#4952)
fixes #4951
-rw-r--r-- | lib/parse.js | 8 | ||||
-rw-r--r-- | test/compress/classes.js | 31 | ||||
-rw-r--r-- | test/sandbox.js | 2 |
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); })) { |