forked from vektra/mockery
/
parse.go
81 lines (69 loc) · 1.5 KB
/
parse.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
package mockery
import (
"go/ast"
"go/parser"
"go/token"
"path/filepath"
)
type Parser struct {
file *ast.File
path string
}
func NewParser() *Parser {
return &Parser{}
}
func (p *Parser) Parse(path string) error {
fset := token.NewFileSet()
// Parse the file containing this very example
// but stop after processing the imports.
f, err := parser.ParseFile(fset, path, nil, 0)
if err != nil {
return err
}
abs, err := filepath.Abs(path)
if err != nil {
return err
}
p.path = abs
p.file = f
return nil
}
func (p *Parser) Find(name string) (*Interface, error) {
for _, decl := range p.file.Decls {
if gen, ok := decl.(*ast.GenDecl); ok {
for _, spec := range gen.Specs {
if typespec, ok := spec.(*ast.TypeSpec); ok {
if typespec.Name.Name == name {
if iface, ok := typespec.Type.(*ast.InterfaceType); ok {
return &Interface{name, p.path, p.file, iface}, nil
} else {
return nil, ErrNotInterface
}
}
}
}
}
}
return nil, nil
}
type Interface struct {
Name string
Path string
File *ast.File
Type *ast.InterfaceType
}
func (p *Parser) Interfaces() []*Interface {
var ifaces []*Interface
for _, decl := range p.file.Decls {
if gen, ok := decl.(*ast.GenDecl); ok {
for _, spec := range gen.Specs {
if typespec, ok := spec.(*ast.TypeSpec); ok {
if iface, ok := typespec.Type.(*ast.InterfaceType); ok {
ifaces = append(ifaces, &Interface{typespec.Name.Name, p.path, p.file, iface})
}
}
}
}
}
return ifaces
}