toolchain/span
Where a piece of source is, and nothing else.
The leaf of the toolchain's public API: a compiler-free module that anything
reading Vader source needs and that nothing needs a compiler to understand.
toolchain/ast is built on it, vader/support/diagnostics anchors its diagnostics on
it, and a build-time generator shipped by a library reports through it.
It lives HERE rather than in vader/support/diagnostics because of what depends on it.
A library that ships a generator must not depend on the compiler, and the whole
of toolchain/ast needs exactly one thing from the diagnostics module: Span.
Splitting that one thing out is what makes the AST extractable at all; the rest
of the diagnostic machinery (severities, codes, the phase enums, rendering)
stays behind, because a generator has no use for it.
The three Span impls travel with the type, not with its consumers: an impl
belongs to the module declaring the type, and vader test compiles one
representative per module, so an impl left behind would be missing from every
closure that does not happen to import its old home.
Types
Position :: struct A point in a source file.
offset is a raw UTF-8 byte offset ; column is a 1-based codepoint
index within the line, malformed bytes decoded as codepoint_at_byte decodes
them. The LSP boundary translates to UTF-16 column counts when needed.
Fields
file: string offset: i64 line: i32 column: i32 Span :: struct Half-open span [start, end) in source.
Functions
file_head_span :: fn(path: string) -> Span A Span at the head of path: for a problem that is about the FILE rather
than about anything written in it.
The alternative is empty_span, which renders as <synthetic> and names no
file at all: a reader then has to guess which file to open. Use this whenever
the faulty file is known even though the faulty line is not.
Parameters
| path | string | the file the diagnostic is about. |
Returns
has_source_position :: fn(s: Span) -> bool True when s points at a real source location worth surfacing to a user:
a concrete file with a 1-based line. False for every compiler-minted
marker : the <synthetic> sentinel (empty_span), a blank file
(empty_span(file) with no file), or any non-positive line. Callers gate
per-op #line / DebugPos emission on this so no bogus #line 0 reaches
the C output or the debugger.
Parameters
| s | Span | the span to judge. |
Returns
bool true when the span names a real file at a real line.Constants
SYNTHETIC_FILE: string :: "<synthetic>" Sentinel file name on spans minted by the compiler with no real source origin (test fixtures, intrinsic stubs, lowering-synthesised nodes).