forked from go-kit/kit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
interface.go
70 lines (57 loc) · 1.9 KB
/
interface.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
package main
import "go/ast"
// because "interface" is a keyword...
type iface struct {
name, stubname, rcvrName *ast.Ident
methods []method
}
func (i iface) stubName() *ast.Ident {
return i.stubname
}
func (i iface) stubStructDecl() ast.Decl {
return structDecl(i.stubName(), &ast.FieldList{})
}
func (i iface) endpointsStruct() ast.Decl {
fl := &ast.FieldList{}
for _, m := range i.methods {
fl.List = append(fl.List, &ast.Field{Names: []*ast.Ident{m.name}, Type: sel(id("endpoint"), id("Endpoint"))})
}
return structDecl(id("Endpoints"), fl)
}
func (i iface) httpHandler() ast.Decl {
handlerFn := fetchFuncDecl("NewHTTPHandler")
// does this "inlining" process merit a helper akin to replaceIdent?
handleCalls := []ast.Stmt{}
for _, m := range i.methods {
handleCall := fetchFuncDecl("inlineHandlerBuilder").Body.List[0].(*ast.ExprStmt).X.(*ast.CallExpr)
handleCall = replaceLit(handleCall, `"/bar"`, `"`+m.pathName()+`"`).(*ast.CallExpr)
handleCall = replaceIdent(handleCall, "ExampleEndpoint", m.name).(*ast.CallExpr)
handleCall = replaceIdent(handleCall, "DecodeExampleRequest", m.decodeFuncName()).(*ast.CallExpr)
handleCall = replaceIdent(handleCall, "EncodeExampleResponse", m.encodeFuncName()).(*ast.CallExpr)
handleCalls = append(handleCalls, &ast.ExprStmt{X: handleCall})
}
pasteStmts(handlerFn.Body, 1, handleCalls)
return handlerFn
}
func (i iface) reciever() *ast.Field {
return field(i.receiverName(), i.stubName())
}
func (i iface) receiverName() *ast.Ident {
if i.rcvrName != nil {
return i.rcvrName
}
scope := ast.NewScope(nil)
for _, meth := range i.methods {
for _, arg := range meth.params {
if arg.name != nil {
scope.Insert(ast.NewObj(ast.Var, arg.name.Name))
}
}
for _, arg := range meth.results {
if arg.name != nil {
scope.Insert(ast.NewObj(ast.Var, arg.name.Name))
}
}
}
return id(unexport(inventName(i.name, scope).Name))
}