Documentation
¶
Index ¶
- func OpenDisk(files []string, folder string, includePaths []string) (*Session, *View, []uri.URI)
- func WithGeneration(ctx context.Context, generation uint64) context.Context
- type ChangeResult
- type Checker
- type FileChange
- type FileChangeType
- type FileHandle
- type FileIndex
- type FileSource
- type Overlay
- type OverlayFS
- func (fs *OverlayFS) Exists(ctx context.Context, path string) bool
- func (fs *OverlayFS) Forget(uri uri.URI)
- func (fs *OverlayFS) HasOverlay(uri uri.URI) bool
- func (fs *OverlayFS) ReadFile(ctx context.Context, uri uri.URI) (FileHandle, error)
- func (fs *OverlayFS) Update(_ context.Context, changes []*FileChange) error
- func (fs *OverlayFS) WalkFiles(ctx context.Context, root uri.URI, fn func(uri.URI) error) error
- type ParsedFile
- func (p *ParsedFile) AST() *syntax.Document
- func (p *ParsedFile) AggregatedError() error
- func (p *ParsedFile) Content() ([]byte, error)
- func (p *ParsedFile) Definitions() map[string]syntax.Node
- func (p *ParsedFile) EnumValues() map[string]*syntax.Identifier
- func (p *ParsedFile) Errors() []syntax.Error
- func (p *ParsedFile) Index() *FileIndex
- func (p *ParsedFile) Mapper() *mapper.Mapper
- func (p *ParsedFile) Tokens() map[string]struct{}
- func (p *ParsedFile) URI() uri.URI
- type RefKind
- type Reference
- type Resolver
- func (r *Resolver) GetIncludePath(ast *syntax.Document, includeName string) string
- func (r *Resolver) GetIncludeURI(ctx context.Context, cur uri.URI, ast *syntax.Document, includeName string) uri.URI
- func (r *Resolver) IncludePaths() []string
- func (r *Resolver) ResolveInclude(ctx context.Context, cur uri.URI, includePath string) uri.URI
- func (r *Resolver) ResolveIncludeCandidates(ctx context.Context, cur uri.URI, includePath string) []uri.URI
- type Session
- type View
- func (v *View) ContainsFile(uri uri.URI) bool
- func (v *View) Dependents(file uri.URI) []uri.URI
- func (v *View) Evict(files ...uri.URI)
- func (v *View) FileKnown(u uri.URI) bool
- func (v *View) Folder() uri.URI
- func (v *View) Generation() uint64
- func (v *View) Includers(file uri.URI) []uri.URI
- func (v *View) Includes(file uri.URI) []uri.URI
- func (v *View) IsCurrent(gen uint64) bool
- func (v *View) KnownFiles() []uri.URI
- func (v *View) Parse(ctx context.Context, u uri.URI) (*ParsedFile, error)
- func (v *View) ReadFile(ctx context.Context, u uri.URI) (FileHandle, error)
- func (v *View) Resolver() *Resolver
- func (v *View) TokensForFile(file uri.URI) map[string]struct{}
- func (v *View) Update(ctx context.Context, changes ...*FileChange) ChangeResult
- func (v *View) WalkFiles(ctx context.Context, root uri.URI, fn func(uri.URI) error) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func OpenDisk ¶
OpenDisk opens a session over the disk source with a view rooted at folder, and returns the session, its view, and the files' URIs. It is the non-editor entry point: check, dump, and other CLI frontends share it instead of hand-rolling sessions.
Files are deliberately not placed in the overlay: nothing is open in an editor, so parses read straight from disk and every pass observes what the previous pass wrote.
Types ¶
type ChangeResult ¶
type ChangeResult struct {
// Gen is the generation this change produced. Compare it against
// View.IsCurrent before publishing derived results.
Gen uint64
// Affected holds the changed URIs first, in order, then their
// transitive dependents, deduped. Edges were refreshed from an eager
// re-parse of the changed files, so it reflects the change.
Affected []uri.URI
}
ChangeResult reports what a batch of changes did: the new generation and the affected URIs (changed files plus their transitive dependents).
type Checker ¶
Checker tests file existence by OS path, without reading content. It is the existence half of the resolving system: the include resolver probes candidates through it, and frontends with a custom file layout (build systems, virtual trees) plug in by serving it from their graph. A FileSource that also implements Checker gets cheap probes for free.
type FileChange ¶
type FileChange struct {
URI uri.URI
Version int
Content []byte
From FileChangeType
}
type FileChangeType ¶
type FileChangeType string
const ( FileChangeTypeInitialize FileChangeType = "Initialize" FileChangeTypeDidOpen FileChangeType = "DidOpen" FileChangeTypeDidChange FileChangeType = "DidChange" FileChangeTypeDidClose FileChangeType = "DidClose" )
type FileHandle ¶
type FileHandle interface {
// URI is the URI for this file handle.
// TODO(rfindley): this is not actually well-defined. In some cases, there
// may be more than one URI that resolve to the same FileHandle. Which one is
// this?
URI() uri.URI
// Version returns the file version, as defined by the LSP client.
// For on-disk file handles, Version returns 0.
Version() int32
// Content returns the contents of a file.
// If the file is not available, returns a nil slice and an error.
Content() ([]byte, error)
}
A FileHandle represents the URI, content, and optional version of a file tracked by the LSP session.
File content may be provided by the file system or from an overlay for an open file with unsaved edits. A FileHandle may record an attempt to read a non-existent file, in which case Content returns an error.
type FileIndex ¶
type FileIndex struct {
// contains filtered or unexported fields
}
FileIndex is the per-file semantic index: the file's definitions, enum values, name references, and annotation names, extracted in a single AST walk and cached with the parse. A re-parse replaces the whole ParsedFile, so the index never goes stale.
The index answers "what does this file contain". Cross-file questions — "where is this name defined", "who references it" — belong to source.Index, which composes FileIndexes over the include graph.
func (*FileIndex) Defs ¶
Defs returns the file's top-level definitions indexed by name: structs, unions, exceptions, enums, services, consts, and typedefs. The node's concrete type identifies the definition kind.
func (*FileIndex) EnumValues ¶
func (x *FileIndex) EnumValues() map[string]*syntax.Identifier
EnumValues returns the file's enum value names indexed by name.
func (*FileIndex) References ¶
References returns every name reference in the file, in document order: field and signature type references, constant value identifiers, service extends references, and structured annotation type references.
type FileSource ¶
type FileSource interface {
// ReadFile returns the FileHandle for a given URI, either by
// reading the content of the file or by obtaining it from a cache.
ReadFile(ctx context.Context, uri uri.URI) (FileHandle, error)
// WalkFiles calls fn for every file under root, recursively, in
// lexical order. The caller filters by kind (e.g. extension). An
// error returned by fn stops the walk; per-entry failures (missing
// roots, permissions) are the implementation's to skip or report.
WalkFiles(ctx context.Context, root uri.URI, fn func(uri.URI) error) error
}
A FileSource maps URIs to FileHandles. It is the only filesystem seam: disk in production, in-memory in tests, build-system backed internally. A source may optionally implement Checker (Exists by OS path) to answer include probes without reading file bodies; sources that don't get a ReadFile fallback.
type Overlay ¶
type Overlay struct {
// contains filtered or unexported fields
}
An Overlay is a file open in the editor. It may have unsaved edits. It implements the FileHandle interface.
type OverlayFS ¶
type OverlayFS struct {
// contains filtered or unexported fields
}
An OverlayFS is a FileSource that keeps track of overlays on top of a delegate FileSource.
func NewOverlayFS ¶
func NewOverlayFS(delegate FileSource) *OverlayFS
func (*OverlayFS) Exists ¶
Exists reports whether path names an open overlay or an existing delegate file, without reading content. Open files count even when the disk copy is missing, so includes resolve for unsaved buffers.
func (*OverlayFS) HasOverlay ¶
HasOverlay reports whether uri has an open overlay.
func (*OverlayFS) Update ¶
func (fs *OverlayFS) Update(_ context.Context, changes []*FileChange) error
Update applies changes to the overlay set. DidClose changes remove the overlay; all other types create or replace it.
type ParsedFile ¶
type ParsedFile struct {
// contains filtered or unexported fields
}
func Parse ¶
func Parse(fh FileHandle) (*ParsedFile, error)
Parse lexes and parses the file content into a ParsedFile.
func (*ParsedFile) AST ¶
func (p *ParsedFile) AST() *syntax.Document
func (*ParsedFile) AggregatedError ¶
func (p *ParsedFile) AggregatedError() error
func (*ParsedFile) Content ¶
func (p *ParsedFile) Content() ([]byte, error)
Content returns the file's source text.
func (*ParsedFile) Definitions ¶
func (p *ParsedFile) Definitions() map[string]syntax.Node
Definitions returns the file's top-level definitions indexed by name: structs, unions, exceptions, enums, services, consts, and typedefs. The node's concrete type identifies the definition kind.
func (*ParsedFile) EnumValues ¶
func (p *ParsedFile) EnumValues() map[string]*syntax.Identifier
EnumValues returns the file's enum value names indexed by name.
func (*ParsedFile) Errors ¶
func (p *ParsedFile) Errors() []syntax.Error
func (*ParsedFile) Index ¶
func (p *ParsedFile) Index() *FileIndex
Index returns the file's semantic index: definitions, enum values, name references, and annotation names from a single AST walk.
func (*ParsedFile) Mapper ¶
func (p *ParsedFile) Mapper() *mapper.Mapper
func (*ParsedFile) Tokens ¶
func (p *ParsedFile) Tokens() map[string]struct{}
Tokens returns the identifier tokens of the file, computed once and reused. A re-parse replaces the whole ParsedFile, so the cache never goes stale.
type RefKind ¶
type RefKind uint8
RefKind classifies a name reference by the grammar slot it sits in. The slot decides what the reference can legally point at: an exception is only referenced from signatures, an enum value only from value positions.
const ( // RefFieldType is a type reference in a field-ish position: struct, // union, and exception fields, typedef targets, and const types. RefFieldType RefKind = iota + 1 // RefSignatureType is a type reference in a service signature: a // function return type, argument, or throws member. RefSignatureType // RefConstValue is an identifier in a constant value position: a field // default or a const value, possibly qualified ("Color.RED"). RefConstValue // RefServiceExtends is a service extends reference. RefServiceExtends // RefAnnotationType is a structured annotation's type reference: the // name in "@Name <value>", which must resolve to a declared type, // like the upfluence compiler's get_type call. RefAnnotationType )
type Reference ¶
type Reference struct {
Kind RefKind
// Name is the reference text as written: "User", "shared.User", or
// "shared.thrift.User".
Name string
// Node carries the reference's position: *syntax.Identifier for type
// and service references, *syntax.ConstValue for value references.
// Ranges come from the owning file's AST and mapper.
Node syntax.Node
}
Reference is one name occurrence that resolves to a definition somewhere: in this file or in an included one. It is a raw fact — the name text as written, uninterpreted. Qualifier parsing ("shared.User" vs "shared.thrift.User") and definition matching live in the source layer, which knows the include graph.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver provides centralized include path resolution.
func (*Resolver) GetIncludePath ¶
GetIncludePath returns the include path text for a given include name. Returns empty string if not found.
func (*Resolver) GetIncludeURI ¶
func (r *Resolver) GetIncludeURI(ctx context.Context, cur uri.URI, ast *syntax.Document, includeName string) uri.URI
GetIncludeURI returns the URI for an included file by include name. Returns empty URI if not found.
func (*Resolver) IncludePaths ¶
IncludePaths returns the include paths configured for this resolver.
func (*Resolver) ResolveInclude ¶
ResolveInclude resolves an include path to a file URI. It first tries relative to the current file, then tries each include path.
func (*Resolver) ResolveIncludeCandidates ¶
func (r *Resolver) ResolveIncludeCandidates(ctx context.Context, cur uri.URI, includePath string) []uri.URI
ResolveIncludeCandidates returns the existing locations of includePath for cur, nearest first. More than one location means the include path is shadowed by another include path.
type Session ¶
type Session struct {
// The session owns the OverlayFS: open-editor content lives here, and
// views read through it.
*OverlayFS
// contains filtered or unexported fields
}
func NewSession ¶
func NewSession(fs FileSource) *Session
func (*Session) AddView ¶
AddView registers a view for the workspace folder, returning the existing view when the folder is already tracked. includePaths is the folder's resolved include configuration; the view fixes it at creation.
func (*Session) RemoveView ¶
RemoveView drops the view for the workspace folder, invalidates its asynchronous work, and forgets every cached file-to-view mapping that pointed at it, so ViewOf re-resolves against the remaining folders.
type View ¶
type View struct {
// contains filtered or unexported fields
}
View is one workspace folder's file store: parsed files, the include graph between them, and the include configuration that applies to them.
Concurrency: entries and edges are guarded by mu; reads share immutable values, writes replace entries wholesale. gen bumps on every Update or Evict; asynchronous work compares its captured generation against View.IsCurrent to drop superseded results.
func BuildViewForTest ¶
func BuildViewForTest(files []*FileChange) *View
func BuildViewForTestWithPaths ¶
func BuildViewForTestWithPaths(includePaths []string, files []*FileChange) *View
BuildViewForTestWithPaths is BuildViewForTest with configured include paths, for cross-project include resolution tests.
func (*View) Dependents ¶
Dependents returns every file that directly or transitively includes file, including file itself when a cycle leads back to it. The result is sorted ascending by URI.
func (*View) Evict ¶
Evict removes files from the view and advances its generation. Advancing the generation also invalidates asynchronous work that was started for the evicted entries.
func (*View) Generation ¶
Generation returns the view's change counter. It increments on every FileChange; asynchronous work captures it and re-checks before publishing.
func (*View) Includers ¶
Includers returns the files that include file directly, sorted ascending by URI.
func (*View) IsCurrent ¶
IsCurrent reports whether gen is still the view's latest generation. Used by asynchronous work to drop results that a newer change superseded.
func (*View) KnownFiles ¶
KnownFiles returns the tracked file URIs of the view, sorted for deterministic iteration.
func (*View) Parse ¶
Parse returns the cached parse of uri, parsing it on first use. A parse failure (unreadable file) is not cached; syntax errors are carried on the ParsedFile itself.
func (*View) ReadFile ¶
ReadFile returns the current content of uri: the editor overlay for open files, the disk content otherwise.
func (*View) TokensForFile ¶
TokensForFile returns the identifier tokens of file and its transitively included files. Only already-parsed files contribute; nothing is forced.
func (*View) Update ¶
func (v *View) Update(ctx context.Context, changes ...*FileChange) ChangeResult
Update applies changes to the view: it invalidates the changed files' entries and re-parses them, so their include edges are fresh before any request observes the change. It returns what changed; publishing derived results (diagnostics) is the caller's policy.