-
Notifications
You must be signed in to change notification settings - Fork 0
/
ilookup.go
79 lines (70 loc) · 1.81 KB
/
ilookup.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
// Looking up interface definitions.
package main
import "fmt"
import "go/ast"
// IDKey (interface definition key) is used to identify the
// InterfaceDefinition to be found.
type IDKey struct {
Package string
Name string
}
func (key *IDKey) String() string {
return fmt.Sprintf("%s.%s", key.Package, key.Name)
}
// ExprToIDKey derives an IDKey from the specified expression.
func ExprToIDKey(e ast.Expr, defaultPkg string) *IDKey {
var etk func (recursive bool, e ast.Expr, defaultPkg string) *IDKey
etk = func(recursive bool, e ast.Expr, defaultPkg string) *IDKey {
switch e1 := e.(type) {
case *ast.Ident:
return &IDKey{
Package: defaultPkg,
Name: e1.Name,
}
case *ast.SelectorExpr:
if recursive {
panic("Nexted selector expressions not supported")
}
p, ok := e1.X.(*ast.Ident)
if !ok {
panic(fmt.Sprintf("Unsupported selector %#v", e1))
}
return etk(true, e1.Sel, p.Name)
default:
panic(fmt.Sprintf("Unsupported expression type %T", e1))
}
}
return etk(false, e, defaultPkg)
}
// IDLookup searches the files of the context for an
// InterfaceDefinition matching key.
func (ctx *context) IDLookup(key *IDKey) *InterfaceDefinition {
for _, f := range ctx.files {
found := f.IDLookup(key)
if found != nil {
return found
}
}
return nil
}
// IDLookup searches the File for an InterfaceDefinition matching key.
func (f *File) IDLookup(key *IDKey) *InterfaceDefinition {
for _, i := range f.Interfaces {
found := i.IDLookup(key)
if found != nil {
return found
}
}
return nil
}
// IDLookup searches returns the interface definition if it matches
// key. Otherwise it returns nil.
func (i *InterfaceDefinition) IDLookup(key *IDKey) *InterfaceDefinition {
if i.InterfaceName != key.Name {
return nil
}
if i.Package() != key.Package {
return nil
}
return i
}