mirror of
https://github.com/golang/go
synced 2024-11-18 23:34:45 -07:00
c7d52e45e2
Previous changes to the config mechanism made the config options per-view, not per-session. We should now make sure to obey config changes per-view. This does not fix the configuration handling for "watchChangedFile" however. This should be done in a future CL. Change-Id: I73f6236386c36d2587fdb9c0601670833a4366c3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/194818 Run-TryBot: Rebecca Stambler <rstambler@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
326 lines
11 KiB
Go
326 lines
11 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package source
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"go/ast"
|
|
"go/token"
|
|
"go/types"
|
|
|
|
"golang.org/x/tools/go/analysis"
|
|
"golang.org/x/tools/go/packages"
|
|
"golang.org/x/tools/internal/imports"
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
|
"golang.org/x/tools/internal/span"
|
|
)
|
|
|
|
// FileIdentity uniquely identifies a file at a version from a FileSystem.
|
|
type FileIdentity struct {
|
|
URI span.URI
|
|
Version string
|
|
}
|
|
|
|
func (identity FileIdentity) String() string {
|
|
return fmt.Sprintf("%s%s", identity.URI, identity.Version)
|
|
}
|
|
|
|
// FileHandle represents a handle to a specific version of a single file from
|
|
// a specific file system.
|
|
type FileHandle interface {
|
|
// FileSystem returns the file system this handle was acquired from.
|
|
FileSystem() FileSystem
|
|
|
|
// Identity returns the FileIdentity for the file.
|
|
Identity() FileIdentity
|
|
|
|
// Kind returns the FileKind for the file.
|
|
Kind() FileKind
|
|
|
|
// Read reads the contents of a file and returns it along with its hash value.
|
|
// If the file is not available, returns a nil slice and an error.
|
|
Read(ctx context.Context) ([]byte, string, error)
|
|
}
|
|
|
|
// FileSystem is the interface to something that provides file contents.
|
|
type FileSystem interface {
|
|
// GetFile returns a handle for the specified file.
|
|
GetFile(uri span.URI) FileHandle
|
|
}
|
|
|
|
// FileKind describes the kind of the file in question.
|
|
// It can be one of Go, mod, or sum.
|
|
type FileKind int
|
|
|
|
const (
|
|
Go = FileKind(iota)
|
|
Mod
|
|
Sum
|
|
)
|
|
|
|
// TokenHandle represents a handle to the *token.File for a file.
|
|
type TokenHandle interface {
|
|
// File returns a file handle for which to get the *token.File.
|
|
File() FileHandle
|
|
|
|
// Token returns the *token.File for the file.
|
|
Token(ctx context.Context) (*token.File, error)
|
|
}
|
|
|
|
// ParseGoHandle represents a handle to the AST for a file.
|
|
type ParseGoHandle interface {
|
|
// File returns a file handle for which to get the AST.
|
|
File() FileHandle
|
|
|
|
// Mode returns the parse mode of this handle.
|
|
Mode() ParseMode
|
|
|
|
// Parse returns the parsed AST for the file.
|
|
// If the file is not available, returns nil and an error.
|
|
Parse(ctx context.Context) (*ast.File, error)
|
|
|
|
// Cached returns the AST for this handle, if it has already been stored.
|
|
Cached(ctx context.Context) (*ast.File, error)
|
|
}
|
|
|
|
// ParseMode controls the content of the AST produced when parsing a source file.
|
|
type ParseMode int
|
|
|
|
const (
|
|
// ParseHeader specifies that the main package declaration and imports are needed.
|
|
// This is the mode used when attempting to examine the package graph structure.
|
|
ParseHeader = ParseMode(iota)
|
|
|
|
// ParseExported specifies that the public symbols are needed, but things like
|
|
// private symbols and function bodies are not.
|
|
// This mode is used for things where a package is being consumed only as a
|
|
// dependency.
|
|
ParseExported
|
|
|
|
// ParseFull specifies the full AST is needed.
|
|
// This is used for files of direct interest where the entire contents must
|
|
// be considered.
|
|
ParseFull
|
|
)
|
|
|
|
// CheckPackageHandle represents a handle to a specific version of a package.
|
|
// It is uniquely defined by the file handles that make up the package.
|
|
type CheckPackageHandle interface {
|
|
// ID returns the ID of the package associated with the CheckPackageHandle.
|
|
ID() string
|
|
|
|
// ParseGoHandle returns a ParseGoHandle for which to get the package.
|
|
Files() []ParseGoHandle
|
|
|
|
// Config is the *packages.Config that the package metadata was loaded with.
|
|
Config() *packages.Config
|
|
|
|
// Check returns the type-checked Package for the CheckPackageHandle.
|
|
Check(ctx context.Context) (Package, error)
|
|
|
|
// Cached returns the Package for the CheckPackageHandle if it has already been stored.
|
|
Cached(ctx context.Context) (Package, error)
|
|
}
|
|
|
|
// Cache abstracts the core logic of dealing with the environment from the
|
|
// higher level logic that processes the information to produce results.
|
|
// The cache provides access to files and their contents, so the source
|
|
// package does not directly access the file system.
|
|
// A single cache is intended to be process wide, and is the primary point of
|
|
// sharing between all consumers.
|
|
// A cache may have many active sessions at any given time.
|
|
type Cache interface {
|
|
// A FileSystem that reads file contents from external storage.
|
|
FileSystem
|
|
|
|
// NewSession creates a new Session manager and returns it.
|
|
NewSession(ctx context.Context) Session
|
|
|
|
// FileSet returns the shared fileset used by all files in the system.
|
|
FileSet() *token.FileSet
|
|
|
|
// TokenHandle returns a TokenHandle for the given file handle.
|
|
TokenHandle(fh FileHandle) TokenHandle
|
|
|
|
// ParseGoHandle returns a ParseGoHandle for the given file handle.
|
|
ParseGoHandle(fh FileHandle, mode ParseMode) ParseGoHandle
|
|
}
|
|
|
|
// Session represents a single connection from a client.
|
|
// This is the level at which things like open files are maintained on behalf
|
|
// of the client.
|
|
// A session may have many active views at any given time.
|
|
type Session interface {
|
|
// NewView creates a new View and returns it.
|
|
NewView(ctx context.Context, name string, folder span.URI, options Options) View
|
|
|
|
// Cache returns the cache that created this session.
|
|
Cache() Cache
|
|
|
|
// View returns a view with a matching name, if the session has one.
|
|
View(name string) View
|
|
|
|
// ViewOf returns a view corresponding to the given URI.
|
|
ViewOf(uri span.URI) View
|
|
|
|
// Views returns the set of active views built by this session.
|
|
Views() []View
|
|
|
|
// Shutdown the session and all views it has created.
|
|
Shutdown(ctx context.Context)
|
|
|
|
// A FileSystem prefers the contents from overlays, and falls back to the
|
|
// content from the underlying cache if no overlay is present.
|
|
FileSystem
|
|
|
|
// DidOpen is invoked each time a file is opened in the editor.
|
|
DidOpen(ctx context.Context, uri span.URI, kind FileKind, text []byte)
|
|
|
|
// DidSave is invoked each time an open file is saved in the editor.
|
|
DidSave(uri span.URI)
|
|
|
|
// DidClose is invoked each time an open file is closed in the editor.
|
|
DidClose(uri span.URI)
|
|
|
|
// IsOpen returns whether the editor currently has a file open.
|
|
IsOpen(uri span.URI) bool
|
|
|
|
// Called to set the effective contents of a file from this session.
|
|
SetOverlay(uri span.URI, data []byte) (wasFirstChange bool)
|
|
|
|
// DidChangeOutOfBand is called when a file under the root folder
|
|
// changes. The file is not necessarily open in the editor.
|
|
DidChangeOutOfBand(ctx context.Context, f GoFile, change protocol.FileChangeType)
|
|
|
|
// Options returns a copy of the SessionOptions for this session.
|
|
Options() Options
|
|
|
|
// SetOptions sets the options of this session to new values.
|
|
SetOptions(Options)
|
|
}
|
|
|
|
// View represents a single workspace.
|
|
// This is the level at which we maintain configuration like working directory
|
|
// and build tags.
|
|
type View interface {
|
|
// Session returns the session that created this view.
|
|
Session() Session
|
|
|
|
// Name returns the name this view was constructed with.
|
|
Name() string
|
|
|
|
// Folder returns the root folder for this view.
|
|
Folder() span.URI
|
|
|
|
// BuiltinPackage returns the ast for the special "builtin" package.
|
|
BuiltinPackage() *ast.Package
|
|
|
|
// GetFile returns the file object for a given URI, initializing it
|
|
// if it is not already part of the view.
|
|
GetFile(ctx context.Context, uri span.URI) (File, error)
|
|
|
|
// FindFile returns the file object for a given URI if it is
|
|
// already part of the view.
|
|
FindFile(ctx context.Context, uri span.URI) File
|
|
|
|
// Called to set the effective contents of a file from this view.
|
|
SetContent(ctx context.Context, uri span.URI, content []byte) (wasFirstChange bool, err error)
|
|
|
|
// BackgroundContext returns a context used for all background processing
|
|
// on behalf of this view.
|
|
BackgroundContext() context.Context
|
|
|
|
// Shutdown closes this view, and detaches it from it's session.
|
|
Shutdown(ctx context.Context)
|
|
|
|
// Ignore returns true if this file should be ignored by this view.
|
|
Ignore(span.URI) bool
|
|
|
|
Config(ctx context.Context) *packages.Config
|
|
|
|
// RunProcessEnvFunc runs fn with the process env for this view inserted into opts.
|
|
// Note: the process env contains cached module and filesystem state.
|
|
RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options) error, opts *imports.Options) error
|
|
|
|
// Options returns a copy of the Options for this view.
|
|
Options() Options
|
|
|
|
// SetOptions sets the options of this view to new values.
|
|
// Warning: Do not use this, unless in a test.
|
|
// This function does not correctly invalidate the view when needed.
|
|
SetOptions(Options)
|
|
}
|
|
|
|
// File represents a source file of any type.
|
|
type File interface {
|
|
URI() span.URI
|
|
View() View
|
|
Handle(ctx context.Context) FileHandle
|
|
}
|
|
|
|
// GoFile represents a Go source file that has been type-checked.
|
|
type GoFile interface {
|
|
File
|
|
|
|
Builtin() (*ast.File, bool)
|
|
|
|
// GetCachedPackage returns the cached package for the file, if any.
|
|
GetCachedPackage(ctx context.Context) (Package, error)
|
|
|
|
// GetCachedPackage returns the cached package for the file, if any.
|
|
GetCachedPackages(ctx context.Context) ([]Package, error)
|
|
|
|
// GetPackage returns the CheckPackageHandle for the package that this file belongs to.
|
|
GetCheckPackageHandle(ctx context.Context) (CheckPackageHandle, error)
|
|
|
|
// GetPackages returns the CheckPackageHandles of the packages that this file belongs to.
|
|
GetCheckPackageHandles(ctx context.Context) ([]CheckPackageHandle, error)
|
|
|
|
// GetPackage returns the Package that this file belongs to.
|
|
GetPackage(ctx context.Context) (Package, error)
|
|
|
|
// GetPackages returns the Packages that this file belongs to.
|
|
GetPackages(ctx context.Context) ([]Package, error)
|
|
|
|
// GetActiveReverseDeps returns the active files belonging to the reverse
|
|
// dependencies of this file's package.
|
|
GetActiveReverseDeps(ctx context.Context) []GoFile
|
|
}
|
|
|
|
type ModFile interface {
|
|
File
|
|
}
|
|
|
|
type SumFile interface {
|
|
File
|
|
}
|
|
|
|
// Package represents a Go package that has been type-checked. It maintains
|
|
// only the relevant fields of a *go/packages.Package.
|
|
type Package interface {
|
|
ID() string
|
|
PkgPath() string
|
|
GetHandles() []ParseGoHandle
|
|
GetSyntax(context.Context) []*ast.File
|
|
GetErrors() []packages.Error
|
|
GetTypes() *types.Package
|
|
GetTypesInfo() *types.Info
|
|
GetTypesSizes() types.Sizes
|
|
IsIllTyped() bool
|
|
GetDiagnostics() []Diagnostic
|
|
SetDiagnostics(a *analysis.Analyzer, diag []Diagnostic)
|
|
|
|
// GetImport returns the CheckPackageHandle for a package imported by this package.
|
|
GetImport(ctx context.Context, pkgPath string) (Package, error)
|
|
|
|
// GetActionGraph returns the action graph for the given package.
|
|
GetActionGraph(ctx context.Context, a *analysis.Analyzer) (*Action, error)
|
|
|
|
// FindFile returns the AST and type information for a file that may
|
|
// belong to or be part of a dependency of the given package.
|
|
FindFile(ctx context.Context, uri span.URI, pos token.Pos) (ParseGoHandle, *ast.File, Package, error)
|
|
}
|