cache

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewOverlayFS

func NewOverlayFS(delegate FileSource) *overlayFS

Types

type Cache

type Cache struct {
	IncludePaths []string
	// contains filtered or unexported fields
}

func New

func New(includePaths []string) *Cache

func (*Cache) ID

func (c *Cache) ID() string

func (Cache) ReadFile

func (fs Cache) ReadFile(ctx context.Context, uri uri.URI) (FileHandle, error)

ReadFile stats and (maybe) reads the file, updates the cache, and returns it.

type Context

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

Context tracks, per file, its transitive include dependencies. It owns the IncludeGraph; callers never touch the underlying graph directly.

func NewContext

func NewContext() *Context

NewContext returns an empty context.

func (*Context) Clone

func (c *Context) Clone() *Context

Clone returns a deep copy, for snapshot copy-on-write.

func (*Context) Dependents

func (c *Context) Dependents(file uri.URI) []uri.URI

Dependents returns every file that directly or transitively includes file, including file itself when it transitively includes itself. The result is sorted ascending by URI and cycle-safe.

func (*Context) Forget

func (c *Context) Forget(file uri.URI) []uri.URI

Forget removes file's edges and returns its former dependents.

func (*Context) Register

func (c *Context) Register(file uri.URI, includes []*syntax.Include, resolve func(uri.URI, string) uri.URI) []uri.URI

Register replaces file's include edges, resolving them via resolve the same way snapshot parsing does. It returns the URIs whose dependency set changed: the union of file's old and new transitive dependents.

Duplicate includes resolve once; unknown include paths fall back to a relative path (see resolver.Resolve) and never crash.

type DiskFile

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

A DiskFile is a file on the filesystem, or a failure to read one. It implements the source.FileHandle interface.

func (*DiskFile) Content

func (h *DiskFile) Content() ([]byte, error)

func (*DiskFile) FileIdentity

func (h *DiskFile) FileIdentity() FileIdentity

func (*DiskFile) Saved

func (h *DiskFile) Saved() bool

func (*DiskFile) URI

func (h *DiskFile) URI() uri.URI

func (*DiskFile) Version

func (h *DiskFile) Version() int32

type FileChange

type FileChange struct {
	URI     uri.URI
	Version int
	Content []byte
	From    FileChangeType
}

func FileChangeFromLSPDidChange

func FileChangeFromLSPDidChange(params *protocol.DidChangeTextDocumentParams) []*FileChange

FileChangeFromLSPDidChange converts a didChange payload into file changes. The server advertises whole-document sync, so whole-document events map one-to-one; incremental (partial) events are a client protocol violation and are skipped.

func (*FileChange) FullContent

func (f *FileChange) FullContent(base []byte) []byte

type FileChangeType

type FileChangeType string
const (
	FileChangeTypeInitialize FileChangeType = "Initialize"
	FileChangeTypeDidOpen    FileChangeType = "DidOpen"
	FileChangeTypeDidChange  FileChangeType = "DidChange"
	FileChangeTypeDidSave    FileChangeType = "DidSave"
	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
	// FileIdentity returns a FileIdentity for the file, even if there was an
	// error reading it.
	FileIdentity() FileIdentity
	// Saved reports whether the file has the same content on disk:
	// it is false for files open on an editor with unsaved edits.
	Saved() bool
	// 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, hash, and optional version of a file tracked by the LSP session.

File content may be provided by the file system (for Saved files) or from an overlay, for open files with unsaved edits. A FileHandle may record an attempt to read a non-existent file, in which case Content returns an error.

type FileID

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

A FileID uniquely identifies a file in the file system.

If GetFileID(name1) returns the same ID as GetFileID(name2), the two file names denote the same file. A FileID is comparable, and thus suitable for use as a map key.

func GetFileID

func GetFileID(filename string) (FileID, time.Time, error)

GetFileID returns the file system's identifier for the file, and its modification time. Like os.Stat, it reads through symbolic links.

type FileIdentity

type FileIdentity struct {
	URI  uri.URI
	Hash Hash // digest of file contents
}

FileIdentity uniquely identifies a file at a version from a FileSystem.

func (FileIdentity) String

func (id FileIdentity) String() string

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)
}

A FileSource maps URIs to FileHandles.

type FilesMap

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

FilesMap holds files on disk and overlay files. Snapshots share the underlying maps (Clone is O(1)); the first write after a clone copies copy-on-write.

func (*FilesMap) Clone

func (m *FilesMap) Clone() *FilesMap

Clone returns a view sharing the same entries. The clone and the original both become copy-on-write.

func (*FilesMap) Forget

func (m *FilesMap) Forget(key uri.URI)

func (*FilesMap) Get

func (m *FilesMap) Get(key uri.URI) (FileHandle, bool)

func (*FilesMap) Set

func (m *FilesMap) Set(key uri.URI, file FileHandle)

type Hash

type Hash [sha256.Size]byte

func HashOf

func HashOf(data []byte) Hash

HashOf returns the hash of some data.

func Hashf

func Hashf(format string, args ...any) Hash

Hashf returns the hash of a printf-formatted string.

func (Hash) Less

func (h Hash) Less(other Hash) bool

Less returns true if the given hash is less than the other.

func (Hash) String

func (h Hash) String() string

String returns the digest as a string of hex digits.

func (*Hash) XORWith

func (h *Hash) XORWith(h2 Hash)

XORWith updates *h to *h XOR h2.

type IncludeGraph

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

IncludeGraph tracks include edges between files. Snapshots share the underlying mapper (Clone is O(1)); the first structural change after a clone deep-copies the graph, so edits that do not change include edges never pay for the copy.

func NewIncludeGraph

func NewIncludeGraph() *IncludeGraph

func (*IncludeGraph) Clone

func (g *IncludeGraph) Clone() *IncludeGraph

Clone returns a view sharing the same mapper. The clone and the original both become copy-on-write: the next structural change deep-copies.

func (*IncludeGraph) Debug

func (g *IncludeGraph) Debug()

func (*IncludeGraph) Get

func (g *IncludeGraph) Get(file uri.URI) *IncludeNode

Get returns a copy of file's node. The graph's nodes are mutated in place by Set and removeWithoutLock, so a live node must never escape the lock.

func (*IncludeGraph) Remove

func (g *IncludeGraph) Remove(file uri.URI)

func (*IncludeGraph) Set

func (g *IncludeGraph) Set(file uri.URI, includes []*syntax.Include, resolve func(cur uri.URI, includePath string) uri.URI)

Set records the include edges of file. resolve maps an include path text to the URI of the included file (e.g. the snapshot's include resolver).

type IncludeNode

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

func (*IncludeNode) Clone

func (n *IncludeNode) Clone() *IncludeNode

func (*IncludeNode) InDegree

func (n *IncludeNode) InDegree() []uri.URI

func (*IncludeNode) OutDegree

func (n *IncludeNode) OutDegree() []uri.URI

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 source.FileHandle interface.

func NewOverlay

func NewOverlay(uri uri.URI, content []byte, version int32) *Overlay

func (*Overlay) Content

func (o *Overlay) Content() ([]byte, error)

func (*Overlay) FileIdentity

func (o *Overlay) FileIdentity() FileIdentity

func (*Overlay) Saved

func (o *Overlay) Saved() bool

func (*Overlay) URI

func (o *Overlay) URI() uri.URI

func (*Overlay) Version

func (o *Overlay) Version() int32

type ParseCaches

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

ParseCaches maps URIs to parsed files. Snapshots share the underlying map (Clone is O(1)); the first write after a clone copies the map copy-on-write, so cloning per keystroke is cheap while old snapshots stay immutable.

func NewParseCaches

func NewParseCaches() *ParseCaches

func (*ParseCaches) Clone

func (c *ParseCaches) Clone() *ParseCaches

Clone returns a view sharing the same entries. The clone and the original both become copy-on-write.

func (*ParseCaches) Forget

func (c *ParseCaches) Forget(filePath uri.URI)

func (*ParseCaches) Get

func (c *ParseCaches) Get(filePath uri.URI) *ParsedFile

func (*ParseCaches) Set

func (c *ParseCaches) Set(filePath uri.URI, res *ParsedFile)

func (*ParseCaches) TokensForFile

func (c *ParseCaches) TokensForFile(file uri.URI, getIncludes func(uri.URI) []uri.URI) map[string]struct{}

TokensForFile returns tokens for the given file and its transitively included files. Each file's token set is computed once per parse and reused, so typing does not re-walk the include closure's ASTs.

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) 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) 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 Resolver

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

Resolver provides centralized include path resolution. It wraps the snapshot to provide a clean interface for resolving included files, types, and identifiers.

func NewResolver

func NewResolver(ss *Snapshot) *Resolver

NewResolver creates a resolver for the given snapshot

func (*Resolver) GetIncludePath

func (r *Resolver) GetIncludePath(ast *syntax.Document, includeName string) string

GetIncludePath returns the include path text for a given include name. Returns empty string if not found.

func (*Resolver) GetIncludeURI

func (r *Resolver) GetIncludeURI(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

func (r *Resolver) IncludePaths() []string

IncludePaths returns the include paths configured for this snapshot

func (*Resolver) ResolveInclude

func (r *Resolver) ResolveInclude(cur uri.URI, includePath string) uri.URI

ResolveInclude resolves an include path to a file URI. It first tries relative to the current file, then tries each include path.

type Session

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

func NewSession

func NewSession(cache *Cache) *Session

func (*Session) AddView

func (s *Session) AddView(folder uri.URI) *View

AddView registers a view for the workspace folder, returning the existing view when the folder is already tracked.

func (Session) Forget

func (fs Session) Forget(uri uri.URI)

Forget drops the overlay for uri, falling back to disk content.

func (Session) HasOverlay

func (fs Session) HasOverlay(uri uri.URI) bool

HasOverlay reports whether uri has an open overlay.

func (Session) Overlays

func (fs Session) Overlays() []*Overlay

Overlays returns a new unordered array of overlays.

func (Session) ReadFile

func (fs Session) ReadFile(ctx context.Context, uri uri.URI) (FileHandle, error)

func (*Session) RemoveView

func (s *Session) RemoveView(folder uri.URI)

RemoveView drops the view for the workspace folder and forgets every cached file-to-view mapping that pointed at it, so ViewOf re-resolves against the remaining folders.

func (Session) Update

func (fs Session) Update(ctx context.Context, changes []*FileChange) error

Update applies changes to the overlay set. DidClose changes remove the overlay; all other types create or replace it.

func (*Session) UpdateOverlayFS

func (s *Session) UpdateOverlayFS(ctx context.Context, changes []*FileChange) error

func (*Session) ViewOf

func (s *Session) ViewOf(fileURI uri.URI) (*View, error)

func (*Session) Views

func (s *Session) Views() []*View

Views returns the workspace folders' views.

type Snapshot

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

func BuildSnapshotForTest

func BuildSnapshotForTest(files []*FileChange) *Snapshot

func BuildSnapshotForTestWithPaths

func BuildSnapshotForTestWithPaths(includePaths []string, files []*FileChange) *Snapshot

BuildSnapshotForTestWithPaths is BuildSnapshotForTest with configured include paths, for cross-project include resolution tests.

func NewSnapshot

func NewSnapshot(view *View, includePaths []string) *Snapshot

func (*Snapshot) Acquire

func (s *Snapshot) Acquire() func()

func (*Snapshot) Dependents

func (s *Snapshot) Dependents(uri uri.URI) []uri.URI

Dependents returns the transitive dependents of uri: every file that directly or transitively includes it, in this snapshot.

func (*Snapshot) ForgetFile

func (s *Snapshot) ForgetFile(uri uri.URI)

ForgetFile is called when file changed or removed. It removes file's include edges and drops the parse and file caches for file and every transitive dependent of file: their derived data is rebuilt lazily on the next request, while their content survives on disk (or in the overlay).

func (*Snapshot) Graph

func (s *Snapshot) Graph() *IncludeGraph

func (*Snapshot) Parse

func (s *Snapshot) Parse(ctx context.Context, uri uri.URI) (*ParsedFile, error)

func (*Snapshot) ReadFile

func (s *Snapshot) ReadFile(ctx context.Context, uri uri.URI) (FileHandle, error)

func (*Snapshot) Resolver

func (s *Snapshot) Resolver() *Resolver

Resolver returns a new Resolver instance for this snapshot. The resolver provides centralized include path resolution.

func (*Snapshot) TokensForFile

func (s *Snapshot) TokensForFile(file uri.URI) map[string]struct{}

TokensForFile returns the identifier tokens of file and its transitively included files.

type View

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

func NewView

func NewView(name string, folder uri.URI, fs FileSource, includePaths []string) *View

func (*View) ContainsFile

func (v *View) ContainsFile(uri uri.URI) bool

func (*View) FileChange

func (v *View) FileChange(ctx context.Context, changes []*FileChange, postFns ...func(affected []uri.URI))

FileChange applies changes to the view: it swaps in a new snapshot (an O(1) copy-on-write clone) and re-parses the changed files, then runs the postFns asynchronously with the affected URIs (changed files plus their transitive dependents). The request thread never blocks on postFns, so diagnostics-heavy work (semantic analysis) does not stall the editor.

func (*View) FileKnown

func (v *View) FileKnown(uri uri.URI) bool

func (*View) Folder

func (v *View) Folder() uri.URI

Folder returns the workspace folder the view covers.

func (*View) IsCurrent

func (v *View) IsCurrent(ss *Snapshot) bool

IsCurrent reports whether ss is the view's latest snapshot. Used by asynchronous work to drop results that a newer change superseded.

func (*View) KnownFiles

func (v *View) KnownFiles() []uri.URI

KnownFiles returns the known file URIs of the view, sorted for deterministic iteration.

func (*View) MarkFileKnown

func (v *View) MarkFileKnown(fileURI uri.URI)

func (*View) Snapshot

func (v *View) Snapshot() (*Snapshot, func())

Jump to

Keyboard shortcuts

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