This repository has been archived by the owner on Jul 7, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.go
97 lines (86 loc) · 2.12 KB
/
file.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
93
94
95
96
97
package humanize
import (
"go/ast"
"go/parser"
"go/token"
)
// File is the annotations in package and all its sub types
type File struct {
FileName string
PackageName string
Docs Docs
Functions []*Function
Imports []*Import
Variables []*Variable
Constants []*Constant
Types []*TypeName
}
type walker struct {
src string
File *File
Package *Package
}
func nameFromIdent(i *ast.Ident) (name string) {
if i != nil {
name = i.String()
}
return
}
func docsFromNodeDoc(cgs ...*ast.CommentGroup) Docs {
var res Docs
for _, cg := range cgs {
if cg != nil {
for i := range cg.List {
res = append(res, cg.List[i].Text)
}
}
}
return res
}
func (fv *walker) Visit(node ast.Node) ast.Visitor {
if node != nil {
switch t := node.(type) {
case *ast.File:
fv.File.PackageName = nameFromIdent(t.Name)
fv.File.Docs = docsFromNodeDoc(t.Doc)
case *ast.FuncDecl:
fv.File.Functions = append(fv.File.Functions, NewFunction(t, fv.src, fv.File, fv.Package))
return nil // Do not go deeper
case *ast.GenDecl:
// Constants :/
for i := range t.Specs {
switch decl := t.Specs[i].(type) {
case *ast.ImportSpec:
fv.File.Imports = append(fv.File.Imports, NewImport(decl, t.Doc))
case *ast.ValueSpec:
if t.Tok.String() == "var" {
fv.File.Variables = append(fv.File.Variables, NewVariable(decl, t.Doc, fv.src, fv.File, fv.Package)...)
} else if t.Tok.String() == "const" {
fv.File.Constants = append(fv.File.Constants, NewConstant(decl, t.Doc, fv.src, fv.File, fv.Package)...)
}
case *ast.TypeSpec:
fv.File.Types = append(fv.File.Types, NewType(decl, t.Doc, fv.src, fv.File, fv.Package))
}
}
return nil
default:
//fmt.Printf("\n%T\n", t)
}
}
return fv
}
// ParseFile try to parse a single file for its annotations
func ParseFile(src string, p *Package) (*File, error) {
lastConst = nil
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
if err != nil {
return &File{}, err
}
fv := &walker{}
fv.src = src
fv.File = &File{}
fv.Package = p
ast.Walk(fv, f)
return fv.File, nil
}