1
0
mirror of https://github.com/golang/go synced 2024-10-01 16:28:33 -06:00
go/internal/lsp/cache/overlay.go
Rebecca Stambler d270ebf96e 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>
2019-12-18 19:17:43 +00:00

120 lines
2.7 KiB
Go

// 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
}