gopls/internal/lsp: remove the source.Session interface

The source.Session interface is not needed: the source package should
never need to know about sessions. Remove it in favor of the concrete
*cache.Session type.

Change-Id: I220a1fb1525c57f9fa2a4a4f80152c31a81565ff
Reviewed-on: https://go-review.googlesource.com/c/tools/+/435359
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Robert Findley 2022-09-28 10:42:33 -04:00
parent bddb3720ba
commit ae737bc619
4 changed files with 37 additions and 79 deletions

View File

@ -13,11 +13,11 @@ import (
"sync"
"sync/atomic"
"golang.org/x/tools/gopls/internal/lsp/progress"
"golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/imports"
"golang.org/x/tools/gopls/internal/lsp/progress"
"golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/internal/persistent"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/xcontext"
@ -120,26 +120,31 @@ func (c *closedFile) Version() int32 {
return 0
}
// ID returns the unique identifier for this session on this server.
func (s *Session) ID() string { return s.id }
func (s *Session) String() string { return s.id }
// Options returns a copy of the SessionOptions for this session.
func (s *Session) Options() *source.Options {
s.optionsMu.Lock()
defer s.optionsMu.Unlock()
return s.options
}
// SetOptions sets the options of this session to new values.
func (s *Session) SetOptions(options *source.Options) {
s.optionsMu.Lock()
defer s.optionsMu.Unlock()
s.options = options
}
// SetProgressTracker sets the progress tracker for the session.
func (s *Session) SetProgressTracker(tracker *progress.Tracker) {
// The progress tracker should be set before any view is initialized.
s.progress = tracker
}
// Shutdown the session and all views it has created.
func (s *Session) Shutdown(ctx context.Context) {
var views []*View
s.viewMu.Lock()
@ -153,10 +158,16 @@ func (s *Session) Shutdown(ctx context.Context) {
event.Log(ctx, "Shutdown session", KeyShutdownSession.Of(s))
}
func (s *Session) Cache() interface{} {
// Cache returns the cache that created this session, for debugging only.
func (s *Session) Cache() *Cache {
return s.cache
}
// NewView creates a new View, returning it and its first snapshot. If a
// non-empty tempWorkspace directory is provided, the View will record a copy
// of its gopls workspace module in that directory, so that client tooling
// can execute in the same main module. On success it also returns a release
// function that must be called when the Snapshot is no longer needed.
func (s *Session) NewView(ctx context.Context, name string, folder span.URI, options *source.Options) (source.View, source.Snapshot, func(), error) {
s.viewMu.Lock()
defer s.viewMu.Unlock()
@ -292,7 +303,7 @@ func (s *Session) createView(ctx context.Context, name string, folder span.URI,
return v, snapshot, snapshot.Acquire(), nil
}
// View returns the view by name.
// View returns a view with a matching name, if the session has one.
func (s *Session) View(name string) source.View {
s.viewMu.RLock()
defer s.viewMu.RUnlock()
@ -446,6 +457,11 @@ type fileChange struct {
isUnchanged bool
}
// DidModifyFiles reports a file modification to the session. It returns
// the new snapshots after the modifications have been applied, paired with
// the affected file URIs for those snapshots.
// On success, it returns a release function that
// must be called when the snapshots are no longer needed.
func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModification) (map[source.Snapshot][]span.URI, func(), error) {
s.viewMu.RLock()
defer s.viewMu.RUnlock()
@ -556,6 +572,9 @@ func (s *Session) DidModifyFiles(ctx context.Context, changes []source.FileModif
return snapshotURIs, release, nil
}
// ExpandModificationsToDirectories returns the set of changes with the
// directory changes removed and expanded to include all of the files in
// the directory.
func (s *Session) ExpandModificationsToDirectories(ctx context.Context, changes []source.FileModification) []source.FileModification {
s.viewMu.RLock()
defer s.viewMu.RUnlock()
@ -731,6 +750,7 @@ func (s *Session) updateOverlays(ctx context.Context, changes []source.FileModif
return overlays, nil
}
// GetFile returns a handle for the specified file.
func (s *Session) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) {
if overlay := s.readOverlay(uri); overlay != nil {
return overlay, nil
@ -749,6 +769,7 @@ func (s *Session) readOverlay(uri span.URI) *overlay {
return nil
}
// Overlays returns a slice of file overlays for the session.
func (s *Session) Overlays() []source.Overlay {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
@ -760,6 +781,9 @@ func (s *Session) Overlays() []source.Overlay {
return overlays
}
// FileWatchingGlobPatterns returns glob patterns to watch every directory
// known by the view. For views within a module, this is the module root,
// any directory in the module root, and any replace targets.
func (s *Session) FileWatchingGlobPatterns(ctx context.Context) map[string]struct{} {
s.viewMu.RLock()
defer s.viewMu.RUnlock()

View File

@ -26,6 +26,10 @@ import (
"sync"
"time"
"golang.org/x/tools/gopls/internal/lsp/cache"
"golang.org/x/tools/gopls/internal/lsp/debug/log"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/internal/bug"
"golang.org/x/tools/internal/event"
"golang.org/x/tools/internal/event/core"
"golang.org/x/tools/internal/event/export"
@ -34,12 +38,7 @@ import (
"golang.org/x/tools/internal/event/export/prometheus"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
"golang.org/x/tools/internal/bug"
"golang.org/x/tools/gopls/internal/lsp/cache"
"golang.org/x/tools/gopls/internal/lsp/debug/log"
"golang.org/x/tools/internal/event/tag"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/gopls/internal/lsp/source"
)
type contextKeyType int
@ -88,10 +87,7 @@ func (st *State) Caches() []*cache.Cache {
var caches []*cache.Cache
seen := make(map[string]struct{})
for _, client := range st.Clients() {
cache, ok := client.Session.Cache().(*cache.Cache)
if !ok {
continue
}
cache := client.Session.Cache()
if _, found := seen[cache.ID()]; found {
continue
}
@ -208,7 +204,7 @@ func (st *State) addClient(session *cache.Session) {
}
// DropClient removes a client from the set being served.
func (st *State) dropClient(session source.Session) {
func (st *State) dropClient(session *cache.Session) {
st.mu.Lock()
defer st.mu.Unlock()
for i, c := range st.clients {

View File

@ -10,6 +10,7 @@ import (
"fmt"
"sync"
"golang.org/x/tools/gopls/internal/lsp/cache"
"golang.org/x/tools/gopls/internal/lsp/progress"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/gopls/internal/lsp/source"
@ -21,7 +22,7 @@ const concurrentAnalyses = 1
// NewServer creates an LSP server and binds it to handle incoming client
// messages on on the supplied stream.
func NewServer(session source.Session, client protocol.ClientCloser) *Server {
func NewServer(session *cache.Session, client protocol.ClientCloser) *Server {
tracker := progress.NewTracker(client)
session.SetProgressTracker(tracker)
return &Server{
@ -70,7 +71,7 @@ type Server struct {
// notifications generated before serverInitialized
notifications []*protocol.ShowMessageParams
session source.Session
session *cache.Session
tempDir string

View File

@ -21,7 +21,6 @@ import (
"golang.org/x/mod/module"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/gopls/internal/lsp/progress"
"golang.org/x/tools/gopls/internal/lsp/protocol"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/imports"
@ -332,68 +331,6 @@ type Metadata interface {
ModuleInfo() *packages.Module
}
// 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 {
// ID returns the unique identifier for this session on this server.
ID() string
// NewView creates a new View, returning it and its first snapshot. If a
// non-empty tempWorkspace directory is provided, the View will record a copy
// of its gopls workspace module in that directory, so that client tooling
// can execute in the same main module. On success it also returns a release
// function that must be called when the Snapshot is no longer needed.
NewView(ctx context.Context, name string, folder span.URI, options *Options) (View, Snapshot, func(), error)
// Cache returns the cache that created this session, for debugging only.
Cache() interface{}
// 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, error)
// 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)
// GetFile returns a handle for the specified file.
GetFile(ctx context.Context, uri span.URI) (FileHandle, error)
// DidModifyFile reports a file modification to the session. It returns
// the new snapshots after the modifications have been applied, paired with
// the affected file URIs for those snapshots.
// On success, it returns a release function that
// must be called when the snapshots are no longer needed.
DidModifyFiles(ctx context.Context, changes []FileModification) (map[Snapshot][]span.URI, func(), error)
// ExpandModificationsToDirectories returns the set of changes with the
// directory changes removed and expanded to include all of the files in
// the directory.
ExpandModificationsToDirectories(ctx context.Context, changes []FileModification) []FileModification
// Overlays returns a slice of file overlays for the session.
Overlays() []Overlay
// Options returns a copy of the SessionOptions for this session.
Options() *Options
// SetOptions sets the options of this session to new values.
SetOptions(*Options)
// FileWatchingGlobPatterns returns glob patterns to watch every directory
// known by the view. For views within a module, this is the module root,
// any directory in the module root, and any replace targets.
FileWatchingGlobPatterns(ctx context.Context) map[string]struct{}
// SetProgressTracker sets the progress tracker for the session.
SetProgressTracker(tracker *progress.Tracker)
}
var ErrViewExists = errors.New("view already exists for session")
// Overlay is the type for a file held in memory on a session.