Fix TSX support for oxc-ts and yuku-ts parser (#19909)

This commit is contained in:
fisker Cheung authored and GitHub committed 2026-08-22 06:09:47 +08:00
1 parent 9c7728d3b4
commit 8d2aeedae5
9 files changed
+312 -22

No files matched your search

+17 -10
View File
@@ -5,6 +5,7 @@ import { tryCombinationsSync } from "../../utilities/try-combinations.js";
import postprocess from "./postprocess/index.js";
import createParser from "./utilities/create-parser.js";
import jsxRegexp from "./utilities/jsx-regexp.evaluate.js";
import { shouldEnableJsx } from "./utilities/jsx-support.js";
import {
getSourceType,
SOURCE_TYPE_COMBINATIONS,
@@ -102,18 +103,24 @@ function parseJs(text, options) {
function getLanguageCombinations(text, options) {
const filepath = options?.filepath;
if (typeof filepath === "string") {
if (/\.(?:jsx|tsx)$/i.test(filepath)) {
return ["tsx"];
}
if (filepath.toLowerCase().endsWith(".d.ts")) {
return ["dts"];
}
if (
typeof filepath === "string" &&
filepath.toLowerCase().endsWith(".d.ts")
) {
return ["dts"];
}
const shouldEnableJsx = jsxRegexp.test(text);
return shouldEnableJsx ? ["tsx", "ts", "dts"] : ["ts", "tsx", "dts"];
const isTsx = shouldEnableJsx(filepath);
if (isTsx === true) {
return ["tsx"];
}
if (isTsx === false) {
return ["ts"];
}
return jsxRegexp.test(text) ? ["tsx", "ts", "dts"] : ["ts", "tsx", "dts"];
}
function parseTs(text, options) {
@@ -0,0 +1,23 @@
/**
Follow https://typescript-eslint.io/packages/parser/#jsx
- `.js`, `.mjs`, `.cjs`, `.jsx`, `.tsx` files are always parsed as `{jsx: true}`.
- `.ts`, `.mts`, `.cts` files are always parsed as `{jsx: false}`.
*/
function shouldEnableJsx(filepath) {
if (typeof filepath !== "string") {
return;
}
filepath = filepath.toLowerCase();
if (/\.(?:js|mjs|cjs|jsx|tsx)$/.test(filepath)) {
return true;
}
if (/\.(?:ts|mts|cts)$/.test(filepath)) {
return false;
}
}
export { shouldEnableJsx };
+17 -10
View File
@@ -5,6 +5,7 @@ import { tryCombinationsSync } from "../../utilities/try-combinations.js";
import postprocess from "./postprocess/index.js";
import createParser from "./utilities/create-parser.js";
import jsxRegexp from "./utilities/jsx-regexp.evaluate.js";
import { shouldEnableJsx } from "./utilities/jsx-support.js";
import {
getSourceType,
SOURCE_TYPE_COMBINATIONS,
@@ -86,18 +87,24 @@ function parseJs(text, options) {
function getLanguageCombinations(text, options) {
const filepath = options?.filepath;
if (typeof filepath === "string") {
if (/\.(?:jsx|tsx)$/i.test(filepath)) {
return ["tsx"];
}
if (filepath.toLowerCase().endsWith(".d.ts")) {
return ["dts"];
}
if (
typeof filepath === "string" &&
filepath.toLowerCase().endsWith(".d.ts")
) {
return ["dts"];
}
const shouldEnableJsx = jsxRegexp.test(text);
return shouldEnableJsx ? ["tsx", "ts", "dts"] : ["ts", "tsx", "dts"];
const isTsx = shouldEnableJsx(filepath);
if (isTsx === true) {
return ["tsx"];
}
if (isTsx === false) {
return ["ts"];
}
return jsxRegexp.test(text) ? ["tsx", "ts", "dts"] : ["ts", "tsx", "dts"];
}
function parseTs(text, options) {
@@ -0,0 +1,166 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`snippet: test.cjs format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.cts format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.cts format[oxc-ts] 1`] = `
"Expected \`>\` but found \`/\` (1:6)
> 1 | <div />
| ^"
`;
exports[`snippet: test.cts format[typescript] 1`] = `
"'>' expected. (1:6)
> 1 | <div />
| ^
Cause: '>' expected."
`;
exports[`snippet: test.cts format[yuku-ts] 1`] = `
"Expected '>' to close a type assertion, but found '/' (1:6)
> 1 | <div />
| ^"
`;
exports[`snippet: test.js format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.jsx format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.mjs format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.mts format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.mts format[oxc-ts] 1`] = `
"Expected \`>\` but found \`/\` (1:6)
> 1 | <div />
| ^"
`;
exports[`snippet: test.mts format[typescript] 1`] = `
"'>' expected. (1:6)
> 1 | <div />
| ^
Cause: '>' expected."
`;
exports[`snippet: test.mts format[yuku-ts] 1`] = `
"Expected '>' to close a type assertion, but found '/' (1:6)
> 1 | <div />
| ^"
`;
exports[`snippet: test.ts format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.ts format[oxc-ts] 1`] = `
"Expected \`>\` but found \`/\` (1:6)
> 1 | <div />
| ^"
`;
exports[`snippet: test.ts format[typescript] 1`] = `
"'>' expected. (1:6)
> 1 | <div />
| ^
Cause: '>' expected."
`;
exports[`snippet: test.ts format[yuku-ts] 1`] = `
"Expected '>' to close a type assertion, but found '/' (1:6)
> 1 | <div />
| ^"
`;
exports[`snippet: test.tsx format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
exports[`snippet: test.unset-filepath format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "acorn", "espree", "flow", "meriyah", "typescript", "hermes", "oxc", "oxc-ts", "yuku", "yuku-ts", "__babel_estree"]
printWidth: 80 (default) |
=====================================input======================================
<div />
=====================================output=====================================
<div />;
================================================================================
`;
@@ -0,0 +1,45 @@
runFormatTest(
{
snippets: [
".js",
".cjs",
".mjs",
".jsx",
".ts",
".mts",
".cts",
".tsx",
".unset-filepath",
].map((extension) => {
const filename = `test${extension}`;
return {
name: filename,
code: "<div />",
filename,
};
}),
importMeta: import.meta,
},
[
"babel",
"babel-ts",
"acorn",
"espree",
"flow",
"meriyah",
"typescript",
"hermes",
"oxc",
"oxc-ts",
"yuku",
"yuku-ts",
"__babel_estree",
],
{
errors: {
typescript: ["test.ts", "test.mts", "test.cts"],
"oxc-ts": ["test.ts", "test.mts", "test.cts"],
"yuku-ts": ["test.ts", "test.mts", "test.cts"],
},
},
);
@@ -142,6 +142,15 @@ exports[`keyword.ts format[babel-ts] 1`] = `
Cause: \`module ... {}\` declarations must have a string name. Use \`namespace ... {}\` instead. (1:0)"
`;
exports[`keyword.ts format[oxc-ts] 1`] = `
"Only ambient modules can use quoted names. (35:24)
33 | namespace /* module */ X {}
34 | module /* namespace */ X {}
> 35 | module /* namespace */ "x" {}
| ^^^
36 |"
`;
exports[`module-nested.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1,3 +1,6 @@
runFormatTest(import.meta, ["typescript"], {
errors: { "babel-ts": ["global.ts", "keyword.ts", "module-nested.ts"] },
errors: {
"babel-ts": ["global.ts", "keyword.ts", "module-nested.ts"],
"oxc-ts": ["keyword.ts"],
},
});
@@ -84,6 +84,16 @@ const {
================================================================================
`;
exports[`invalid.ts - {"trailingComma":"all"} format[oxc-ts] 1`] = `
"A rest parameter or binding pattern may not have a trailing comma. (5:10)
3 | longKeySoThisWillGoOnMultipleLines2,
4 | longKeySoThisWillGoOnMultipleLines3,
> 5 | ...rest,
| ^
6 | } = something;
7 |"
`;
exports[`invalid.ts - {"trailingComma":"all"} format[yuku-ts] 1`] = `
"Rest element cannot have a trailing comma in object destructuring. (1:7)
> 1 | const {
@@ -125,6 +135,16 @@ const {
================================================================================
`;
exports[`invalid.ts - {"trailingComma":"es5"} format[oxc-ts] 1`] = `
"A rest parameter or binding pattern may not have a trailing comma. (5:10)
3 | longKeySoThisWillGoOnMultipleLines2,
4 | longKeySoThisWillGoOnMultipleLines3,
> 5 | ...rest,
| ^
6 | } = something;
7 |"
`;
exports[`invalid.ts - {"trailingComma":"es5"} format[yuku-ts] 1`] = `
"Rest element cannot have a trailing comma in object destructuring. (1:7)
> 1 | const {
@@ -166,6 +186,16 @@ const {
================================================================================
`;
exports[`invalid.ts - {"trailingComma":"none"} format[oxc-ts] 1`] = `
"A rest parameter or binding pattern may not have a trailing comma. (5:10)
3 | longKeySoThisWillGoOnMultipleLines2,
4 | longKeySoThisWillGoOnMultipleLines3,
> 5 | ...rest,
| ^
6 | } = something;
7 |"
`;
exports[`invalid.ts - {"trailingComma":"none"} format[yuku-ts] 1`] = `
"Rest element cannot have a trailing comma in object destructuring. (1:7)
> 1 | const {
@@ -1,4 +1,4 @@
const errors = { "yuku-ts": ["invalid.ts"] };
const errors = { "oxc-ts": ["invalid.ts"], "yuku-ts": ["invalid.ts"] };
runFormatTest(import.meta, ["typescript"], { trailingComma: "all", errors });
runFormatTest(import.meta, ["typescript"], { trailingComma: "es5", errors });