fix(javascript): parse declaration artifacts in ambient mode
This commit is contained in:
1 parent
a0523b375e
commit
4896adcd0f
2 files changed
+63
-6
No files matched your search
@@ -0,0 +1,54 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
|
||||
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
|
||||
import { parseJavaScriptSource } from "../../domain/javascript/javascriptSourceParser.js";
|
||||
import { analyzeJavaScriptApplication } from "./JavaScriptApplicationService.js";
|
||||
|
||||
it.each(["types.d.ts", "types.d.mts", "types.d.cts"])(
|
||||
"keeps valid ambient declarations complete in %s",
|
||||
async (path) => {
|
||||
const root = await createTestTempDirectory("rea-declaration-file-");
|
||||
const source = "export const value: number;\n";
|
||||
await writeFile(join(root, path), source);
|
||||
const result = await analyzeJavaScriptApplication({
|
||||
input_path: root,
|
||||
format: "directory",
|
||||
});
|
||||
if (!result.ok) throw result.error;
|
||||
const analysis = javascriptApplicationAnalysisResultSchema.parse(
|
||||
result.value.normalized_result,
|
||||
);
|
||||
expect(analysis.graph.coverage.status).toBe("complete");
|
||||
expect(parseJavaScriptSource(source, path)?.errors).toEqual([]);
|
||||
},
|
||||
);
|
||||
|
||||
it("retains the missing-initializer diagnostic for ordinary TypeScript", () => {
|
||||
const errors = parseJavaScriptSource(
|
||||
"export const value: number;",
|
||||
"types.ts",
|
||||
)?.errors;
|
||||
expect(errors?.map(({ message }) => message)).toContain(
|
||||
"Missing initializer in const declaration. (1:26)",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps CommonJS TypeScript angle-bracket assertions complete", async () => {
|
||||
const root = await createTestTempDirectory("rea-cts-assertion-");
|
||||
const source = "export const value = <number>42;\n";
|
||||
await writeFile(join(root, "app.cts"), source);
|
||||
const result = await analyzeJavaScriptApplication({
|
||||
input_path: root,
|
||||
format: "directory",
|
||||
});
|
||||
if (!result.ok) throw result.error;
|
||||
const analysis = javascriptApplicationAnalysisResultSchema.parse(
|
||||
result.value.normalized_result,
|
||||
);
|
||||
expect(analysis.graph.coverage.status).toBe("complete");
|
||||
expect(parseJavaScriptSource(source, "app.cts")?.errors).toEqual([]);
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { parse } from "@babel/parser";
|
||||
import { parse, type ParserPlugin } from "@babel/parser";
|
||||
|
||||
/** Babel AST produced by REA's inert JavaScript parser boundary. */
|
||||
export type ParsedJavaScriptSource = ReturnType<typeof parse>;
|
||||
@@ -8,6 +8,10 @@ export const parseJavaScriptSource = (
|
||||
source: string,
|
||||
sourcePath?: string,
|
||||
): ParsedJavaScriptSource | null => {
|
||||
const typescript: ParserPlugin = [
|
||||
"typescript",
|
||||
{ dts: /\.d\.(?:ts|mts|cts)$/iu.test(sourcePath ?? "") },
|
||||
];
|
||||
try {
|
||||
return parse(source, {
|
||||
sourceType: "unambiguous",
|
||||
@@ -17,12 +21,11 @@ export const parseJavaScriptSource = (
|
||||
// forms, including parameter decorators. Without it a decorated
|
||||
// TypeScript source fails to parse at all rather than reporting
|
||||
// recovered syntax, which loses every fact derived from that source.
|
||||
// Plain .ts artifacts admit angle-bracket type assertions instead of JSX.
|
||||
// Plain .ts and .cts artifacts admit angle-bracket type assertions instead of JSX.
|
||||
// Unknown paths retain the existing JSX-capable parser contract.
|
||||
plugins:
|
||||
sourcePath?.toLowerCase().endsWith(".ts") === true
|
||||
? ["decorators-legacy", "typescript"]
|
||||
: ["decorators-legacy", "jsx", "typescript"],
|
||||
plugins: /\.(?:ts|cts)$/iu.test(sourcePath ?? "")
|
||||
? ["decorators-legacy", typescript]
|
||||
: ["decorators-legacy", "jsx", typescript],
|
||||
});
|
||||
} catch (cause: unknown) {
|
||||
// Unparseable source is represented by the null return.
|
||||
|
||||
Reference in new issue
Block a user