moonreport

Source-aware diagnostic reports for MoonBit developer tools

diagnostic
source
span
compiler
reporting
moon add zlhahaha/moonreport@0.1.0
Download zip
Author
Version
0.1.0
License
Apache-2.0
Last updated
20 days ago
Downloads
2
README

#MoonReport

MoonReport is a pure MoonBit toolkit for turning byte offsets and validation failures into readable, source-aware diagnostics. It is useful anywhere a developer tool needs to point at the exact part of an input that caused a problem.

It is designed for parsers, configuration validators, linters, compilers, code generators, test frameworks, and command-line tools. A caller supplies source files, spans, labels, and optional help text; MoonReport produces stable plain-text or ANSI output without requiring a terminal or filesystem.

#Features

  • UTF-8-aware source files, line indexes, tabs, and display columns
  • errors, warnings, notes, help, codes, and multiple labeled spans
  • deterministic context selection and folding for distant labels
  • single-line and multi-line annotations
  • plain text, ANSI, compact, JSON, and JSON Lines renderers
  • dark/light terminal themes and ANSI stripping
  • diagnostic batches, severity summaries, filtering, and CI exit thresholds
  • stable diagnostic metrics grouped by severity, code, and source
  • atomic source fixes with overlap, bounds, and UTF-8 boundary validation
  • human-readable fix previews and stable machine-readable JSON
  • conservative batch fix plans for unattended formatter and linter workflows

#Quick start

let sources = @report.SourceMap::new()
let id = sources.add("app.conf", "port = 70000")
let problem = @report.Diagnostic::new(Error, "invalid port")
.with_code("CFG002")
.with_label(
@report.Label::primary(
id,
@report.Span::new(7, 12).unwrap(),
"expected a value from 1 to 65535",
),
)
.with_help("try port 8080")

println(@report.render(sources, problem))

Run the included configuration-validator demo:

moon run cmd/main

See docs/quickstart.md for package setup, renderer selection, batch reporting, source fixes, and output integration.

The implementation is original and released under Apache-2.0. See docs/project-charter.md for the library boundary and docs/roadmap.md for future extension candidates.

#Development and verification

moon check --deny-warn moon test moon fmt --check moon build moon info moon run cmd/main

The library has no runtime I/O dependency; callers decide how sources are loaded and where reports are sent. This keeps output deterministic across native, JavaScript, and WebAssembly environments.

The current release contains more than 4,000 physical lines of MoonBit across the library, tests, and runnable example, with 89 passing tests.

#
Applicability

pub(all) enum Applicability {
MachineApplicable
MaybeIncorrect
HasPlaceholders
Unspecified
} derive(Eq,
Debug
)

How confidently an automated edit can be applied.

#
Applicability::is_automatic

fn Applicability::is_automatic(self : Applicability) -> Bool

#
Applicability::name

fn Applicability::name(self : Applicability) -> String

#
CodeCount

pub struct CodeCount {
code : String
count : Int
} derive(Eq,
Debug
)

A stable count associated with one diagnostic code.

#
CodeCount::code

fn CodeCount::code(self : CodeCount) -> String

#
CodeCount::count

fn CodeCount::count(self : CodeCount) -> Int

#
Color

pub(all) enum Color {
Default
Black
Red
Green
Yellow
Blue
Magenta
Cyan
White
BrightBlack
BrightRed
BrightYellow
BrightBlue
BrightCyan
BrightWhite
} derive(Eq,
Debug
)

Named ANSI color used by terminal themes.

#
Diagnostic

pub struct Diagnostic {
severity : Severity
message : String
code : String?
help : String?
notes : Array[String]
labels : Array[Label]
} derive(Eq,
Debug
)

A complete problem report independent of presentation format.

#
Diagnostic::code

fn Diagnostic::code(self : Diagnostic) -> String?

#
Diagnostic::help

fn Diagnostic::help(self : Diagnostic) -> String?

#
Diagnostic::is_valid

fn Diagnostic::is_valid(self : Diagnostic) -> Bool

#
Diagnostic::labels

fn Diagnostic::labels(self : Diagnostic) -> Array[Label]

#
Diagnostic::message

fn Diagnostic::message(self : Diagnostic) -> String

#
Diagnostic::new

fn Diagnostic::new(severity : Severity, message : String) -> Diagnostic

#
Diagnostic::notes

fn Diagnostic::notes(self : Diagnostic) -> Array[String]

#
Diagnostic::primary_label

fn Diagnostic::primary_label(self : Diagnostic) -> Label?

#
Diagnostic::severity

fn Diagnostic::severity(self : Diagnostic) -> Severity

#
Diagnostic::with_code

fn Diagnostic::with_code(self : Diagnostic, code : String) -> Diagnostic

#
Diagnostic::with_help

fn Diagnostic::with_help(self : Diagnostic, help : String) -> Diagnostic

#
Diagnostic::with_label

fn Diagnostic::with_label(self : Diagnostic, label : Label) -> Diagnostic

#
Diagnostic::with_note

fn Diagnostic::with_note(self : Diagnostic, note : String) -> Diagnostic

#
Diagnostic::with_severity

fn Diagnostic::with_severity(self : Diagnostic, severity : Severity) -> Diagnostic

#
DiagnosticBag

pub struct DiagnosticBag {
items : Array[Diagnostic]
}

An insertion-ordered batch of diagnostics.

#
DiagnosticBag::add

fn DiagnosticBag::add(self : DiagnosticBag, diagnostic : Diagnostic) -> Unit

#
DiagnosticBag::at_least

fn DiagnosticBag::at_least(self : DiagnosticBag, minimum : Severity) -> Array[Diagnostic]

Returns diagnostics at or above the requested severity.

#
DiagnosticBag::exit_code

fn DiagnosticBag::exit_code(self : DiagnosticBag, fail_on? : Severity) -> Int

Conventional process exit code: one when a diagnostic reaches the failure threshold, otherwise zero.

#
DiagnosticBag::from_array

fn DiagnosticBag::from_array(items : Array[Diagnostic]) -> DiagnosticBag

#
DiagnosticBag::is_empty

fn DiagnosticBag::is_empty(self : DiagnosticBag) -> Bool

#
DiagnosticBag::length

fn DiagnosticBag::length(self : DiagnosticBag) -> Int

#
DiagnosticBag::metrics

Computes metrics without changing the bag or its diagnostics.

A diagnostic contributes at most once to a source's diagnostic count, even when it has several labels in that source. Every label still contributes to the corresponding label count.

#
DiagnosticBag::new

#
DiagnosticBag::render

fn DiagnosticBag::render(self : DiagnosticBag, sources : SourceMap, config? : RenderConfig) -> String

Renders a diagnostic batch, separated by one blank line.

#
DiagnosticBag::render_json_lines

fn DiagnosticBag::render_json_lines(self : DiagnosticBag, sources : SourceMap) -> String

Serializes a batch as newline-delimited JSON.

#
DiagnosticBag::summary

fn DiagnosticBag::summary(self : DiagnosticBag) -> Summary

#
DiagnosticBag::to_array

fn DiagnosticBag::to_array(self : DiagnosticBag) -> Array[Diagnostic]

#
DiagnosticMetrics

pub struct DiagnosticMetrics {
summary : Summary
coded : Int
labels : Int
primary_labels : Int
secondary_labels : Int
code_counts : Array[CodeCount]
source_counts : Array[SourceCount]
} derive(Eq,
Debug
)

Aggregate information for dashboards, CI summaries, and batch reports.

Code and source groups preserve first-seen order, which makes output stable without imposing a sorting policy on callers.

#
DiagnosticMetrics::code_counts

#
DiagnosticMetrics::coded

fn DiagnosticMetrics::coded(self : DiagnosticMetrics) -> Int

#
DiagnosticMetrics::count_for_code

fn DiagnosticMetrics::count_for_code(self : DiagnosticMetrics, code : String) -> Int

#
DiagnosticMetrics::diagnostics_for_source

fn DiagnosticMetrics::diagnostics_for_source(self : DiagnosticMetrics, source : SourceId) -> Int

#
DiagnosticMetrics::labels

fn DiagnosticMetrics::labels(self : DiagnosticMetrics) -> Int

#
DiagnosticMetrics::labels_for_source

fn DiagnosticMetrics::labels_for_source(self : DiagnosticMetrics, source : SourceId) -> Int

#
DiagnosticMetrics::primary_labels

fn DiagnosticMetrics::primary_labels(self : DiagnosticMetrics) -> Int

#
DiagnosticMetrics::secondary_labels

fn DiagnosticMetrics::secondary_labels(self : DiagnosticMetrics) -> Int

#
DiagnosticMetrics::source_counts

#
DiagnosticMetrics::summary

#
DiagnosticMetrics::uncoded

fn DiagnosticMetrics::uncoded(self : DiagnosticMetrics) -> Int

#
DiagnosticMetrics::unique_codes

fn DiagnosticMetrics::unique_codes(self : DiagnosticMetrics) -> Int

#
DiagnosticMetrics::unique_sources

fn DiagnosticMetrics::unique_sources(self : DiagnosticMetrics) -> Int

#
DiagnosticPolicy

pub struct DiagnosticPolicy {
minimum : Severity
allowed_codes : Array[String]
selected_codes : Array[String]
denied_codes : Array[String]
warnings_as_errors : Bool
deduplicate : Bool
advice_limit : Int?
warning_limit : Int?
error_limit : Int?
total_limit : Int?
}

Filtering, promotion, de-duplication, and output-budget rules.

Rules are evaluated in this order: minimum severity, allow-list suppression, selection, promotion, de-duplication, per-severity budget, then total budget.

#
DiagnosticPolicy::allow_code

fn DiagnosticPolicy::allow_code(self : DiagnosticPolicy, code : String) -> DiagnosticPolicy

#
DiagnosticPolicy::apply

#
DiagnosticPolicy::deduplicates

fn DiagnosticPolicy::deduplicates(self : DiagnosticPolicy) -> Bool

#
DiagnosticPolicy::deny_code

fn DiagnosticPolicy::deny_code(self : DiagnosticPolicy, code : String) -> DiagnosticPolicy

#
DiagnosticPolicy::limits

fn DiagnosticPolicy::limits(self : DiagnosticPolicy, advice? : Int?, warnings? : Int?, errors? : Int?, total? : Int?) -> DiagnosticPolicy

#
DiagnosticPolicy::minimum

#
DiagnosticPolicy::new

#
DiagnosticPolicy::select_code

fn DiagnosticPolicy::select_code(self : DiagnosticPolicy, code : String) -> DiagnosticPolicy

#
DiagnosticPolicy::warnings_as_errors

fn DiagnosticPolicy::warnings_as_errors(self : DiagnosticPolicy) -> Bool

#
DiagnosticPolicy::with_advice_limit

fn DiagnosticPolicy::with_advice_limit(self : DiagnosticPolicy, limit : Int) -> DiagnosticPolicy

#
DiagnosticPolicy::with_deduplication

fn DiagnosticPolicy::with_deduplication(self : DiagnosticPolicy, enabled : Bool) -> DiagnosticPolicy

#
DiagnosticPolicy::with_error_limit

fn DiagnosticPolicy::with_error_limit(self : DiagnosticPolicy, limit : Int) -> DiagnosticPolicy

#
DiagnosticPolicy::with_minimum

fn DiagnosticPolicy::with_minimum(self : DiagnosticPolicy, minimum : Severity) -> DiagnosticPolicy

#
DiagnosticPolicy::with_total_limit

fn DiagnosticPolicy::with_total_limit(self : DiagnosticPolicy, limit : Int) -> DiagnosticPolicy

#
DiagnosticPolicy::with_warning_limit

fn DiagnosticPolicy::with_warning_limit(self : DiagnosticPolicy, limit : Int) -> DiagnosticPolicy

#
DiagnosticPolicy::with_warnings_as_errors

fn DiagnosticPolicy::with_warnings_as_errors(self : DiagnosticPolicy, enabled : Bool) -> DiagnosticPolicy

#
DisplayConfig

pub struct DisplayConfig {
tab_width : Int
ambiguous_width : Int
} derive(Eq,
Debug
)

Rendering policy for tabs and non-ASCII source text.

#
DisplayConfig::default

fn DisplayConfig::default() -> DisplayConfig

#
DisplayConfig::new

fn DisplayConfig::new(tab_width : Int, ambiguous_width : Int) -> DisplayConfig

#
DisplayConfig::tab_width

fn DisplayConfig::tab_width(self : DisplayConfig) -> Int

#
EditPreview

pub struct EditPreview {
source : SourceId
source_name : String
span : Span
start : Location
end : Location
original : String
replacement : String
}

One edit enriched with source locations for display and transport.

#
EditPreview::end

fn EditPreview::end(self : EditPreview) -> Location

#
EditPreview::is_deletion

fn EditPreview::is_deletion(self : EditPreview) -> Bool

#
EditPreview::is_insertion

fn EditPreview::is_insertion(self : EditPreview) -> Bool

#
EditPreview::original

fn EditPreview::original(self : EditPreview) -> String

#
EditPreview::replacement

fn EditPreview::replacement(self : EditPreview) -> String

#
EditPreview::source

fn EditPreview::source(self : EditPreview) -> SourceId

#
EditPreview::source_name

fn EditPreview::source_name(self : EditPreview) -> String

#
EditPreview::span

fn EditPreview::span(self : EditPreview) -> Span

#
EditPreview::start

fn EditPreview::start(self : EditPreview) -> Location

#
Fix

pub struct Fix {
title : String
applicability : Applicability
edits : Array[TextEdit]
}

A named group of edits that should be accepted or rejected together.

#
Fix::applicability

fn Fix::applicability(self : Fix) -> Applicability

#
Fix::apply

fn Fix::apply(self : Fix, sources : SourceMap) -> (SourceMap?, FixValidation)

Applies this fix and returns a new source map.

The original map is never mutated. Invalid fixes return their validation result and no partial edit is observable.

#
Fix::apply_to_source

fn Fix::apply_to_source(self : Fix, sources : SourceMap, source_id : SourceId) -> (String?, FixValidation)

Applies only edits for one source and leaves validation explicit.

#
Fix::edits

fn Fix::edits(self : Fix) -> Array[TextEdit]

#
Fix::is_automatic

fn Fix::is_automatic(self : Fix) -> Bool

#
Fix::new

fn Fix::new(title : String, applicability? : Applicability) -> Fix

#
Fix::preview

fn Fix::preview(self : Fix, sources : SourceMap) -> (FixPreview?, FixValidation)

Builds a preview only after the complete fix has passed validation.

#
Fix::render_json

fn Fix::render_json(self : Fix, sources : SourceMap) -> (String?, FixValidation)

Convenience operation for callers that want validation and JSON in one step.

#
Fix::render_preview

fn Fix::render_preview(self : Fix, sources : SourceMap) -> (String?, FixValidation)

Convenience operation for callers that want validation and text in one step.

#
Fix::title

fn Fix::title(self : Fix) -> String

#
Fix::validate

fn Fix::validate(self : Fix, sources : SourceMap) -> FixValidation

#
Fix::with_edit

fn Fix::with_edit(self : Fix, edit : TextEdit) -> Fix

#
FixMode

pub(all) enum FixMode {
AllFixes
AutomaticFixes
} derive(Eq,
Debug
)

Selects which fixes participate in a batch operation.

#
FixMode::name

fn FixMode::name(self : FixMode) -> String

#
FixPlan

pub struct FixPlan {
fixes : Array[Fix]
}

An ordered collection of independent fixes.

A plan validates the complete edit set before changing any source. This makes unattended formatter, linter, migration, and code-action workflows atomic: either every selected edit is safe to apply, or nothing changes.

#
FixPlan::apply

fn FixPlan::apply(self : FixPlan, sources : SourceMap, mode? : FixMode) -> (SourceMap?, FixPlanValidation)

Applies the selected fixes atomically to a copy of the source map.

The default is deliberately conservative: only machine-applicable fixes are selected. Pass AllFixes when a user has reviewed every suggestion.

#
FixPlan::fixes

fn FixPlan::fixes(self : FixPlan) -> Array[Fix]

#
FixPlan::is_empty

fn FixPlan::is_empty(self : FixPlan) -> Bool

#
FixPlan::length

fn FixPlan::length(self : FixPlan) -> Int

#
FixPlan::new

fn FixPlan::new() -> FixPlan

#
FixPlan::summary

fn FixPlan::summary(self : FixPlan, mode? : FixMode) -> FixPlanSummary

#
FixPlan::validate

fn FixPlan::validate(self : FixPlan, sources : SourceMap, mode? : FixMode) -> FixPlanValidation

Validates every selected fix and then detects conflicts across fixes.

#
FixPlan::with_fix

fn FixPlan::with_fix(self : FixPlan, fix : Fix) -> FixPlan

#
FixPlanSummary

pub struct FixPlanSummary {
total_fixes : Int
selected_fixes : Int
skipped_fixes : Int
selected_edits : Int
}

Counts describing a plan before it is applied.

#
FixPlanSummary::selected_edits

fn FixPlanSummary::selected_edits(self : FixPlanSummary) -> Int

#
FixPlanSummary::selected_fixes

fn FixPlanSummary::selected_fixes(self : FixPlanSummary) -> Int

#
FixPlanSummary::skipped_fixes

fn FixPlanSummary::skipped_fixes(self : FixPlanSummary) -> Int

#
FixPlanSummary::total_fixes

fn FixPlanSummary::total_fixes(self : FixPlanSummary) -> Int

#
FixPlanValidation

pub(all) enum FixPlanValidation {
PlanValid
EmptyPlan
NoSelectedFixes
InvalidPlannedFix(Int, FixValidation)
ConflictingPlannedFixes(FixValidation)
} derive(Eq,
Debug
)

The result of validating a selected batch of fixes.

#
FixPlanValidation::is_valid

fn FixPlanValidation::is_valid(self : FixPlanValidation) -> Bool

#
FixPlanValidation::message

fn FixPlanValidation::message(self : FixPlanValidation) -> String

#
FixPreview

pub struct FixPreview {
title : String
applicability : Applicability
edits : Array[EditPreview]
}

A validated, presentation-ready view of a fix.

#
FixPreview::applicability

fn FixPreview::applicability(self : FixPreview) -> Applicability

#
FixPreview::edit_count

fn FixPreview::edit_count(self : FixPreview) -> Int

#
FixPreview::edits

fn FixPreview::edits(self : FixPreview) -> Array[EditPreview]

#
FixPreview::source_count

fn FixPreview::source_count(self : FixPreview) -> Int

#
FixPreview::title

fn FixPreview::title(self : FixPreview) -> String

#
FixValidation

pub(all) enum FixValidation {
Valid
Empty
UnknownSource(SourceId)
OutOfBounds(SourceId, Span, Int)
Overlapping(SourceId, Span, Span)
} derive(Eq,
Debug
)

The outcome of checking a fix against a source registry.

#
FixValidation::is_valid

fn FixValidation::is_valid(self : FixValidation) -> Bool

#
FixValidation::message

fn FixValidation::message(self : FixValidation) -> String

#
Label

pub struct Label {
source : SourceId
span : Span
message : String
primary : Bool
} derive(Eq,
Debug
)

A source range and its optional explanatory text.

#
Label::is_primary

fn Label::is_primary(self : Label) -> Bool

#
Label::message

fn Label::message(self : Label) -> String

#
Label::primary

fn Label::primary(source : SourceId, span : Span, message : String) -> Label

#
Label::secondary

fn Label::secondary(source : SourceId, span : Span, message : String) -> Label

#
Label::source

fn Label::source(self : Label) -> SourceId

#
Label::span

fn Label::span(self : Label) -> Span

#
LineWindow

pub struct LineWindow {
first : Int
last : Int
focus_first : Int
focus_last : Int
} derive(Eq,
Debug
)

Inclusive source-line window selected for a diagnostic label.

#
LineWindow::first

fn LineWindow::first(self : LineWindow) -> Int

#
LineWindow::focus_first

fn LineWindow::focus_first(self : LineWindow) -> Int

#
LineWindow::focus_last

fn LineWindow::focus_last(self : LineWindow) -> Int

#
LineWindow::last

fn LineWindow::last(self : LineWindow) -> Int

#
Location

pub struct Location {
line : Int
column : Int
offset : Int
} derive(Eq,
Debug
)

A zero-based line and byte column.

#
Location::column

fn Location::column(self : Location) -> Int

#
Location::line

fn Location::line(self : Location) -> Int

#
Location::offset

fn Location::offset(self : Location) -> Int

#
PolicyResult

pub struct PolicyResult {
emitted : DiagnosticBag
suppressed : Array[SuppressedDiagnostic]
summary : PolicySummary
}

Result of applying a policy without mutating the input bag.

#
PolicyResult::emitted

fn PolicyResult::emitted(self : PolicyResult) -> DiagnosticBag

#
PolicyResult::has_suppressed

fn PolicyResult::has_suppressed(self : PolicyResult) -> Bool

#
PolicyResult::summary

fn PolicyResult::summary(self : PolicyResult) -> PolicySummary

#
PolicyResult::suppressed

#
PolicySummary

pub struct PolicySummary {
input : Int
emitted : Int
promoted : Int
suppressed : Int
duplicates : Int
budgeted : Int
}

Statistics produced while applying a diagnostic policy.

#
PolicySummary::budgeted

fn PolicySummary::budgeted(self : PolicySummary) -> Int

#
PolicySummary::duplicates

fn PolicySummary::duplicates(self : PolicySummary) -> Int

#
PolicySummary::emitted

fn PolicySummary::emitted(self : PolicySummary) -> Int

#
PolicySummary::input

fn PolicySummary::input(self : PolicySummary) -> Int

#
PolicySummary::promoted

fn PolicySummary::promoted(self : PolicySummary) -> Int

#
PolicySummary::suppressed

fn PolicySummary::suppressed(self : PolicySummary) -> Int

#
RenderConfig

pub struct RenderConfig {
context_lines : Int
tab_width : Int
show_source_name : Bool
show_code : Bool
} derive(Eq,
Debug
)

Options for human-readable source reports.

#
RenderConfig::default

fn RenderConfig::default() -> RenderConfig

#
RenderConfig::new

fn RenderConfig::new(context_lines? : Int, tab_width? : Int, show_source_name? : Bool, show_code? : Bool) -> RenderConfig

#
Severity

pub(all) enum Severity {
Advice
Warning
Error
} derive(Eq,
Debug
)

Importance of a diagnostic, ordered from least to most severe.

#
Severity::name

fn Severity::name(self : Severity) -> String

#
Severity::rank

fn Severity::rank(self : Severity) -> Int

#
Source

pub struct Source {
name : String
text : String
bytes : Bytes
line_starts : Array[Int]
}

Immutable source text with a precomputed line-start index.

#
Source::byte_length

fn Source::byte_length(self : Source) -> Int

#
Source::line_count

fn Source::line_count(self : Source) -> Int

#
Source::line_span

fn Source::line_span(self : Source, line : Int) -> Span?

#
Source::line_text

fn Source::line_text(self : Source, line : Int) -> String?

#
Source::location

fn Source::location(self : Source, offset : Int) -> Location

#
Source::name

fn Source::name(self : Source) -> String

#
Source::new

fn Source::new(name : String, text : String) -> Source

#
Source::slice

fn Source::slice(self : Source, span : Span) -> String

#
Source::slice_offsets

fn Source::slice_offsets(self : Source, start : Int, end : Int) -> String

Returns the source text between two byte offsets after clamping both ends.

This is primarily useful to consumers that assemble transformed source without exposing the source's internal UTF-8 byte buffer.

#
Source::text

fn Source::text(self : Source) -> String

#
Source::window

fn Source::window(self : Source, span : Span, context_lines? : Int) -> LineWindow

Selects a bounded context window around a span.

#
SourceCount

pub struct SourceCount {
source : SourceId
diagnostics : Int
labels : Int
} derive(Eq,
Debug
)

A stable count associated with one source.

#
SourceCount::diagnostics

fn SourceCount::diagnostics(self : SourceCount) -> Int

#
SourceCount::labels

fn SourceCount::labels(self : SourceCount) -> Int

#
SourceCount::source

fn SourceCount::source(self : SourceCount) -> SourceId

#
SourceId

pub(all) struct SourceId(Int) derive(Compare, Eq, Hash,
Debug
)

A stable identifier for one source registered in a SourceMap.

#
SourceId::new

fn SourceId::new(value : Int) -> SourceId?

#
SourceId::value

fn SourceId::value(self : SourceId) -> Int

#
SourceMap

pub struct SourceMap {
sources : Array[Source]
}

Registry that assigns stable IDs to source files used by diagnostics.

#
SourceMap::add

fn SourceMap::add(self : SourceMap, name : String, text : String) -> SourceId

#
SourceMap::contains

fn SourceMap::contains(self : SourceMap, id : SourceId) -> Bool

#
SourceMap::find_by_name

fn SourceMap::find_by_name(self : SourceMap, name : String) -> SourceId?

#
SourceMap::get

fn SourceMap::get(self : SourceMap, id : SourceId) -> Source?

#
SourceMap::is_empty

fn SourceMap::is_empty(self : SourceMap) -> Bool

#
SourceMap::length

fn SourceMap::length(self : SourceMap) -> Int

#
SourceMap::new

fn SourceMap::new() -> SourceMap

#
SourceMap::validate

fn SourceMap::validate(self : SourceMap, diagnostic : Diagnostic) -> Bool

#
SourceMap::validate_label

fn SourceMap::validate_label(self : SourceMap, label : Label) -> Bool

#
Span

pub struct Span {
start : Int
end : Int
} derive(Eq,
Debug
)

A half-open byte range in a source file.

#
Span::at

fn Span::at(offset : Int) -> Span?

#
Span::clamp

fn Span::clamp(self : Span, length : Int) -> Span

#
Span::contains

fn Span::contains(self : Span, offset : Int) -> Bool

#
Span::cover

fn Span::cover(self : Span, other : Span) -> Span

#
Span::end

fn Span::end(self : Span) -> Int

#
Span::intersects

fn Span::intersects(self : Span, other : Span) -> Bool

#
Span::is_empty

fn Span::is_empty(self : Span) -> Bool

#
Span::length

fn Span::length(self : Span) -> Int

#
Span::new

fn Span::new(start : Int, end : Int) -> Span?

Creates a span when both offsets are non-negative and ordered.

#
Span::start

fn Span::start(self : Span) -> Int

#
Span::touches

fn Span::touches(self : Span, other : Span) -> Bool

#
Summary

pub struct Summary {
advice : Int
warnings : Int
errors : Int
} derive(Eq,
Debug
)

Counts diagnostics by severity without exposing mutable internal state.

#
Summary::advice

fn Summary::advice(self : Summary) -> Int

#
Summary::errors

fn Summary::errors(self : Summary) -> Int

#
Summary::has_errors

fn Summary::has_errors(self : Summary) -> Bool

#
Summary::total

fn Summary::total(self : Summary) -> Int

#
Summary::warnings

fn Summary::warnings(self : Summary) -> Int

#
SuppressedDiagnostic

pub struct SuppressedDiagnostic {
diagnostic : Diagnostic
reason : SuppressionReason
}

A diagnostic together with the reason it was suppressed.

#
SuppressedDiagnostic::diagnostic

#
SuppressedDiagnostic::reason

#
SuppressionReason

pub(all) enum SuppressionReason {
BelowMinimum
CodeAllowed(String)
NotSelected(String)
Duplicate
SeverityBudget(Severity, Int)
TotalBudget(Int)
} derive(Eq,
Debug
)

Why a diagnostic was not emitted by a policy evaluation.

#
SuppressionReason::message

fn SuppressionReason::message(self : SuppressionReason) -> String

#
SuppressionReason::name

fn SuppressionReason::name(self : SuppressionReason) -> String

#
TextEdit

pub struct TextEdit {
source : SourceId
span : Span
replacement : String
} derive(Eq,
Debug
)

One UTF-8 byte-range replacement in a registered source.

#
TextEdit::delete

fn TextEdit::delete(source : SourceId, span : Span) -> TextEdit

#
TextEdit::insert

fn TextEdit::insert(source : SourceId, offset : Int, text : String) -> TextEdit?

#
TextEdit::is_deletion

fn TextEdit::is_deletion(self : TextEdit) -> Bool

#
TextEdit::is_insertion

fn TextEdit::is_insertion(self : TextEdit) -> Bool

#
TextEdit::replace

fn TextEdit::replace(source : SourceId, span : Span, replacement : String) -> TextEdit

#
TextEdit::replacement

fn TextEdit::replacement(self : TextEdit) -> String

#
TextEdit::source

fn TextEdit::source(self : TextEdit) -> SourceId

#
TextEdit::span

fn TextEdit::span(self : TextEdit) -> Span

#
Theme

pub struct Theme {
error : Color
warning : Color
advice : Color
line_number : Color
primary : Color
secondary : Color
note : Color
help : Color
bold_header : Bool
} derive(Eq,
Debug
)

Semantic terminal colors for a diagnostic report.

#
Theme::dark

fn Theme::dark() -> Theme

A legible theme for dark terminal backgrounds.

#
Theme::light

fn Theme::light() -> Theme

A lower-intensity theme for light terminal backgrounds.

#
Theme::severity

fn Theme::severity(self : Theme, severity : Severity) -> Color

#
diagnostic_fingerprint

fn diagnostic_fingerprint(diagnostic : Diagnostic) -> String

Stable identity used by policy de-duplication.

Notes and help are intentionally excluded: producers often attach contextual notes at different layers while referring to the same underlying problem.

#
display_column

fn display_column(text : String, byte_offset : Int, config? : DisplayConfig) -> Int

Converts a UTF-8 byte offset into a terminal-cell column.

#
display_width

fn display_width(text : String, config? : DisplayConfig) -> Int

Returns the number of terminal cells occupied by UTF-8 text.

#
expand_tabs

fn expand_tabs(text : String, config? : DisplayConfig) -> String

Replaces tabs with spaces while preserving tab-stop alignment.

#
merge_windows

fn merge_windows(windows : Array[LineWindow], gap? : Int) -> Array[LineWindow]

Merges windows that overlap or are separated by at most gap lines.

#
render

fn render(sources : SourceMap, diagnostic : Diagnostic, config? : RenderConfig) -> String

Renders a diagnostic with source context and aligned labels.

Invalid source IDs are omitted from source blocks but the diagnostic header, notes, and help remain visible.

#
render_all

fn render_all(sources : SourceMap, diagnostics : Array[Diagnostic], config? : RenderConfig) -> String

Renders multiple reports with one blank line between them.

#
render_ansi

fn render_ansi(sources : SourceMap, diagnostic : Diagnostic, enabled? : Bool, theme? : Theme, config? : RenderConfig) -> String

Adds ANSI color to a plain report. When enabled is false, the output is byte-for-byte identical to render.

#
render_compact

fn render_compact(sources : SourceMap, diagnostic : Diagnostic) -> String

Renders one diagnostic as a stable, grep-friendly line plus notes.

#
render_compact_all

fn render_compact_all(sources : SourceMap, diagnostics : Array[Diagnostic]) -> String

Renders diagnostics separated by newlines without a trailing newline.

#
render_fix_json

fn render_fix_json(preview : FixPreview) -> String

Serializes a validated fix preview to stable JSON for editor integrations.

#
render_fix_preview

fn render_fix_preview(preview : FixPreview) -> String

Renders a compact unified-diff-like preview.

Locations are one-based for humans. The format is deliberately a preview rather than a patch file: replacements may start or end mid-line.

#
render_json

fn render_json(sources : SourceMap, diagnostic : Diagnostic) -> String

Serializes one diagnostic to a stable, compact JSON object.

Byte offsets are zero-based. Human-facing line and column values are one-based. Unknown source IDs remain representable with a null name.

#
render_json_lines

fn render_json_lines(sources : SourceMap, diagnostics : Array[Diagnostic]) -> String

Emits newline-delimited JSON for streaming into editors and CI systems.

#
strip_ansi

fn strip_ansi(text : String) -> String

Removes common Select Graphic Rendition sequences emitted by MoonReport. This is useful for snapshot tests and log sanitization.