-
Notifications
You must be signed in to change notification settings - Fork 0
/
references.go
117 lines (99 loc) · 2.18 KB
/
references.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package langd
import (
"fmt"
"go/token"
"go/types"
"github.com/object88/langd/collections"
)
type ref struct {
dp *DistinctPackage
pos token.Pos
}
func (w *Workspace) locateReferences(obj types.Object, dp *DistinctPackage) []*ref {
if obj == nil {
fmt.Printf("No obj provided\n")
// Special case
}
// If this is a package name, do something special also.
if _, ok := obj.(*types.PkgName); ok {
// *shrug*
fmt.Printf("Package name\n")
}
if obj.Pkg() == nil {
// Uhhh, not sure what this is? A keyword or something?
fmt.Printf("obj.Pkg is nil\n")
}
// Start off with in-package references, shall we?
var refs []*ref
for id, use := range dp.checker.Uses {
if sameObj(obj, use) {
refs = append(refs, &ref{
dp: dp,
pos: id.Pos(),
})
}
}
if obj.Exported() {
n, ok := w.LoaderEngine.caravan.Find(dp.Hash())
if !ok {
// Should never get here.
panic("Shit.")
}
asc := flattenAscendants(false, n)
ascRefs := w.checkAscendants(asc, obj)
for _, r := range ascRefs {
refs = append(refs, r)
}
}
fmt.Printf("Returning %d refs\n", len(refs))
return refs
}
func (w *Workspace) checkAscendants(ascendants map[string]*DistinctPackage, obj types.Object) []*ref {
refs := []*ref{}
for _, dp := range ascendants {
for id, use := range dp.checker.Uses {
if sameObj(obj, use) {
refs = append(refs, &ref{
dp: dp,
pos: id.Pos(),
})
}
}
}
return refs
}
func flattenAscendants(includeNodes bool, nodes ...*collections.Node) map[string]*DistinctPackage {
asc := map[string]*DistinctPackage{}
var f func(n *collections.Node)
f = func(n *collections.Node) {
for _, n1 := range n.Ascendants {
dp := n1.Element.(*DistinctPackage)
if _, ok := asc[dp.Package.AbsPath]; !ok {
asc[dp.Package.AbsPath] = dp
f(n1)
}
}
}
for _, n := range nodes {
if includeNodes {
dp := n.Element.(*DistinctPackage)
asc[dp.Package.AbsPath] = dp
}
f(n)
}
return asc
}
func sameObj(x, y types.Object) bool {
if x == y {
return true
}
xPkgname, ok := x.(*types.PkgName)
if !ok {
return false
}
yPkgname, ok := y.(*types.PkgName)
if !ok {
return false
}
return xPkgname.Imported() == yPkgname.Imported()
}