From d270ebf96e8890cc1f2c8add38e093b6f7a39eba Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Tue, 17 Dec 2019 15:43:36 -0500 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Heschi Kreinick --- internal/lsp/cache/analysis.go | 4 + internal/lsp/cache/builtin.go | 4 + internal/lsp/cache/debug.go | 72 +++++++++++++++ internal/lsp/cache/errors.go | 4 + internal/lsp/cache/overlay.go | 119 ++++++++++++++++++++++++ internal/lsp/cache/session.go | 163 --------------------------------- internal/lsp/cache/snapshot.go | 4 + internal/lsp/cache/view.go | 5 - 8 files changed, 207 insertions(+), 168 deletions(-) create mode 100644 internal/lsp/cache/debug.go create mode 100644 internal/lsp/cache/overlay.go diff --git a/internal/lsp/cache/analysis.go b/internal/lsp/cache/analysis.go index 3e31b6f9ed..a1b39ac7f7 100644 --- a/internal/lsp/cache/analysis.go +++ b/internal/lsp/cache/analysis.go @@ -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 import ( diff --git a/internal/lsp/cache/builtin.go b/internal/lsp/cache/builtin.go index 597268c2ac..00d68326da 100644 --- a/internal/lsp/cache/builtin.go +++ b/internal/lsp/cache/builtin.go @@ -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 import ( diff --git a/internal/lsp/cache/debug.go b/internal/lsp/cache/debug.go new file mode 100644 index 0000000000..f1865b54d9 --- /dev/null +++ b/internal/lsp/cache/debug.go @@ -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, + } +} diff --git a/internal/lsp/cache/errors.go b/internal/lsp/cache/errors.go index 0d93ccc33d..f6877fc770 100644 --- a/internal/lsp/cache/errors.go +++ b/internal/lsp/cache/errors.go @@ -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 import ( diff --git a/internal/lsp/cache/overlay.go b/internal/lsp/cache/overlay.go new file mode 100644 index 0000000000..e793f15d94 --- /dev/null +++ b/internal/lsp/cache/overlay.go @@ -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 +} diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go index ffd5d47597..32d44226e1 100644 --- a/internal/lsp/cache/session.go +++ b/internal/lsp/cache/session.go @@ -7,7 +7,6 @@ package cache import ( "context" "path/filepath" - "sort" "strconv" "strings" "sync" @@ -40,19 +39,6 @@ type session struct { 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 { 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) } -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 { 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, - } -} diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index b06eb71c38..7aae7d2f1b 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -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 import ( diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go index f397095715..76eda8c05c 100644 --- a/internal/lsp/cache/view.go +++ b/internal/lsp/cache/view.go @@ -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()) } - -type debugView struct{ *view } - -func (v debugView) ID() string { return v.id } -func (v debugView) Session() debug.Session { return debugSession{v.session} }