Skip to content

Commit 1cf777d

Browse files
author
zhihaopan
committed
feat: endLine
1 parent 57750c5 commit 1cf777d

File tree

1 file changed

+127
-26
lines changed

1 file changed

+127
-26
lines changed

components/document_symbol.go

Lines changed: 127 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,93 @@ package components
22

33
import (
44
"context"
5+
6+
protobuf "github.com/emicklei/proto"
57
"github.com/lasorda/protobuf-language-server/proto/view"
68

79
"github.com/lasorda/protobuf-language-server/go-lsp/logs"
810
"github.com/lasorda/protobuf-language-server/go-lsp/lsp/defines"
911
)
1012

13+
// calculateEndPosition calculates the end position for a symbol based on its elements
14+
func calculateEndPosition(startLine int, elements []protobuf.Visitee) uint {
15+
if len(elements) == 0 {
16+
return uint(startLine)
17+
}
18+
19+
maxLine := startLine
20+
for _, element := range elements {
21+
switch v := element.(type) {
22+
case *protobuf.NormalField:
23+
if v.Position.Line > maxLine {
24+
maxLine = v.Position.Line
25+
}
26+
case *protobuf.MapField:
27+
if v.Position.Line > maxLine {
28+
maxLine = v.Position.Line
29+
}
30+
case *protobuf.Oneof:
31+
if v.Position.Line > maxLine {
32+
maxLine = v.Position.Line
33+
}
34+
case *protobuf.EnumField:
35+
if v.Position.Line > maxLine {
36+
maxLine = v.Position.Line
37+
}
38+
case *protobuf.Enum:
39+
if v.Position.Line > maxLine {
40+
maxLine = v.Position.Line
41+
}
42+
// Recursively check nested enum elements
43+
if nestedEnd := int(calculateEndPosition(v.Position.Line, v.Elements)); nestedEnd > maxLine {
44+
maxLine = nestedEnd
45+
}
46+
case *protobuf.Message:
47+
if v.Position.Line > maxLine {
48+
maxLine = v.Position.Line
49+
}
50+
// Recursively check nested message elements
51+
if nestedEnd := int(calculateEndPosition(v.Position.Line, v.Elements)); nestedEnd > maxLine {
52+
maxLine = nestedEnd
53+
}
54+
case *protobuf.RPC:
55+
if v.Position.Line > maxLine {
56+
maxLine = v.Position.Line
57+
}
58+
case *protobuf.Option:
59+
if v.Position.Line > maxLine {
60+
maxLine = v.Position.Line
61+
}
62+
}
63+
}
64+
65+
return uint(maxLine)
66+
}
67+
68+
// calculateMessageEndPosition calculates the end position for a message considering all nested elements
69+
func calculateMessageEndPosition(messageProto *protobuf.Message) uint {
70+
if messageProto == nil {
71+
return 0
72+
}
73+
return calculateEndPosition(messageProto.Position.Line, messageProto.Elements)
74+
}
75+
76+
// calculateEnumEndPosition calculates the end position for an enum considering all its fields
77+
func calculateEnumEndPosition(enumProto *protobuf.Enum) uint {
78+
if enumProto == nil {
79+
return 0
80+
}
81+
return calculateEndPosition(enumProto.Position.Line, enumProto.Elements)
82+
}
83+
84+
// calculateServiceEndPosition calculates the end position for a service considering all its RPCs
85+
func calculateServiceEndPosition(serviceProto *protobuf.Service) uint {
86+
if serviceProto == nil {
87+
return 0
88+
}
89+
return calculateEndPosition(serviceProto.Position.Line, serviceProto.Elements)
90+
}
91+
1192
func ProvideDocumentSymbol(ctx context.Context, req *defines.DocumentSymbolParams) (result *[]defines.DocumentSymbol, err error) {
1293
if !view.IsProtoFile(req.TextDocument.Uri) {
1394
return nil, nil
@@ -19,90 +100,110 @@ func ProvideDocumentSymbol(ctx context.Context, req *defines.DocumentSymbolParam
19100
return &res, nil
20101
}
21102
for _, pack := range file.Proto().Packages() {
103+
packLine := pack.ProtoPackage.Position.Line - 1
22104
res = append(res, defines.DocumentSymbol{
23105
Name: pack.ProtoPackage.Name,
24106
Kind: defines.SymbolKindPackage,
25107
SelectionRange: defines.Range{
26-
Start: defines.Position{Line: uint(pack.ProtoPackage.Position.Line - 1)},
27-
End: defines.Position{Line: uint(pack.ProtoPackage.Position.Line - 1)},
108+
Start: defines.Position{Line: uint(packLine)},
109+
End: defines.Position{Line: uint(packLine)},
28110
},
29111
Range: defines.Range{
30-
Start: defines.Position{Line: uint(pack.ProtoPackage.Position.Line - 1)},
31-
End: defines.Position{Line: uint(pack.ProtoPackage.Position.Line - 1)},
112+
Start: defines.Position{Line: uint(packLine)},
113+
End: defines.Position{Line: uint(packLine)},
32114
},
33115
})
34116
}
35117
for _, imp := range file.Proto().Imports() {
118+
impLine := imp.ProtoImport.Position.Line - 1
36119
res = append(res, defines.DocumentSymbol{
37120
Name: imp.ProtoImport.Filename,
38121
Kind: defines.SymbolKindFile,
39122
SelectionRange: defines.Range{
40-
Start: defines.Position{Line: uint(imp.ProtoImport.Position.Line - 1)},
41-
End: defines.Position{Line: uint(imp.ProtoImport.Position.Line - 1)},
123+
Start: defines.Position{Line: uint(impLine)},
124+
End: defines.Position{Line: uint(impLine)},
42125
},
43126
Range: defines.Range{
44-
Start: defines.Position{Line: uint(imp.ProtoImport.Position.Line - 1)},
45-
End: defines.Position{Line: uint(imp.ProtoImport.Position.Line - 1)},
127+
Start: defines.Position{Line: uint(impLine)},
128+
End: defines.Position{Line: uint(impLine)},
46129
},
47130
})
48131

49132
}
50133
for _, enums := range file.Proto().Enums() {
134+
enumProto := enums.Protobuf()
135+
startLine := enumProto.Position.Line - 1
136+
endLine := int(calculateEnumEndPosition(enumProto)) - 1
137+
if endLine < startLine {
138+
endLine = startLine
139+
}
51140
res = append(res, defines.DocumentSymbol{
52-
Name: enums.Protobuf().Name,
141+
Name: enumProto.Name,
53142
Kind: defines.SymbolKindEnum,
54143
SelectionRange: defines.Range{
55-
Start: defines.Position{Line: uint(enums.Protobuf().Position.Line - 1)},
56-
End: defines.Position{Line: uint(enums.Protobuf().Position.Line - 1)},
144+
Start: defines.Position{Line: uint(startLine)},
145+
End: defines.Position{Line: uint(startLine)},
57146
},
58147
Range: defines.Range{
59-
Start: defines.Position{Line: uint(enums.Protobuf().Position.Line - 1)},
60-
End: defines.Position{Line: uint(enums.Protobuf().Position.Line - 1)},
148+
Start: defines.Position{Line: uint(startLine)},
149+
End: defines.Position{Line: uint(endLine)},
61150
},
62151
})
63152
}
64153
for _, message := range file.Proto().Messages() {
65154
message_proto := message.Protobuf()
155+
startLine := message_proto.Position.Line - 1
156+
endLine := int(calculateMessageEndPosition(message_proto)) - 1
157+
if endLine < startLine {
158+
endLine = startLine
159+
}
66160
res = append(res, defines.DocumentSymbol{
67161
Name: message_proto.Name,
68162
Kind: defines.SymbolKindClass,
69163
SelectionRange: defines.Range{
70-
Start: defines.Position{Line: uint(message_proto.Position.Line - 1)},
71-
End: defines.Position{Line: uint(message_proto.Position.Line - 1)},
164+
Start: defines.Position{Line: uint(startLine)},
165+
End: defines.Position{Line: uint(startLine)},
72166
},
73167
Range: defines.Range{
74-
Start: defines.Position{Line: uint(message_proto.Position.Line - 1)},
75-
End: defines.Position{Line: uint(message_proto.Position.Line - 1)},
168+
Start: defines.Position{Line: uint(startLine)},
169+
End: defines.Position{Line: uint(endLine)},
76170
},
77171
})
78172
}
79173
for _, service := range file.Proto().Services() {
174+
serviceProto := service.Protobuf()
175+
startLine := serviceProto.Position.Line - 1
176+
endLine := int(calculateServiceEndPosition(serviceProto)) - 1
177+
if endLine < startLine {
178+
endLine = startLine
179+
}
80180
service_sym := defines.DocumentSymbol{
81-
Name: service.Protobuf().Name,
181+
Name: serviceProto.Name,
82182
Kind: defines.SymbolKindNamespace,
83183
SelectionRange: defines.Range{
84-
Start: defines.Position{Line: uint(service.Protobuf().Position.Line - 1)},
85-
End: defines.Position{Line: uint(service.Protobuf().Position.Line - 1)},
184+
Start: defines.Position{Line: uint(startLine)},
185+
End: defines.Position{Line: uint(startLine)},
86186
},
87187
Range: defines.Range{
88-
Start: defines.Position{Line: uint(service.Protobuf().Position.Line - 1)},
89-
End: defines.Position{Line: uint(service.Protobuf().Position.Line - 1)},
188+
Start: defines.Position{Line: uint(startLine)},
189+
End: defines.Position{Line: uint(endLine)},
90190
},
91191

92192
Children: &[]defines.DocumentSymbol{},
93193
}
94194
child := []defines.DocumentSymbol{}
95195
for _, rpc := range service.RPCs() {
196+
rpcLine := rpc.ProtoRPC.Position.Line - 1
96197
rpc := defines.DocumentSymbol{
97198
Name: rpc.ProtoRPC.Name,
98199
Kind: defines.SymbolKindMethod,
99200
SelectionRange: defines.Range{
100-
Start: defines.Position{Line: uint(rpc.ProtoRPC.Position.Line - 1)},
101-
End: defines.Position{Line: uint(rpc.ProtoRPC.Position.Line - 1)},
201+
Start: defines.Position{Line: uint(rpcLine)},
202+
End: defines.Position{Line: uint(rpcLine)},
102203
},
103204
Range: defines.Range{
104-
Start: defines.Position{Line: uint(rpc.ProtoRPC.Position.Line - 1)},
105-
End: defines.Position{Line: uint(rpc.ProtoRPC.Position.Line - 1)},
205+
Start: defines.Position{Line: uint(rpcLine)},
206+
End: defines.Position{Line: uint(rpcLine)},
106207
},
107208
}
108209
child = append(child, rpc)

0 commit comments

Comments
 (0)