diagnostic

package
v1.75.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: BSD-3-Clause Imports: 9 Imported by: 0

Documentation

Overview

Package diagnostic provides Rust-style annotated error rendering for ELPS CLI output. It is intentionally independent of the lisp/ package so that it can be used by any CLI command without creating import cycles.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ColorMode

type ColorMode int

ColorMode controls when ANSI color codes are used.

const (
	ColorAuto   ColorMode = iota // detect based on terminal and NO_COLOR
	ColorAlways                  // always use colors
	ColorNever                   // never use colors
)

type Diagnostic

type Diagnostic struct {
	Severity Severity
	Message  string
	Spans    []Span
	Notes    []string // "= note:" lines (stack trace frames, etc.)
}

Diagnostic represents a single error, warning, or note with optional source annotations and trailing notes.

type Renderer

type Renderer struct {
	// Color controls ANSI color output. Default is ColorAuto.
	Color ColorMode

	// SourceReader reads source file contents. If nil, os.ReadFile is used.
	SourceReader func(string) ([]byte, error)
}

Renderer formats diagnostics as Rust-style annotated source snippets.

func (*Renderer) NewSession added in v1.62.0

func (r *Renderer) NewSession(ctx context.Context, w io.Writer, limit int) *Session

NewSession reserves space for a truncation marker within limit bytes. The request context and work budget cover construction, source reads and writing.

func (*Renderer) Render

func (r *Renderer) Render(w io.Writer, d Diagnostic) error

Render writes a single diagnostic to w.

func (*Renderer) RenderAll

func (r *Renderer) RenderAll(w io.Writer, diags []Diagnostic) error

RenderAll writes all diagnostics to w separated by blank lines.

type Session added in v1.62.0

type Session struct {
	// contains filtered or unexported fields
}

Session streams one complete diagnostic under a shared byte/work budget. Callers must check Step before constructing fields and use Remaining before allocating variable-sized text. Text writes existing fields in bounded chunks. Finish emits a fitting marker on exhaustion, including cancellation by a writer. Like io.Writer, a session cannot interrupt a Write already in progress.

func (*Session) Finish added in v1.62.0

func (s *Session) Finish() (int, error)

Finish completes the report, returning the actual bytes written and I/O error.

func (*Session) Header added in v1.62.0

func (s *Session) Header(message func())

Header writes an error header, invoking message only while work remains.

func (*Session) Note added in v1.62.0

func (s *Session) Note(note func())

Note streams a note without building an intermediate concatenated string.

func (*Session) Remaining added in v1.62.0

func (s *Session) Remaining() int

Remaining is the space available for content, excluding the reserved marker.

func (*Session) Span added in v1.62.0

func (s *Session) Span(span Span)

Span displays a source location and snippet under this session's budget.

func (*Session) Step added in v1.62.0

func (s *Session) Step() bool

Step charges one unit of work and checks cancellation. All producers share it.

func (*Session) Stop added in v1.62.0

func (s *Session) Stop()

Stop records that the complete diagnostic could not be produced.

func (*Session) Text added in v1.62.0

func (s *Session) Text(parts ...string)

Text writes fields separately so concatenation cannot allocate beyond the cap.

func (*Session) Write added in v1.62.0

func (s *Session) Write(p []byte) (int, error)

Write implements io.Writer for the renderer's fixed-size formatting pieces.

type Severity

type Severity int

Severity indicates the severity level of a diagnostic.

const (
	SeverityError Severity = iota
	SeverityWarning
	SeverityNote
)

func (Severity) String

func (s Severity) String() string

type Span

type Span struct {
	File   string // path for reading source; display name if unreadable
	Line   int    // 1-based line number
	Col    int    // 1-based start byte column
	EndCol int    // 1-based end byte column, INCLUSIVE (0 = auto-detect from source)
	Label  string // text shown under the underline
}

Span identifies a region of source code to highlight in the diagnostic.

UNITS AND CONVENTION. Col and EndCol are 1-based BYTE columns, and EndCol is INCLUSIVE -- it names the column of the span's last byte, not the one after it. A span covering "false" at columns 7 through 11 is Col: 7, EndCol: 11.

That is the OPPOSITE of parser/token.Location.EndCol, which is documented (as of the #463 fix) as an EXCLUSIVE byte column. The two types have same-named fields with opposite conventions, and nothing in the tree bridges one into the other today: cmd/diagnostic.go and repl/diagnostic.go both set Col and leave EndCol zero for auto-detection. The first caller to wire an analyser's end position straight into a Span would get an underline one caret too long, which is why the convention is written down here rather than left to be inferred (issue #469). Converting is `EndCol: loc.EndCol - 1`.

The RENDERER measures the underline in terminal CELLS rather than in bytes, so the carets line up with what a terminal draws even when the span holds multi-byte, East Asian wide, or combining characters -- see displayWidth in renderer.go. The byte convention here is about how a caller ADDRESSES the source; it is not the unit the carets are counted in.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL