@@ -107,7 +107,7 @@ func main() {
107107
108108 var writers []* Writer
109109 if isGoGenerate || write {
110- // We should support Go suffixes like `_linux.go` properly .
110+ // We should respect Go suffixes like `_linux.go`.
111111 name , tags , ext := splitOSArchTags (& buildCtx , gofile )
112112 if verbose {
113113 log .Printf (
@@ -261,9 +261,7 @@ func main() {
261261 text , ok := TrimConfigComment (c .Text )
262262 if ok {
263263 if item == nil {
264- item = & GenItem {
265- File : pkgFiles [i ],
266- }
264+ item = & GenItem {}
267265 }
268266 if err := item .ParseComment (text ); err != nil {
269267 log .Fatalf (
@@ -292,18 +290,24 @@ func main() {
292290 Package : pkg ,
293291 BuildConstraints : buildConstraints ,
294292 }
293+ traces := make (map [string ]* Trace )
295294 for _ , item := range items {
296- t := Trace {
295+ t := & Trace {
297296 Name : item .Ident .Name ,
298297 Flag : item .Flag ,
299298 }
299+ p .Traces = append (p .Traces , t )
300+ traces [item .Ident .Name ] = t
301+ }
302+ for i , item := range items {
303+ t := p .Traces [i ]
300304 for _ , field := range item .StructType .Fields .List {
301305 name := field .Names [0 ].Name
302306 fn , ok := field .Type .(* ast.FuncType )
303307 if ! ok {
304308 continue
305309 }
306- f , err := buildFunc (info , fn )
310+ f , err := buildFunc (info , traces , fn )
307311 if err != nil {
308312 log .Printf (
309313 "skipping hook %s due to error: %v" ,
@@ -333,7 +337,6 @@ func main() {
333337 Flag : item .GenConfig .Flag | config .Flag ,
334338 })
335339 }
336- p .Traces = append (p .Traces , t )
337340 }
338341 for _ , w := range writers {
339342 if err := w .Write (p ); err != nil {
@@ -344,7 +347,8 @@ func main() {
344347 log .Println ("OK" )
345348}
346349
347- func buildFunc (info types.Info , fn * ast.FuncType ) (ret Func , err error ) {
350+ func buildFunc (info types.Info , traces map [string ]* Trace , fn * ast.FuncType ) (ret * Func , err error ) {
351+ ret = new (Func )
348352 for _ , p := range fn .Params .List {
349353 t := info .TypeOf (p .Type )
350354 if t == nil {
@@ -363,26 +367,34 @@ func buildFunc(info types.Info, fn *ast.FuncType) (ret Func, err error) {
363367 return ret , nil
364368 }
365369 if len (fn .Results .List ) > 1 {
366- return ret , fmt .Errorf (
370+ return nil , fmt .Errorf (
367371 "unsupported number of function results" ,
368372 )
369373 }
370374
371- p := fn .Results .List [0 ]
372- fn , ok := p .Type .(* ast.FuncType )
373- if ! ok {
374- return ret , fmt .Errorf (
375- "unsupported function result type %s" ,
376- info .TypeOf (p .Type ),
377- )
378- }
379- result , err := buildFunc (info , fn )
380- if err != nil {
381- return ret , err
375+ r := fn .Results .List [0 ]
376+
377+ switch x := r .Type .(type ) {
378+ case * ast.FuncType :
379+ result , err := buildFunc (info , traces , x )
380+ if err != nil {
381+ return nil , err
382+ }
383+ ret .Result = append (ret .Result , result )
384+ return ret , nil
385+
386+ case * ast.Ident :
387+ if t , ok := traces [x .Name ]; ok {
388+ t .Nested = true
389+ ret .Result = append (ret .Result , t )
390+ return ret , nil
391+ }
382392 }
383- ret .Result = append (ret .Result , result )
384393
385- return ret , nil
394+ return nil , fmt .Errorf (
395+ "unsupported function result type %s" ,
396+ info .TypeOf (r .Type ),
397+ )
386398}
387399
388400func splitOSArchTags (ctx * build.Context , name string ) (base , tags , ext string ) {
@@ -420,18 +432,21 @@ type Package struct {
420432 * types.Package
421433
422434 BuildConstraints []string
423- Traces []Trace
435+ Traces []* Trace
424436}
425437
426438type Trace struct {
427- Name string
428- Hooks []Hook
429- Flag GenFlag
439+ Name string
440+ Hooks []Hook
441+ Flag GenFlag
442+ Nested bool
430443}
431444
445+ func (* Trace ) isFuncResult () bool { return true }
446+
432447type Hook struct {
433448 Name string
434- Func Func
449+ Func * Func
435450 Flag GenFlag
436451}
437452
@@ -440,12 +455,18 @@ type Param struct {
440455 Type types.Type
441456}
442457
458+ type FuncResult interface {
459+ isFuncResult () bool
460+ }
461+
443462type Func struct {
444463 Params []Param
445- Result []Func // 0 or 1.
464+ Result []FuncResult // 0 or 1.
446465}
447466
448- func (f Func ) HasResult () bool {
467+ func (* Func ) isFuncResult () bool { return true }
468+
469+ func (f * Func ) HasResult () bool {
449470 return len (f .Result ) > 0
450471}
451472
@@ -506,9 +527,7 @@ func (g *GenConfig) ParseParameter(text string) (err error) {
506527
507528type GenItem struct {
508529 GenConfig
509- File * os.File
510530 Ident * ast.Ident
511- TypeSpec * ast.TypeSpec
512531 StructType * ast.StructType
513532}
514533
0 commit comments