added hover doc to variable
This commit is contained in:
@@ -593,6 +593,9 @@ func HandleHover(params HoverParams) *Hover {
|
|||||||
content = fmt.Sprintf("**Field**: `%s`", res.Field.Name)
|
content = fmt.Sprintf("**Field**: `%s`", res.Field.Name)
|
||||||
} else if res.Variable != nil {
|
} else if res.Variable != nil {
|
||||||
content = fmt.Sprintf("**Variable**: `%s`\nType: `%s`", res.Variable.Name, res.Variable.TypeExpr)
|
content = fmt.Sprintf("**Variable**: `%s`\nType: `%s`", res.Variable.Name, res.Variable.TypeExpr)
|
||||||
|
if res.Variable.DefaultValue != nil {
|
||||||
|
content += fmt.Sprintf("\nDefault: `%s`", valueToString(res.Variable.DefaultValue))
|
||||||
|
}
|
||||||
} else if res.Reference != nil {
|
} else if res.Reference != nil {
|
||||||
targetName := "Unresolved"
|
targetName := "Unresolved"
|
||||||
fullInfo := ""
|
fullInfo := ""
|
||||||
@@ -606,12 +609,15 @@ func HandleHover(params HoverParams) *Hover {
|
|||||||
v := res.Reference.TargetVariable
|
v := res.Reference.TargetVariable
|
||||||
targetName = v.Name
|
targetName = v.Name
|
||||||
fullInfo = fmt.Sprintf("**Variable**: `%s`\nType: `%s`", v.Name, v.TypeExpr)
|
fullInfo = fmt.Sprintf("**Variable**: `%s`\nType: `%s`", v.Name, v.TypeExpr)
|
||||||
|
if v.DefaultValue != nil {
|
||||||
|
fullInfo += fmt.Sprintf("\nDefault: `%s`", valueToString(v.DefaultValue))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content = fmt.Sprintf("**Reference**: `%s` -> `%s`", res.Reference.Name, targetName)
|
content = fmt.Sprintf("**Reference**: `%s` -> `%s`", res.Reference.Name, targetName)
|
||||||
if fullInfo != "" {
|
if fullInfo != "" {
|
||||||
content += fmt.Sprintf("\n\n---\n%s", fullInfo)
|
content += fmt.Sprintf("\n\n---\n%s", fullInfo)
|
||||||
} else if targetDoc != "" { // Fallback if formatNodeInfo returned empty (unlikely)
|
} else if targetDoc != "" {
|
||||||
content += fmt.Sprintf("\n\n%s", targetDoc)
|
content += fmt.Sprintf("\n\n%s", targetDoc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -628,6 +634,34 @@ func HandleHover(params HoverParams) *Hover {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func valueToString(val parser.Value) string {
|
||||||
|
switch v := val.(type) {
|
||||||
|
case *parser.StringValue:
|
||||||
|
if v.Quoted {
|
||||||
|
return fmt.Sprintf("\"%s\"", v.Value)
|
||||||
|
}
|
||||||
|
return v.Value
|
||||||
|
case *parser.IntValue:
|
||||||
|
return v.Raw
|
||||||
|
case *parser.FloatValue:
|
||||||
|
return v.Raw
|
||||||
|
case *parser.BoolValue:
|
||||||
|
return fmt.Sprintf("%v", v.Value)
|
||||||
|
case *parser.ReferenceValue:
|
||||||
|
return v.Value
|
||||||
|
case *parser.VariableReferenceValue:
|
||||||
|
return v.Name
|
||||||
|
case *parser.ArrayValue:
|
||||||
|
elements := []string{}
|
||||||
|
for _, e := range v.Elements {
|
||||||
|
elements = append(elements, valueToString(e))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("{ %s }", strings.Join(elements, " "))
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func HandleCompletion(params CompletionParams) *CompletionList {
|
func HandleCompletion(params CompletionParams) *CompletionList {
|
||||||
uri := params.TextDocument.URI
|
uri := params.TextDocument.URI
|
||||||
path := uriToPath(uri)
|
path := uriToPath(uri)
|
||||||
|
|||||||
67
test/lsp_hover_variable_test.go
Normal file
67
test/lsp_hover_variable_test.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/index"
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/lsp"
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLSPHoverVariable(t *testing.T) {
|
||||||
|
lsp.Tree = index.NewProjectTree()
|
||||||
|
lsp.Documents = make(map[string]string)
|
||||||
|
|
||||||
|
content := `
|
||||||
|
#var MyInt: int = 123
|
||||||
|
+Obj = {
|
||||||
|
Field = $MyInt
|
||||||
|
}
|
||||||
|
`
|
||||||
|
uri := "file://hover_var.marte"
|
||||||
|
lsp.Documents[uri] = content
|
||||||
|
p := parser.NewParser(content)
|
||||||
|
cfg, err := p.Parse()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
lsp.Tree.AddFile("hover_var.marte", cfg)
|
||||||
|
lsp.Tree.ResolveReferences()
|
||||||
|
|
||||||
|
// 1. Hover on Definition (#var MyInt)
|
||||||
|
// Line 2 (index 1). # is at 0. Name "MyInt" is at 5.
|
||||||
|
paramsDef := lsp.HoverParams{
|
||||||
|
TextDocument: lsp.TextDocumentIdentifier{URI: uri},
|
||||||
|
Position: lsp.Position{Line: 1, Character: 5},
|
||||||
|
}
|
||||||
|
resDef := lsp.HandleHover(paramsDef)
|
||||||
|
if resDef == nil {
|
||||||
|
t.Fatal("Expected hover for definition")
|
||||||
|
}
|
||||||
|
contentDef := resDef.Contents.(lsp.MarkupContent).Value
|
||||||
|
if !strings.Contains(contentDef, "Type: `int`") {
|
||||||
|
t.Errorf("Hover def missing type. Got: %s", contentDef)
|
||||||
|
}
|
||||||
|
if !strings.Contains(contentDef, "Default: `123`") {
|
||||||
|
t.Errorf("Hover def missing default value. Got: %s", contentDef)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Hover on Reference ($MyInt)
|
||||||
|
// Line 4 (index 3). $MyInt is at col 12.
|
||||||
|
paramsRef := lsp.HoverParams{
|
||||||
|
TextDocument: lsp.TextDocumentIdentifier{URI: uri},
|
||||||
|
Position: lsp.Position{Line: 3, Character: 12},
|
||||||
|
}
|
||||||
|
resRef := lsp.HandleHover(paramsRef)
|
||||||
|
if resRef == nil {
|
||||||
|
t.Fatal("Expected hover for reference")
|
||||||
|
}
|
||||||
|
contentRef := resRef.Contents.(lsp.MarkupContent).Value
|
||||||
|
if !strings.Contains(contentRef, "Type: `int`") {
|
||||||
|
t.Errorf("Hover ref missing type. Got: %s", contentRef)
|
||||||
|
}
|
||||||
|
if !strings.Contains(contentRef, "Default: `123`") {
|
||||||
|
t.Errorf("Hover ref missing default value. Got: %s", contentRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
62
test/lsp_variable_refs_test.go
Normal file
62
test/lsp_variable_refs_test.go
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/index"
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/lsp"
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLSPVariableRefs(t *testing.T) {
|
||||||
|
lsp.Tree = index.NewProjectTree()
|
||||||
|
lsp.Documents = make(map[string]string)
|
||||||
|
|
||||||
|
content := `
|
||||||
|
#var MyVar: int = 1
|
||||||
|
+Obj = {
|
||||||
|
Field = $MyVar
|
||||||
|
}
|
||||||
|
`
|
||||||
|
uri := "file://vars.marte"
|
||||||
|
lsp.Documents[uri] = content
|
||||||
|
p := parser.NewParser(content)
|
||||||
|
cfg, err := p.Parse()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
lsp.Tree.AddFile("vars.marte", cfg)
|
||||||
|
lsp.Tree.ResolveReferences()
|
||||||
|
|
||||||
|
// 1. Definition from Usage
|
||||||
|
// Line 4: " Field = $MyVar"
|
||||||
|
// $ is at col 12 (0-based) ?
|
||||||
|
// " Field = " is 4 + 6 + 3 = 13 chars?
|
||||||
|
// 4 spaces. Field (5). " = " (3). 4+5+3 = 12.
|
||||||
|
// So $ is at 12.
|
||||||
|
paramsDef := lsp.DefinitionParams{
|
||||||
|
TextDocument: lsp.TextDocumentIdentifier{URI: uri},
|
||||||
|
Position: lsp.Position{Line: 3, Character: 12},
|
||||||
|
}
|
||||||
|
resDef := lsp.HandleDefinition(paramsDef)
|
||||||
|
locs, ok := resDef.([]lsp.Location)
|
||||||
|
if !ok || len(locs) != 1 {
|
||||||
|
t.Fatalf("Expected 1 definition location, got %v", resDef)
|
||||||
|
}
|
||||||
|
// Line 2 in file is index 1.
|
||||||
|
if locs[0].Range.Start.Line != 1 {
|
||||||
|
t.Errorf("Expected definition at line 1, got %d", locs[0].Range.Start.Line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. References from Definition
|
||||||
|
// #var at line 2 (index 1). Col 0.
|
||||||
|
paramsRef := lsp.ReferenceParams{
|
||||||
|
TextDocument: lsp.TextDocumentIdentifier{URI: uri},
|
||||||
|
Position: lsp.Position{Line: 1, Character: 1},
|
||||||
|
Context: lsp.ReferenceContext{IncludeDeclaration: true},
|
||||||
|
}
|
||||||
|
resRef := lsp.HandleReferences(paramsRef)
|
||||||
|
if len(resRef) != 2 { // Decl + Usage
|
||||||
|
t.Errorf("Expected 2 references, got %d", len(resRef))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user