mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-15 06:39:17 +00:00
feat(packages/codegen)!: printSync return an object (#25720)
`oxc-codegen`'s current API requires passing in a `SourceMapGenerator` as an option to generate source maps. This is currently really slow, and I imagine we'll want to generate source maps internally (perhaps in Rust), and return a source map string from `printSync` instead.
Alter `printSync`'s return type now, to support that without a breaking change later.
- Before: `function printSync(node: ESTree.Node, options?: Options): string`
- After: `function printSync(node: ESTree.Node, options?: Options): { code: string }`
Later on, it can return `{ code: string, map: string }` and that won't break existing users.
This commit is contained in:
1 parent
1cbbcb7c3e
commit
365274ea16
6 files changed
+23
-21
No files matched your search
@@ -26,7 +26,7 @@ import { printSync } from "oxc-codegen";
|
||||
import { parseSync } from "oxc-parser";
|
||||
|
||||
const { program } = parseSync("input.js", "const answer=6*7");
|
||||
const code = printSync(program);
|
||||
const { code } = printSync(program);
|
||||
|
||||
console.log(code);
|
||||
// const answer = 6 * 7;
|
||||
@@ -57,7 +57,7 @@ const program = {
|
||||
],
|
||||
};
|
||||
|
||||
console.log(printSync(program));
|
||||
console.log(printSync(program).code);
|
||||
// console.log("Hello!");
|
||||
```
|
||||
|
||||
@@ -68,7 +68,7 @@ Set `ts` when the AST can contain TypeScript nodes. For TSX, set both `ts` and `
|
||||
```js
|
||||
const { program } = parseSync("component.tsx", "const Box = <T,>(value: T) => <div>{value}</div>");
|
||||
|
||||
const code = printSync(program, {
|
||||
const { code } = printSync(program, {
|
||||
ts: true,
|
||||
jsx: true,
|
||||
});
|
||||
@@ -79,7 +79,7 @@ const code = printSync(program, {
|
||||
### `printSync(node, options?)`
|
||||
|
||||
```ts
|
||||
function printSync(node: Node, options?: Options): string;
|
||||
function printSync(node: Node, options?: Options): { code: string };
|
||||
```
|
||||
|
||||
Prints a complete `Program` or a single statement and returns the generated source code.
|
||||
|
||||
@@ -59,9 +59,9 @@ const printers: (PrintModule["printSync"] | null)[] = [null, null, null, null];
|
||||
*
|
||||
* @param node - AST node to print, a `Program` or a single statement
|
||||
* @param options - Printing options (optional)
|
||||
* @returns Generated code
|
||||
* @returns Object holding the generated code
|
||||
*/
|
||||
export function printSync(node: ESTree.Node, options?: Options): string {
|
||||
export function printSync(node: ESTree.Node, options?: Options): { code: string } {
|
||||
// The printer is built 4 times, over whether the AST may contain TypeScript and whether
|
||||
// source mappings are wanted. This picks the build the options call for and loads it on first use,
|
||||
// so a caller printing only JavaScript never pays for the TypeScript printers.
|
||||
|
||||
@@ -23,11 +23,13 @@ import type * as ESTree from "../../../../npm/oxc-types/types.d.ts";
|
||||
* One of these exists per build. The package entry point picks the build and calls it -
|
||||
* callers of the package never reach this directly.
|
||||
*
|
||||
* The result is an object so that further outputs (a source map) can be added without a breaking change.
|
||||
*
|
||||
* @param state - Created by the entry point, so that all 4 builds share one class and so one object shape
|
||||
* @param options - The same options `state` was created from, for the parts only this build acts on
|
||||
* @returns Generated code
|
||||
* @returns Object holding the generated code
|
||||
*/
|
||||
export function printSync(node: ESTree.Node, state: State, options: Options): string {
|
||||
export function printSync(node: ESTree.Node, state: State, options: Options): { code: string } {
|
||||
if (node.type === "Program") {
|
||||
printProgram(node, state);
|
||||
} else {
|
||||
@@ -45,7 +47,7 @@ export function printSync(node: ESTree.Node, state: State, options: Options): st
|
||||
emitMappings(state, options.sourceMap);
|
||||
}
|
||||
|
||||
return state.output;
|
||||
return { code: state.output };
|
||||
}
|
||||
|
||||
export type { Mapping, Options, Position, SourceMapGenerator } from "./options.ts";
|
||||
@@ -101,7 +101,7 @@ type Case = [name: string, ast: ESTree.Node, output: string];
|
||||
*/
|
||||
function checkCases(cases: Case[]): void {
|
||||
test.each(cases)("%s", (_name, ast, output) => {
|
||||
expect(printSync(ast)).toBe(output);
|
||||
expect(printSync(ast).code).toBe(output);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ describe("starting indent level", () => {
|
||||
const ast = e(id("x"));
|
||||
|
||||
test("indents from a valid level", () => {
|
||||
expect(printSync(ast, { startingIndentLevel: 1 })).toBe("\tx;\n");
|
||||
expect(printSync(ast, { startingIndentLevel: 1 }).code).toBe("\tx;\n");
|
||||
});
|
||||
|
||||
test("accepts the maximum level", () => {
|
||||
expect(printSync(ast, { startingIndentLevel: 1000 })).toBe(`${"\t".repeat(1000)}x;\n`);
|
||||
expect(printSync(ast, { startingIndentLevel: 1000 }).code).toBe(`${"\t".repeat(1000)}x;\n`);
|
||||
});
|
||||
|
||||
test.each([
|
||||
@@ -240,7 +240,7 @@ describe("strings", () => {
|
||||
PARSE_OPTIONS,
|
||||
);
|
||||
if (errors.length > 0) throw new Error(`fixture parse failed: ${errors[0].message}`);
|
||||
expect(printSync(parsed)).toBe("const value = `before <\\/ScRiPt> after`;\n");
|
||||
expect(printSync(parsed).code).toBe("const value = `before <\\/ScRiPt> after`;\n");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -333,7 +333,7 @@ describe("directives", () => {
|
||||
])("%s", (_name, source, output) => {
|
||||
const { program: parsed, errors } = parseSync("fixture.js", source, PARSE_OPTIONS);
|
||||
if (errors.length > 0) throw new Error(`fixture parse failed: ${errors[0].message}`);
|
||||
expect(printSync(parsed)).toBe(output);
|
||||
expect(printSync(parsed).code).toBe(output);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -376,7 +376,7 @@ describe("export default declarations", () => {
|
||||
])("%s", (_name, source, output) => {
|
||||
const { program: parsed, errors } = parseSync("fixture.ts", source, PARSE_OPTIONS);
|
||||
if (errors.length > 0) throw new Error(`fixture parse failed: ${errors[0].message}`);
|
||||
expect(printSync(parsed, { ts: true })).toBe(output);
|
||||
expect(printSync(parsed, { ts: true }).code).toBe(output);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -416,12 +416,12 @@ describe("JSX strings", () => {
|
||||
};
|
||||
|
||||
// From `raw`, as a parser supplies it
|
||||
expect(printSync(parse(), { jsx: true })).toBe(output);
|
||||
expect(printSync(parse(), { jsx: true }).code).toBe(output);
|
||||
|
||||
// From `value`, which is where a change in the parser would show
|
||||
const fromValue = parse();
|
||||
dropJsxRaw(fromValue);
|
||||
expect(printSync(fromValue, { jsx: true })).toBe(output);
|
||||
expect(printSync(fromValue, { jsx: true }).code).toBe(output);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -235,8 +235,8 @@ for (const fixture of FIXTURES) {
|
||||
|
||||
// Both builds through the public API - `printSync` picks the maps build when given a
|
||||
// `sourceMap`, and the no-maps build when not
|
||||
const withMaps = printSync(program, { jsx, ts, sourceMap: collector });
|
||||
const withoutMaps = printSync(program, { jsx, ts });
|
||||
const withMaps = printSync(program, { jsx, ts, sourceMap: collector }).code;
|
||||
const withoutMaps = printSync(program, { jsx, ts }).code;
|
||||
|
||||
printed = {
|
||||
withMaps,
|
||||
@@ -364,7 +364,7 @@ describe("indent option", () => {
|
||||
const out = printSync(program, {
|
||||
indent: indent as string | undefined,
|
||||
sourceMap: collector,
|
||||
});
|
||||
}).code;
|
||||
|
||||
const expectedIndent = typeof indent === "string" && /^[ \t]+$/.test(indent) ? indent : "\t";
|
||||
const lines = out.split("\n");
|
||||
|
||||
@@ -97,7 +97,7 @@ export function checkFixture(
|
||||
// rather than a printer one, and saying so is more use than a diff of printed output.
|
||||
expect(errors, "Rust parsed this fixture cleanly but `oxc-parser` did not").toEqual([]);
|
||||
|
||||
const actual = printSync(program, { ts, jsx });
|
||||
const actual = printSync(program, { ts, jsx }).code;
|
||||
expect(actual, `preserveParens: ${preserveParens}`).toBe(expected);
|
||||
checked = true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user