Last active
September 2, 2024 01:52
-
-
Save leaysgur/f4ac50a45645967a0f4bdb38112c3212 to your computer and use it in GitHub Desktop.
Try to use `oxc-parser` as Prettier parser for `estree` printer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { format, __debug } from "./standalone.js"; | |
import * as meriyahPlugin from "./src/plugins/meriyah.js"; | |
import * as oxcPlugin from "./src/plugins/oxc.js"; | |
import * as estreePlugin from "./src/plugins/estree.js"; | |
const plugins = [estreePlugin, meriyahPlugin, oxcPlugin]; | |
const source = ` | |
// 1 | |
let a | |
= 42 // 2 | |
`.trim(); | |
for (const parser of ["meriyah", "oxc"]) { | |
console.log(`🦄 ${parser}`); | |
const ast = await __debug.parse(source, { parser, plugins }); | |
console.log(JSON.stringify(ast, null, 2)); | |
const doc = await __debug.printToDoc(source, { parser, plugins }); | |
console.log(JSON.stringify(doc, null, 2)); | |
const formatted = await format(source, { parser, plugins }); | |
console.log(["```", formatted, "```"].join("\n")); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/language-js/parse/oxc.js b/src/language-js/parse/oxc.js | |
new file mode 100644 | |
index 000000000..fbfada4ee | |
--- /dev/null | |
+++ b/src/language-js/parse/oxc.js | |
@@ -0,0 +1,71 @@ | |
+import { parseSync as oxcParse } from "oxc-parser"; | |
+ | |
+import createError from "../../common/parser-create-error.js"; | |
+import postprocess from "./postprocess/index.js"; | |
+import createParser from "./utils/create-parser.js"; | |
+import getSourceType from "./utils/get-source-type.js"; | |
+ | |
+const parseOptions = { | |
+ preserveParens: true, | |
+}; | |
+ | |
+function parseWithOptions(text, sourceType) { | |
+ const { program, comments, errors } = oxcParse(text, { | |
+ sourceType, | |
+ ...parseOptions, | |
+ }); | |
+ | |
+ if (errors.length !== 0) throw new Error(errors[0]); | |
+ | |
+ const ast = JSON.parse(program); | |
+ ast.comments = comments.map((comment) => ({ | |
+ ...comment, | |
+ start: comment.start - 2, | |
+ })); | |
+ | |
+ return ast; | |
+} | |
+ | |
+// TODO: Not sure | |
+function createParseError(error) { | |
+ let { message, line, column } = error; | |
+ | |
+ const matches = message.match( | |
+ /^\[(?<line>\d+):(?<column>\d+)\]: (?<message>.*)$/u, | |
+ )?.groups; | |
+ | |
+ if (matches) { | |
+ message = matches.message; | |
+ | |
+ /* c8 ignore next 4 */ | |
+ if (typeof line !== "number") { | |
+ line = Number(matches.line); | |
+ column = Number(matches.column); | |
+ } | |
+ } | |
+ | |
+ /* c8 ignore next 3 */ | |
+ if (typeof line !== "number") { | |
+ return error; | |
+ } | |
+ | |
+ return createError(message, { | |
+ loc: { start: { line, column } }, | |
+ cause: error, | |
+ }); | |
+} | |
+ | |
+function parse(text, options = {}) { | |
+ const sourceType = getSourceType(options); | |
+ | |
+ let ast; | |
+ try { | |
+ ast = parseWithOptions(text, sourceType); | |
+ } catch (/** @type {any} */ { errors: [error] }) { | |
+ throw createParseError(error); | |
+ } | |
+ | |
+ return postprocess(ast, { parser: "oxc", text }); | |
+} | |
+ | |
+export const oxc = createParser(parse); | |
diff --git a/src/language-js/parse/postprocess/index.js b/src/language-js/parse/postprocess/index.js | |
index f148bc8b3..5bbdb56aa 100644 | |
--- a/src/language-js/parse/postprocess/index.js | |
+++ b/src/language-js/parse/postprocess/index.js | |
@@ -59,6 +59,18 @@ function postprocess(ast, options) { | |
}); | |
} | |
+ if (parser === "oxc") { | |
+ ast = visitNode(ast, (node) => { | |
+ // TODO: Other literals may need to be fixed too | |
+ if (node.type === "StringLiteral") { | |
+ node.extra = { raw: node.value }; | |
+ } | |
+ if (node.type === "NumericLiteral") { | |
+ node.extra = { raw: node.raw }; | |
+ } | |
+ }); | |
+ } | |
+ | |
ast = visitNode(ast, (node) => { | |
switch (node.type) { | |
case "LogicalExpression": | |
diff --git a/src/plugins/oxc.js b/src/plugins/oxc.js | |
new file mode 100644 | |
index 000000000..dfda20300 | |
--- /dev/null | |
+++ b/src/plugins/oxc.js | |
@@ -0,0 +1 @@ | |
+export * as parsers from "../language-js/parse/oxc.js"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not practical at all.
It works with
let a = 42;
but for other case, many AST modifications are still required...