1
0
mirror of https://github.com/golang/go synced 2024-11-19 04:34:39 -07:00
go/internal/lsp/cache/cache.go
Ian Cottrell f1f4a3381f internal/lsp: move configuration options to structs
This cl is the first in a set that change the configuration behaviour.
This one should have no behaviour differences, but makes a lot of preparatory changes.
The same options are set to the same values in the same places.
The options are now stored on the Session instead of the Server
The View supports options, but does not have any yet.

Change-Id: Ie966cceca6878861686a1766d63bb8a78021259b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/193726
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2019-09-06 17:30:54 +00:00

124 lines
2.6 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"
"crypto/sha1"
"fmt"
"go/token"
"strconv"
"sync/atomic"
"golang.org/x/tools/internal/lsp/debug"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/memoize"
"golang.org/x/tools/internal/span"
)
func New() source.Cache {
index := atomic.AddInt64(&cacheIndex, 1)
c := &cache{
fs: &nativeFileSystem{},
id: strconv.FormatInt(index, 10),
fset: token.NewFileSet(),
}
debug.AddCache(debugCache{c})
return c
}
type cache struct {
fs source.FileSystem
id string
fset *token.FileSet
store memoize.Store
}
type fileKey struct {
identity source.FileIdentity
}
type fileHandle struct {
cache *cache
underlying source.FileHandle
handle *memoize.Handle
}
type fileData struct {
memoize.NoCopy
bytes []byte
hash string
err error
}
func (c *cache) GetFile(uri span.URI) source.FileHandle {
underlying := c.fs.GetFile(uri)
key := fileKey{
identity: underlying.Identity(),
}
h := c.store.Bind(key, func(ctx context.Context) interface{} {
data := &fileData{}
data.bytes, data.hash, data.err = underlying.Read(ctx)
return data
})
return &fileHandle{
cache: c,
underlying: underlying,
handle: h,
}
}
func (c *cache) NewSession(ctx context.Context) source.Session {
index := atomic.AddInt64(&sessionIndex, 1)
s := &session{
cache: c,
id: strconv.FormatInt(index, 10),
options: source.DefaultSessionOptions,
overlays: make(map[span.URI]*overlay),
filesWatchMap: NewWatchMap(),
}
debug.AddSession(debugSession{s})
return s
}
func (c *cache) FileSet() *token.FileSet {
return c.fset
}
func (h *fileHandle) FileSystem() source.FileSystem {
return h.cache
}
func (h *fileHandle) Identity() source.FileIdentity {
return h.underlying.Identity()
}
func (h *fileHandle) Kind() source.FileKind {
return h.underlying.Kind()
}
func (h *fileHandle) Read(ctx context.Context) ([]byte, string, error) {
v := h.handle.Get(ctx)
if v == nil {
return nil, "", ctx.Err()
}
data := v.(*fileData)
return data.bytes, data.hash, data.err
}
func hashContents(contents []byte) string {
// TODO: consider whether sha1 is the best choice here
// This hash is used for internal identity detection only
return fmt.Sprintf("%x", sha1.Sum(contents))
}
var cacheIndex, sessionIndex, viewIndex int64
type debugCache struct{ *cache }
func (c *cache) ID() string { return c.id }
func (c debugCache) FileSet() *token.FileSet { return c.fset }