Skip to content
This repository was archived by the owner on Jan 31, 2025. It is now read-only.

Commit a2f18c7

Browse files
authored
feat: provide builtin types and intrinsics (#7)
* feat: bake-in completion item for intrinsics * fix: fix codegen script * feat: make snippet syntax optional * feat: add builtin lookup table * feat: provide completions * chore: remove mention of unsupported channels and goroutines * feat: use "go:generate" for codegen * fix: use .txt for builtins to prevent build fails * chore: remove obsolete comment * fix: goimports * fix: skip detail generation for primitive types and literals * fix: goimports * fix: trim doc string * fix: use go/doc/comment as markdown generator * fix: avoid copy of *token.FileSet
1 parent e0df7e3 commit a2f18c7

File tree

17 files changed

+1438
-15
lines changed

17 files changed

+1438
-15
lines changed

Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ PROJECT_NAME = gnopls
33
BUILD_FLAGS = -mod=readonly -ldflags='$(LD_FLAGS)'
44
BUILD_FOLDER = ./build
55

6-
.PHONY: install build clean
6+
.PHONY: install build clean gen
77

88
## install: Install the binary.
99
install:
@@ -22,3 +22,7 @@ clean:
2222
@echo Cleaning build cache...
2323
@-rm -rf $(BUILD_FOLDER) 2> /dev/null
2424
@go clean ./...
25+
26+
## gen: runs "go:generate" across all Go files
27+
gen:
28+
@find . -name '*.go' -print0 | xargs -0 grep -l '//go:generate' | xargs -I {} go generate {}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ require (
2323
github.com/cespare/xxhash v1.1.0 // indirect
2424
github.com/cespare/xxhash/v2 v2.1.1 // indirect
2525
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
26+
github.com/dave/jennifer v1.7.0 // indirect
2627
github.com/davecgh/go-spew v1.1.1 // indirect
2728
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
2829
github.com/dgraph-io/badger/v3 v3.2103.4 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz
4343
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
4444
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
4545
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
46+
github.com/dave/jennifer v1.7.0 h1:uRbSBH9UTS64yXbh4FrMHfgfY762RD+C7bUPKODpSJE=
47+
github.com/dave/jennifer v1.7.0/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
4648
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4749
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4850
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

internal/builtin/builtin_gen.go

+323
Large diffs are not rendered by default.

internal/builtin/lookup.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package builtin
2+
3+
import (
4+
"strings"
5+
6+
"go.lsp.dev/protocol"
7+
)
8+
9+
//go:generate go run ../../tools/codegen-builtins -src ../../tools/gendata/builtin.go.txt -dest ./builtin_gen.go -omit Type,Type1,IntegerType,FloatType,ComplexType
10+
11+
// GetCompletions provides list of builtin symbols that has passed prefix in a name.
12+
func GetCompletions(prefix string) []protocol.CompletionItem {
13+
prefix = strings.TrimSpace(prefix)
14+
if prefix == "" {
15+
return nil
16+
}
17+
18+
key, remainder := getBucketKey(prefix)
19+
bucket, ok := buckets[key]
20+
if !ok {
21+
return nil
22+
}
23+
24+
if remainder == 0 {
25+
return bucket
26+
}
27+
28+
// most buckets contain only single value
29+
if len(bucket) == 1 && strings.HasPrefix(bucket[0].Label, prefix) {
30+
return bucket
31+
}
32+
33+
var items []protocol.CompletionItem
34+
for _, item := range bucket {
35+
// TODO: use fuzzy find?
36+
if strings.HasPrefix(item.Label, prefix) {
37+
items = append(items, item)
38+
}
39+
}
40+
41+
return items
42+
}
43+
44+
func getBucketKey(str string) (rune, int) {
45+
runes := []rune(str)
46+
return runes[0], len(runes) - 1
47+
}

internal/lsp/check.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ func (tcr *TypeCheckResult) Errors() []ErrorInfo {
193193

194194
// Prints types.Info in a tabular form
195195
// Kept only for debugging purpose.
196-
func formatTypeInfo(fset token.FileSet, info *types.Info) string {
196+
func formatTypeInfo(fset *token.FileSet, info *types.Info) string {
197197
var items []string = nil
198198
for expr, tv := range info.Types {
199199
var buf strings.Builder
@@ -215,7 +215,7 @@ func formatTypeInfo(fset token.FileSet, info *types.Info) string {
215215
// Prints types.Info in a tabular form
216216
// Kept only for debugging purpose.
217217
func getTypeAndValue(
218-
fset token.FileSet,
218+
fset *token.FileSet,
219219
info *types.Info,
220220
tok string,
221221
line, offset int,
@@ -248,7 +248,7 @@ func getTypeAndValue(
248248
// Use getTypeAndValue instead
249249
// TODO: should be removed
250250
func getTypeAndValueLight(
251-
fset token.FileSet,
251+
fset *token.FileSet,
252252
info *types.Info,
253253
tok string,
254254
line int,

internal/lsp/completion.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"unicode"
1919

2020
"github.com/gnolang/gno/gnovm/pkg/gnomod"
21+
"github.com/gnolang/gnopls/internal/builtin"
2122
cmap "github.com/orcaman/concurrent-map/v2"
2223
"go.lsp.dev/jsonrpc2"
2324
"go.lsp.dev/protocol"
@@ -199,7 +200,7 @@ func (s *server) Completion(ctx context.Context, reply jsonrpc2.Replier, req jso
199200
switch n := paths[0].(type) {
200201
case *ast.Ident:
201202
_, tv := getTypeAndValue(
202-
*pgf.Fset,
203+
pgf.Fset,
203204
pkg.TypeCheckResult.info, n.Name,
204205
int(line),
205206
offset,
@@ -267,7 +268,7 @@ func (s *server) Completion(ctx context.Context, reply jsonrpc2.Replier, req jso
267268
return reply(ctx, nil, nil)
268269
case *ast.CallExpr:
269270
_, tv := getTypeAndValue(
270-
*pgf.Fset,
271+
pgf.Fset,
271272
pkg.TypeCheckResult.info, types.ExprString(n),
272273
int(line),
273274
offset,
@@ -330,14 +331,17 @@ func (s *server) Completion(ctx context.Context, reply jsonrpc2.Replier, req jso
330331
}
331332

332333
func completionPackageIdent(ctx context.Context, s *server, reply jsonrpc2.Replier, params protocol.CompletionParams, pgf *ParsedGnoFile, i *ast.Ident, includeFuncs bool) error {
334+
// This function is called not just for packages but also as fallback for unresolved cases.
335+
// So, let's also propose builtins first.
336+
items := builtin.GetCompletions(i.Name)
337+
333338
for _, spec := range pgf.File.Imports {
334339
path := spec.Path.Value[1 : len(spec.Path.Value)-1]
335340
parts := strings.Split(path, "/")
336341
last := parts[len(parts)-1]
337342
if last == i.Name {
338343
pkg := s.completionStore.lookupPkg(last)
339344
if pkg != nil {
340-
items := []protocol.CompletionItem{}
341345
if includeFuncs {
342346
for _, f := range pkg.Functions {
343347
if !f.IsExported() {
@@ -367,12 +371,12 @@ func completionPackageIdent(ctx context.Context, s *server, reply jsonrpc2.Repli
367371
Documentation: s.Doc,
368372
})
369373
}
370-
return reply(ctx, items, nil)
374+
break
371375
}
372376
}
373377
}
374378

375-
return reply(ctx, nil, nil)
379+
return reply(ctx, items, nil)
376380
}
377381

378382
// End

internal/lsp/definition.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func (s *server) Definition(ctx context.Context, reply jsonrpc2.Replier, req jso
8181
switch n := paths[0].(type) {
8282
case *ast.Ident:
8383
_, tv := getTypeAndValue(
84-
*pkg.TypeCheckResult.fset,
84+
pkg.TypeCheckResult.fset,
8585
info, n.Name,
8686
int(line),
8787
offset,
@@ -138,7 +138,7 @@ func definitionSelectorExpr(ctx context.Context, s *server, reply jsonrpc2.Repli
138138
parentStr := types.ExprString(parent)
139139

140140
_, tv := getTypeAndValueLight(
141-
*pkg.TypeCheckResult.fset,
141+
pkg.TypeCheckResult.fset,
142142
pkg.TypeCheckResult.info,
143143
exprStr,
144144
int(line),
@@ -149,7 +149,7 @@ func definitionSelectorExpr(ctx context.Context, s *server, reply jsonrpc2.Repli
149149
tvStr := tv.Type.String()
150150

151151
_, tvParent := getTypeAndValueLight(
152-
*pkg.TypeCheckResult.fset,
152+
pkg.TypeCheckResult.fset,
153153
pkg.TypeCheckResult.info,
154154
parentStr,
155155
int(line),

internal/lsp/hover.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (s *server) Hover(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2
7070
switch n := paths[0].(type) {
7171
case *ast.Ident:
7272
_, tv := getTypeAndValue(
73-
*pkg.TypeCheckResult.fset,
73+
pkg.TypeCheckResult.fset,
7474
info, n.Name,
7575
int(line),
7676
offset,
@@ -164,7 +164,7 @@ func hoverSelectorExpr(ctx context.Context, s *server, reply jsonrpc2.Replier, p
164164
parentStr := types.ExprString(parent)
165165

166166
_, tv := getTypeAndValueLight(
167-
*pkg.TypeCheckResult.fset,
167+
pkg.TypeCheckResult.fset,
168168
pkg.TypeCheckResult.info,
169169
exprStr,
170170
int(line),
@@ -175,7 +175,7 @@ func hoverSelectorExpr(ctx context.Context, s *server, reply jsonrpc2.Replier, p
175175
tvStr := tv.Type.String()
176176

177177
_, tvParent := getTypeAndValueLight(
178-
*pkg.TypeCheckResult.fset,
178+
pkg.TypeCheckResult.fset,
179179
pkg.TypeCheckResult.info,
180180
parentStr,
181181
int(line),

0 commit comments

Comments
 (0)