Skip to content

Commit

Permalink
Support babel v7.21 (prettier#14391)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker authored and medikoo committed Feb 8, 2024
1 parent b7d7da8 commit 66201a7
Show file tree
Hide file tree
Showing 26 changed files with 519 additions and 291 deletions.
3 changes: 3 additions & 0 deletions changelog_unreleased/javascript/14391.md
@@ -0,0 +1,3 @@
#### Support regexp modifiers proposal (#14391 by @fisker)

See [Regular Expression Pattern Modifiers for ECMAScript](https://github.com/tc39/proposal-regexp-modifiers).
6 changes: 6 additions & 0 deletions changelog_unreleased/typescript/14391-2.md
@@ -0,0 +1,6 @@
#### Support TypeScript 5.0 via `babel-ts` parser (#14391 by @fisker)

TypeScript 5.0 introduces two new syntactic features:

- `const` modifiers for type parameters
- `export type *` declarations
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -33,7 +33,7 @@
"@angular/compiler": "15.1.5",
"@babel/code-frame": "7.18.6",
"@babel/parser": "7.21.3",
"@babel/types": "7.20.7",
"@babel/types": "7.21.0",
"@glimmer/syntax": "0.84.2",
"@iarna/toml": "2.2.5",
"@prettier/is-es5-identifier-name": "0.1.0",
Expand Down Expand Up @@ -106,7 +106,7 @@
"yaml-unist-parser": "2.0.1"
},
"devDependencies": {
"@babel/generator": "7.20.14",
"@babel/generator": "7.21.1",
"@esbuild-plugins/node-modules-polyfill": "0.2.2",
"@glimmer/reference": "0.84.2",
"@types/estree": "1.0.0",
Expand Down
3 changes: 2 additions & 1 deletion src/language-js/parse/babel.js
Expand Up @@ -23,6 +23,7 @@ const parseOptions = {
sourceType: "module",
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
allowNewTargetOutsideFunction: true,
allowSuperOutsideMethod: true,
allowUndeclaredExports: true,
errorRecovery: true,
Expand All @@ -36,7 +37,7 @@ const parseOptions = {
"functionSent",
"throwExpressions",
"partialApplication",
["decorators", { decoratorsBeforeExport: false }],
"decorators",
"importAssertions",
"decimal",
"moduleBlocks",
Expand Down
1 change: 1 addition & 0 deletions src/language-js/parse/postprocess/typescript.js
Expand Up @@ -103,6 +103,7 @@ function throwErrorForInvalidModifier(node) {
if (
modifier.kind !== SyntaxKind.InKeyword &&
modifier.kind !== SyntaxKind.OutKeyword &&
modifier.kind !== SyntaxKind.ConstKeyword &&
node.kind === SyntaxKind.TypeParameter
) {
throwErrorOnTsNode(
Expand Down
3 changes: 1 addition & 2 deletions src/language-js/print/type-parameters.js
Expand Up @@ -111,9 +111,8 @@ function printDanglingCommentsForInline(path, options) {
}

function printTypeParameter(path, options, print) {
const { node } = path;
const { node, parent } = path;
const parts = [node.type === "TSTypeParameter" && node.const ? "const " : ""];
const { parent } = path;

const name = node.type === "TSTypeParameter" ? print("name") : node.name;

Expand Down
10 changes: 0 additions & 10 deletions tests/format/flow-repo/async/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -465,16 +465,6 @@ async function baz() {
================================================================================
`;
exports[`await_parse.js [babel-flow] format 1`] = `
"Can not use 'await' as identifier inside an async function. (23:5)
21 | console.log(x.await);
22 |
> 23 | var await = 3;
| ^
24 | var y = { await };
25 |"
`;
exports[`await_parse.js format 1`] = `
====================================options=====================================
parsers: ["flow"]
Expand Down
4 changes: 1 addition & 3 deletions tests/format/flow-repo/async/jsfmt.spec.js
@@ -1,3 +1 @@
run_spec(import.meta, ["flow"], {
errors: { "babel-flow": ["await_parse.js"] },
});
run_spec(import.meta, ["flow"]);
35 changes: 35 additions & 0 deletions tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -2313,6 +2313,41 @@ printWidth: 80
================================================================================
`;
exports[`regexp-modifiers.js [acorn] format 1`] = `
"Invalid regular expression: /^(?i:[a-z])[a-z]$/: Invalid group (1:13)
> 1 | const re = /^(?i:[a-z])[a-z]$/;
| ^
2 |"
`;
exports[`regexp-modifiers.js [espree] format 1`] = `
"Invalid regular expression: /^(?i:[a-z])[a-z]$/: Invalid group (1:13)
> 1 | const re = /^(?i:[a-z])[a-z]$/;
| ^
2 |"
`;
exports[`regexp-modifiers.js [meriyah] format 1`] = `
"Unterminated regular expression (1:30)
> 1 | const re = /^(?i:[a-z])[a-z]$/;
| ^
2 |"
`;
exports[`regexp-modifiers.js format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "babel-flow"]
printWidth: 80
| printWidth
=====================================input======================================
const re = /^(?i:[a-z])[a-z]$/;
=====================================output=====================================
const re = /^(?i:[a-z])[a-z]$/;
================================================================================
`;
exports[`throw-expressions.js [acorn] format 1`] = `
"Unexpected token (3:23)
1 | // https://babeljs.io/docs/en/babel-plugin-proposal-throw-expressions
Expand Down
3 changes: 3 additions & 0 deletions tests/format/js/babel-plugins/jsfmt.spec.js
Expand Up @@ -29,6 +29,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], {
"decorator-auto-accessors.js",
"import-reflection.js",
"explicit-resource-management.js",
"regexp-modifiers.js",
],
espree: [
"decimal.js",
Expand Down Expand Up @@ -56,6 +57,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], {
"decorator-auto-accessors.js",
"import-reflection.js",
"explicit-resource-management.js",
"regexp-modifiers.js",
],
meriyah: [
"decimal.js",
Expand Down Expand Up @@ -84,6 +86,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], {
"regex-v-flag.js",
"import-reflection.js",
"explicit-resource-management.js",
"regexp-modifiers.js",
],
babel: ["flow.js", "typescript.js"],
__babel_estree: ["flow.js", "typescript.js"],
Expand Down
1 change: 1 addition & 0 deletions tests/format/js/babel-plugins/regexp-modifiers.js
@@ -0,0 +1 @@
const re = /^(?i:[a-z])[a-z]$/;
98 changes: 98 additions & 0 deletions tests/format/js/new-target/__snapshots__/jsfmt.spec.js.snap
@@ -0,0 +1,98 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`outside-functions.js [acorn] format 1`] = `
"'new.target' can only be used in functions and class static block (1:11)
> 1 | const x = new.target;
| ^
2 |"
`;

exports[`outside-functions.js [espree] format 1`] = `
"'new.target' can only be used in functions and class static block (1:11)
> 1 | const x = new.target;
| ^
2 |"
`;

exports[`outside-functions.js [flow] format 1`] = `
"Unexpected token \`.\` (1:14)
> 1 | const x = new.target;
| ^
2 |"
`;

exports[`outside-functions.js [meriyah] format 1`] = `
"new.target only allowed within functions (1:20)
> 1 | const x = new.target;
| ^
2 |"
`;

exports[`outside-functions.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
const x = new.target;
=====================================output=====================================
const x = new.target;
================================================================================
`;

exports[`range.js [acorn] format 1`] = `
"'new.target' can only be used in functions and class static block (2:1)
1 | const x =
> 2 | new.target;
| ^"
`;

exports[`range.js [espree] format 1`] = `
"'new.target' can only be used in functions and class static block (2:1)
1 | const x =
> 2 | new.target;
| ^"
`;

exports[`range.js [flow] format 1`] = `
"Unexpected token \`.\` (2:4)
1 | const x =
> 2 | new.target;
| ^"
`;

exports[`range.js [meriyah] format 1`] = `
"new.target only allowed within functions (2:10)
1 | const x =
> 2 | new.target;
| ^"
`;

exports[`range.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
rangeEnd: 52
rangeStart: 38
| | printWidth
=====================================input======================================
1 | class A {
2 | constructor() {
> 3 | const x =
| ^^^
> 4 | new.target;
| ^^^^^^^^^^
5 | }
6 | }
7 |
=====================================output=====================================
class A {
constructor() {
const x = new.target;
}
}
================================================================================
`;
8 changes: 8 additions & 0 deletions tests/format/js/new-target/jsfmt.spec.js
@@ -0,0 +1,8 @@
run_spec(import.meta, ["babel", "flow", "typescript"], {
errors: {
acorn: true,
espree: true,
meriyah: true,
flow: true,
},
});
1 change: 1 addition & 0 deletions tests/format/js/new-target/outside-functions.js
@@ -0,0 +1 @@
const x = new.target;
6 changes: 6 additions & 0 deletions tests/format/js/new-target/range.js
@@ -0,0 +1,6 @@
class A {
constructor() {
const <<<PRETTIER_RANGE_START>>>x =
new.target<<<PRETTIER_RANGE_END>>>;
}
}
45 changes: 45 additions & 0 deletions tests/format/js/regex/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -30,6 +30,51 @@ printWidth: 80
================================================================================
`;

exports[`regexp-modifiers.js [acorn] format 1`] = `
"Invalid regular expression: /(?ims:^[a-z])/: Invalid group (1:2)
> 1 | /(?ims:^[a-z])/u;
| ^
2 | /(?-ims:^[a-z].)(^[a-z].)/uims;
3 | /(?ims:^[a-z].1$)/;
4 |"
`;

exports[`regexp-modifiers.js [espree] format 1`] = `
"Invalid regular expression: /(?ims:^[a-z])/: Invalid group (1:2)
> 1 | /(?ims:^[a-z])/u;
| ^
2 | /(?-ims:^[a-z].)(^[a-z].)/uims;
3 | /(?ims:^[a-z].1$)/;
4 |"
`;

exports[`regexp-modifiers.js [meriyah] format 1`] = `
"Unterminated regular expression (1:16)
> 1 | /(?ims:^[a-z])/u;
| ^
2 | /(?-ims:^[a-z].)(^[a-z].)/uims;
3 | /(?ims:^[a-z].1$)/;
4 |"
`;

exports[`regexp-modifiers.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
/(?ims:^[a-z])/u;
/(?-ims:^[a-z].)(^[a-z].)/uims;
/(?ims:^[a-z].1$)/;
=====================================output=====================================
/(?ims:^[a-z])/u;
/(?-ims:^[a-z].)(^[a-z].)/imsu;
/(?ims:^[a-z].1$)/;
================================================================================
`;

exports[`test.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
Expand Down
6 changes: 3 additions & 3 deletions tests/format/js/regex/jsfmt.spec.js
@@ -1,8 +1,8 @@
run_spec(import.meta, ["babel", "flow", "typescript"], {
errors: {
flow: ["v-flag.js"],
acorn: ["v-flag.js"],
espree: ["v-flag.js"],
meriyah: ["v-flag.js"],
acorn: ["v-flag.js", "regexp-modifiers.js"],
espree: ["v-flag.js", "regexp-modifiers.js"],
meriyah: ["v-flag.js", "regexp-modifiers.js"],
},
});
3 changes: 3 additions & 0 deletions tests/format/js/regex/regexp-modifiers.js
@@ -0,0 +1,3 @@
/(?ims:^[a-z])/u;
/(?-ims:^[a-z].)(^[a-z].)/uims;
/(?ims:^[a-z].1$)/;
@@ -0,0 +1,33 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`snippet: #0 [babel] format 1`] = `
"Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time. (2:8)
1 | @decorator1
> 2 | export @decorator2 class A{}
| ^"
`;

exports[`snippet: #1 [babel] format 1`] = `
"Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time. (2:16)
1 | @decorator1
> 2 | export default @decorator2 class A{}
| ^"
`;

exports[`snippet: #2 [babel] format 1`] = `
"Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time. (1:20)
> 1 | @decorator1 export @decorator2 class A {}
| ^"
`;

exports[`snippet: #3 [babel] format 1`] = `
"Decorators can be placed *either* before or after the 'export' keyword, but not in both locations at the same time. (1:28)
> 1 | @decorator1 export default @decorator2 class A {}
| ^"
`;

exports[`snippet: #4 [babel] format 1`] = `
"Leading decorators must be attached to a class declaration. (1:20)
> 1 | export @decorator2 default class A {}
| ^"
`;
21 changes: 21 additions & 0 deletions tests/format/misc/errors/js/decorators/jsfmt.spec.js
@@ -0,0 +1,21 @@
import { outdent } from "outdent";

run_spec(
{
importMeta: import.meta,
snippets: [
outdent`
@decorator1
export @decorator2 class A{}
`,
outdent`
@decorator1
export default @decorator2 class A{}
`,
"@decorator1 export @decorator2 class A {}",
"@decorator1 export default @decorator2 class A {}",
"export @decorator2 default class A {}",
],
},
["babel"]
);

0 comments on commit 66201a7

Please sign in to comment.