From c41be0bf9c367c12394a0436a5699ffef8acfc50 Mon Sep 17 00:00:00 2001 From: Cole Ellison Date: Sat, 12 Sep 2026 15:06:14 -0400 Subject: [PATCH] Correct identification of `in`/`instanceof` identifiers (#20019) Co-authored-by: fisker Cheung --- changelog_unreleased/javascript/20019.md | 22 +++++++++++++++ src/language-js/print/class-body.js | 4 +-- .../no-semi/__snapshots__/format.test.js.snap | 28 +++++++++++++++++++ tests/format/js/no-semi/private-field.js | 7 +++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 changelog_unreleased/javascript/20019.md diff --git a/changelog_unreleased/javascript/20019.md b/changelog_unreleased/javascript/20019.md new file mode 100644 index 000000000..2e72e2a77 --- /dev/null +++ b/changelog_unreleased/javascript/20019.md @@ -0,0 +1,22 @@ +#### Avoid unnecessary semicolons before private members named `#in` or `#instanceof` (#20019 by @cellison-figma) + + +```js +// Input +class Graph { + #nodes = {}; + #in = {}; +} + +// Prettier stable (--parser oxc --no-semi) +class Graph { + #nodes = {}; + #in = {} +} + +// Prettier main (--parser oxc --no-semi) +class Graph { + #nodes = {} + #in = {} +} +``` diff --git a/src/language-js/print/class-body.js b/src/language-js/print/class-body.js index 56fb7d258..2df22f50b 100644 --- a/src/language-js/print/class-body.js +++ b/src/language-js/print/class-body.js @@ -256,8 +256,8 @@ function shouldPrintSemicolonAfterClassProperty( return false; } - if (!nextNode.computed) { - const name = nextNode.key?.name; + if (!nextNode.computed && nextNode.key?.type === "Identifier") { + const { name } = nextNode.key; if (name === "in" || name === "instanceof") { return true; } diff --git a/tests/format/js/no-semi/__snapshots__/format.test.js.snap b/tests/format/js/no-semi/__snapshots__/format.test.js.snap index cbc91e3b8..46e81a55e 100644 --- a/tests/format/js/no-semi/__snapshots__/format.test.js.snap +++ b/tests/format/js/no-semi/__snapshots__/format.test.js.snap @@ -2104,12 +2104,26 @@ class C { ["method"]() {} } +class PrivateKeywordFields { + a = {}; + #in = {}; + b = {}; + #instanceof = {}; +} + =====================================output===================================== class C { #field = "value"; ["method"]() {} } +class PrivateKeywordFields { + a = {} + #in = {} + b = {} + #instanceof = {} +} + ================================================================================ `; @@ -2123,12 +2137,26 @@ class C { ["method"]() {} } +class PrivateKeywordFields { + a = {}; + #in = {}; + b = {}; + #instanceof = {}; +} + =====================================output===================================== class C { #field = "value"; ["method"]() {} } +class PrivateKeywordFields { + a = {}; + #in = {}; + b = {}; + #instanceof = {}; +} + ================================================================================ `; diff --git a/tests/format/js/no-semi/private-field.js b/tests/format/js/no-semi/private-field.js index feca225a4..47fab1340 100644 --- a/tests/format/js/no-semi/private-field.js +++ b/tests/format/js/no-semi/private-field.js @@ -2,3 +2,10 @@ class C { #field = 'value'; ["method"]() {} } + +class PrivateKeywordFields { + a = {}; + #in = {}; + b = {}; + #instanceof = {}; +}