+157
-23
lines changedFilter options
+157
-23
lines changed Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ func (p *Processor) extractObjectRangesFromDesugaredObjs(desugaredObjs []*ast.De
96
96
}
97
97
if len(indexList) == 0 {
98
98
for _, found := range foundFields {
99
-
ranges = append(ranges, FieldToRange(*found))
99
+
ranges = append(ranges, p.FieldToRange(*found))
100
100
101
101
// If the field is not PlusSuper (field+: value), we stop there. Other previous values are not relevant
102
102
// If partialMatchCurrentField is true, we can continue to look for other fields
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@ import (
5
5
"strings"
6
6
7
7
"github.com/google/go-jsonnet/ast"
8
+
position "github.com/grafana/jsonnet-language-server/pkg/position_conversion"
9
+
"github.com/jdbaldry/go-language-server-protocol/lsp/protocol"
8
10
)
9
11
10
12
type ObjectRange struct {
@@ -15,41 +17,56 @@ type ObjectRange struct {
15
17
Node ast.Node
16
18
}
17
19
18
-
func FieldToRange(field ast.DesugaredObjectField) ObjectRange {
20
+
func (p *Processor) FieldToRange(field ast.DesugaredObjectField) ObjectRange {
19
21
selectionRange := ast.LocationRange{
20
22
Begin: ast.Location{
21
23
Line: field.LocRange.Begin.Line,
22
24
Column: field.LocRange.Begin.Column,
23
25
},
24
26
End: ast.Location{
25
27
Line: field.LocRange.Begin.Line,
26
-
Column: field.LocRange.Begin.Column + len(FieldNameToString(field.Name)),
28
+
Column: field.LocRange.Begin.Column + len(p.FieldNameToString(field.Name)),
27
29
},
28
30
}
29
31
return ObjectRange{
30
32
Filename: field.LocRange.FileName,
31
33
SelectionRange: selectionRange,
32
34
FullRange: field.LocRange,
33
-
FieldName: FieldNameToString(field.Name),
35
+
FieldName: p.FieldNameToString(field.Name),
34
36
Node: field.Body,
35
37
}
36
38
}
37
39
38
-
func FieldNameToString(fieldName ast.Node) string {
39
-
if fieldName, ok := fieldName.(*ast.LiteralString); ok {
40
+
func (p *Processor) FieldNameToString(fieldName ast.Node) string {
41
+
const unknown = "<unknown>"
42
+
43
+
switch fieldName := fieldName.(type) {
44
+
case *ast.LiteralString:
40
45
return fieldName.Value
41
-
}
42
-
if fieldName, ok := fieldName.(*ast.Index); ok {
46
+
case *ast.Index:
43
47
// We only want to wrap in brackets at the top level, so we trim at all step and then rewrap
44
48
return fmt.Sprintf("[%s.%s]",
45
-
strings.Trim(FieldNameToString(fieldName.Target), "[]"),
46
-
strings.Trim(FieldNameToString(fieldName.Index), "[]"),
49
+
strings.Trim(p.FieldNameToString(fieldName.Target), "[]"),
50
+
strings.Trim(p.FieldNameToString(fieldName.Index), "[]"),
47
51
)
48
-
}
49
-
if fieldName, ok := fieldName.(*ast.Var); ok {
52
+
case *ast.Var:
50
53
return string(fieldName.Id)
54
+
default:
55
+
loc := fieldName.Loc()
56
+
if loc == nil {
57
+
return unknown
58
+
}
59
+
fname := loc.FileName
60
+
if fname == "" {
61
+
return unknown
62
+
}
63
+
64
+
content, err := p.cache.GetContents(protocol.URIFromPath(fname), position.RangeASTToProtocol(*loc))
65
+
if err != nil {
66
+
return unknown
67
+
}
68
+
return content
51
69
}
52
-
return ""
53
70
}
54
71
55
72
func LocalBindToRange(bind ast.LocalBind) ObjectRange {
Original file line number Diff line number Diff line change
@@ -107,7 +107,11 @@ func (c *Cache) GetContents(uri protocol.DocumentURI, position protocol.Range) (
107
107
for i := position.Start.Line; i <= position.End.Line; i++ {
108
108
switch i {
109
109
case position.Start.Line:
110
-
contentBuilder.WriteString(lines[i][position.Start.Character:])
110
+
if i == position.End.Line {
111
+
contentBuilder.WriteString(lines[i][position.Start.Character:position.End.Character])
112
+
} else {
113
+
contentBuilder.WriteString(lines[i][position.Start.Character:])
114
+
}
111
115
case position.End.Line:
112
116
contentBuilder.WriteString(lines[i][:position.End.Character])
113
117
default:
Original file line number Diff line number Diff line change
@@ -259,7 +259,7 @@ func TestHover(t *testing.T) {
259
259
expectedContent: protocol.Hover{
260
260
Contents: protocol.MarkupContent{
261
261
Kind: protocol.Markdown,
262
-
Value: "```jsonnet\nbar: 'innerfoo',\n```\n",
262
+
Value: "```jsonnet\nbar: 'innerfoo'\n```\n",
263
263
},
264
264
Range: protocol.Range{
265
265
Start: protocol.Position{Line: 9, Character: 5},
Original file line number Diff line number Diff line change
@@ -27,7 +27,8 @@ func (s *Server) DocumentSymbol(_ context.Context, params *protocol.DocumentSymb
27
27
return nil, nil
28
28
}
29
29
30
-
symbols := buildDocumentSymbols(doc.AST)
30
+
processor := processing.NewProcessor(s.cache, nil)
31
+
symbols := s.buildDocumentSymbols(processor, doc.AST)
31
32
32
33
result := make([]interface{}, len(symbols))
33
34
for i, symbol := range symbols {
@@ -37,13 +38,13 @@ func (s *Server) DocumentSymbol(_ context.Context, params *protocol.DocumentSymb
37
38
return result, nil
38
39
}
39
40
40
-
func buildDocumentSymbols(node ast.Node) []protocol.DocumentSymbol {
41
+
func (s *Server) buildDocumentSymbols(processor *processing.Processor, node ast.Node) []protocol.DocumentSymbol {
41
42
var symbols []protocol.DocumentSymbol
42
43
43
44
switch node := node.(type) {
44
45
case *ast.Binary:
45
-
symbols = append(symbols, buildDocumentSymbols(node.Left)...)
46
-
symbols = append(symbols, buildDocumentSymbols(node.Right)...)
46
+
symbols = append(symbols, s.buildDocumentSymbols(processor, node.Left)...)
47
+
symbols = append(symbols, s.buildDocumentSymbols(processor, node.Right)...)
47
48
case *ast.Local:
48
49
for _, bind := range node.Binds {
49
50
objectRange := processing.LocalBindToRange(bind)
@@ -55,21 +56,21 @@ func buildDocumentSymbols(node ast.Node) []protocol.DocumentSymbol {
55
56
Detail: symbolDetails(bind.Body),
56
57
})
57
58
}
58
-
symbols = append(symbols, buildDocumentSymbols(node.Body)...)
59
+
symbols = append(symbols, s.buildDocumentSymbols(processor, node.Body)...)
59
60
case *ast.DesugaredObject:
60
61
for _, field := range node.Fields {
61
62
kind := protocol.Field
62
63
if field.Hide == ast.ObjectFieldHidden {
63
64
kind = protocol.Property
64
65
}
65
-
fieldRange := processing.FieldToRange(field)
66
+
fieldRange := processor.FieldToRange(field)
66
67
symbols = append(symbols, protocol.DocumentSymbol{
67
-
Name: processing.FieldNameToString(field.Name),
68
+
Name: processor.FieldNameToString(field.Name),
68
69
Kind: kind,
69
70
Range: position.RangeASTToProtocol(fieldRange.FullRange),
70
71
SelectionRange: position.RangeASTToProtocol(fieldRange.SelectionRange),
71
72
Detail: symbolDetails(field.Body),
72
-
Children: buildDocumentSymbols(field.Body),
73
+
Children: s.buildDocumentSymbols(processor, field.Body),
73
74
})
74
75
}
75
76
}
Original file line number Diff line number Diff line change
@@ -266,6 +266,112 @@ func TestSymbols(t *testing.T) {
266
266
},
267
267
},
268
268
},
269
+
{
270
+
name: "Conditional fields",
271
+
filename: "testdata/conditional-fields.jsonnet",
272
+
expectSymbols: []interface{}{
273
+
protocol.DocumentSymbol{
274
+
Name: "flag",
275
+
Detail: "Boolean",
276
+
Kind: protocol.Variable,
277
+
Range: protocol.Range{
278
+
Start: protocol.Position{
279
+
Line: 0,
280
+
Character: 6,
281
+
},
282
+
End: protocol.Position{
283
+
Line: 0,
284
+
Character: 17,
285
+
},
286
+
},
287
+
SelectionRange: protocol.Range{
288
+
Start: protocol.Position{
289
+
Line: 0,
290
+
Character: 6,
291
+
},
292
+
End: protocol.Position{
293
+
Line: 0,
294
+
Character: 10,
295
+
},
296
+
},
297
+
},
298
+
protocol.DocumentSymbol{
299
+
Name: "if flag then 'hello'",
300
+
Detail: "String",
301
+
Kind: protocol.Field,
302
+
Range: protocol.Range{
303
+
Start: protocol.Position{
304
+
Line: 2,
305
+
Character: 2,
306
+
},
307
+
End: protocol.Position{
308
+
Line: 2,
309
+
Character: 34,
310
+
},
311
+
},
312
+
SelectionRange: protocol.Range{
313
+
Start: protocol.Position{
314
+
Line: 2,
315
+
Character: 2,
316
+
},
317
+
End: protocol.Position{
318
+
Line: 2,
319
+
Character: 22,
320
+
},
321
+
},
322
+
},
323
+
protocol.DocumentSymbol{
324
+
Name: "if flag then 'hello1' else 'hello2'",
325
+
Detail: "String",
326
+
Kind: protocol.Field,
327
+
Range: protocol.Range{
328
+
Start: protocol.Position{
329
+
Line: 3,
330
+
Character: 2,
331
+
},
332
+
End: protocol.Position{
333
+
Line: 3,
334
+
Character: 49,
335
+
},
336
+
},
337
+
SelectionRange: protocol.Range{
338
+
Start: protocol.Position{
339
+
Line: 3,
340
+
Character: 2,
341
+
},
342
+
End: protocol.Position{
343
+
Line: 3,
344
+
Character: 37,
345
+
},
346
+
},
347
+
},
348
+
protocol.DocumentSymbol{
349
+
Name: "if false == flag then 'hello3' else (function() 'test')()",
350
+
Detail: "String",
351
+
Kind: protocol.Field,
352
+
Range: protocol.Range{
353
+
Start: protocol.Position{
354
+
Line: 4,
355
+
Character: 2,
356
+
},
357
+
End: protocol.Position{
358
+
Line: 4,
359
+
Character: 71,
360
+
},
361
+
},
362
+
SelectionRange: protocol.Range{
363
+
Start: protocol.Position{
364
+
Line: 4,
365
+
Character: 2,
366
+
},
367
+
End: protocol.Position{
368
+
Line: 4,
369
+
Character: 59,
370
+
},
371
+
},
372
+
},
373
+
},
374
+
},
269
375
} {
270
376
t.Run(tc.name, func(t *testing.T) {
271
377
params := &protocol.DocumentSymbolParams{
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
1
+
local flag = true;
2
+
{
3
+
[if flag then 'hello']: 'world!',
4
+
[if flag then 'hello1' else 'hello2']: 'world!',
5
+
[if false == flag then 'hello3' else (function() 'test')()]: 'world!',
6
+
}
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4