aboutsummaryrefslogtreecommitdiff
path: root/gopls/internal/lsp/cache/maps.go
diff options
context:
space:
mode:
Diffstat (limited to 'gopls/internal/lsp/cache/maps.go')
-rw-r--r--gopls/internal/lsp/cache/maps.go121
1 files changed, 121 insertions, 0 deletions
diff --git a/gopls/internal/lsp/cache/maps.go b/gopls/internal/lsp/cache/maps.go
new file mode 100644
index 000000000..0ad4ac90f
--- /dev/null
+++ b/gopls/internal/lsp/cache/maps.go
@@ -0,0 +1,121 @@
+// Copyright 2022 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 (
+ "strings"
+
+ "golang.org/x/tools/gopls/internal/lsp/source"
+ "golang.org/x/tools/gopls/internal/span"
+ "golang.org/x/tools/internal/persistent"
+)
+
+// TODO(euroelessar): Use generics once support for go1.17 is dropped.
+
+type filesMap struct {
+ impl *persistent.Map
+}
+
+// uriLessInterface is the < relation for "any" values containing span.URIs.
+func uriLessInterface(a, b interface{}) bool {
+ return a.(span.URI) < b.(span.URI)
+}
+
+func newFilesMap() filesMap {
+ return filesMap{
+ impl: persistent.NewMap(uriLessInterface),
+ }
+}
+
+func (m filesMap) Clone() filesMap {
+ return filesMap{
+ impl: m.impl.Clone(),
+ }
+}
+
+func (m filesMap) Destroy() {
+ m.impl.Destroy()
+}
+
+func (m filesMap) Get(key span.URI) (source.FileHandle, bool) {
+ value, ok := m.impl.Get(key)
+ if !ok {
+ return nil, false
+ }
+ return value.(source.FileHandle), true
+}
+
+func (m filesMap) Range(do func(key span.URI, value source.FileHandle)) {
+ m.impl.Range(func(key, value interface{}) {
+ do(key.(span.URI), value.(source.FileHandle))
+ })
+}
+
+func (m filesMap) Set(key span.URI, value source.FileHandle) {
+ m.impl.Set(key, value, nil)
+}
+
+func (m filesMap) Delete(key span.URI) {
+ m.impl.Delete(key)
+}
+
+func packageIDLessInterface(x, y interface{}) bool {
+ return x.(PackageID) < y.(PackageID)
+}
+
+type knownDirsSet struct {
+ impl *persistent.Map
+}
+
+func newKnownDirsSet() knownDirsSet {
+ return knownDirsSet{
+ impl: persistent.NewMap(func(a, b interface{}) bool {
+ return a.(span.URI) < b.(span.URI)
+ }),
+ }
+}
+
+func (s knownDirsSet) Clone() knownDirsSet {
+ return knownDirsSet{
+ impl: s.impl.Clone(),
+ }
+}
+
+func (s knownDirsSet) Destroy() {
+ s.impl.Destroy()
+}
+
+func (s knownDirsSet) Contains(key span.URI) bool {
+ _, ok := s.impl.Get(key)
+ return ok
+}
+
+func (s knownDirsSet) Range(do func(key span.URI)) {
+ s.impl.Range(func(key, value interface{}) {
+ do(key.(span.URI))
+ })
+}
+
+func (s knownDirsSet) SetAll(other knownDirsSet) {
+ s.impl.SetAll(other.impl)
+}
+
+func (s knownDirsSet) Insert(key span.URI) {
+ s.impl.Set(key, nil, nil)
+}
+
+func (s knownDirsSet) Remove(key span.URI) {
+ s.impl.Delete(key)
+}
+
+// analysisKeyLessInterface is the less-than relation for analysisKey
+// values wrapped in an interface.
+func analysisKeyLessInterface(a, b interface{}) bool {
+ x, y := a.(analysisKey), b.(analysisKey)
+ if cmp := strings.Compare(x.analyzerNames, y.analyzerNames); cmp != 0 {
+ return cmp < 0
+ }
+ return x.pkgid < y.pkgid
+}