Skip to content

Commit d83e811

Browse files
committed
diagnosticディレクトリを削除
1 parent cfa2490 commit d83e811

5 files changed

Lines changed: 196 additions & 196 deletions

File tree

‎packages/runtime/src/diagnostics/index.ts‎

Lines changed: 0 additions & 2 deletions
This file was deleted.

‎packages/runtime/src/diagnostics/python.ts‎

Lines changed: 0 additions & 89 deletions
This file was deleted.

‎packages/runtime/src/diagnostics/ruby.ts‎

Lines changed: 0 additions & 100 deletions
This file was deleted.

‎packages/runtime/src/worker/pyodide.worker.ts‎

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import { loadPyodide } from "pyodide";
77
import { version as pyodideVersion } from "pyodide/package.json";
88
import type { PyCallable } from "pyodide/ffi";
99
import type { WorkerAPI, WorkerCapabilities } from "./runtime";
10-
import type { Diagnostic, ReplOutput, UpdatedFile } from "../interface";
11-
import { parsePythonTraceback } from "../diagnostics/python";
10+
import type {
11+
Diagnostic,
12+
DiagnosticFrame,
13+
ReplOutput,
14+
UpdatedFile,
15+
} from "../interface";
1216

1317
import execfile_py from "./pyodide/execfile.py?raw";
1418
import check_syntax_py from "./pyodide/check_syntax.py?raw";
@@ -176,7 +180,7 @@ async function runFile(
176180
.trim(),
177181
});
178182
if (onDiagnostic) {
179-
const diagnostics = parsePythonTraceback(e.message, HOME);
183+
const diagnostics = parsePythonTraceback(e.message);
180184
for (const diag of diagnostics) {
181185
await onDiagnostic(diag);
182186
}
@@ -227,6 +231,95 @@ async function restoreState(): Promise<object> {
227231
throw new Error("not implemented");
228232
}
229233

234+
/**
235+
* Parses Python error/traceback string into a single Diagnostic with multiple frames.
236+
*
237+
* @param traceback - The traceback string or error message from Python
238+
* @returns Array of Diagnostic objects (at most 1 per error)
239+
*/
240+
export function parsePythonTraceback(traceback: string): Diagnostic[] {
241+
if (!traceback) return [];
242+
243+
const lines = traceback.trim().split("\n");
244+
if (lines.length === 0) return [];
245+
246+
// Extract the last error message line (e.g., "Exception: This is a test error" or "SyntaxError: ...")
247+
let errorMessage = "";
248+
for (let i = lines.length - 1; i >= 0; i--) {
249+
const line = lines[i].trim();
250+
if (
251+
line &&
252+
!line.startsWith("^") &&
253+
!line.startsWith('File "') &&
254+
!line.startsWith("Traceback")
255+
) {
256+
errorMessage = line;
257+
break;
258+
}
259+
}
260+
261+
const frames: DiagnosticFrame[] = [];
262+
const fileLineRegex = /File "([^"]+)", line (\d+)(?:, in (.+))?/;
263+
264+
for (let i = 0; i < lines.length; i++) {
265+
const match = fileLineRegex.exec(lines[i]);
266+
if (match) {
267+
let rawFilename = match[1];
268+
const lineNum = parseInt(match[2], 10);
269+
270+
// Normalize filename by removing homePrefix or leading slashes
271+
if (rawFilename.startsWith(HOME)) {
272+
rawFilename = rawFilename.slice(HOME.length);
273+
}
274+
if (rawFilename.startsWith("/")) {
275+
rawFilename = rawFilename.replace(/^\/+/, "");
276+
}
277+
278+
// Ignore internal names like <exec>, <string> if not matching normal files
279+
if (rawFilename === "<exec>" || rawFilename === "<string>") {
280+
continue;
281+
}
282+
283+
// Check if there is a column indicator on subsequent lines (e.g. for SyntaxError with ^)
284+
let startColumn: number | undefined = undefined;
285+
let endColumn: number | undefined = undefined;
286+
for (let j = i + 1; j < Math.min(i + 4, lines.length); j++) {
287+
const nextLine = lines[j];
288+
if (fileLineRegex.test(nextLine)) break;
289+
const caretIndex = nextLine.indexOf("^");
290+
if (caretIndex !== -1) {
291+
// In Python SyntaxError output, caret points to character (1-indexed)
292+
startColumn = caretIndex + 1;
293+
const caretEnd = nextLine.lastIndexOf("^");
294+
if (caretEnd > caretIndex) {
295+
endColumn = caretEnd + 2;
296+
}
297+
break;
298+
}
299+
}
300+
301+
frames.push({
302+
filename: rawFilename,
303+
startLineNumber: lineNum,
304+
startColumn,
305+
endLineNumber: lineNum,
306+
endColumn,
307+
});
308+
}
309+
}
310+
311+
if (frames.length === 0) return [];
312+
313+
// Return a single Diagnostic with all frames (1 error = 1 Diagnostic)
314+
return [
315+
{
316+
frames,
317+
message: errorMessage,
318+
severity: "error",
319+
},
320+
];
321+
}
322+
230323
const api: WorkerAPI = {
231324
init,
232325
runCode,

0 commit comments

Comments
 (0)