/
module_path.go
92 lines (77 loc) · 1.82 KB
/
module_path.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
package addr
import (
"bytes"
"fmt"
)
type ModulePath []ModulePathStep
type ModulePathStep interface {
modulePathStep()
}
type modulePathName string
func (n modulePathName) modulePathStep() {
}
type modulePathIndex struct {
EachIndex
}
func (n modulePathIndex) modulePathStep() {
}
// RootModulePath is a ModulePath representing the root module
var RootModulePath ModulePath
func (m ModulePath) String() string {
var buf bytes.Buffer
for _, rawStep := range m {
switch step := rawStep.(type) {
case modulePathName:
buf.WriteByte('.')
buf.WriteString(string(step))
case modulePathIndex:
buf.WriteByte('[')
buf.WriteString(step.String())
buf.WriteByte(']')
default:
// should never happen since we ensure no other step types are
// included in ParseModulePath
panic(fmt.Errorf("unsupported %T step in ModulePath traversal", rawStep))
}
}
return buf.String()
}
func (m ModulePath) append(step ModulePathStep) ModulePath {
new := make(ModulePath, len(m), len(m)+1)
copy(new, m)
new = append(new, step)
return new
}
func (m ModulePath) AppendName(name string) ModulePath {
return m.append(modulePathName(name))
}
func (m ModulePath) AppendIndex(key EachIndex) ModulePath {
return m.append(modulePathIndex{key})
}
func (m ModulePath) Parent() ModulePath {
if len(m) == 0 {
return RootModulePath
}
path := m
for path = path[:len(path)-1]; len(path) > 0; path = path[:len(path)-1] {
if _, ok := path[len(path)-1].(modulePathName); ok {
return path
}
}
return RootModulePath
}
func (m ModulePath) NearestName() ModulePath {
path := m
if len(path) == 0 {
return RootModulePath
}
for ; len(path) > 0; path = path[:len(path)-1] {
if _, ok := path[len(path)-1].(modulePathName); ok {
return path
}
}
return RootModulePath
}
func (m ModulePath) IsRoot() bool {
return len(m) == 0
}