Documentation
¶
Overview ¶
Package sema lowers a parse tree to the resolved semantic model in the ir package: it resolves names, lowers sugar to prelude types, and interns type references.
It is private and free to change. `ir` and `proto` are the compatibility surface, not this.
See docs/design/ir-plan.md for what each pass adds: the declaration table, the interned type and unit tables, scopes and shadowing, the recursion rules, imports, classes and instances, constraints, and targets.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Diagnostic ¶
Diagnostic is one problem found while lowering, at a source position.
func (*Diagnostic) Error ¶
func (d *Diagnostic) Error() string
type Diagnostics ¶
type Diagnostics []*Diagnostic
Diagnostics is every problem one pass found.
A pass reports all of them rather than stopping at the first, the way the parser reports every syntax error. A non-empty list means no later pass should run: every diagnostic it produced against a model this one rejected would be noise.
func Lower ¶
Lower turns a parsed file into a model. It returns the model and every diagnostic the pass produced; a non-empty diagnostic list means the model is incomplete and no later pass should run against it.
The prelude is loaded into an outer scope, so a file may declare a name the prelude already has and its own declaration wins.
func (Diagnostics) Error ¶
func (ds Diagnostics) Error() string
type FSLoader ¶
type FSLoader struct{}
FSLoader resolves an import as a filesystem path relative to the file that imports it, which is what the spec says a bare path means.
type Loader ¶
type Loader interface {
// Load returns the resolved name of the file imported as path from the
// file at from, and its source.
Load(from, path string) (name, src string, err error)
}
Loader reads the source of an imported file.
Lowering does not touch the filesystem itself, so a caller can supply dependency roots, an in-memory tree, or a vendored directory without lowering knowing about any of it.
type Option ¶
type Option func(*config)
Option configures a lowering.
func WithLoader ¶
WithLoader supplies the Loader that reads imported files. Without one, a file that imports anything is a diagnostic rather than a filesystem read nobody asked for.
func WithPrelude ¶
WithPrelude lowers against the given prelude source instead of the embedded one. Pointing at a replacement is what makes the prelude replaceable rather than built in.
func WithReferences ¶ added in v0.2.2
func WithReferences(out *References) Option
WithReferences records every name lowering resolves into out.
Recording is opt-in because nothing but an editor wants it: `tdl check` and `tdl gen` resolve the same names and throw the answers away, and they should keep doing that rather than allocate a table nobody reads.
type Reference ¶ added in v0.2.2
type Reference struct {
Pos ast.Position // where the name was written
Len int // its length in bytes, so a caller can underline it
Name string // the name as written
// Target is where what the name refers to was declared, and is zero
// when there is nowhere to go: a name that did not resolve has none,
// and neither does a qualified one, whose declaration is in a
// dependency this model parsed for its names and not for its
// positions. A name a `_` import merged in has the position it was
// declared at, in the dependency that declares it.
Target ast.Position
// Decl is the declaration the name refers to, for a caller that wants
// the model entry rather than a position. It is unset for a type
// parameter, which declares nothing, and for an unresolved name.
Decl *ir.ID
}
Reference is one name, as written, and what it resolved to.
Lowering resolves every name and then keeps only the answer's effect: a type reference is interned into the type table, and the table is keyed by structure, so the second mention of a name is not a second entry and a cursor on it has nothing to find. This records the question instead, which is what a "go to definition" is asking.
Target is where to go. It is where the name was bound rather than a position derived later, so the ladder that decided what a name means, shadowing, the prelude, and `_` imports, is applied once, by the code that already applies it.
type References ¶ added in v0.2.2
type References []Reference
References is every name one lowering resolved, in source order.
func (References) At ¶ added in v0.2.2
func (rs References) At(filename string, offset int) (Reference, bool)
At returns the reference covering a byte offset in a file, and whether there is one.
References are sorted, so this is a binary search rather than a walk: an editor asks this on every hover, and a model is not small.