Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(290)

Side by Side Diff: third_party/go/src/golang.org/x/mobile/bind/gengo.go

Issue 1275153002: Remove third_party/golang.org/x/mobile as it is no longer used with Go 1.5. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Remove golang.org/x/mobile Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package bind
6
7 import (
8 "fmt"
9 "go/token"
10 "log"
11 "strings"
12
13 "golang.org/x/tools/go/types"
14 )
15
16 type goGen struct {
17 *printer
18 fset *token.FileSet
19 pkg *types.Package
20 err ErrorList
21 }
22
23 func (g *goGen) errorf(format string, args ...interface{}) {
24 g.err = append(g.err, fmt.Errorf(format, args...))
25 }
26
27 const goPreamble = `// Package go_%s is an autogenerated binder stub for package %s.
28 // gobind -lang=go %s
29 //
30 // File is generated by gobind. Do not edit.
31 package go_%s
32
33 import (
34 "golang.org/x/mobile/bind/seq"
35 %q
36 )
37
38 `
39
40 func (g *goGen) genPreamble() {
41 n := g.pkg.Name()
42 g.Printf(goPreamble, n, n, g.pkg.Path(), n, g.pkg.Path())
43 }
44
45 func (g *goGen) genFuncBody(o *types.Func, selectorLHS string) {
46 sig := o.Type().(*types.Signature)
47 params := sig.Params()
48 for i := 0; i < params.Len(); i++ {
49 p := params.At(i)
50 g.genRead("param_"+p.Name(), "in", p.Type())
51 }
52
53 res := sig.Results()
54 if res.Len() > 2 || res.Len() == 2 && !isErrorType(res.At(1).Type()) {
55 g.errorf("functions and methods must return either zero or one v alues, and optionally an error")
56 return
57 }
58 returnsValue := false
59 returnsError := false
60 if res.Len() == 1 {
61 if isErrorType(res.At(0).Type()) {
62 returnsError = true
63 g.Printf("err := ")
64 } else {
65 returnsValue = true
66 g.Printf("res := ")
67 }
68 } else if res.Len() == 2 {
69 returnsValue = true
70 returnsError = true
71 g.Printf("res, err := ")
72 }
73
74 g.Printf("%s.%s(", selectorLHS, o.Name())
75 for i := 0; i < params.Len(); i++ {
76 if i > 0 {
77 g.Printf(", ")
78 }
79 g.Printf("param_%s", params.At(i).Name())
80 }
81 g.Printf(")\n")
82
83 if returnsValue {
84 g.genWrite("res", "out", res.At(0).Type())
85 }
86 if returnsError {
87 g.genWrite("err", "out", res.At(res.Len()-1).Type())
88 }
89 }
90
91 func (g *goGen) genWrite(valName, seqName string, T types.Type) {
92 if isErrorType(T) {
93 g.Printf("if %s == nil {\n", valName)
94 g.Printf(" %s.WriteUTF16(\"\");\n", seqName)
95 g.Printf("} else {\n")
96 g.Printf(" %s.WriteUTF16(%s.Error());\n", seqName, valName)
97 g.Printf("}\n")
98 return
99 }
100 switch T := T.(type) {
101 case *types.Pointer:
102 // TODO(crawshaw): test *int
103 // TODO(crawshaw): test **Generator
104 switch T := T.Elem().(type) {
105 case *types.Named:
106 obj := T.Obj()
107 if obj.Pkg() != g.pkg {
108 g.errorf("type %s not defined in package %s", T, g.pkg)
109 return
110 }
111 g.Printf("%s.WriteGoRef(%s)\n", seqName, valName)
112 default:
113 g.errorf("unsupported type %s", T)
114 }
115 case *types.Named:
116 switch u := T.Underlying().(type) {
117 case *types.Interface, *types.Pointer:
118 g.Printf("%s.WriteGoRef(%s)\n", seqName, valName)
119 default:
120 g.errorf("unsupported, direct named type %s: %s", T, u)
121 }
122 default:
123 g.Printf("%s.Write%s(%s);\n", seqName, seqType(T), valName)
124 }
125 }
126
127 func (g *goGen) genFunc(o *types.Func) {
128 g.Printf("func proxy_%s(out, in *seq.Buffer) {\n", o.Name())
129 g.Indent()
130 g.genFuncBody(o, g.pkg.Name())
131 g.Outdent()
132 g.Printf("}\n\n")
133 }
134
135 func exportedMethodSet(T types.Type) []*types.Func {
136 var methods []*types.Func
137 methodset := types.NewMethodSet(T)
138 for i := 0; i < methodset.Len(); i++ {
139 obj := methodset.At(i).Obj()
140 if !obj.Exported() {
141 continue
142 }
143 switch obj := obj.(type) {
144 case *types.Func:
145 methods = append(methods, obj)
146 default:
147 log.Panicf("unexpected methodset obj: %s", obj)
148 }
149 }
150 return methods
151 }
152
153 func exportedFields(T *types.Struct) []*types.Var {
154 var fields []*types.Var
155 for i := 0; i < T.NumFields(); i++ {
156 f := T.Field(i)
157 if !f.Exported() {
158 continue
159 }
160 fields = append(fields, f)
161 }
162 return fields
163 }
164
165 func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) {
166 fields := exportedFields(T)
167 methods := exportedMethodSet(types.NewPointer(obj.Type()))
168
169 g.Printf("const (\n")
170 g.Indent()
171 g.Printf("proxy%sDescriptor = \"go.%s.%s\"\n", obj.Name(), g.pkg.Name(), obj.Name())
172 for i, f := range fields {
173 g.Printf("proxy%s%sGetCode = 0x%x0f\n", obj.Name(), f.Name(), i)
174 g.Printf("proxy%s%sSetCode = 0x%x1f\n", obj.Name(), f.Name(), i)
175 }
176 for i, m := range methods {
177 g.Printf("proxy%s%sCode = 0x%x0c\n", obj.Name(), m.Name(), i)
178 }
179 g.Outdent()
180 g.Printf(")\n\n")
181
182 g.Printf("type proxy%s seq.Ref\n\n", obj.Name())
183
184 for _, f := range fields {
185 g.Printf("func proxy%s%sSet(out, in *seq.Buffer) {\n", obj.Name( ), f.Name())
186 g.Indent()
187 g.Printf("ref := in.ReadRef()\n")
188 g.Printf("v := in.Read%s()\n", seqType(f.Type()))
189 // TODO(crawshaw): other kinds of non-ptr types.
190 g.Printf("ref.Get().(*%s.%s).%s = v\n", g.pkg.Name(), obj.Name() , f.Name())
191 g.Outdent()
192 g.Printf("}\n\n")
193
194 g.Printf("func proxy%s%sGet(out, in *seq.Buffer) {\n", obj.Name( ), f.Name())
195 g.Indent()
196 g.Printf("ref := in.ReadRef()\n")
197 g.Printf("v := ref.Get().(*%s.%s).%s\n", g.pkg.Name(), obj.Name( ), f.Name())
198 g.Printf("out.Write%s(v)\n", seqType(f.Type()))
199 g.Outdent()
200 g.Printf("}\n\n")
201 }
202
203 for _, m := range methods {
204 g.Printf("func proxy%s%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name())
205 g.Indent()
206 g.Printf("ref := in.ReadRef()\n")
207 g.Printf("v := ref.Get().(*%s.%s)\n", g.pkg.Name(), obj.Name())
208 g.genFuncBody(m, "v")
209 g.Outdent()
210 g.Printf("}\n\n")
211 }
212
213 g.Printf("func init() {\n")
214 g.Indent()
215 for _, f := range fields {
216 n := f.Name()
217 g.Printf("seq.Register(proxy%sDescriptor, proxy%s%sSetCode, prox y%s%sSet)\n", obj.Name(), obj.Name(), n, obj.Name(), n)
218 g.Printf("seq.Register(proxy%sDescriptor, proxy%s%sGetCode, prox y%s%sGet)\n", obj.Name(), obj.Name(), n, obj.Name(), n)
219 }
220 for _, m := range methods {
221 n := m.Name()
222 g.Printf("seq.Register(proxy%sDescriptor, proxy%s%sCode, proxy%s %s)\n", obj.Name(), obj.Name(), n, obj.Name(), n)
223 }
224 g.Outdent()
225 g.Printf("}\n\n")
226 }
227
228 func (g *goGen) genInterface(obj *types.TypeName) {
229 iface := obj.Type().(*types.Named).Underlying().(*types.Interface)
230
231 // Descriptor and code for interface methods.
232 g.Printf("const (\n")
233 g.Indent()
234 g.Printf("proxy%sDescriptor = \"go.%s.%s\"\n", obj.Name(), g.pkg.Name(), obj.Name())
235 for i := 0; i < iface.NumMethods(); i++ {
236 g.Printf("proxy%s%sCode = 0x%x0a\n", obj.Name(), iface.Method(i) .Name(), i+1)
237 }
238 g.Outdent()
239 g.Printf(")\n\n")
240
241 // Define the entry points.
242 for i := 0; i < iface.NumMethods(); i++ {
243 m := iface.Method(i)
244 g.Printf("func proxy%s%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name())
245 g.Indent()
246 g.Printf("ref := in.ReadRef()\n")
247 g.Printf("v := ref.Get().(%s.%s)\n", g.pkg.Name(), obj.Name())
248 g.genFuncBody(m, "v")
249 g.Outdent()
250 g.Printf("}\n\n")
251 }
252
253 // Register the method entry points.
254 g.Printf("func init() {\n")
255 g.Indent()
256 for i := 0; i < iface.NumMethods(); i++ {
257 g.Printf("seq.Register(proxy%sDescriptor, proxy%s%sCode, proxy%s %s)\n",
258 obj.Name(), obj.Name(), iface.Method(i).Name(), obj.Name (), iface.Method(i).Name())
259 }
260 g.Outdent()
261 g.Printf("}\n\n")
262
263 // Define a proxy interface.
264 g.Printf("type proxy%s seq.Ref\n\n", obj.Name())
265
266 for i := 0; i < iface.NumMethods(); i++ {
267 m := iface.Method(i)
268 sig := m.Type().(*types.Signature)
269 params := sig.Params()
270 res := sig.Results()
271
272 if res.Len() > 2 ||
273 (res.Len() == 2 && !isErrorType(res.At(1).Type())) {
274 g.errorf("functions and methods must return either zero or one value, and optionally an error: %s.%s", obj.Name(), m.Name())
275 continue
276 }
277
278 g.Printf("func (p *proxy%s) %s(", obj.Name(), m.Name())
279 for i := 0; i < params.Len(); i++ {
280 if i > 0 {
281 g.Printf(", ")
282 }
283 g.Printf("%s %s", paramName(params, i), g.typeString(par ams.At(i).Type()))
284 }
285 g.Printf(") ")
286
287 if res.Len() == 1 {
288 g.Printf(g.typeString(res.At(0).Type()))
289 } else if res.Len() == 2 {
290 g.Printf("(%s, error)", g.typeString(res.At(0).Type()))
291 }
292 g.Printf(" {\n")
293 g.Indent()
294
295 g.Printf("in := new(seq.Buffer)\n")
296 for i := 0; i < params.Len(); i++ {
297 g.genWrite(paramName(params, i), "in", params.At(i).Type ())
298 }
299
300 if res.Len() == 0 {
301 g.Printf("seq.Transact((*seq.Ref)(p), proxy%s%sCode, in) \n", obj.Name(), m.Name())
302 } else {
303 g.Printf("out := seq.Transact((*seq.Ref)(p), proxy%s%sCo de, in)\n", obj.Name(), m.Name())
304 var rvs []string
305 for i := 0; i < res.Len(); i++ {
306 rv := fmt.Sprintf("res_%d", i)
307 g.genRead(rv, "out", res.At(i).Type())
308 rvs = append(rvs, rv)
309 }
310 g.Printf("return %s\n", strings.Join(rvs, ","))
311 }
312
313 g.Outdent()
314 g.Printf("}\n\n")
315 }
316 }
317
318 func (g *goGen) genRead(valName, seqName string, typ types.Type) {
319 if isErrorType(typ) {
320 g.Printf("%s := %s.ReadError()\n", valName, seqName)
321 return
322 }
323 switch t := typ.(type) {
324 case *types.Pointer:
325 switch u := t.Elem().(type) {
326 case *types.Named:
327 o := u.Obj()
328 if o.Pkg() != g.pkg {
329 g.errorf("type %s not defined in package %s", u, g.pkg)
330 return
331 }
332 g.Printf("// Must be a Go object\n")
333 g.Printf("%s_ref := %s.ReadRef()\n", valName, seqName)
334 g.Printf("%s := %s_ref.Get().(*%s.%s)\n", valName, valNa me, g.pkg.Name(), o.Name())
335 default:
336 g.errorf("unsupported type %s", t)
337 }
338 case *types.Named:
339 switch t.Underlying().(type) {
340 case *types.Interface, *types.Pointer:
341 o := t.Obj()
342 if o.Pkg() != g.pkg {
343 g.errorf("type %s not defined in package %s", t, g.pkg)
344 return
345 }
346 g.Printf("var %s %s\n", valName, g.typeString(t))
347 g.Printf("%s_ref := %s.ReadRef()\n", valName, seqName)
348 g.Printf("if %s_ref.Num < 0 { // go object \n", valName)
349 g.Printf(" %s = %s_ref.Get().(%s.%s)\n", valName, valN ame, g.pkg.Name(), o.Name())
350 g.Printf("} else { // foreign object \n")
351 g.Printf(" %s = (*proxy%s)(%s_ref)\n", valName, o.Name (), valName)
352 g.Printf("}\n")
353 }
354 default:
355 g.Printf("%s := %s.Read%s()\n", valName, seqName, seqType(t))
356 }
357 }
358
359 func (g *goGen) typeString(typ types.Type) string {
360 pkg := g.pkg
361
362 switch t := typ.(type) {
363 case *types.Named:
364 obj := t.Obj()
365 if obj.Pkg() == nil { // e.g. error type is *types.Named.
366 return types.TypeString(pkg, typ)
367 }
368 if obj.Pkg() != g.pkg {
369 g.errorf("type %s not defined in package %s", t, g.pkg)
370 }
371
372 switch t.Underlying().(type) {
373 case *types.Interface, *types.Struct:
374 return fmt.Sprintf("%s.%s", pkg.Name(), types.TypeString (pkg, typ))
375 default:
376 g.errorf("unsupported named type %s / %T", t, t)
377 }
378 case *types.Pointer:
379 switch t := t.Elem().(type) {
380 case *types.Named:
381 return fmt.Sprintf("*%s", g.typeString(t))
382 default:
383 g.errorf("not yet supported, pointer type %s / %T", t, t )
384 }
385 default:
386 return types.TypeString(pkg, typ)
387 }
388 return ""
389 }
390
391 func (g *goGen) gen() error {
392 g.genPreamble()
393
394 var funcs []string
395
396 scope := g.pkg.Scope()
397 names := scope.Names()
398 for _, name := range names {
399 obj := scope.Lookup(name)
400 if !obj.Exported() {
401 continue
402 }
403
404 switch obj := obj.(type) {
405 // TODO(crawshaw): case *types.Const:
406 // TODO(crawshaw): case *types.Var:
407 case *types.Func:
408 g.genFunc(obj)
409 funcs = append(funcs, obj.Name())
410 case *types.TypeName:
411 named := obj.Type().(*types.Named)
412 switch T := named.Underlying().(type) {
413 case *types.Struct:
414 g.genStruct(obj, T)
415 case *types.Interface:
416 g.genInterface(obj)
417 }
418
419 default:
420 g.errorf("not yet supported, name for %v / %T", obj, obj )
421 continue
422 }
423 }
424
425 g.Printf("func init() {\n")
426 g.Indent()
427 for i, name := range funcs {
428 g.Printf("seq.Register(%q, %d, proxy_%s)\n", g.pkg.Name(), i+1, name)
429 }
430 g.Outdent()
431 g.Printf("}\n")
432
433 if len(g.err) > 0 {
434 return g.err
435 }
436 return nil
437 }
OLDNEW
« no previous file with comments | « third_party/go/src/golang.org/x/mobile/bind/bind_test.go ('k') | third_party/go/src/golang.org/x/mobile/bind/genjava.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698