Repository navigation
Expand file tree
/
Copy pathnamespace_index.go
More file actions
74 lines (69 loc) · 1.97 KB
/
Copy pathnamespace_index.go
File metadata and controls
74 lines (69 loc) · 1.97 KB
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
package codegraph
import (
"context"
"sort"
)
type namespaceStep struct {
parent string
relation string
}
type namespaceIndex struct {
parents map[string][]namespaceStep
owners map[string]bool
}
// Each immutable publication owns its index. Failed or canceled construction is
// not cached; relation evidence remains in the graph, independent of query policy.
func (g *Graph) namespaces(ctx context.Context) (*namespaceIndex, error) {
g.namespaceMu.Lock()
defer g.namespaceMu.Unlock()
if err := ctx.Err(); err != nil {
return nil, err
}
if g.namespaceIndex != nil {
return g.namespaceIndex, nil
}
index := &namespaceIndex{parents: map[string][]namespaceStep{}, owners: map[string]bool{}}
for id, n := range g.nodes {
if err := ctx.Err(); err != nil {
return nil, err
}
if namespaceKind(n.Kind) {
index.owners[id] = true
}
}
for id, r := range g.relations {
if err := ctx.Err(); err != nil {
return nil, err
}
switch r.Kind {
case Contains:
index.parents[r.Target] = append(index.parents[r.Target], namespaceStep{r.Source, id})
index.owners[r.Source] = true
case InNamespace:
index.parents[r.Source] = append(index.parents[r.Source], namespaceStep{r.Target, id})
index.owners[r.Target] = true
case OccursIn:
index.parents[r.Source] = append(index.parents[r.Source], namespaceStep{r.Target, id})
}
}
for _, parents := range index.parents {
if err := ctx.Err(); err != nil {
return nil, err
}
sort.Slice(parents, func(i, j int) bool { return parents[i].relation < parents[j].relation })
}
if err := ctx.Err(); err != nil {
return nil, err
}
g.namespaceIndex = index
return index, nil
}
// Concrete kinds cover empty namespaces; graph ownership also admits other
// language-defined member owners, such as a function containing local declarations.
func namespaceKind(kind NodeKind) bool {
switch kind {
case Package, Module, Namespace, Class, Struct, Interface, Type, Enum, Record, Trait, Union:
return true
}
return false
}