forked from rodrigo-brito/gocity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvisitor.go
88 lines (72 loc) · 2.38 KB
/
visitor.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
package analyzer
import (
"go/ast"
"go/token"
"github.com/rodrigo-brito/gocity/utils"
)
type NodeInfo struct {
File string
ObjectName string
NumberLines int
NumberMethods int
NumberAttributes int
Line int
}
type Visitor struct {
FileSet *token.FileSet
StructInfo map[string]*NodeInfo
PackageName string
Path string
}
func (v Visitor) getNumberOfLines(start, end token.Pos) int {
return v.FileSet.Position(end).Line - v.FileSet.Position(start).Line + 1
}
func (v *Visitor) Visit(node ast.Node) ast.Visitor {
if node == nil {
return nil
}
switch definition := node.(type) {
case *ast.ValueSpec: // Atributes
identifier := utils.GetIdentifier(v.Path, v.PackageName, "")
if _, ok := v.StructInfo[identifier]; !ok {
v.StructInfo[identifier] = new(NodeInfo)
}
v.StructInfo[identifier].NumberAttributes++
v.StructInfo[identifier].Line = v.FileSet.Position(definition.Pos()).Line
case *ast.TypeSpec: // Structs
if structObj, ok := definition.Type.(*ast.StructType); ok {
identifier := utils.GetIdentifier(v.Path, v.PackageName, definition.Name.Name)
if _, ok := v.StructInfo[identifier]; !ok {
v.StructInfo[identifier] = new(NodeInfo)
}
v.StructInfo[identifier].ObjectName = definition.Name.Name
v.StructInfo[identifier].NumberAttributes = len(structObj.Fields.List)
v.StructInfo[identifier].NumberLines += v.getNumberOfLines(structObj.Pos(), structObj.End())
v.StructInfo[identifier].Line = v.FileSet.Position(structObj.Pos()).Line
}
case *ast.FuncDecl: // Methods
var structName = ""
if definition.Recv != nil && len(definition.Recv.List) > 0 {
typeObj := definition.Recv.List[0].Type
if ident, ok := typeObj.(*ast.Ident); ok {
structName = ident.Name
} else {
if ident, ok := typeObj.(*ast.StarExpr).X.(*ast.Ident); ok {
structName = ident.Name
} else if ident, ok := typeObj.(*ast.StarExpr).X.(*ast.SelectorExpr); ok {
structName = ident.Sel.Name
}
}
}
identifier := utils.GetIdentifier(v.Path, v.PackageName, structName)
if _, ok := v.StructInfo[identifier]; !ok {
v.StructInfo[identifier] = new(NodeInfo)
v.StructInfo[identifier].ObjectName = structName
}
v.StructInfo[identifier].NumberMethods++
if definition.Body != nil {
v.StructInfo[identifier].NumberLines += v.getNumberOfLines(definition.Body.Pos(), definition.Body.End())
}
}
return v
}