Skip to content

Commit

Permalink
Show struct definition on hover
Browse files Browse the repository at this point in the history
  • Loading branch information
harry-hov committed Jan 19, 2024
1 parent f9fa75d commit 52d0ba1
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 20 deletions.
51 changes: 41 additions & 10 deletions internal/lsp/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"log/slog"
Expand Down Expand Up @@ -71,8 +72,9 @@ type Package struct {
ImportPath string
Symbols []*Symbol

Functions []*Function
Methods cmap.ConcurrentMap[string, []*Method]
Functions []*Function
Methods cmap.ConcurrentMap[string, []*Method]
Structures []*Structure
}

type Symbol struct {
Expand All @@ -88,7 +90,7 @@ type Function struct {
Position token.Position
FileURI uri.URI
Name string
Arguments []*Argument
Arguments []*Field
Doc string
Signature string
Kind string
Expand All @@ -105,7 +107,7 @@ type Method struct {
Position token.Position
FileURI uri.URI
Name string
Arguments []*Argument
Arguments []*Field
Doc string
Signature string
Kind string
Expand All @@ -118,7 +120,16 @@ func (f *Method) IsExported() bool {
return unicode.IsUpper([]rune(f.Name)[0])
}

type Argument struct {
type Structure struct {
Position token.Position
FileURI uri.URI
Name string
Fields []*Field
Doc string
String string
}

type Field struct {
Position token.Position
Name string
Kind string
Expand Down Expand Up @@ -217,6 +228,7 @@ func PackageFromDir(path string, onlyExports bool) (*Package, error) {

var symbols []*Symbol
var functions []*Function
var structures []*Structure
var packageName string
methods := cmap.New[[]*Method]()
for _, fname := range files {
Expand Down Expand Up @@ -258,7 +270,7 @@ func PackageFromDir(path string, onlyExports bool) (*Package, error) {
Position: fset.Position(t.Pos()),
FileURI: getURI(absPath),
Name: t.Name.Name,
Arguments: []*Argument{}, // TODO: fill args
Arguments: []*Field{}, // TODO: fill args
Doc: t.Doc.Text(),
Signature: strings.Split(text[t.Pos()-1:t.End()-1], " {")[0], // TODO: use ast
Kind: "func",
Expand All @@ -275,7 +287,7 @@ func PackageFromDir(path string, onlyExports bool) (*Package, error) {
Position: fset.Position(t.Pos()),
FileURI: getURI(absPath),
Name: t.Name.Name,
Arguments: []*Argument{}, // TODO: fill args
Arguments: []*Field{}, // TODO: fill args
Doc: t.Doc.Text(),
Signature: strings.Split(text[t.Pos()-1:t.End()-1], " {")[0], // TODO: use ast
Kind: "func",
Expand All @@ -291,6 +303,24 @@ func PackageFromDir(path string, onlyExports bool) (*Package, error) {
}
symbol = function(n, text)
case *ast.GenDecl:
for _, spec := range t.Specs {
switch s := spec.(type) {
case *ast.TypeSpec:
switch tt := s.Type.(type) {
case *ast.StructType:
buf := new(strings.Builder)
format.Node(buf, fset, tt)
structures = append(structures, &Structure{
Position: fset.Position(tt.Pos()),
FileURI: getURI(absPath),
Name: s.Name.Name,
Fields: []*Field{}, // TODO: fill fields
Doc: t.Doc.Text(),
String: buf.String(),
})
}
}
}
symbol = declaration(n, text)
}

Expand All @@ -311,9 +341,10 @@ func PackageFromDir(path string, onlyExports bool) (*Package, error) {
}
return gm.Module.Mod.Path
}(),
Symbols: symbols,
Functions: functions,
Methods: methods,
Symbols: symbols,
Functions: functions,
Methods: methods,
Structures: structures,
}, nil
}

Expand Down
28 changes: 18 additions & 10 deletions internal/lsp/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,25 +307,33 @@ func (s *server) Hover(ctx context.Context, reply jsonrpc2.Replier, req jsonrpc2
if !ok {
return reply(ctx, nil, nil)
}
methods, ok := pkg.Methods.Get(k)
if !ok {
var structure *Structure
for _, st := range pkg.Structures {
if st.Name == fmt.Sprintf("%s", t.X) {
structure = st
break
}
}
if structure == nil {
return reply(ctx, nil, nil)
}
body := func() string { // TODO: sort
out := "```gno\n"
var header, body string
header = fmt.Sprintf("type %s %s\n\n", structure.Name, structure.String)
methods, ok := pkg.Methods.Get(k)
if ok {
body = "```gno\n"
for _, m := range methods {
if m.IsExported() {
out += fmt.Sprintf("%s\n", m.Signature)
body += fmt.Sprintf("%s\n", m.Signature)
}
}
out += "```"
return out
}()
// TODO: look for structure/type as well for header
body += "```\n"
body += structure.Doc + "\n"
}
return reply(ctx, protocol.Hover{
Contents: protocol.MarkupContent{
Kind: protocol.Markdown,
Value: FormatHoverContent(k, body),
Value: FormatHoverContent(header, body),
},
Range: posToRange(
int(params.Position.Line),
Expand Down

0 comments on commit 52d0ba1

Please sign in to comment.