///|
priv enum ReplControlFlow {
ContinueRepl
ExitRepl
}
///|
const DEFAULT_SOURCE_LINE_COUNT : Int = 10
///|
priv struct CommandHelpEntry {
name : String
aliases : Array[String]
usage : String
summary : String
}
///|
fn CommandHelpEntry::alias_usage(self : CommandHelpEntry) -> String {
guard self.aliases is [_, ..] else { return "" }
let suffix = match self.usage.strip_prefix(self.name) {
Some(suffix) => suffix
None => ""
}
let alias_usage = self.aliases
.map(command_alias => "\{command_alias}\{suffix}")
.join(", ")
alias_usage
}
///|
priv enum PresentationEvent {
HelpPresentation(Array[CommandHelpEntry])
UserErrorPresentation(String)
DebuggeeOutputPresentation(Array[@debugger.DebugOutput])
ProgramRestartingPresentation
BreakpointPendingPresentation(Int, String, Int)
BreakpointUpdatePresentation(@debugger.BreakpointSnapshot)
FunctionBreakpointPendingPresentation(Int, String)
FunctionBreakpointUpdatePresentation(@debugger.FunctionBreakpointSnapshot)
BreakpointErrorPresentation(BreakpointCommandError)
BreakpointsPresentation(Array[@debugger.BreakpointListEntry])
BreakpointManagedPresentation(@debugger.BreakpointManagementResult)
BreakpointManagementFailurePresentation(BreakpointManagementFailure)
StopPresentation(@debugger.StopSnapshot)
BacktracePresentation(BacktraceView)
FrameSelectedPresentation(@debugger.StackFrameSnapshot)
FrameSelectionFailurePresentation(FrameSelectionFailure)
SourceViewPresentation(SourceView)
VariablePresentation(@debugger.VariableSnapshot)
VariableLookupFailurePresentation(@debugger.VariableLookupFailure)
LocalsPresentation(@debugger.LocalVariablesSnapshot)
NoStoppedSourcePresentation
ProcessExitPresentation(Int?)
OperationNotAllowedPresentation(@debugger.DebugSessionState, String)
AdapterFailurePresentation(String)
}
///|
priv struct BacktraceView {
frames : Array[@debugger.StackFrameSnapshot]
selected_frame : Int?
}
///|
fn BacktraceView::from_stack(
stack : @debugger.StackSnapshot,
selected_frame : Int?,
show_all~ : Bool,
) -> BacktraceView {
let frames : Array[@debugger.StackFrameSnapshot] = []
if show_all {
for frame in stack.frames() {
frames.push(frame)
}
} else {
for frame in stack.visible_frames() {
frames.push(frame)
}
}
if !show_all && frames is [] && stack.frames() is [first, ..] {
frames.push(first)
}
{ frames, selected_frame, }
}
///|
priv enum FrameSelectionFailure {
FrameUnavailable(Int)
CurrentFrameUnavailable
CallerBoundary(Int)
CalleeBoundary(Int)
}
///|
/// A renderer-independent request for source context around one line. Source
/// loading and MoonBit highlighting remain presentation responsibilities.
priv struct SourceView {
source_path : String?
line : Int?
line_count : Int
}
///|
fn SourceView::from_stop(
snapshot : @debugger.StopSnapshot,
line_count~ : Int,
) -> SourceView {
{ source_path: snapshot.source_path(), line: snapshot.line(), line_count, }
}
///|
fn SourceView::from_frame(
frame : @debugger.StackFrameSnapshot,
line_count~ : Int,
) -> SourceView {
{ source_path: frame.source_path(), line: frame.line(), line_count, }
}
///|
/// Errors specific to the user-facing source breakpoint command. Keeping the
/// cases semantic lets non-human renderers distinguish invalid paths from
/// debugger-state failures without parsing terminal text.
priv enum BreakpointCommandError {
BreakpointCurrentFrameMissing
BreakpointCurrentFrameSourceMissing
BreakpointSourceNotFound(String)
BreakpointSourceNotAFile(String)
BreakpointOperationNotAllowed(@debugger.DebugSessionState, String)
BreakpointFunctionContextMissing
BreakpointUnknownPackageAlias(String)
BreakpointUnexpectedFailure(String)
}
///|
priv enum BreakpointManagementFailure {
BreakpointIdNotFound(Int)
BreakpointManagementRefused(String)
}
///|
/// Result returned by every command.
priv struct CommandResult {
control : ReplControlFlow
events : Array[PresentationEvent]
}
///|
fn CommandResult::continuing(
events? : Array[PresentationEvent] = [],
) -> CommandResult {
{ control: ContinueRepl, events, }
}
///|
fn CommandResult::exiting() -> CommandResult {
{ control: ExitRepl, events: [], }
}
///|
priv trait PresentationRenderer {
async fn render(Self, events : Array[PresentationEvent]) -> Unit
}