mirror of https://github.com/golang/go.git
internal/lsp/cache: consolidate function to update overlays
This change merges the small helper functions that modified overlays into a single function and removes the openFiles sync.Map in the view. Change-Id: Id94c7d86228c9628b7373fab0030ad0c8018dda5 Reviewed-on: https://go-review.googlesource.com/c/tools/+/212037 Run-TryBot: Rebecca Stambler <rstambler@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
parent
62b9674312
commit
85a3356613
|
|
@ -23,15 +23,6 @@ func (s debugSession) Cache() debug.Cache { return debugCache{s.cache} }
|
|||
func (s debugSession) Files() []*debug.File {
|
||||
var files []*debug.File
|
||||
seen := make(map[span.URI]*debug.File)
|
||||
s.openFiles.Range(func(key interface{}, value interface{}) bool {
|
||||
uri, ok := key.(span.URI)
|
||||
if ok {
|
||||
f := &debug.File{Session: s, URI: uri}
|
||||
seen[uri] = f
|
||||
files = append(files, f)
|
||||
}
|
||||
return true
|
||||
})
|
||||
s.overlayMu.Lock()
|
||||
defer s.overlayMu.Unlock()
|
||||
for _, overlay := range s.overlays {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
package cache
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
|
|
@ -42,87 +41,59 @@ func (o *overlay) Read(ctx context.Context) ([]byte, string, error) {
|
|||
return o.data, o.hash, nil
|
||||
}
|
||||
|
||||
func (s *session) setOverlay(uri span.URI, version float64, data []byte) error {
|
||||
func (s *session) updateOverlay(ctx context.Context, c source.FileModification) error {
|
||||
s.overlayMu.Lock()
|
||||
defer s.overlayMu.Unlock()
|
||||
|
||||
o, ok := s.overlays[uri]
|
||||
if !ok {
|
||||
return errors.Errorf("setting overlay for unopened file %s", uri)
|
||||
o, ok := s.overlays[c.URI]
|
||||
|
||||
// Determine the file kind on open, otherwise, assume it has been cached.
|
||||
var kind source.FileKind
|
||||
switch c.Action {
|
||||
case source.Open:
|
||||
kind = source.DetectLanguage(c.LanguageID, c.URI.Filename())
|
||||
default:
|
||||
if !ok {
|
||||
return errors.Errorf("updateOverlay: modifying unopened overlay %v", c.URI)
|
||||
}
|
||||
kind = o.kind
|
||||
}
|
||||
s.overlays[uri] = &overlay{
|
||||
session: s,
|
||||
uri: uri,
|
||||
kind: o.kind,
|
||||
data: data,
|
||||
hash: hashContents(data),
|
||||
version: version,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) closeOverlay(uri span.URI) error {
|
||||
s.openFiles.Delete(uri)
|
||||
|
||||
s.overlayMu.Lock()
|
||||
defer s.overlayMu.Unlock()
|
||||
|
||||
_, ok := s.overlays[uri]
|
||||
if !ok {
|
||||
return errors.Errorf("closing unopened overlay %s", uri)
|
||||
}
|
||||
delete(s.overlays, uri)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) openOverlay(ctx context.Context, uri span.URI, languageID string, version float64, data []byte) error {
|
||||
kind := source.DetectLanguage(languageID, uri.Filename())
|
||||
if kind == source.UnknownKind {
|
||||
return errors.Errorf("openOverlay: unknown file kind for %s", uri)
|
||||
return errors.Errorf("updateOverlay: unknown file kind for %s", c.URI)
|
||||
}
|
||||
|
||||
s.openFiles.Store(uri, true)
|
||||
|
||||
s.overlayMu.Lock()
|
||||
defer s.overlayMu.Unlock()
|
||||
|
||||
s.overlays[uri] = &overlay{
|
||||
session: s,
|
||||
uri: uri,
|
||||
kind: kind,
|
||||
data: data,
|
||||
hash: hashContents(data),
|
||||
version: version,
|
||||
// Closing a file just deletes its overlay.
|
||||
if c.Action == source.Close {
|
||||
delete(s.overlays, c.URI)
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the file is on disk, check if its content is the same as the overlay.
|
||||
if _, hash, err := s.cache.GetFile(uri, kind).Read(ctx); err == nil {
|
||||
if hash == s.overlays[uri].hash {
|
||||
s.overlays[uri].sameContentOnDisk = true
|
||||
hash := hashContents(c.Text)
|
||||
var sameContentOnDisk bool
|
||||
switch c.Action {
|
||||
case source.Open:
|
||||
_, h, err := s.cache.GetFile(c.URI, kind).Read(ctx)
|
||||
sameContentOnDisk = (err == nil && h == hash)
|
||||
case source.Save:
|
||||
// Make sure the version and content (if present) is the same.
|
||||
if o.version != c.Version {
|
||||
return errors.Errorf("updateOverlay: saving %s at version %v, currently at %v", c.URI, c.Version, o.version)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *session) saveOverlay(uri span.URI, version float64, data []byte) error {
|
||||
s.overlayMu.Lock()
|
||||
defer s.overlayMu.Unlock()
|
||||
|
||||
o, ok := s.overlays[uri]
|
||||
if !ok {
|
||||
return errors.Errorf("saveOverlay: unopened overlay %s", uri)
|
||||
}
|
||||
if o.version != version {
|
||||
return errors.Errorf("saveOverlay: saving %s at version %v, currently at %v", uri, version, o.version)
|
||||
}
|
||||
if data != nil {
|
||||
if !bytes.Equal(o.data, data) {
|
||||
return errors.Errorf("saveOverlay: overlay %s changed on save", uri)
|
||||
if c.Text != nil && o.hash != hash {
|
||||
return errors.Errorf("updateOverlay: overlay %s changed on save", c.URI)
|
||||
}
|
||||
o.data = data
|
||||
sameContentOnDisk = true
|
||||
}
|
||||
s.overlays[c.URI] = &overlay{
|
||||
session: s,
|
||||
uri: c.URI,
|
||||
data: c.Text,
|
||||
version: c.Version,
|
||||
kind: kind,
|
||||
hash: hash,
|
||||
sameContentOnDisk: sameContentOnDisk,
|
||||
}
|
||||
o.sameContentOnDisk = true
|
||||
o.version = version
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ type session struct {
|
|||
|
||||
overlayMu sync.Mutex
|
||||
overlays map[span.URI]*overlay
|
||||
|
||||
openFiles sync.Map
|
||||
}
|
||||
|
||||
func (s *session) Options() source.Options {
|
||||
|
|
@ -276,25 +274,11 @@ func (s *session) dropView(ctx context.Context, v *view) (int, error) {
|
|||
func (s *session) DidModifyFile(ctx context.Context, c source.FileModification) ([]source.Snapshot, error) {
|
||||
ctx = telemetry.URI.With(ctx, c.URI)
|
||||
|
||||
// Perform session-specific actions.
|
||||
switch c.Action {
|
||||
case source.Open:
|
||||
if err := s.openOverlay(ctx, c.URI, c.LanguageID, c.Version, c.Text); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case source.Change:
|
||||
if err := s.setOverlay(c.URI, c.Version, c.Text); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case source.Save:
|
||||
if err := s.saveOverlay(c.URI, c.Version, c.Text); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case source.Close:
|
||||
if err := s.closeOverlay(c.URI); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Perform the session-specific updates.
|
||||
if err := s.updateOverlay(ctx, c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var snapshots []source.Snapshot
|
||||
for _, view := range s.viewsOf(c.URI) {
|
||||
if view.Ignore(c.URI) {
|
||||
|
|
@ -311,7 +295,10 @@ func (s *session) DidModifyFile(ctx context.Context, c source.FileModification)
|
|||
}
|
||||
|
||||
func (s *session) IsOpen(uri span.URI) bool {
|
||||
_, open := s.openFiles.Load(uri)
|
||||
s.overlayMu.Lock()
|
||||
defer s.overlayMu.Unlock()
|
||||
|
||||
_, open := s.overlays[uri]
|
||||
return open
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue