Skip to content

Commit 4a094f7

Browse files
Merge pull request #25 from grafana/julienduchesne/more-self-cases
`self` complex scope improvements
2 parents 546b258 + b120df4 commit 4a094f7

File tree

5 files changed

+68
-10
lines changed

5 files changed

+68
-10
lines changed

pkg/nodestack/nodestack.go

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ func (s *NodeStack) Pop() (*NodeStack, ast.Node) {
4040
return s, n
4141
}
4242

43+
func (s *NodeStack) Peek() ast.Node {
44+
if len(s.Stack) == 0 {
45+
return nil
46+
}
47+
return s.Stack[len(s.Stack)-1]
48+
}
49+
4350
func (s *NodeStack) IsEmpty() bool {
4451
return len(s.Stack) == 0
4552
}

pkg/processing/find_field.go

+20-3
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,14 @@ func FindRangesFromIndexList(stack *nodestack.NodeStack, indexList []string, vm
4848
}
4949
foundDesugaredObjects = append(foundDesugaredObjects, lhsObject)
5050
} else if start == "self" {
51-
tmpStack := nodestack.NewNodeStack(stack.From)
52-
tmpStack.Stack = make([]ast.Node, len(stack.Stack))
53-
copy(tmpStack.Stack, stack.Stack)
51+
tmpStack := stack.Clone()
52+
53+
// Special case. If the index was part of a binary node (ex: self.foo + {...}),
54+
// then the second element's content should not be considered to find the index's reference
55+
if _, ok := tmpStack.Peek().(*ast.Binary); ok {
56+
tmpStack.Pop()
57+
}
58+
5459
foundDesugaredObjects = filterSelfScope(findTopLevelObjects(tmpStack, vm))
5560
} else if start == "std" {
5661
return nil, fmt.Errorf("cannot get definition of std lib")
@@ -189,6 +194,18 @@ func findTopLevelObjects(stack *nodestack.NodeStack, vm *jsonnet.VM) []*ast.Desu
189194
filename := curr.File.Value
190195
rootNode, _, _ := vm.ImportAST(string(curr.Loc().File.DiagnosticFileName), filename)
191196
stack = stack.Push(rootNode)
197+
case *ast.Index:
198+
container := stack.Peek()
199+
if containerObj, containerIsObj := container.(*ast.DesugaredObject); containerIsObj {
200+
indexValue, indexIsString := curr.Index.(*ast.LiteralString)
201+
if !indexIsString {
202+
continue
203+
}
204+
obj := findObjectFieldInObject(containerObj, indexValue.Value)
205+
if obj != nil {
206+
stack.Push(obj.Body)
207+
}
208+
}
192209
}
193210
}
194211
return objects

pkg/server/definition_test.go

+27-1
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,32 @@ func TestDefinition(t *testing.T) {
343343
End: protocol.Position{Line: 0, Character: 12},
344344
},
345345
},
346+
{
347+
name: "goto self complex scope 1",
348+
filename: "testdata/goto-self-complex-scoping.jsonnet",
349+
position: protocol.Position{Line: 10, Character: 15},
350+
targetRange: protocol.Range{
351+
Start: protocol.Position{Line: 6, Character: 2},
352+
End: protocol.Position{Line: 8, Character: 3},
353+
},
354+
targetSelectionRange: protocol.Range{
355+
Start: protocol.Position{Line: 6, Character: 2},
356+
End: protocol.Position{Line: 6, Character: 6},
357+
},
358+
},
359+
{
360+
name: "goto self complex scope 2",
361+
filename: "testdata/goto-self-complex-scoping.jsonnet",
362+
position: protocol.Position{Line: 11, Character: 19},
363+
targetRange: protocol.Range{
364+
Start: protocol.Position{Line: 7, Character: 4},
365+
End: protocol.Position{Line: 7, Character: 18},
366+
},
367+
targetSelectionRange: protocol.Range{
368+
Start: protocol.Position{Line: 7, Character: 4},
369+
End: protocol.Position{Line: 7, Character: 9},
370+
},
371+
},
346372
}
347373
for _, tc := range testCases {
348374
t.Run(tc.name, func(t *testing.T) {
@@ -471,7 +497,7 @@ func TestDefinitionFail(t *testing.T) {
471497
params: protocol.DefinitionParams{
472498
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
473499
TextDocument: protocol.TextDocumentIdentifier{
474-
URI: "testdata/goto-self-out-of-scope.jsonnet",
500+
URI: "testdata/goto-self-complex-scoping.jsonnet",
475501
},
476502
Position: protocol.Position{
477503
Line: 3,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
test: 'test',
3+
sub: {
4+
test2: self.test, // Should not be found
5+
},
6+
7+
sub2: {
8+
test3: 'test3',
9+
},
10+
11+
sub3: self.sub2 { // sub2 should be found
12+
test4: self.test3, // test3 should be found
13+
},
14+
}

pkg/server/testdata/goto-self-out-of-scope.jsonnet

-6
This file was deleted.

0 commit comments

Comments
 (0)