返回 DeepSeek-Reasonix
results.go
根目录 / internal / lsp / results.go
1 package lsp
2
3 import (
4 "encoding/json"
5 "fmt"
6 "strings"
7 )
8
9 // parseLocations decodes the three shapes textDocument/definition and
10 // /references may return: Location, Location[], or LocationLink[].
11 func parseLocations(raw json.RawMessage) []Location {
12 s := strings.TrimSpace(string(raw))
13 if s == "" || s == "null" {
14 return nil
15 }
16 if s[0] == '[' {
17 var arr []Location
18 if json.Unmarshal(raw, &arr) == nil && len(arr) > 0 && arr[0].URI != "" {
19 return arr
20 }
21 var links []struct {
22 TargetURI string `json:"targetUri"`
23 TargetRange Range `json:"targetRange"`
24 }
25 if json.Unmarshal(raw, &links) == nil {
26 out := make([]Location, 0, len(links))
27 for _, l := range links {
28 if l.TargetURI != "" {
29 out = append(out, Location{URI: l.TargetURI, Range: l.TargetRange})
30 }
31 }
32 return out
33 }
34 return nil
35 }
36 var one Location
37 if json.Unmarshal(raw, &one) == nil && one.URI != "" {
38 return []Location{one}
39 }
40 return nil
41 }
42
43 // parseHover decodes a Hover.contents, which may be a MarkupContent, a single
44 // MarkedString, or an array of them.
45 func parseHover(raw json.RawMessage) string {
46 var h struct {
47 Contents json.RawMessage `json:"contents"`
48 }
49 if json.Unmarshal(raw, &h) != nil || len(h.Contents) == 0 {
50 return ""
51 }
52 return strings.TrimSpace(markedToText(h.Contents))
53 }
54
55 func markedToText(raw json.RawMessage) string {
56 s := strings.TrimSpace(string(raw))
57 if s == "" || s == "null" {
58 return ""
59 }
60 switch s[0] {
61 case '"':
62 var str string
63 _ = json.Unmarshal(raw, &str)
64 return str
65 case '{':
66 var mc struct {
67 Kind string `json:"kind"`
68 Value string `json:"value"`
69 }
70 if json.Unmarshal(raw, &mc) == nil && mc.Value != "" {
71 return mc.Value
72 }
73 var ms struct {
74 Language string `json:"language"`
75 Value string `json:"value"`
76 }
77 _ = json.Unmarshal(raw, &ms)
78 return ms.Value
79 case '[':
80 var parts []json.RawMessage
81 _ = json.Unmarshal(raw, &parts)
82 var out []string
83 for _, p := range parts {
84 if t := markedToText(p); t != "" {
85 out = append(out, t)
86 }
87 }
88 return strings.Join(out, "\n")
89 }
90 return ""
91 }
92
93 var severityName = map[int]string{1: "error", 2: "warning", 3: "info", 4: "hint"}
94
95 func formatDiagnostics(rel string, diags []Diagnostic) string {
96 if len(diags) == 0 {
97 return "no diagnostics for " + rel
98 }
99 var b strings.Builder
100 fmt.Fprintf(&b, "%d diagnostic(s) in %s:\n", len(diags), rel)
101 for _, d := range diags {
102 sev := severityName[d.Severity]
103 if sev == "" {
104 sev = "error"
105 }
106 src := ""
107 if d.Source != "" {
108 src = " [" + d.Source + "]"
109 }
110 fmt.Fprintf(&b, "%d:%d %s%s %s\n",
111 d.Range.Start.Line+1, d.Range.Start.Character+1, sev, src,
112 strings.TrimSpace(d.Message))
113 }
114 return strings.TrimRight(b.String(), "\n")
115 }
116
116 lines GO