104 lines
2.9 KiB
TypeScript
104 lines
2.9 KiB
TypeScript
/**
|
|
* @wrnexus/compiler — the `.wrn` language compiler.
|
|
*
|
|
* Parsing and language diagnostics are provided by the canonical
|
|
* `@wrnexus/syntax` package. This package owns platform-specific codegen.
|
|
*/
|
|
|
|
import {
|
|
assertValidAst,
|
|
diagnose,
|
|
diagnosticFromError,
|
|
formatDiagnostic,
|
|
parse,
|
|
ParseError,
|
|
type PageAst,
|
|
type WrnDiagnostic,
|
|
} from "@wrnexus/syntax";
|
|
import { generate } from "./codegen.ts";
|
|
import { generateNative } from "./native-codegen.ts";
|
|
|
|
export {
|
|
assertValidAst,
|
|
diagnose,
|
|
diagnosticFromError,
|
|
formatDiagnostic,
|
|
parse,
|
|
ParseError,
|
|
} from "@wrnexus/syntax";
|
|
export { generate } from "./codegen.ts";
|
|
export { generateNative, NativeCompileError } from "./native-codegen.ts";
|
|
export { Lexer, LexError } from "@wrnexus/syntax";
|
|
export { eraseFunctionTypes, inferredRuntimeType, runtimeTypeOf } from "@wrnexus/syntax";
|
|
export type {
|
|
ActionBlock,
|
|
ApiBlock,
|
|
Attr,
|
|
ComputedDecl,
|
|
DataApiBlock,
|
|
DataMode,
|
|
EffectBlock,
|
|
EventDecl,
|
|
LoadBlock,
|
|
ModeFunctionsBlock,
|
|
PageAst,
|
|
PropDecl,
|
|
RealtimeBlock,
|
|
SeoBlock,
|
|
StateDecl,
|
|
ViewNode,
|
|
WrnDiagnostic,
|
|
} from "@wrnexus/syntax";
|
|
|
|
export interface CompileResult {
|
|
code: string;
|
|
ast: PageAst;
|
|
/** Backward-compatible plain diagnostic messages. */
|
|
diagnostics: string[];
|
|
/** Structured diagnostics for editors, CI, and the DevToolbar. */
|
|
richDiagnostics: WrnDiagnostic[];
|
|
}
|
|
|
|
/** Compile `.wrn` source into an Expo Router React Native screen. */
|
|
export function compileNativeWireFile(source: string): string {
|
|
const ast = parse(source);
|
|
assertValidAst(ast);
|
|
return generateNative(ast);
|
|
}
|
|
|
|
/**
|
|
* Compile `.wrn` source into TypeScript source. Errors include a stable code,
|
|
* source location, code frame, and actionable hint whenever available.
|
|
*/
|
|
export function compileWireFile(source: string, filePath = "<inline .wrn>"): string {
|
|
try {
|
|
const ast = parse(source);
|
|
assertValidAst(ast, { file: filePath, accessibility: true });
|
|
return `// compiled from .wrn\n${generate(ast)}`;
|
|
} catch (error) {
|
|
const diagnostic = diagnosticFromError(source, error, { file: filePath });
|
|
throw new Error(`Failed to parse ${filePath}:\n\n${formatDiagnostic(source, diagnostic)}`, {
|
|
cause: error,
|
|
});
|
|
}
|
|
}
|
|
|
|
/** Richer entry point returning the AST and structured diagnostics. */
|
|
export function compile(source: string, filePath = "<inline .wrn>"): CompileResult {
|
|
const richDiagnostics = diagnose(source, { file: filePath, accessibility: true });
|
|
const errors = richDiagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
if (errors.length > 0) {
|
|
throw new ParseError(
|
|
errors.map((diagnostic) => diagnostic.message).join("\n"),
|
|
errors[0]!.code,
|
|
);
|
|
}
|
|
const ast = parse(source);
|
|
return {
|
|
code: `// compiled from .wrn\n${generate(ast)}`,
|
|
ast,
|
|
diagnostics: richDiagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`),
|
|
richDiagnostics,
|
|
};
|
|
}
|