feat: added syntax check

This commit is contained in:
2026-02-23 21:38:12 +01:00
parent e68e845e70
commit 7cc2f7cab2
14 changed files with 507 additions and 10 deletions

View File

@@ -1,5 +1,6 @@
import { createPythonRuntimeWorker } from './createPythonRuntimeWorker';
import type { PythonWorkerMessage, PythonWorkerRequest } from './runtimeProtocol';
import type { PythonSyntaxError } from './runtimeProtocol';
import { parseMacroContextV1, parseMacroResultV1, type MacroContextV1, type MacroResultV1 } from './abiV1';
type WorkerFactory = () => Worker;
@@ -10,9 +11,9 @@ interface InitializeDeferred {
}
interface PendingRun {
kind: 'run' | 'macro-v1' | 'inspect-entrypoints';
kind: 'run' | 'macro-v1' | 'inspect-entrypoints' | 'syntax-check';
stdout: string;
resolve: (value: PythonRunResult | PythonMacroV1Result | string[]) => void;
resolve: (value: PythonRunResult | PythonMacroV1Result | string[] | PythonSyntaxCheckResult) => void;
reject: (error: Error) => void;
timeoutId: ReturnType<typeof setTimeout> | null;
}
@@ -43,6 +44,10 @@ export interface PythonMacroV1Result {
stdout: string;
}
export interface PythonSyntaxCheckResult {
errors: PythonSyntaxError[];
}
export class PythonRuntimeManager {
private worker: Worker | null = null;
private initializingPromise: Promise<void> | null = null;
@@ -197,6 +202,42 @@ export class PythonRuntimeManager {
});
}
async syntaxCheck(code: string, options?: PythonExecuteOptions): Promise<PythonSyntaxCheckResult> {
await this.initialize();
if (!this.worker || !this.ready) {
throw new Error('Python runtime is not ready');
}
const requestId = this.nextRequestId();
const timeoutMs = options?.timeoutMs ?? 5000;
return new Promise<PythonSyntaxCheckResult>((resolve, reject) => {
const timeoutId = setTimeout(() => {
this.pendingRuns.delete(requestId);
this.resetRuntime(`Python script execution timed out after ${timeoutMs}ms`);
reject(new Error(`Python script execution timed out after ${timeoutMs}ms`));
}, timeoutMs);
this.pendingRuns.set(requestId, {
kind: 'syntax-check',
stdout: '',
resolve: (value) => resolve(value as PythonSyntaxCheckResult),
reject,
timeoutId,
});
const message: PythonWorkerRequest = {
type: 'syntaxCheck',
requestId,
code,
cacheKey: options?.cacheKey,
};
this.worker!.postMessage(message);
});
}
isReady(): boolean {
return this.ready;
}
@@ -252,6 +293,15 @@ export class PythonRuntimeManager {
return;
}
if (payload.type === 'syntaxResult') {
if (pendingRun.kind !== 'syntax-check') {
pendingRun.reject(new Error('Invalid response type for pending syntax check request'));
return;
}
pendingRun.resolve({ errors: payload.errors });
return;
}
if (payload.type === 'macroResult') {
if (pendingRun.kind !== 'macro-v1') {
pendingRun.reject(new Error('Invalid response type for pending run request'));