mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
Native SDK preparation transformed declarations separately for diagnostics, then repeated preflight and transformation during in-memory emission. Keep configuration and requested semantic validation, collect declaration errors from EmitResult, and reject errors or skipped emission before publication. Remove the unused includeDeclaration diagnostic option. Measured cold Node 24 preparation fell from 156.294s to 89.817s; sampled process-group memory fell from 8.845 to 6.961 GiB. The existing 300-second limit and Go memory settings are unchanged. This removes proven duplicate work; it does not conclusively reproduce the historical CI timeout. Proof: real native tests reject TS4094 and lazy-global TS2318 in both modes, reject TS2322 in all mode, and accept valid declarations. Focused suite: 14 passed/3 platform skips, 6.176s wall. Sibling preparation and tsdown integration: 52 passed/7 platform skips. Changed-file checks, types/lint, and final independent review through P2 pass. The native API global-diagnostics handler already forces semantic checking before collecting fileless diagnostics; source inspection and real API probes resolve the apparent late-global diagnostic gap. Declaration member order and synthesized readonly modifiers vary across unchanged original compiler runs, so generated byte equivalence is not claimed.
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import type { Project as AsyncProject } from "typescript/unstable/async";
|
|
import { DiagnosticCategory, type Diagnostic, type Project } from "typescript/unstable/sync";
|
|
|
|
type DiagnosticOptions = { includeSemantic?: boolean };
|
|
|
|
function diagnosticQueries(options: DiagnosticOptions) {
|
|
return [
|
|
"getConfigFileParsingDiagnostics",
|
|
"getProgramDiagnostics",
|
|
"getGlobalDiagnostics",
|
|
"getSyntacticDiagnostics",
|
|
"getBindDiagnostics",
|
|
...(options.includeSemantic === false ? [] : ["getSemanticDiagnostics" as const]),
|
|
] as const;
|
|
}
|
|
|
|
function uniqueDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {
|
|
const seen = new Set<string>();
|
|
return diagnostics.filter((diagnostic) => {
|
|
const identity = JSON.stringify(diagnostic);
|
|
if (seen.has(identity)) {
|
|
return false;
|
|
}
|
|
seen.add(identity);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
/** Preserve compiler diagnostics across the native program's separate query surfaces. */
|
|
export function collectNativeTypeScriptDiagnostics(
|
|
project: Project,
|
|
options: DiagnosticOptions = {},
|
|
): Diagnostic[] {
|
|
return uniqueDiagnostics(diagnosticQueries(options).flatMap((query) => project.program[query]()));
|
|
}
|
|
|
|
export async function collectNativeTypeScriptDiagnosticsAsync(
|
|
project: AsyncProject,
|
|
options: DiagnosticOptions = {},
|
|
): Promise<Diagnostic[]> {
|
|
const diagnostics: Diagnostic[] = [];
|
|
for (const query of diagnosticQueries(options)) {
|
|
diagnostics.push(...(await project.program[query]()));
|
|
}
|
|
return uniqueDiagnostics(diagnostics);
|
|
}
|
|
|
|
export function formatNativeTypeScriptDiagnostics(diagnostics: readonly Diagnostic[]): string {
|
|
const format = (diagnostic: Diagnostic, indent = ""): string => {
|
|
const location = diagnostic.fileName
|
|
? `${diagnostic.fileName}${diagnostic.pos >= 0 ? `@${diagnostic.pos}` : ""}: `
|
|
: "";
|
|
const category = (DiagnosticCategory[diagnostic.category] ?? "Error").toLowerCase();
|
|
return [
|
|
`${indent}${location}${category} TS${diagnostic.code}: ${diagnostic.text}`,
|
|
...(diagnostic.messageChain ?? []).map((message) => format(message, `${indent} `)),
|
|
...(diagnostic.relatedInformation ?? []).map((message) => format(message, `${indent} `)),
|
|
].join("\n");
|
|
};
|
|
return diagnostics.map((diagnostic) => format(diagnostic)).join("\n");
|
|
}
|