Add oxc-ts parser (#17483)

This commit is contained in:
fisker Cheung authored and GitHub committed 2025-05-27 13:32:23 +08:00
1 parent 3c1475b1e7
commit 9e814108ca
57 files changed
+545 -63

No files matched your search

+1 -1
View File
@@ -48,7 +48,7 @@ function runFormatTest(
Parameters:
- **`fixtures`**: Must be set to `import.meta` or to an object of the shape `{ importMeta: import.meta, ... }`. The object may have the `snippets` property to specify an array of extra input entries in addition to the files in the current directory. For each input entry (a file or a snippet), `runFormatTest` configures and runs a number of tests. The main check is that for a given input the output should match the snapshot (for snippets, the expected output can also be specified directly). [Additional checks](#deeper-testing) are controlled by options and environment variables.
- **`parsers`**: A list of parser names. The tests verify that the parsers in this list produce the same output. If the list includes `typescript`, then `babel-ts` is included implicitly. If the list includes `flow`, then `babel-flow` is included implicitly. If the list includes `babel`, and the current directory is inside `tests/format/js` or `tests/format/jsx`, then `acorn`, `espree`, `meriyah`, and `oxc` are included implicitly.
- **`parsers`**: A list of parser names. The tests verify that the parsers in this list produce the same output. If the list includes `typescript`, then `babel-ts`, and `oxc-ts` is included implicitly. If the list includes `flow`, then `babel-flow` is included implicitly. If the list includes `babel`, and the current directory is inside `tests/format/js` or `tests/format/jsx`, then `acorn`, `espree`, `meriyah`, and `oxc` are included implicitly.
- **`options`**: In addition to Prettier's formatting options, can contain the `errors` property to specify that it's expected that the formatting shouldn't be successful and an error should be thrown for all (`errors: true`) or some combinations of input entries and parsers.
The implementation of `runFormatTest` can be found in [`tests/config/run-format-test.js`](tests/config/run-format-test.js).
+3 -3
View File
@@ -189,9 +189,9 @@
"build": "node ./scripts/build/build.js",
"build:website": "node ./scripts/build-website.js",
"gen:changelog": "node ./scripts/generate-changelog.js",
"debug": "node bin/prettier.js --ignore-path=.prettierignore",
"debug:watch": "node --watch bin/prettier.js --ignore-path=.prettierignore",
"debug:inspect": "node --inspect-brk bin/prettier.js --ignore-path=.prettierignore"
"debug": "node bin/prettier.js --ignore-path=.prettierignore --plugin=./packages/plugin-oxc/index.js",
"debug:watch": "node --watch bin/prettier.js --ignore-path=.prettierignore --plugin=./packages/plugin-oxc/index.js",
"debug:inspect": "node --inspect-brk bin/prettier.js --ignore-path=.prettierignore --plugin=./packages/plugin-oxc/index.js"
},
"c8": {
"reporter": [
+8 -1
View File
@@ -16,11 +16,18 @@ Create or modify your [prettier configuration file](https://prettier.io/docs/en/
{
"overrides": [
{
"files": ["**/*.{js,mjs,cjs}"],
"files": ["**/*.{js,mjs,cjs,jsx}"],
"options": {
"plugins": ["@prettier/plugin-oxc"],
"parser": "oxc"
}
},
{
"files": ["**/*.{ts,mts,cts,tsx}"],
"options": {
"plugins": ["@prettier/plugin-oxc"],
"parser": "oxc-ts"
}
}
]
}
+1 -3
View File
@@ -1,3 +1 @@
import { oxc } from "../../src/language-js/parse/oxc.js";
export const parsers = { oxc };
export * as parsers from "../../src/language-js/parse/oxc.js";
@@ -46,6 +46,7 @@ function getCommentChildNodes(node, options) {
options.parser === "flow" ||
options.parser === "acorn" ||
options.parser === "oxc" ||
options.parser === "oxc-ts" ||
options.parser === "espree" ||
options.parser === "meriyah" ||
options.parser === "__babel_estree") &&
+77 -7
View File
@@ -31,13 +31,11 @@ const isRawTransferSupported = () => {
return cachedIsRawTransferSupported;
};
async function parseWithOptions(filename, text, sourceType) {
async function parseWithOptions(filename, text, options) {
const result = await oxcParse(filename, text, {
sourceType,
lang: "jsx",
preserveParens: true,
// @ts-expect-error -- missing
experimentalRawTransfer: isRawTransferSupported(),
...options,
});
const { errors } = result;
@@ -56,7 +54,7 @@ async function parseWithOptions(filename, text, sourceType) {
return result;
}
async function parse(text, options = {}) {
async function parseJs(text, options = {}) {
const sourceType = getSourceType(options);
let { filepath } = options;
if (typeof filepath !== "string") {
@@ -64,7 +62,8 @@ async function parse(text, options = {}) {
}
const combinations = (sourceType ? [sourceType] : ["module", "script"]).map(
(sourceType) => () => parseWithOptions(filepath, text, sourceType),
(sourceType) => () =>
parseWithOptions(filepath, text, { sourceType, lang: "jsx" }),
);
let result;
@@ -81,4 +80,75 @@ async function parse(text, options = {}) {
return postprocess(ast, { text, parser: "oxc" });
}
export const oxc = createParser(parse);
function getTsParseOptionsCombinations(text, options) {
const sourceType = getSourceType(options);
/** @type {("module" | "script") []} */
const sourceTypes = sourceType ? [sourceType] : ["module", "script"];
const combinations = sourceTypes.map((sourceType) => ({ sourceType }));
const extension = options.filepath?.toLowerCase().split(".").at(-1);
const isKnownJsx = extension === "jsx" || extension === "tsx";
if (isKnownJsx) {
return combinations.map((parseOptions) => ({
...parseOptions,
lang: "tsx",
}));
}
const shouldEnableJsx = isProbablyJsx(text);
return combinations.flatMap((parseOptions) =>
[shouldEnableJsx, !shouldEnableJsx].map((jsx) =>
jsx ? { ...parseOptions, lang: "tsx" } : { ...parseOptions, lang: "ts" },
),
);
}
async function parseTs(text, options = {}) {
const parseOptionsCombinations = getTsParseOptionsCombinations(text, options);
let { filepath } = options;
if (typeof filepath !== "string") {
filepath = "prettier.tsx";
}
let result;
try {
result = await tryCombinationsAsync(
parseOptionsCombinations.map(
(parseOptions) => () =>
parseWithOptions(filepath, text, { ...parseOptions, astType: "ts" }),
),
);
} catch ({
// @ts-expect-error -- expected
errors: [error],
}) {
throw error;
}
const { program: ast, comments } = result;
// @ts-expect-error -- expected
ast.comments = comments;
return postprocess(ast, { text, parser: "oxc", oxcAstType: "ts" });
}
/**
* Use a naive regular expression to detect JSX
* copied from typescript.js
*/
function isProbablyJsx(text) {
return new RegExp(
// eslint-disable-next-line regexp/no-useless-non-capturing-group -- possible bug
[
"(?:^[^\"'`]*</)", // Contains "</" when probably not in a string
"|",
"(?:^[^/]{2}.*/>)", // Contains "/>" on line not starting with "//"
].join(""),
"mu",
).test(text);
}
const oxc = createParser(parseJs);
const oxcTs = createParser(parseTs);
export { oxc, oxcTs as "oxc-ts" };
+19 -2
View File
@@ -34,6 +34,7 @@ const isNodeWithRaw = createTypeCheckFunction([
* @param {{
* text: string,
* parser?: string,
* oxcAstType?: string,
* }} options
*/
function postprocess(ast, options) {
@@ -49,6 +50,12 @@ function postprocess(ast, options) {
delete program.interpreter;
}
if (parser === "oxc" && options.oxcAstType === "ts" && ast.hashbang) {
const { comments, hashbang } = ast;
comments.unshift(hashbang);
delete program.hashbang;
}
if (ast.comments.length > 0) {
let followingComment;
for (let i = ast.comments.length - 1; i >= 0; i--) {
@@ -117,13 +124,23 @@ function postprocess(ast, options) {
}
break;
// This happens when use `oxc-parser` to parse `` `${foo satisfies bar}`; ``
// https://github.com/oxc-project/oxc/issues/11313
case "TemplateLiteral":
/* c8 ignore next 3 */
if (node.expressions.length !== node.quasis.length - 1) {
throw new Error("Malformed template literal.");
}
break;
case "TemplateElement":
// `flow` and `typescript` follows the `espree` style positions
// `flow`, `typescript`, and `oxc`(with `{astType: 'ts'}`) follows the `espree` style positions
// https://github.com/eslint/js/blob/5826877f7b33548e5ba984878dd4a8eac8448f87/packages/espree/lib/espree.js#L213
if (
parser === "flow" ||
parser === "espree" ||
parser === "typescript"
parser === "typescript" ||
(parser === "oxc" && options.oxcAstType === "ts")
) {
const start = locStart(node) + 1;
const end = locEnd(node) - (node.tail ? 1 : 2);
+7 -2
View File
@@ -56,7 +56,8 @@ function isStringKeySafeToUnquote(node, options) {
// See https://github.com/microsoft/TypeScript/pull/20075
!(
(options.parser === "babel-ts" && node.type === "ClassProperty") ||
(options.parser === "typescript" && node.type === "PropertyDefinition")
((options.parser === "typescript" || options.parser === "oxc-ts") &&
node.type === "PropertyDefinition")
)
) {
return true;
@@ -90,7 +91,11 @@ function shouldQuotePropertyKey(path, options) {
String(key.value) === printNumber(getRaw(key)) &&
// Quoting number keys is safe in JS and Flow, but not in TypeScript (as
// mentioned in `isStringKeySafeToUnquote`).
!(options.parser === "typescript" || options.parser === "babel-ts"))) &&
!(
options.parser === "typescript" ||
options.parser === "babel-ts" ||
options.parser === "oxc-ts"
))) &&
(options.parser === "json" ||
options.parser === "jsonc" ||
(options.quoteProps === "consistent" && needsQuoteProps.get(path.parent)))
+1 -1
View File
@@ -16,7 +16,7 @@ const isLineComment = createTypeCheckFunction([
"HashbangComment",
"HTMLOpen",
"HTMLClose",
// `espree`
// `espree`, and `oxc`(with `{astType: 'ts'}`)
"Hashbang",
// `babel` and `flow` hashbang
"InterpreterDirective",
+1
View File
@@ -178,6 +178,7 @@ function isSourceElement(opts, node, parentNode) {
case "espree":
case "meriyah":
case "oxc":
case "oxc-ts":
case "__babel_estree":
return isJsSourceElement(node.type, parentNode?.type);
case "json":
+15 -7
View File
@@ -97,6 +97,12 @@ const oxcDisabledTests = new Set(
"js/ignore/class-expression-decorator.js",
].map((file) => path.join(__dirname, "../format", file)),
);
const oxcTsDisabledTests = new Set(
[
// https://github.com/oxc-project/oxc/issues/11029
"typescript/decorators/abstract-method.ts",
].map((file) => path.join(__dirname, "../format", file)),
);
const isUnstable = (filename, options) => {
const testFunction = unstableTests.get(filename);
@@ -255,12 +261,13 @@ function runFormatTest(fixtures, parsers, options) {
}
}
if (
parsers.includes("typescript") &&
!parsers.includes("babel-ts") &&
!IS_TYPESCRIPT_ONLY_TEST
) {
allParsers.push("babel-ts");
if (parsers.includes("typescript") && !IS_TYPESCRIPT_ONLY_TEST) {
if (!parsers.includes("babel-ts")) {
allParsers.push("babel-ts");
}
if (!parsers.includes("oxc-ts")) {
allParsers.push("oxc-ts");
}
}
if (parsers.includes("flow") && !parsers.includes("babel-flow")) {
@@ -306,6 +313,7 @@ function runFormatTest(fixtures, parsers, options) {
(currentParser === "espree" && espreeDisabledTests.has(filename)) ||
(currentParser === "meriyah" && meriyahDisabledTests.has(filename)) ||
(currentParser === "oxc" && oxcDisabledTests.has(filename)) ||
(currentParser === "oxc-ts" && oxcTsDisabledTests.has(filename)) ||
(currentParser === "babel-ts" && babelTsDisabledTests.has(filename))
) {
continue;
@@ -554,7 +562,7 @@ async function format(originalText, originalOptions) {
}
async function loadPlugins(options) {
if (options.parser === "oxc") {
if (options.parser === "oxc" || options.parser === "oxc-ts") {
const plugins = options.plugins ?? [];
const url = new URL(
isProduction
+4 -3
View File
@@ -57,13 +57,14 @@ const categoryParsers = new Map([
[
"js",
{
parsers: ["babel", "acorn", "espree", "meriyah", "oxc"],
parsers: ["babel", "acorn", "espree", "meriyah", "oxc", "oxc-ts"],
verifyParsers: [
"babel",
"acorn",
"espree",
"meriyah",
"oxc",
"oxc-ts",
"flow",
"babel-flow",
"typescript",
@@ -133,8 +134,8 @@ const categoryParsers = new Map([
[
"typescript",
{
parsers: ["typescript", "babel-ts"],
verifyParsers: ["typescript", "babel-ts", "flow", "babel-flow"],
parsers: ["typescript", "babel-ts", "oxc-ts"],
verifyParsers: ["typescript", "babel-ts", "flow", "babel-flow", "oxc-ts"],
extensions: [".ts", ".tsx", ".cts", ".mts"],
},
],
@@ -24,6 +24,17 @@ exports[`comments.js [babel-ts] format 1`] = `
Cause: Unexpected token (3:2)"
`;
exports[`comments.js [oxc-ts] format 1`] = `
"Unexpected token (3:3)
1 | type Type = {
2 | // comment
> 3 | +[T in number]: number;
| ^
4 | };
5 |
6 | type Type = {"
`;
exports[`comments.js [typescript] format 1`] = `
"Property or signature expected. (3:3)
1 | type Type = {
@@ -151,6 +162,17 @@ exports[`mapped-types.js [babel-ts] format 1`] = `
Cause: Unexpected token (5:27)"
`;
exports[`mapped-types.js [oxc-ts] format 1`] = `
"Unexpected token (5:28)
3 | type Mapped = {[key in keyof O]: O[key]};
4 | type MappedLong = {[key in keyof AReallyLongNameThatShouldReallyMostDefinitelyCauseALineWrap]: number};
> 5 | type MappedWithVariance = {+[key in keyof O]: number};
| ^
6 | type MappedWithVarianceLong = {-[key in keyof AReallyLongNameThatShouldReallyMostDefinitelyCauseALineWrap]: number};
7 | type MappedWithPlusOptional = {[key in keyof O]+?: number};
8 | type MappedWithMinusOptional = {[key in keyof O]-?: number};"
`;
exports[`mapped-types.js [typescript] format 1`] = `
"Property or signature expected. (5:28)
3 | type Mapped = {[key in keyof O]: O[key]};
@@ -3,5 +3,6 @@ runFormatTest(import.meta, ["flow", "typescript"], {
"babel-flow": ["comments.js", "mapped-types.js", "ts-compatibility.js"],
"babel-ts": ["comments.js", "mapped-types.js"],
typescript: ["comments.js", "mapped-types.js"],
"oxc-ts": ["comments.js", "mapped-types.js"],
},
});
+7 -1
View File
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -94,6 +94,24 @@ runFormatTest(import.meta, ["babel", "babel-ts", "babel-flow"], {
"typescript.js",
"v8intrinsic.js",
],
"oxc-ts": [
"async-do-expressions.js",
"destructuring-private.js",
"do-expressions.js",
"export-default-from.js",
"flow.js",
"function-bind.js",
"function-sent.js",
"module-blocks.js",
"optional-chaining-assignment.js",
"partial-application.js",
"pipeline-operator-fsharp.js",
"pipeline-operator-hack.js",
"pipeline-operator-minimal.js",
"throw-expressions.js",
"typescript.js",
"v8intrinsic.js",
],
babel: ["flow.js", "typescript.js"],
__babel_estree: ["flow.js", "typescript.js"],
},
@@ -1,7 +1,10 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
});
runFormatTest(import.meta, ["babel"], {
semi: false,
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
});
const errors = {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
};
runFormatTest(import.meta, ["babel"], { errors });
runFormatTest(import.meta, ["babel"], { semi: false, errors });
@@ -6,5 +6,6 @@ runFormatTest(import.meta, ["babel"], {
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -12,6 +12,7 @@ runFormatTest(import.meta, ["babel"], {
espree: [...importDeferTests, ...invalidSyntaxTests],
meriyah: [...importDeferTests, ...invalidSyntaxTests],
oxc: invalidSyntaxTests,
"oxc-ts": invalidSyntaxTests,
babel: invalidSyntaxTests,
__babel_estree: invalidSyntaxTests,
},
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel", "babel-flow", "babel-ts"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
+7 -1
View File
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -866,6 +866,15 @@ exports[`valid-module-block-top-level-await-using-binding.js [oxc] format 1`] =
4 |"
`;
exports[`valid-module-block-top-level-await-using-binding.js [oxc-ts] format 1`] = `
"Expected a semicolon or an implicit semicolon after a statement, but found none (1:17)
> 1 | const m = module {
| ^
2 | await using foo = bar();
3 | }
4 |"
`;
exports[`valid-module-block-top-level-await-using-binding.js [typescript] format 1`] = `
"',' expected. (1:18)
> 1 | const m = module {
@@ -942,6 +951,15 @@ exports[`valid-module-block-top-level-using-binding.js [oxc] format 1`] = `
4 |"
`;
exports[`valid-module-block-top-level-using-binding.js [oxc-ts] format 1`] = `
"Expected a semicolon or an implicit semicolon after a statement, but found none (1:7)
> 1 | module {
| ^
2 | using foo = bar();
3 | }
4 |"
`;
exports[`valid-module-block-top-level-using-binding.js [typescript] format 1`] = `
"Namespace must be given a name. (1:8)
> 1 | module {
@@ -109,5 +109,11 @@ runFormatTest(import.meta, ["babel", "flow", "typescript"], {
"valid-module-block-top-level-using-binding.js",
"valid-module-block-top-level-await-using-binding.js",
],
"oxc-ts": [
// "invalid-duplicate-using-bindings.js",
// "invalid-script-top-level-using-binding.js",
"valid-module-block-top-level-using-binding.js",
"valid-module-block-top-level-await-using-binding.js",
],
},
});
@@ -1,3 +1,10 @@
runFormatTest(import.meta, ["babel", "flow"], {
errors: { acorn: true, espree: true, meriyah: true, flow: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
flow: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -4,5 +4,6 @@ runFormatTest(import.meta, ["babel"], {
espree: ["module-blocks.js", "range.js", "comments.js", "worker.js"],
meriyah: ["module-blocks.js", "range.js", "comments.js", "worker.js"],
oxc: ["module-blocks.js", "range.js", "comments.js", "worker.js"],
"oxc-ts": ["module-blocks.js", "range.js", "comments.js", "worker.js"],
},
});
@@ -56,6 +56,17 @@ exports[`text.js [oxc] format 1`] = `
9 | foo = foo\`\\u{prettier}\${foo}pr\\u{0065}ttier\`;"
`;
exports[`text.js [oxc-ts] format 1`] = `
"Bad escape sequence in untagged template literal (6:18)
4 | foo = markdown\`\\u{prettier}\\u{0065}\`;
5 | foo = css\`\\u{prettier}\\u{0065}\`;
> 6 | foo = /* HTML */\`\\u{prettier}\\u{0065}\`;
| ^^^^^^^^^^^^^^^^^^^^
7 | foo = /* GraphQL */\`\\u{prettier}\\u{0065}\`;
8 |
9 | foo = foo\`\\u{prettier}\${foo}pr\\u{0065}ttier\`;"
`;
exports[`text.js [typescript] format 1`] = `
"Hexadecimal digit expected. (6:21)
4 | foo = markdown\`\\u{prettier}\\u{0065}\`;
@@ -6,5 +6,6 @@ runFormatTest(import.meta, ["babel", "flow", "typescript"], {
typescript: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -1,7 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
});
runFormatTest(import.meta, ["babel"], {
semi: false,
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
});
const errors = {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
};
runFormatTest(import.meta, ["babel"], { errors });
runFormatTest(import.meta, ["babel"], { semi: false, errors });
@@ -128,6 +128,17 @@ exports[`expression.js [oxc] format 1`] = `
8 | ({} = 0);"
`;
exports[`expression.js [oxc-ts] format 1`] = `
"Expected \`,\` but found \`:\` (5:4)
3 | a = () => ({}).x;
4 | ({} && a, b);
> 5 | ({}::b, 0);
| ^
6 | ({}::b()\`\`[''].c++ && 0 ? 0 : 0, 0);
7 | ({}(), 0);
8 | ({} = 0);"
`;
exports[`expression.js [typescript] format 1`] = `
"')' expected. (5:4)
3 | a = () => ({}).x;
+1
View File
@@ -5,6 +5,7 @@ runFormatTest(import.meta, ["babel", "typescript", "flow"], {
typescript: ["expression.js"],
meriyah: ["expression.js"],
oxc: ["expression.js"],
"oxc-ts": ["expression.js"],
flow: ["expression.js"],
},
});
@@ -32,6 +32,7 @@ runFormatTest(import.meta, ["babel"], {
...invalidSyntaxTests,
],
oxc: [...optionalChainingAssignTests, ...invalidSyntaxTests],
"oxc-ts": [...optionalChainingAssignTests, ...invalidSyntaxTests],
babel: invalidSyntaxTests,
__babel_estree: invalidSyntaxTests,
},
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
@@ -14,6 +14,7 @@ runFormatTest(import.meta, ["babel"], {
espree: [...importSourceTests, ...invalidSyntaxTests],
meriyah: [...importSourceTests, ...invalidSyntaxTests],
oxc: invalidSyntaxTests,
"oxc-ts": invalidSyntaxTests,
babel: invalidSyntaxTests,
__babel_estree: invalidSyntaxTests,
},
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
+7 -1
View File
@@ -1,3 +1,9 @@
runFormatTest(import.meta, ["babel"], {
errors: { acorn: true, espree: true, meriyah: true, oxc: true },
errors: {
acorn: true,
espree: true,
meriyah: true,
oxc: true,
"oxc-ts": true,
},
});
+1
View File
@@ -4,5 +4,6 @@ runFormatTest(import.meta, ["babel"], {
espree: ["do.js"],
meriyah: ["do.js"],
oxc: ["do.js"],
"oxc-ts": ["do.js"],
},
});
@@ -34,6 +34,17 @@ abstract class Bar {
================================================================================
`;
exports[`constructor.ts [oxc-ts] format 1`] = `
"Classes can't have a field named 'constructor' (8:5)
6 |
7 | class A {
> 8 | 'constructor': typeof A
| ^^^^^^^^^^^^^
9 | static Foo() {
10 | return new A()
11 | }"
`;
exports[`constructor.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
+8 -1
View File
@@ -1 +1,8 @@
runFormatTest(import.meta, ["typescript"]);
runFormatTest(import.meta, ["typescript"], {
errors: {
"oxc-ts": [
// TODO: Ask typescript-eslint to throw
"constructor.ts",
],
},
});
@@ -509,6 +509,15 @@ exports[`readonlyReadonly.ts [babel-ts] format 1`] = `
Cause: Duplicate modifier: 'readonly'. (2:13)"
`;
exports[`readonlyReadonly.ts [oxc-ts] format 1`] = `
"readonly' modifier already seen. (2:14)
1 | class C {
> 2 | readonly readonly x: number;
| ^^^^^^^^
3 | constructor(readonly readonly y: number) {}
4 | }"
`;
exports[`readonlyReadonly.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1,5 +1,6 @@
runFormatTest(import.meta, ["typescript"], {
errors: {
"babel-ts": ["readonlyInConstructorParameters.ts", "readonlyReadonly.ts"],
"oxc-ts": ["readonlyReadonly.ts"],
},
});
@@ -603,6 +603,16 @@ exports[`functionOverloadErrorsSyntax.ts [babel-ts] format 1`] = `
Cause: Rest element must be last element. (9:35)"
`;
exports[`functionOverloadErrorsSyntax.ts [oxc-ts] format 1`] = `
"A rest parameter must be last in a parameter list (9:25)
7 |
8 | //Function overload signature with rest param followed by non-optional parameter
> 9 | function fn5(x: string, ...y: any[], z: string);
| ^^^^^^^^^^^
10 | function fn5() { }
11 |"
`;
exports[`functionOverloadErrorsSyntax.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1,3 +1,6 @@
runFormatTest(import.meta, ["typescript"], {
errors: { "babel-ts": ["functionOverloadErrorsSyntax.ts"] },
errors: {
"babel-ts": ["functionOverloadErrorsSyntax.ts"],
"oxc-ts": ["functionOverloadErrorsSyntax.ts"],
},
});
@@ -1,6 +1,7 @@
runFormatTest(import.meta, ["typescript"], {
errors: {
typescript: ["abstract-method.ts"],
"oxc-ts": ["abstract-method.ts"],
"babel-ts": ["issue-9102.ts"],
},
});
@@ -11,6 +11,16 @@ exports[`computed-members.ts [babel-ts] format 1`] = `
Cause: Unexpected token (2:2)"
`;
exports[`computed-members.ts [oxc-ts] format 1`] = `
"Computed property names are not allowed in enums. (2:4)
1 | enum A {
> 2 | [i++],
| ^^^
3 | }
4 |
5 | const bar = "bar""
`;
exports[`computed-members.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1,5 +1,6 @@
runFormatTest(import.meta, ["typescript"], {
errors: {
"babel-ts": ["computed-members.ts"],
"oxc-ts": ["computed-members.ts"],
},
});
@@ -1,5 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`generic.ts [oxc-ts] format 1`] = `
"Type parameters cannot appear on a constructor declaration (8:16)
6 |
7 | class f4 {
> 8 | constructor<>() {}
| ^^
9 | }
10 |
11 | const f5 = function<>() {}"
`;
exports[`generic.ts - {"trailingComma":"all"} [oxc-ts] format 1`] = `
"Type parameters cannot appear on a constructor declaration (8:16)
6 |
7 | class f4 {
> 8 | constructor<>() {}
| ^^
9 | }
10 |
11 | const f5 = function<>() {}"
`;
exports[`generic.ts - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -51,6 +73,17 @@ class f7<> {
================================================================================
`;
exports[`generic.ts - {"trailingComma":"es5"} [oxc-ts] format 1`] = `
"Type parameters cannot appear on a constructor declaration (8:16)
6 |
7 | class f4 {
> 8 | constructor<>() {}
| ^^
9 | }
10 |
11 | const f5 = function<>() {}"
`;
exports[`generic.ts - {"trailingComma":"es5"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -164,6 +197,15 @@ exports[`index-signature.ts [babel-ts] format 1`] = `
Cause: Unexpected token, expected "]" (4:12)"
`;
exports[`index-signature.ts [oxc-ts] format 1`] = `
"Unexpected token (1:26)
> 1 | type A = { [key: string] };
| ^
2 |
3 | type TwoParams = {
4 | [a: string, b: string]: string;"
`;
exports[`index-signature.ts - {"trailingComma":"all"} [babel-ts] format 1`] = `
"Unexpected token, expected "]" (4:13)
2 |
@@ -176,6 +218,15 @@ exports[`index-signature.ts - {"trailingComma":"all"} [babel-ts] format 1`] = `
Cause: Unexpected token, expected "]" (4:12)"
`;
exports[`index-signature.ts - {"trailingComma":"all"} [oxc-ts] format 1`] = `
"Unexpected token (1:26)
> 1 | type A = { [key: string] };
| ^
2 |
3 | type TwoParams = {
4 | [a: string, b: string]: string;"
`;
exports[`index-signature.ts - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -251,6 +302,15 @@ exports[`index-signature.ts - {"trailingComma":"es5"} [babel-ts] format 1`] = `
Cause: Unexpected token, expected "]" (4:12)"
`;
exports[`index-signature.ts - {"trailingComma":"es5"} [oxc-ts] format 1`] = `
"Unexpected token (1:26)
> 1 | type A = { [key: string] };
| ^
2 |
3 | type TwoParams = {
4 | [a: string, b: string]: string;"
`;
exports[`index-signature.ts - {"trailingComma":"es5"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -386,6 +446,15 @@ exports[`jsdoc_only_types.ts [babel-ts] format 1`] = `
Cause: Unexpected token (1:7)"
`;
exports[`jsdoc_only_types.ts [oxc-ts] format 1`] = `
"Unexpected token (1:8)
> 1 | let a: *;
| ^
2 | function b(x: ?) {}
3 | let c: ?string;
4 | let d: string?;"
`;
exports[`jsdoc_only_types.ts - {"trailingComma":"all"} [babel-ts] format 1`] = `
"Unexpected token (1:8)
> 1 | let a: *;
@@ -396,6 +465,15 @@ exports[`jsdoc_only_types.ts - {"trailingComma":"all"} [babel-ts] format 1`] = `
Cause: Unexpected token (1:7)"
`;
exports[`jsdoc_only_types.ts - {"trailingComma":"all"} [oxc-ts] format 1`] = `
"Unexpected token (1:8)
> 1 | let a: *;
| ^
2 | function b(x: ?) {}
3 | let c: ?string;
4 | let d: string?;"
`;
exports[`jsdoc_only_types.ts - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -435,6 +513,15 @@ exports[`jsdoc_only_types.ts - {"trailingComma":"es5"} [babel-ts] format 1`] = `
Cause: Unexpected token (1:7)"
`;
exports[`jsdoc_only_types.ts - {"trailingComma":"es5"} [oxc-ts] format 1`] = `
"Unexpected token (1:8)
> 1 | let a: *;
| ^
2 | function b(x: ?) {}
3 | let c: ?string;
4 | let d: string?;"
`;
exports[`jsdoc_only_types.ts - {"trailingComma":"es5"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1,4 +1,12 @@
const errors = { "babel-ts": ["jsdoc_only_types.ts", "index-signature.ts"] };
const errors = {
"babel-ts": ["jsdoc_only_types.ts", "index-signature.ts"],
"oxc-ts": [
"jsdoc_only_types.ts",
"index-signature.ts",
// TODO: Ask typescript-eslint to throw
"generic.ts",
],
};
runFormatTest(import.meta, ["typescript"], { errors });
runFormatTest(import.meta, ["typescript"], { trailingComma: "es5", errors });
runFormatTest(import.meta, ["typescript"], { trailingComma: "all", errors });
@@ -10,6 +10,15 @@ exports[`invalid-await.ts [babel-ts] format 1`] = `
Cause: 'await' is only allowed within async functions and at the top levels of modules. (2:12)"
`;
exports[`invalid-await.ts [oxc-ts] format 1`] = `
"\`await\` is only allowed within async functions and at the top levels of modules (2:13)
1 | namespace N {
> 2 | const x = await 42;
| ^^^^^
3 | }
4 |"
`;
exports[`invalid-await.ts format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1 +1,3 @@
runFormatTest(import.meta, ["typescript"], { errors: { "babel-ts": true } });
runFormatTest(import.meta, ["typescript"], {
errors: { "babel-ts": true, "oxc-ts": true },
});
@@ -63,6 +63,16 @@ const f2 = <
================================================================================
`;
exports[`trailing.ts - {"trailingComma":"all"} [oxc-ts] format 1`] = `
"Unexpected trailing comma after rest element (15:10)
13 | longKeySoThisWillGoOnMultipleLines2,
14 | longKeySoThisWillGoOnMultipleLines3,
> 15 | ...rest,
| ^
16 | } = something;
17 |"
`;
exports[`trailing.ts - {"trailingComma":"all"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -107,6 +117,16 @@ const {
================================================================================
`;
exports[`trailing.ts - {"trailingComma":"es5"} [oxc-ts] format 1`] = `
"Unexpected trailing comma after rest element (15:10)
13 | longKeySoThisWillGoOnMultipleLines2,
14 | longKeySoThisWillGoOnMultipleLines3,
> 15 | ...rest,
| ^
16 | } = something;
17 |"
`;
exports[`trailing.ts - {"trailingComma":"es5"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -151,6 +171,16 @@ const {
================================================================================
`;
exports[`trailing.ts - {"trailingComma":"none"} [oxc-ts] format 1`] = `
"Unexpected trailing comma after rest element (15:10)
13 | longKeySoThisWillGoOnMultipleLines2,
14 | longKeySoThisWillGoOnMultipleLines3,
> 15 | ...rest,
| ^
16 | } = something;
17 |"
`;
exports[`trailing.ts - {"trailingComma":"none"} format 1`] = `
====================================options=====================================
parsers: ["typescript"]
@@ -1,3 +1,7 @@
runFormatTest(import.meta, ["typescript"], { trailingComma: "all" });
runFormatTest(import.meta, ["typescript"], { trailingComma: "es5" });
runFormatTest(import.meta, ["typescript"], { trailingComma: "none" });
const errors = {
"oxc-ts": ["trailing.ts"],
};
runFormatTest(import.meta, ["typescript"], { trailingComma: "all", errors });
runFormatTest(import.meta, ["typescript"], { trailingComma: "es5", errors });
runFormatTest(import.meta, ["typescript"], { trailingComma: "none", errors });
@@ -42,6 +42,13 @@ printWidth: 80
================================================================================
`;
exports[`3.ts [oxc-ts] format 1`] = `
"Expected \`{\` but found \`<<\` (1:17)
> 1 | (class extends f<<T>(v: T) => void> {});
| ^^
2 |"
`;
exports[`3.ts [typescript] format 1`] = `
"',' expected. (1:17)
> 1 | (class extends f<<T>(v: T) => void> {});
@@ -81,6 +88,13 @@ printWidth: 80
================================================================================
`;
exports[`5.tsx [oxc-ts] format 1`] = `
"Unexpected token (1:11)
> 1 | <Component<<T>(v: T) => void> />
| ^^
2 |"
`;
exports[`5.tsx [typescript] format 1`] = `
"Identifier expected. (1:11)
> 1 | <Component<<T>(v: T) => void> />
@@ -1,3 +1,3 @@
runFormatTest(import.meta, ["typescript"], {
errors: { typescript: ["3.ts", "5.tsx"] },
errors: { typescript: ["3.ts", "5.tsx"], "oxc-ts": ["3.ts", "5.tsx"] },
});