-
Notifications
You must be signed in to change notification settings - Fork 3
/
definition.go
129 lines (102 loc) · 2.88 KB
/
definition.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package eapi
import (
"fmt"
"go/ast"
"strings"
"github.com/gotomicro/eapi/spec"
"golang.org/x/tools/go/packages"
)
type Definition interface {
Pkg() *packages.Package
File() *ast.File
Key() string
definition()
}
var _ Definition = &FuncDefinition{}
type FuncDefinition struct {
pkg *packages.Package
file *ast.File
Decl *ast.FuncDecl
}
func NewFuncDefinition(pkg *packages.Package, file *ast.File, decl *ast.FuncDecl) *FuncDefinition {
return &FuncDefinition{pkg: pkg, file: file, Decl: decl}
}
func (f *FuncDefinition) Key() string {
if f.Decl.Recv.NumFields() == 1 {
receiver := f.Decl.Recv.List[0]
switch t := receiver.Type.(type) {
case *ast.Ident:
return f.pkg.PkgPath + "." + t.Name + "." + f.Decl.Name.Name
case *ast.StarExpr:
i, ok := t.X.(*ast.Ident)
if !ok {
fmt.Printf("invalid function receiver at %s", f.pkg.Fset.Position(receiver.Pos()).String())
break
}
return "*" + f.pkg.PkgPath + "." + i.Name + "." + f.Decl.Name.Name
default:
fmt.Printf("invalid function receiver at %s", f.pkg.Fset.Position(receiver.Pos()).String())
}
ident, ok := receiver.Type.(*ast.Ident)
if !ok {
fmt.Printf("invalid function receiver at %s", f.pkg.Fset.Position(receiver.Pos()).String())
return f.pkg.PkgPath + "." + f.Decl.Name.Name
}
return f.pkg.PkgPath + "." + ident.Name + f.Decl.Name.Name
}
return f.pkg.PkgPath + "." + f.Decl.Name.Name
}
func (f *FuncDefinition) Pkg() *packages.Package {
return f.pkg
}
func (f *FuncDefinition) File() *ast.File {
return f.file
}
func (f *FuncDefinition) definition() {}
var _ Definition = &TypeDefinition{}
type TypeDefinition struct {
Spec *ast.TypeSpec
// Enum items
Enums []*spec.ExtendedEnumItem
pkg *packages.Package
file *ast.File
}
func NewTypeDefinition(pkg *packages.Package, file *ast.File, spec *ast.TypeSpec) *TypeDefinition {
return &TypeDefinition{pkg: pkg, file: file, Spec: spec}
}
func (t *TypeDefinition) definition() {}
func (t *TypeDefinition) Pkg() *packages.Package {
return t.pkg
}
func (t *TypeDefinition) File() *ast.File {
return t.file
}
func (t *TypeDefinition) Key() string {
return t.pkg.PkgPath + "." + t.Spec.Name.Name
}
func (t *TypeDefinition) ModelKey(typeArgs ...*spec.SchemaRef) string {
sb := strings.Builder{}
sb.WriteString(strings.ReplaceAll(t.pkg.PkgPath, "/", "_"))
sb.WriteString(".")
sb.WriteString(t.Spec.Name.Name)
if len(typeArgs) > 0 {
sb.WriteString("[")
sb.WriteString(typeArgs[0].GetKey())
for _, arg := range typeArgs[1:] {
sb.WriteString(",")
sb.WriteString(arg.GetKey())
}
sb.WriteString("]")
}
return sb.String()
}
func (t *TypeDefinition) RefKey(typeArgs ...*spec.SchemaRef) string {
return "#/components/schemas/" + t.ModelKey(typeArgs...)
}
type Definitions map[string]Definition
func (d *Definitions) Set(def Definition) {
(*d)[def.Key()] = def
}
func (d *Definitions) Get(key string) Definition {
return (*d)[key]
}