diff --git a/packages/safe-ds-lang/src/language/runner/safe-ds-runner.ts b/packages/safe-ds-lang/src/language/runner/safe-ds-runner.ts index d7fc85463..fae5126d7 100644 --- a/packages/safe-ds-lang/src/language/runner/safe-ds-runner.ts +++ b/packages/safe-ds-lang/src/language/runner/safe-ds-runner.ts @@ -10,6 +10,7 @@ import { ProgramCodeMap, PythonServerMessage, RuntimeErrorBacktraceFrame, + RuntimeErrorMessage, } from './messages.js'; import { BasicSourceMapConsumer, SourceMapConsumer } from 'source-map'; import treeKill from 'tree-kill'; @@ -56,8 +57,60 @@ export class SafeDsRunner { outputInfo(_value: string) {}, displayError(_value: string) {}, }; + this.registerMessageLoggingCallbacks(); } + /* c8 ignore start */ + private registerMessageLoggingCallbacks() { + this.addMessageCallback((message) => { + this.logging.outputInfo( + `Placeholder value is (${message.id}): ${message.data.name} of type ${message.data.type} = ${message.data.value}`, + ); + }, 'placeholder_value'); + this.addMessageCallback((message) => { + this.logging.outputInfo( + `Placeholder was calculated (${message.id}): ${message.data.name} of type ${message.data.type}`, + ); + const execInfo = this.getExecutionContext(message.id)!; + execInfo.calculatedPlaceholders.set(message.data.name, message.data.type); + // this.sendMessageToPythonServer( + // messages.createPlaceholderQueryMessage(message.id, message.data.name), + //); + }, 'placeholder_type'); + this.addMessageCallback((message) => { + this.logging.outputInfo(`Runner-Progress (${message.id}): ${message.data}`); + }, 'runtime_progress'); + this.addMessageCallback(async (message) => { + let readableStacktraceSafeDs: string[] = []; + const execInfo = this.getExecutionContext(message.id)!; + const readableStacktracePython = await Promise.all( + (message).data.backtrace.map(async (frame) => { + const mappedFrame = await this.tryMapToSafeDSSource(message.id, frame); + if (mappedFrame) { + readableStacktraceSafeDs.push( + `\tat ${URI.file(execInfo.path)}#${mappedFrame.line} (${execInfo.path} line ${ + mappedFrame.line + })`, + ); + return `\tat ${frame.file} line ${frame.line} (mapped to '${mappedFrame.file}' line ${mappedFrame.line})`; + } + return `\tat ${frame.file} line ${frame.line}`; + }), + ); + this.logging.outputError( + `Runner-RuntimeError (${message.id}): ${ + (message).data.message + } \n${readableStacktracePython.join('\n')}`, + ); + this.logging.outputError( + `Safe-DS Error (${message.id}): ${(message).data.message} \n${readableStacktraceSafeDs + .reverse() + .join('\n')}`, + ); + }, 'runtime_error'); + } + /* c8 ignore stop */ + /** * Change the command to start the runner process. This will not cause the runner process to restart, if it is already running. * @@ -244,7 +297,7 @@ export class SafeDsRunner { * @param executionId Id that uniquely identifies the execution that produced this stack frame * @param frame Stack frame from the python execution */ - public async tryMapToSafeDSSource( + private async tryMapToSafeDSSource( executionId: string, frame: RuntimeErrorBacktraceFrame | undefined, ): Promise { diff --git a/packages/safe-ds-lang/src/language/safe-ds-module.ts b/packages/safe-ds-lang/src/language/safe-ds-module.ts index 0f76c9700..a3f8d69e4 100644 --- a/packages/safe-ds-lang/src/language/safe-ds-module.ts +++ b/packages/safe-ds-lang/src/language/safe-ds-module.ts @@ -78,6 +78,9 @@ export type SafeDsAddedServices = { purity: { PurityComputer: SafeDsPurityComputer; }; + runtime: { + Runner: SafeDsRunner; + }; typing: { ClassHierarchy: SafeDsClassHierarchy; CoreTypes: SafeDsCoreTypes; @@ -89,9 +92,6 @@ export type SafeDsAddedServices = { PackageManager: SafeDsPackageManager; SettingsProvider: SafeDsSettingsProvider; }; - runtime: { - Runner: SafeDsRunner; - }; }; /** @@ -151,6 +151,9 @@ export const SafeDsModule: Module new SafeDsScopeComputation(services), ScopeProvider: (services) => new SafeDsScopeProvider(services), }, + runtime: { + Runner: (services) => new SafeDsRunner(services), + }, typing: { ClassHierarchy: (services) => new SafeDsClassHierarchy(services), CoreTypes: (services) => new SafeDsCoreTypes(services), @@ -162,9 +165,6 @@ export const SafeDsModule: Module new SafeDsPackageManager(services), SettingsProvider: (services) => new SafeDsSettingsProvider(services), }, - runtime: { - Runner: (services) => new SafeDsRunner(services), - }, }; export type SafeDsSharedServices = LangiumSharedServices; diff --git a/packages/safe-ds-vscode/src/extension/mainClient.ts b/packages/safe-ds-vscode/src/extension/mainClient.ts index c3ceb5d4b..04874dce9 100644 --- a/packages/safe-ds-vscode/src/extension/mainClient.ts +++ b/packages/safe-ds-vscode/src/extension/mainClient.ts @@ -6,7 +6,7 @@ import { ast, createSafeDsServices, getModuleMembers, messages, SafeDsServices } import { NodeFileSystem } from 'langium/node'; import { getSafeDSOutputChannel, initializeLog, logError, logOutput, printOutputMessage } from './output.js'; import crypto from 'crypto'; -import { LangiumDocument, URI, AstUtils, AstNode } from 'langium'; +import { AstNode, AstUtils, LangiumDocument } from 'langium'; import { EDAPanel } from './eda/edaPanel.ts'; import { dumpDiagnostics } from './commands/dumpDiagnostics.js'; import { openDiagnosticsDumps } from './commands/openDiagnosticsDumps.js'; @@ -91,63 +91,12 @@ const startLanguageClient = function (context: vscode.ExtensionContext): Languag }; const acceptRunRequests = async function (context: vscode.ExtensionContext) { - // Register logging message callbacks - registerMessageLoggingCallbacks(); // Register VS Code Entry Points registerVSCodeCommands(context); // Register watchers registerVSCodeWatchers(); }; -const registerMessageLoggingCallbacks = function () { - services.runtime.Runner.addMessageCallback((message) => { - printOutputMessage( - `Placeholder value is (${message.id}): ${message.data.name} of type ${message.data.type} = ${message.data.value}`, - ); - }, 'placeholder_value'); - services.runtime.Runner.addMessageCallback((message) => { - printOutputMessage( - `Placeholder was calculated (${message.id}): ${message.data.name} of type ${message.data.type}`, - ); - const execInfo = services.runtime.Runner.getExecutionContext(message.id)!; - execInfo.calculatedPlaceholders.set(message.data.name, message.data.type); - // services.runtime.Runner.sendMessageToPythonServer( - // messages.createPlaceholderQueryMessage(message.id, message.data.name), - //); - }, 'placeholder_type'); - services.runtime.Runner.addMessageCallback((message) => { - printOutputMessage(`Runner-Progress (${message.id}): ${message.data}`); - }, 'runtime_progress'); - services.runtime.Runner.addMessageCallback(async (message) => { - let readableStacktraceSafeDs: string[] = []; - const execInfo = services.runtime.Runner.getExecutionContext(message.id)!; - const readableStacktracePython = await Promise.all( - (message).data.backtrace.map(async (frame) => { - const mappedFrame = await services.runtime.Runner.tryMapToSafeDSSource(message.id, frame); - if (mappedFrame) { - readableStacktraceSafeDs.push( - `\tat ${URI.file(execInfo.path)}#${mappedFrame.line} (${execInfo.path} line ${ - mappedFrame.line - })`, - ); - return `\tat ${frame.file} line ${frame.line} (mapped to '${mappedFrame.file}' line ${mappedFrame.line})`; - } - return `\tat ${frame.file} line ${frame.line}`; - }), - ); - logOutput( - `Runner-RuntimeError (${message.id}): ${ - (message).data.message - } \n${readableStacktracePython.join('\n')}`, - ); - printOutputMessage( - `Safe-DS Error (${message.id}): ${(message).data.message} \n${readableStacktraceSafeDs - .reverse() - .join('\n')}`, - ); - }, 'runtime_error'); -}; - const registerVSCodeCommands = function (context: vscode.ExtensionContext) { const registerCommandWithCheck = (commandId: string, callback: (...args: any[]) => Promise) => { return vscode.commands.registerCommand(commandId, (...args: any[]) => {