diff --git a/changelog_unreleased/javascript/pr-9408.md b/changelog_unreleased/javascript/pr-9408.md index c1503f46d..b496ce45f 100644 --- a/changelog_unreleased/javascript/pr-9408.md +++ b/changelog_unreleased/javascript/pr-9408.md @@ -1,4 +1,4 @@ -#### Update to `@babel/parser` 7.12 (#9408 by @sosukesuzuki) +#### Update to `@babel/parser` 7.12 (#9408, #9476 by @sosukesuzuki) Updated the JavaScript parser to [`@babel/parser` 7.12](https://babeljs.io/blog/2020/10/15/7.12.0). This fixes several bugs and supports some new syntax. @@ -20,3 +20,19 @@ Due to a [bug in `@babel/parser`](https://github.com/babel/babel/issues/12209), let happy = "happy"; export { happy as "😃" }; ``` + +##### Support class static blocks + +```js +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} +``` diff --git a/src/language-js/parser-babel.js b/src/language-js/parser-babel.js index 810131166..539571361 100644 --- a/src/language-js/parser-babel.js +++ b/src/language-js/parser-babel.js @@ -39,6 +39,7 @@ function babelOptions({ sourceType, extraPlugins = [] }) { ["recordAndTuple", { syntaxType: "hash" }], "decimal", "moduleStringNames", + "classStaticBlock", ...extraPlugins, ], tokens: true, diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 98a46ea5d..e5ddd325e 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -894,11 +894,16 @@ function printPathNoParens(path, options, print, args) { case "Import": return "import"; case "TSModuleBlock": - case "BlockStatement": { + case "BlockStatement": + case "StaticBlock": { const naked = path.call((bodyPath) => { return printStatementSequence(bodyPath, options, print); }, "body"); + if (n.type === "StaticBlock") { + parts.push("static "); + } + const hasContent = n.body.some((node) => node.type !== "EmptyStatement"); const hasDirectives = n.directives && n.directives.length > 0; @@ -920,9 +925,10 @@ function printPathNoParens(path, options, print, args) { parent.type === "DoExpression" || (parent.type === "CatchClause" && !parentParent.finalizer) || parent.type === "TSModuleDeclaration" || - parent.type === "TSDeclareFunction") + parent.type === "TSDeclareFunction" || + n.type === "StaticBlock") ) { - return "{}"; + return concat([...parts, "{}"]); } parts.push("{"); diff --git a/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap b/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap index 3fb0f223c..26bfa6f5f 100644 --- a/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap +++ b/tests/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap @@ -356,6 +356,40 @@ console.log(Bork.staticFunction()); // > "babelIsCool" ================================================================================ `; +exports[`class-static-block.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "babel-ts", "babel-flow"] +printWidth: 80 + | printWidth +=====================================input====================================== +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} + +=====================================output===================================== +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} + +================================================================================ +`; + exports[`decimal.js format 1`] = ` ====================================options===================================== parsers: ["babel", "babel-ts", "babel-flow"] diff --git a/tests/js/babel-plugins/class-static-block.js b/tests/js/babel-plugins/class-static-block.js new file mode 100644 index 000000000..a707b82ce --- /dev/null +++ b/tests/js/babel-plugins/class-static-block.js @@ -0,0 +1,11 @@ +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} diff --git a/tests/js/babel-plugins/jsfmt.spec.js b/tests/js/babel-plugins/jsfmt.spec.js index 35b39843d..0e1838e07 100644 --- a/tests/js/babel-plugins/jsfmt.spec.js +++ b/tests/js/babel-plugins/jsfmt.spec.js @@ -27,6 +27,7 @@ run_spec(__dirname, ["babel", "babel-ts", "babel-flow"], { "v8intrinsic.js", "optional-chaining.js", "module-string-names.js", + "class-static-block.js", ], }, }); diff --git a/tests/js/class-static-block/__snapshots__/jsfmt.spec.js.snap b/tests/js/class-static-block/__snapshots__/jsfmt.spec.js.snap new file mode 100644 index 000000000..90642e44c --- /dev/null +++ b/tests/js/class-static-block/__snapshots__/jsfmt.spec.js.snap @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`class-static-block.js format 1`] = ` +====================================options===================================== +parsers: ["babel"] +printWidth: 80 + | printWidth +=====================================input====================================== +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} + +class Foo { + static {} +} + +class A1 { + static { + foo; + } +} + +class A2 { + static { + foo; + bar; + } +} + +=====================================output===================================== +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} + +class Foo { + static {} +} + +class A1 { + static { + foo; + } +} + +class A2 { + static { + foo; + bar; + } +} + +================================================================================ +`; diff --git a/tests/js/class-static-block/class-static-block.js b/tests/js/class-static-block/class-static-block.js new file mode 100644 index 000000000..026fe6f47 --- /dev/null +++ b/tests/js/class-static-block/class-static-block.js @@ -0,0 +1,29 @@ +class C { + static #x = 42; + static y; + static { + try { + this.y = doSomethingWith(this.#x); + } catch { + this.y = "unknown"; + } + } +} + +class Foo { + static {} +} + +class A1 { + static { + foo; + } +} + +class A2 { + static { + foo; + bar; + } +} + \ No newline at end of file diff --git a/tests/js/class-static-block/jsfmt.spec.js b/tests/js/class-static-block/jsfmt.spec.js new file mode 100644 index 000000000..726eaec01 --- /dev/null +++ b/tests/js/class-static-block/jsfmt.spec.js @@ -0,0 +1 @@ +run_spec(__dirname, ["babel"], { errors: { espree: true } });