forked from src-d/proteus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
111 lines (92 loc) · 2.25 KB
/
context.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
package rpc
import (
"fmt"
"go/types"
"strings"
"gopkg.in/src-d/proteus.v1/protobuf"
)
type context struct {
implName string
constructorName string
proto *protobuf.Package
pkg *types.Package
imports []string
}
func (c *context) isNameDefined(name string) bool {
for _, n := range c.pkg.Scope().Names() {
if n == name {
return true
}
}
return false
}
func (c *context) findMessage(name string) *protobuf.Message {
for _, m := range c.proto.Messages {
if m.Name == name {
return m
}
}
return nil
}
func (c *context) findSignature(rpc *protobuf.RPC) *types.Signature {
var fn types.Object
if rpc.Recv != "" {
recv := c.pkg.Scope().Lookup(rpc.Recv)
fn, _, _ = types.LookupFieldOrMethod(recv.Type(), true, c.pkg, rpc.Method)
} else {
fn = c.pkg.Scope().Lookup(rpc.Method)
}
return fn.Type().(*types.Signature)
}
func (c *context) argumentType(rpc *protobuf.RPC) string {
signature := c.findSignature(rpc)
obj := firstTypeName(signature.Params())
c.addImport(obj.Pkg().Path())
return c.objectNameInContext(obj)
}
func (c *context) returnType(rpc *protobuf.RPC) string {
signature := c.findSignature(rpc)
obj := firstTypeName(signature.Results())
c.addImport(obj.Pkg().Path())
return c.objectNameInContext(obj)
}
// objectNameInContext returns the name of the object prefixed by its package name
// if needed
func (c *context) objectNameInContext(obj types.Object) string {
if c.pkg.Path() == obj.Pkg().Path() {
return obj.Name()
} else {
return fmt.Sprintf("%s.%s", obj.Pkg().Name(), obj.Name())
}
}
func firstTypeName(tuple *types.Tuple) types.Object {
t := tuple.At(0).Type()
if inner, ok := t.(*types.Pointer); ok {
t = inner.Elem()
}
return t.(*types.Named).Obj()
}
func (c *context) pkgPath() string {
if c.pkg != nil {
return c.pkg.Path()
}
return ""
}
func (c *context) addImport(path string) {
if path == c.pkgPath() {
return
}
for _, i := range c.imports {
if i == path {
return
}
}
c.imports = append(c.imports, path)
}
func serviceImplName(pkg *protobuf.Package) string {
n := pkg.ServiceName()
return strings.ToLower(string(n[0])) + n[1:] + "Server"
}
func constructorName(pkg *protobuf.Package) string {
return fmt.Sprintf("New%sServer", pkg.ServiceName())
}