Skip to content

Commit 1677c8a

Browse files
authored
fix/modify types for clangd (#28)
* Allow custom struct fields for LSP types * Open file in definition tool
1 parent 3e0ec05 commit 1677c8a

File tree

11 files changed

+157
-119
lines changed

11 files changed

+157
-119
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ This is beta software. Please let me know by creating an issue if you run into a
155155

156156
## Contributing
157157

158-
Please keep PRs small and open Issues first for anything substantial. AI slop OK as long as it is tested, passes checks, and doesn't smell too bad.
158+
Please keep PRs small and open Issues first for anything substantial. AI slop O.K. as long as it is tested, passes checks, and doesn't smell too bad.
159159

160160
### Setup
161161

cmd/generate/README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,35 @@ Types have been modified to always be union types. A method generator has also b
77
## Use
88

99
From the root of the repo, run
10+
1011
```bash
1112
go run ./cmd/generate_protocol
1213
```
14+
1315
This will generate LSP message types in `internal/protocol`
1416

1517
## Key Differences from gopls
1618

1719
The main difference from the gopls implementation is in the handling of union types. While gopls simplifies some union types to single types for backward compatibility and easy operability with gopls, this implementation preserves the full union types as specified in the LSP spec.
1820

21+
### Custom Field Additions
22+
23+
The generator supports adding custom fields to generated types through the `additionalFields` map in `tables.go`. This allows extending LSP types with non-standard fields needed for specific language servers.
24+
25+
e.g.
26+
27+
```go
28+
// additionalFields defines extra fields to add to specific types during generation
29+
// The key is the Go struct name (after applying goName), the value is a slice of field definitions
30+
var additionalFields = map[string][]string{
31+
"BaseSymbolInformation": {
32+
"Score float64 `json:\"score,omitempty\"` // Added for clangd compatibility",
33+
},
34+
}
35+
```
36+
37+
This adds a `Score` field to the `BaseSymbolInformation` type, necessary for `clangd`.
38+
1939
## Attribution
2040

2141
This folder, and the code generated by the generate command is based on code from the Go tools repository, specifically the gopls language server. It has been modified to prioritize LSP specification compliance over backward compatibility.
@@ -38,7 +58,7 @@ exact version can be tied to a githash. By default, the command will download th
3858

3959
The specification has five sections
4060

41-
1. Requests, which describe the Request and Response types for request methods (e.g., *textDocument/didChange*),
61+
1. Requests, which describe the Request and Response types for request methods (e.g., _textDocument/didChange_),
4262
2. Notifications, which describe the Request types for notification methods,
4363
3. Structures, which describe named struct-like types,
4464
4. TypeAliases, which describe type aliases,

cmd/generate/generate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func propStar(name string, t NameType, gotype string) (string, string) {
6767
star = "" // passed by reference, so no need for *
6868
} else {
6969
switch gotype {
70-
case "bool", "uint32", "int32", "string", "interface{}":
70+
case "bool", "uint32", "int32", "string", "interface{}", "any":
7171
star = "" // gopls compatibility if t.Optional
7272
}
7373
}

cmd/generate/methods.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func generateMethodForRequest(out *bytes.Buffer, r *Request) {
6262
}
6363
if notNil(r.Result) {
6464
resultType = goplsName(r.Result)
65-
if resultType == "interface{}" || resultType == "string" {
65+
if resultType == "interface{}" || resultType == "string" || resultType == "any" {
6666
} else if strings.HasPrefix(resultType, "*") {
6767
resultType = "*protocol." + resultType[1:]
6868
} else if strings.HasPrefix(resultType, "[]") {

cmd/generate/output.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,21 @@ func genStructs(model *Model) {
237237
for _, ex := range s.Mixins {
238238
fmt.Fprintf(out, "\t%s\n", goName(ex.Name))
239239
}
240+
241+
// Add any additional fields defined in additionalFields map
242+
if additionalFields, ok := additionalFields[nm]; ok {
243+
for _, field := range additionalFields {
244+
fmt.Fprintf(out, "\t%s\n", field)
245+
}
246+
}
247+
240248
out.WriteString("}\n")
241249
types[nm] = out.String()
242250
}
243251

244252
// base types
245253
// (For URI and DocumentUri, see ../uri.go.)
246-
types["LSPAny"] = "type LSPAny = interface{}\n"
254+
types["LSPAny"] = "type LSPAny = any\n"
247255
// A special case, the only previously existing Or type
248256
types["DocumentDiagnosticReport"] = "type DocumentDiagnosticReport = Or_DocumentDiagnosticReport // (alias) \n"
249257

@@ -320,7 +328,7 @@ func genGenTypes() {
320328
sort.Strings(names)
321329
fmt.Fprintf(out, "// created for Or %v\n", names)
322330
fmt.Fprintf(out, "type %s struct {%s\n", nm, linex(nt.line+1))
323-
fmt.Fprintf(out, "\tValue interface{} `json:\"value\"`\n")
331+
fmt.Fprintf(out, "\tValue any `json:\"value\"`\n")
324332

325333
case "and":
326334
fmt.Fprintf(out, "// created for And\n")

cmd/generate/tables.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,21 @@ var disambiguate = map[string]adjust{
116116
// which entries of disambiguate got used
117117
var usedDisambiguate = make(map[string]bool)
118118

119+
// additionalFields defines extra fields to add to specific types during generation
120+
// The key is the Go struct name (after applying goName), the value is a slice of field definitions
121+
var additionalFields = map[string][]string{
122+
"BaseSymbolInformation": {
123+
"Score float64 `json:\"score,omitempty\"` // added for clangd compatibility",
124+
},
125+
}
126+
119127
// For spec compliance, we keep only essential type mappings that don't override OR types
120128
var goplsType = map[string]string{
121129
"ConfigurationParams": "ParamConfiguration",
122130
// "DocumentUri": "DocumentUri",
123131
"InitializeParams": "ParamInitialize",
124-
"LSPAny": "interface{}",
125-
"[]LSPAny": "[]interface{}",
132+
"LSPAny": "any",
133+
"[]LSPAny": "[]any",
126134
"[]uinteger": "[]uint32",
127135
"boolean": "bool",
128136
"decimal": "float64",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No hover information available for this position on the following line:

0 commit comments

Comments
 (0)