Skip to content

Commit a23afdf

Browse files
committed
internal/gopls: rewrite gopls/cuelsp
Implement the foundation of LSP for CUE. This foundation is written using terms that refer to the LSP spec itself, such as "Workspace" and "WorkspaceFolder". https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/ The gopls terms such as "session", "view", "snapshot" are all gone. This foundation achieves the following: - workspaces can be created, containing one or more workspace folders - workspaces can be reconfigured - workspace folders can be configured, and reconfigured - the server understands text modification messages from the client - it can search for and load cue modules - it can search for and load cue packages within modules - it understands when modules and packages need to be reloaded, including: - a file changes package - a package vanishes - one package is imported by another and the upstream is dirtied - it can apply cue canonical formatting to a file This currently does not cope at all with cue files which are not part of any package and module. This does not perform any analysis of cue files beyond extracting their package and imports. Signed-off-by: Matthew Sackman <[email protected]> Change-Id: I28e66d8ee294aeed50f0dfae05bf5f508886c9d1 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1218103 Reviewed-by: Roger Peppe <[email protected]> Unity-Result: CUE porcuepine <[email protected]> TryBot-Result: CUEcueckoo <[email protected]>
1 parent ca86fb0 commit a23afdf

File tree

32 files changed

+2392
-601
lines changed

32 files changed

+2392
-601
lines changed

cmd/cue/cmd/integration/base/base_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//go:build !windows
2-
31
package feature
42

53
import (
@@ -16,7 +14,6 @@ func TestMain(m *testing.M) {
1614
}
1715

1816
func TestFormatFile(t *testing.T) {
19-
t.Skip("cuelsp disabled")
2017
const files = `
2118
-- cue.mod/module.cue --
2219
module: "mod.example"

cmd/cue/cmd/integration/workspace/editing_test.go

Lines changed: 126 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//go:build !windows
2-
31
package workspace
42

53
import (
@@ -11,7 +9,6 @@ import (
119
)
1210

1311
func TestEditing(t *testing.T) {
14-
t.Skip("cuelsp disabled")
1512
const files = `
1613
-- cue.mod/module.cue --
1714
module: "mod.example/x"
@@ -41,75 +38,158 @@ v2: "hi"
4138
v3: a.v1
4239
`
4340

44-
t.Run("open", func(t *testing.T) {
41+
t.Run("open - one package only", func(t *testing.T) {
4542
WithOptions(RootURIAsDefaultFolder()).Run(t, files, func(t *testing.T, env *Env) {
43+
rootURI := env.Sandbox.Workdir.RootURI()
44+
env.Await(
45+
LogExactf(protocol.Debug, 1, false, "Workspace folder added: %v", rootURI),
46+
)
4647
env.OpenFile("a/a.cue")
4748
env.Await(
48-
// There's a snapshot for a/a.cue (because it was opened):
49-
LogMatching(protocol.Debug, `/a/a\.cue":{"file://`, 1, false),
50-
// a/a.cue belongs to two packages:
51-
LogMatching(protocol.Debug, `/a/a\.cue":\["mod\.example/x/a","mod\.example/x/a@v0:a"\]`, 1, false),
52-
// a/d/d.cue belongs to one package:
53-
LogMatching(protocol.Debug, `/a/d/d\.cue":\["mod\.example/x/a/d@v0:e"\]`, 1, false),
54-
// b/b.cue is used in two packages because of ancestor imports:
55-
LogMatching(protocol.Debug, `/b/b\.cue":\["mod\.example/x/b/c@v0:b","mod\.example/x/b@v0:b"\]`, 1, false),
56-
// b/c/c.cue only exists in one package:
57-
LogMatching(protocol.Debug, `/b/c/c.cue":\["mod\.example/x/b/c@v0:b"\]`, 1, false),
49+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=unknown Created", rootURI),
50+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Reloaded", rootURI),
51+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/a/a.cue found [Package dir=%v/a importPath=mod.example/x/a@v0]", rootURI, rootURI, rootURI),
52+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/a@v0]", rootURI),
53+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a importPath=mod.example/x/a@v0", rootURI, rootURI),
5854
)
5955
})
6056
})
6157

62-
t.Run("edit - split ancestor imports", func(t *testing.T) {
58+
t.Run("open - one package only - ancestor", func(t *testing.T) {
6359
WithOptions(RootURIAsDefaultFolder()).Run(t, files, func(t *testing.T, env *Env) {
64-
env.OpenFile("b/b.cue")
60+
rootURI := env.Sandbox.Workdir.RootURI()
6561
env.Await(
66-
// There's a snapshot for b/b.cue (because it was opened):
67-
LogMatching(protocol.Debug, `/b/b\.cue":{"file://`, 1, false),
68-
// b/b.cue is used in two packages because of ancestor imports:
69-
LogMatching(protocol.Debug, `/b/b\.cue":\["mod\.example/x/b/c@v0:b","mod\.example/x/b@v0:b"\]`, 1, false),
70-
// b/c/c.cue only exists in one package:
71-
LogMatching(protocol.Debug, `/b/c/c.cue":\["mod\.example/x/b/c@v0:b"\]`, 1, false),
62+
LogExactf(protocol.Debug, 1, false, "Workspace folder added: %v", rootURI),
7263
)
64+
env.OpenFile("b/c/c.cue")
65+
env.Await(
66+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=unknown Created", rootURI),
67+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Reloaded", rootURI),
68+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/b/c/c.cue found [Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b]", rootURI, rootURI, rootURI),
69+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b]", rootURI),
70+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b", rootURI, rootURI),
71+
// We do not load the parent/same package
72+
NoLogExactf(protocol.Debug, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b@v0]", rootURI),
73+
)
74+
// Although we have not loaded the mod.example/x/b@v0
75+
// package, the b/b.cue file will have been loaded and will
76+
// be being modelled. We can prove this by changing this file
77+
// (without opening it) and observing the x/b/c:b package
78+
// gets reloaded.
79+
//
80+
// WriteWorkspaceFile issues a file-watch notification to the
81+
// server. This tells the server the file has changed on
82+
// disk, but has not been opened in the editor.
83+
env.WriteWorkspaceFile("b/b.cue", "package b\n\nv2: int\n")
84+
env.Await(
85+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b]", rootURI),
86+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b", rootURI, rootURI),
87+
// We still do not load the parent/same package
88+
NoLogExactf(protocol.Debug, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b@v0]", rootURI),
89+
)
90+
})
91+
})
7392

74-
// change b/b.cue (which is an ancestor import of b/c/c.cue)
75-
// package from "b" to "bz" (thus impacting the build files
76-
// of b/c/c.cue)
77-
env.EditBuffer("b/b.cue", fake.NewEdit(0, 9, 0, 9, "z"))
93+
t.Run("open - import chain", func(t *testing.T) {
94+
WithOptions(RootURIAsDefaultFolder()).Run(t, files, func(t *testing.T, env *Env) {
95+
rootURI := env.Sandbox.Workdir.RootURI()
96+
env.Await(
97+
LogExactf(protocol.Debug, 1, false, "Workspace folder added: %v", rootURI),
98+
)
99+
env.OpenFile("b/c/c.cue")
100+
env.Await(
101+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=unknown Created", rootURI),
102+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Reloaded", rootURI),
103+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/b/c/c.cue found [Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b]", rootURI, rootURI, rootURI),
104+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b]", rootURI),
105+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b", rootURI, rootURI),
106+
// b/c/c.cue imports mod.example/x/a. So we should see a
107+
// load for x/a as a side-effect of loading pkg x/b/c:b
108+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a importPath=mod.example/x/a@v0", rootURI, rootURI),
109+
)
110+
// Even with a.cue not open in the editor, if we rewrite
111+
// a.cue, we should see a reload of x/a and x/b/c:b
112+
env.WriteWorkspaceFile("a/a.cue", "package a\n\nv1: string\n")
113+
env.Await(
114+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/a@v0 mod.example/x/b/c@v0:b]", rootURI),
115+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a importPath=mod.example/x/a@v0", rootURI, rootURI),
116+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b", rootURI, rootURI),
117+
)
118+
})
119+
})
78120

121+
t.Run("edit - change package", func(t *testing.T) {
122+
WithOptions(RootURIAsDefaultFolder()).Run(t, files, func(t *testing.T, env *Env) {
123+
rootURI := env.Sandbox.Workdir.RootURI()
124+
env.OpenFile("b/b.cue")
125+
env.Await(
126+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/b/b.cue found [Package dir=%v/b importPath=mod.example/x/b@v0]", rootURI, rootURI, rootURI),
127+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b@v0]", rootURI),
128+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b importPath=mod.example/x/b@v0", rootURI, rootURI),
129+
// We do not load the child/same package
130+
NoLogExactf(protocol.Debug, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b]", rootURI),
131+
)
132+
// Now open the child/same package
133+
env.OpenFile("b/c/c.cue")
134+
env.Await(
135+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/b/c/c.cue found [Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b]", rootURI, rootURI, rootURI),
136+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b]", rootURI),
137+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b/c importPath=mod.example/x/b/c@v0:b", rootURI, rootURI),
138+
)
139+
// Change b/b.cue (which is an ancestor import of b/c/c.cue)
140+
// package from "b" to "bz"
141+
env.EditBuffer("b/b.cue", fake.NewEdit(0, 9, 0, 9, "z"))
142+
env.Await(
143+
// We should see a single reload of both existing packages:
144+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b mod.example/x/b@v0]", rootURI),
145+
// The load of mod.example/x/b@v0 will have failed, so we should see a new pkg search for b.cue:
146+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/b/b.cue found [Package dir=%v/b importPath=mod.example/x/b@v0:bz]", rootURI, rootURI, rootURI),
147+
// And we should now see that the mod.example/x/b@v0:bz package gets loaded successfully
148+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b@v0:bz]", rootURI),
149+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b importPath=mod.example/x/b@v0:bz", rootURI, rootURI),
150+
)
151+
// A further edit of b/b.cue should now cause package x/b:bz to be reloaded, but x/b/c:b does not get reloaded:
152+
env.EditBuffer("b/b.cue", fake.NewEdit(2, 0, 2, 0, "w"))
79153
env.Await(
80-
// There's still a snapshot for b/b.cue:
81-
LogMatching(protocol.Debug, `/b/b\.cue":{"file://`, 2, false),
82-
// b.cue is now only in the package bz
83-
LogMatching(protocol.Debug, `/b/b\.cue":\["mod\.example/x/b@v0:bz"\]`, 1, false),
84-
// b/c/c.cue only exists in one package:
85-
LogMatching(protocol.Debug, `/b/c/c.cue":\["mod\.example/x/b/c@v0:b"\]`, 2, false),
154+
// Now 2 loads of x/b:bz
155+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b@v0:bz]", rootURI),
156+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/b importPath=mod.example/x/b@v0:bz", rootURI, rootURI),
157+
// Still exactly 1 explicit load of x/b/c:b
158+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/b/c@v0:b]", rootURI),
86159
)
87160
})
88161
})
89162

90163
t.Run("edit - create ancestor imports", func(t *testing.T) {
91164
WithOptions(RootURIAsDefaultFolder()).Run(t, files, func(t *testing.T, env *Env) {
165+
rootURI := env.Sandbox.Workdir.RootURI()
92166
env.OpenFile("a/a.cue")
93167
env.Await(
94-
// There's a snapshot for a/a.cue (because it was opened):
95-
LogMatching(protocol.Debug, `/a/a\.cue":{"file://`, 1, false),
96-
// a/a.cue belongs to two packages:
97-
LogMatching(protocol.Debug, `/a/a\.cue":\["mod\.example/x/a","mod\.example/x/a@v0:a"\]`, 1, false),
98-
// a/d/d.cue belongs to one package:
99-
LogMatching(protocol.Debug, `/a/d/d\.cue":\["mod\.example/x/a/d@v0:e"\]`, 1, false),
168+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/a/a.cue found [Package dir=%v/a importPath=mod.example/x/a@v0]", rootURI, rootURI, rootURI),
169+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/a@v0]", rootURI),
170+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a importPath=mod.example/x/a@v0", rootURI, rootURI),
171+
)
172+
env.OpenFile("a/d/d.cue")
173+
env.Await(
174+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/a/d/d.cue found [Package dir=%v/a/d importPath=mod.example/x/a/d@v0:e]", rootURI, rootURI, rootURI),
175+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/a/d@v0:e]", rootURI),
176+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a/d importPath=mod.example/x/a/d@v0:e", rootURI, rootURI),
100177
)
101-
102178
// change a/a.cue package from "a" to "e". This makes it
103179
// become the same package as a/d/d.cue
104180
env.EditBuffer("a/a.cue", fake.NewEdit(0, 8, 0, 9, "e"))
105-
106181
env.Await(
107-
// There's still a snapshot for a/a.cue:
108-
LogMatching(protocol.Debug, `/a/a\.cue":{"file://`, 2, false),
109-
// a/a.cue has moved into the e package, both in the x/a/d/ path, and the x/a/ path:
110-
LogMatching(protocol.Debug, `/a/a\.cue":\["mod\.example/x/a/d@v0:e","mod\.example/x/a@v0:e"\]`, 1, false),
111-
// a/d/d.cue still belongs to one package:
112-
LogMatching(protocol.Debug, `/a/d/d\.cue":\["mod\.example/x/a/d@v0:e"\]`, 2, false),
182+
// We should first see a reload of x/a, which will fail.
183+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/a@v0]", rootURI),
184+
// There'll then be a new search and it should find both packages.
185+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 For file %v/a/a.cue found ["+
186+
"Package dir=%v/a importPath=mod.example/x/a@v0:e "+
187+
"Package dir=%v/a/d importPath=mod.example/x/a/d@v0:e]",
188+
rootURI, rootURI, rootURI, rootURI),
189+
// And both packages should get reloaded in one go:
190+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loading packages [mod.example/x/a/d@v0:e mod.example/x/a@v0:e]", rootURI),
191+
LogExactf(protocol.Debug, 2, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a/d importPath=mod.example/x/a/d@v0:e", rootURI, rootURI),
192+
LogExactf(protocol.Debug, 1, false, "Module dir=%v module=mod.example/x@v0 Loaded Package dir=%v/a importPath=mod.example/x/a@v0:e", rootURI, rootURI),
113193
)
114194
})
115195
})

cmd/cue/cmd/integration/workspace/workspace_folders_test.go

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
//go:build !windows
2-
31
package workspace
42

53
import (
6-
"fmt"
7-
"path/filepath"
84
"testing"
95

106
"cuelang.org/go/internal/golangorgx/gopls/hooks"
@@ -21,7 +17,6 @@ func TestMain(m *testing.M) {
2117
// works, or fails, as expected, due to various combinations of
2218
// WorkspaceFolders and the RootURI being set or unset.
2319
func TestWorkspaceFoldersRootURI(t *testing.T) {
24-
t.Skip("cuelsp disabled")
2520
const filesOneModule = `
2621
-- cue.mod/module.cue --
2722
module: "mod.example/b"
@@ -63,7 +58,7 @@ package a
6358
name: "no workspace folders, no rooturi",
6459
opts: []RunOption{
6560
WorkspaceFolders(),
66-
InitializeError("initialize: got 0 WorkspaceFolders; expected 1"),
61+
InitializeError("initialize: no WorkspaceFolders"),
6762
},
6863
files: filesOneModule,
6964
expectSuccess: false,
@@ -99,26 +94,13 @@ package a
9994
expectSuccess: true,
10095
},
10196
{
102-
// cue lsp does not currently support multiple workspace folders.
97+
// cue lsp supports multiple workspace folders.
10398
name: "multiple folders, one module",
10499
opts: []RunOption{
105100
WorkspaceFolders("a", "b"),
106-
InitializeError("initialize: got 2 WorkspaceFolders; expected 1"),
107101
},
108102
files: filesOneModule,
109-
expectSuccess: false,
110-
},
111-
{
112-
// cue lsp does not currently support multiple workspace
113-
// folders, even if they correctly refer to different
114-
// modules.
115-
name: "multiple folders, two modules",
116-
opts: []RunOption{
117-
WorkspaceFolders("a", "b"),
118-
InitializeError("initialize: got 2 WorkspaceFolders; expected 1"),
119-
},
120-
files: filesTwoModules,
121-
expectSuccess: false,
103+
expectSuccess: true,
122104
},
123105
}
124106

@@ -153,40 +135,3 @@ package a
153135
// folder. This is possible in VSCode at least. We currently implement the
154136
// error handling in vscode-cue in that instance but perhaps it should live in
155137
// 'cue lsp'.
156-
157-
// TestNoContainingModule verifies that user is shown an error message in the
158-
// case that they open a .cue file in the context of a workspace folder where
159-
// the workspace folder does not correspond to the root of a CUE module. In
160-
// this case there is simply no CUE module.
161-
func TestNoContainingModule(t *testing.T) {
162-
t.Skip("cuelsp disabled")
163-
const files = `
164-
-- a.cue --
165-
package a
166-
`
167-
WithOptions().Run(t, files, func(t *testing.T, env *Env) {
168-
want := fmt.Sprintf("WorkspaceFolder %s does not correspond to a CUE module", env.Sandbox.Workdir.RootURI().Path())
169-
env.Await(ShownMessage(want))
170-
})
171-
}
172-
173-
// TestNoContainingModule verifies that user is shown an error message in the
174-
// case that they open a .cue file in the context of a workspace folder where
175-
// the workspace folder does not correspond to the root of a CUE module. In
176-
// this case, the parent directory corresponds to the root of CUE module, but
177-
// the workspace folder itself corresponds to a subdirectory in the CUE module.
178-
func TestWorkspaceFolderWithCUEModInParent(t *testing.T) {
179-
t.Skip("cuelsp disabled")
180-
const files = `
181-
-- cue.mod/module.cue --
182-
-- a/a.cue --
183-
package a
184-
`
185-
WithOptions(
186-
WorkspaceFolders("a"),
187-
).Run(t, files, func(t *testing.T, env *Env) {
188-
workspaceFolder := filepath.Join(env.Sandbox.Workdir.RootURI().Path(), "a")
189-
want := fmt.Sprintf("WorkspaceFolder %s does not correspond to a CUE module", workspaceFolder)
190-
env.Await(ShownMessage(want))
191-
})
192-
}

internal/golangorgx/gopls/cache/cache.go

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,37 @@
55
package cache
66

77
import (
8-
"strconv"
9-
"sync/atomic"
10-
11-
"cuelang.org/go/internal/golangorgx/tools/memoize"
8+
"cuelang.org/go/internal/lsp/fscache"
9+
"cuelang.org/go/internal/mod/modpkgload"
10+
"cuelang.org/go/internal/mod/modrequirements"
11+
"cuelang.org/go/mod/modconfig"
1212
)
1313

14-
// New Creates a new cache for gopls operation results, using the given file
15-
// set, shared store, and session options.
16-
//
17-
// Both the fset and store may be nil, but if store is non-nil so must be fset
18-
// (and they must always be used together), otherwise it may be possible to get
19-
// cached data referencing token.Pos values not mapped by the FileSet.
20-
func New() *Cache {
21-
index := atomic.AddInt64(&cacheIndex, 1)
22-
23-
c := &Cache{
24-
id: strconv.FormatInt(index, 10),
14+
// New creates a new Cache.
15+
func New() (*Cache, error) {
16+
modcfg := &modconfig.Config{
17+
ClientType: "cuelsp",
2518
}
26-
return c
19+
var err error
20+
registry, err := modconfig.NewRegistry(modcfg)
21+
if err != nil {
22+
return nil, err
23+
}
24+
25+
return &Cache{
26+
fs: fscache.NewCUECachedFS(),
27+
registry: registry,
28+
}, nil
2729
}
2830

29-
// A Cache holds content that is shared across multiple gopls sessions.
31+
// A Cache holds content that is shared across multiple cuelsp
32+
// client/editor connections.
3033
type Cache struct {
31-
id string
32-
33-
// store holds cached calculations.
34-
//
35-
// TODO(rfindley): at this point, these are not important, as we've moved our
36-
// content-addressable cache to the file system (the filecache package). It
37-
// is unlikely that this shared cache provides any shared value. We should
38-
// consider removing it, replacing current uses with a simpler futures cache,
39-
// as we've done for e.g. type-checked packages.
40-
store *memoize.Store
34+
fs *fscache.CUECacheFS
35+
registry modregistry
4136
}
4237

43-
var cacheIndex, sessionIndex, viewIndex int64
44-
45-
func (c *Cache) ID() string { return c.id }
38+
type modregistry interface {
39+
modrequirements.Registry
40+
modpkgload.Registry
41+
}

0 commit comments

Comments
 (0)