1
0
mirror of https://github.com/golang/go synced 2024-11-05 18:46:11 -07:00

internal/lsp/cache: move overlay and debug handling into separate files

This change has no code modifications. Just move the handling for
overlays and debugging into separate files to make them easier to find.
Also, add some missing copyrights.

Change-Id: I7256f704c017457fa3418818d03f89f061af6fc9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/211757
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:
Rebecca Stambler 2019-12-17 15:43:36 -05:00
parent bc4a8d3946
commit d270ebf96e
8 changed files with 207 additions and 168 deletions

View File

@ -1,3 +1,7 @@
// Copyright 2019 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 cache package cache
import ( import (

View File

@ -1,3 +1,7 @@
// Copyright 2019 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 cache package cache
import ( import (

72
internal/lsp/cache/debug.go vendored Normal file
View File

@ -0,0 +1,72 @@
// Copyright 2019 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 cache
import (
"sort"
"golang.org/x/tools/internal/lsp/debug"
"golang.org/x/tools/internal/span"
)
type debugView struct{ *view }
func (v debugView) ID() string { return v.id }
func (v debugView) Session() debug.Session { return debugSession{v.session} }
type debugSession struct{ *session }
func (s debugSession) ID() string { return s.id }
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 {
f, ok := seen[overlay.uri]
if !ok {
f = &debug.File{Session: s, URI: overlay.uri}
seen[overlay.uri] = f
files = append(files, f)
}
f.Data = string(overlay.data)
f.Error = nil
f.Hash = overlay.hash
}
sort.Slice(files, func(i int, j int) bool {
return files[i].URI < files[j].URI
})
return files
}
func (s debugSession) File(hash string) *debug.File {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
for _, overlay := range s.overlays {
if overlay.hash == hash {
return &debug.File{
Session: s,
URI: overlay.uri,
Data: string(overlay.data),
Error: nil,
Hash: overlay.hash,
}
}
}
return &debug.File{
Session: s,
Hash: hash,
}
}

View File

@ -1,3 +1,7 @@
// Copyright 2019 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 cache package cache
import ( import (

119
internal/lsp/cache/overlay.go vendored Normal file
View File

@ -0,0 +1,119 @@
// Copyright 2019 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 cache
import (
"context"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/span"
)
type overlay struct {
session *session
uri span.URI
data []byte
hash string
version float64
kind source.FileKind
// sameContentOnDisk is true if a file has been saved on disk,
// and therefore does not need to be part of the overlay sent to go/packages.
sameContentOnDisk bool
}
func (o *overlay) FileSystem() source.FileSystem {
return o.session
}
func (o *overlay) Identity() source.FileIdentity {
return source.FileIdentity{
URI: o.uri,
Identifier: o.hash,
Version: o.version,
Kind: o.kind,
}
}
func (o *overlay) Read(ctx context.Context) ([]byte, string, error) {
return o.data, o.hash, nil
}
func (s *session) setOverlay(f source.File, version float64, data []byte) {
s.overlayMu.Lock()
defer func() {
s.overlayMu.Unlock()
s.filesWatchMap.Notify(f.URI(), source.Change)
}()
if data == nil {
delete(s.overlays, f.URI())
return
}
s.overlays[f.URI()] = &overlay{
session: s,
uri: f.URI(),
kind: f.Kind(),
data: data,
hash: hashContents(data),
version: version,
}
}
func (s *session) clearOverlay(uri span.URI) {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
delete(s.overlays, uri)
}
// openOverlay adds the file content to the overlay.
// It also checks if the provided content is equivalent to the file's content on disk.
func (s *session) openOverlay(ctx context.Context, uri span.URI, kind source.FileKind, version float64, data []byte) {
s.overlayMu.Lock()
defer func() {
s.overlayMu.Unlock()
s.filesWatchMap.Notify(uri, source.Open)
}()
s.overlays[uri] = &overlay{
session: s,
uri: uri,
kind: kind,
data: data,
hash: hashContents(data),
version: version,
}
// 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
}
}
}
func (s *session) readOverlay(uri span.URI) *overlay {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
// We might have the content saved in an overlay.
if overlay, ok := s.overlays[uri]; ok {
return overlay
}
return nil
}
func (s *session) buildOverlay() map[string][]byte {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
overlays := make(map[string][]byte)
for uri, overlay := range s.overlays {
if overlay.sameContentOnDisk {
continue
}
overlays[uri.Filename()] = overlay.data
}
return overlays
}

View File

@ -7,7 +7,6 @@ package cache
import ( import (
"context" "context"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -40,19 +39,6 @@ type session struct {
filesWatchMap *WatchMap filesWatchMap *WatchMap
} }
type overlay struct {
session *session
uri span.URI
data []byte
hash string
version float64
kind source.FileKind
// sameContentOnDisk is true if a file has been saved on disk,
// and therefore does not need to be part of the overlay sent to go/packages.
sameContentOnDisk bool
}
func (s *session) Options() source.Options { func (s *session) Options() source.Options {
return s.options return s.options
} }
@ -377,155 +363,6 @@ func (s *session) GetFile(uri span.URI, kind source.FileKind) source.FileHandle
return s.cache.GetFile(uri, kind) return s.cache.GetFile(uri, kind)
} }
func (s *session) setOverlay(f source.File, version float64, data []byte) {
s.overlayMu.Lock()
defer func() {
s.overlayMu.Unlock()
s.filesWatchMap.Notify(f.URI(), source.Change)
}()
if data == nil {
delete(s.overlays, f.URI())
return
}
s.overlays[f.URI()] = &overlay{
session: s,
uri: f.URI(),
kind: f.Kind(),
data: data,
hash: hashContents(data),
version: version,
}
}
func (s *session) clearOverlay(uri span.URI) {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
delete(s.overlays, uri)
}
// openOverlay adds the file content to the overlay.
// It also checks if the provided content is equivalent to the file's content on disk.
func (s *session) openOverlay(ctx context.Context, uri span.URI, kind source.FileKind, version float64, data []byte) {
s.overlayMu.Lock()
defer func() {
s.overlayMu.Unlock()
s.filesWatchMap.Notify(uri, source.Open)
}()
s.overlays[uri] = &overlay{
session: s,
uri: uri,
kind: kind,
data: data,
hash: hashContents(data),
version: version,
}
// 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
}
}
}
func (s *session) readOverlay(uri span.URI) *overlay {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
// We might have the content saved in an overlay.
if overlay, ok := s.overlays[uri]; ok {
return overlay
}
return nil
}
func (s *session) buildOverlay() map[string][]byte {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
overlays := make(map[string][]byte)
for uri, overlay := range s.overlays {
if overlay.sameContentOnDisk {
continue
}
overlays[uri.Filename()] = overlay.data
}
return overlays
}
func (s *session) DidChangeOutOfBand(ctx context.Context, uri span.URI, action source.FileAction) bool { func (s *session) DidChangeOutOfBand(ctx context.Context, uri span.URI, action source.FileAction) bool {
return s.filesWatchMap.Notify(uri, action) return s.filesWatchMap.Notify(uri, action)
} }
func (o *overlay) FileSystem() source.FileSystem {
return o.session
}
func (o *overlay) Identity() source.FileIdentity {
return source.FileIdentity{
URI: o.uri,
Identifier: o.hash,
Version: o.version,
Kind: o.kind,
}
}
func (o *overlay) Read(ctx context.Context) ([]byte, string, error) {
return o.data, o.hash, nil
}
type debugSession struct{ *session }
func (s debugSession) ID() string { return s.id }
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 {
f, ok := seen[overlay.uri]
if !ok {
f = &debug.File{Session: s, URI: overlay.uri}
seen[overlay.uri] = f
files = append(files, f)
}
f.Data = string(overlay.data)
f.Error = nil
f.Hash = overlay.hash
}
sort.Slice(files, func(i int, j int) bool {
return files[i].URI < files[j].URI
})
return files
}
func (s debugSession) File(hash string) *debug.File {
s.overlayMu.Lock()
defer s.overlayMu.Unlock()
for _, overlay := range s.overlays {
if overlay.hash == hash {
return &debug.File{
Session: s,
URI: overlay.uri,
Data: string(overlay.data),
Error: nil,
Hash: overlay.hash,
}
}
}
return &debug.File{
Session: s,
Hash: hash,
}
}

View File

@ -1,3 +1,7 @@
// Copyright 2019 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 cache package cache
import ( import (

View File

@ -529,8 +529,3 @@ func findFileInPackage(pkg source.Package, uri span.URI) (source.ParseGoHandle,
} }
return nil, nil, errors.Errorf("no file for %s in package %s", uri, pkg.ID()) return nil, nil, errors.Errorf("no file for %s in package %s", uri, pkg.ID())
} }
type debugView struct{ *view }
func (v debugView) ID() string { return v.id }
func (v debugView) Session() debug.Session { return debugSession{v.session} }