Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // +build api_tool | 1 // +build api_tool |
2 | 2 |
3 // Copyright 2011 The Go Authors. All rights reserved. | 3 // Copyright 2011 The Go Authors. All rights reserved. |
4 // Use of this source code is governed by a BSD-style | 4 // Use of this source code is governed by a BSD-style |
5 // license that can be found in the LICENSE file. | 5 // license that can be found in the LICENSE file. |
6 | 6 |
7 // Binary api computes the exported API of a set of Go packages. | 7 // Binary api computes the exported API of a set of Go packages. |
8 package main | 8 package main |
9 | 9 |
10 import ( | 10 import ( |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
633 } | 633 } |
634 | 634 |
635 func (w *Walker) emitObj(obj types.Object) { | 635 func (w *Walker) emitObj(obj types.Object) { |
636 switch obj := obj.(type) { | 636 switch obj := obj.(type) { |
637 case *types.Const: | 637 case *types.Const: |
638 w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type())) | 638 w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type())) |
639 | 639 |
640 case *types.Var: | 640 case *types.Var: |
641 w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type())) | 641 w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type())) |
642 | 642 |
643 case *types.TypeName: | 643 case *types.TypeName: |
bradfitz
2013/08/07 21:47:52
move this to a new emitType method? it's big enou
gri
2013/08/07 21:55:03
Done.
| |
644 » » name := obj.Name() | 644 » » w.emitType(obj) |
645 » » typ := obj.Type() | |
646 » » switch typ := typ.Underlying().(type) { | |
647 » » case *types.Struct: | |
648 » » » w.emitStructType(name, typ) | |
649 » » case *types.Interface: | |
650 » » » w.emitIfaceType(name, typ) | |
651 » » » return // methods are handled by emitIfaceType | |
652 » » default: | |
653 » » » w.emitf("type %s %s", name, w.typeString(typ.Underlying( ))) | |
654 » » } | |
655 | |
656 » » // emit methods with value receiver | |
657 » » var methodNames map[string]bool | |
658 » » vset := typ.MethodSet() | |
659 » » for i, n := 0, vset.Len(); i < n; i++ { | |
660 » » » m := vset.At(i) | |
661 » » » if m.Obj().IsExported() { | |
662 » » » » w.emitMethod(m) | |
663 » » » » if methodNames == nil { | |
664 » » » » » methodNames = make(map[string]bool) | |
665 » » » » } | |
666 » » » » methodNames[m.Obj().Name()] = true | |
667 » » » } | |
668 » » } | |
669 | |
670 » » // emit methods with pointer receiver; exclude | |
671 » » // methods that we have emitted already | |
672 » » // (the method set of *T includes the methods of T) | |
673 » » pset := types.NewPointer(typ).MethodSet() | |
674 » » for i, n := 0, pset.Len(); i < n; i++ { | |
675 » » » m := pset.At(i) | |
676 » » » if m.Obj().IsExported() && !methodNames[m.Obj().Name()] { | |
677 » » » » w.emitMethod(m) | |
678 » » » } | |
679 » » } | |
680 | 645 |
681 case *types.Func: | 646 case *types.Func: |
682 w.emitFunc(obj) | 647 w.emitFunc(obj) |
683 | 648 |
684 default: | 649 default: |
685 panic("unknown object: " + obj.String()) | 650 panic("unknown object: " + obj.String()) |
651 } | |
652 } | |
653 | |
654 func (w *Walker) emitType(obj *types.TypeName) { | |
655 name := obj.Name() | |
656 typ := obj.Type() | |
657 switch typ := typ.Underlying().(type) { | |
658 case *types.Struct: | |
659 w.emitStructType(name, typ) | |
660 case *types.Interface: | |
661 w.emitIfaceType(name, typ) | |
662 return // methods are handled by emitIfaceType | |
663 default: | |
664 w.emitf("type %s %s", name, w.typeString(typ.Underlying())) | |
665 } | |
666 | |
667 // emit methods with value receiver | |
668 var methodNames map[string]bool | |
669 vset := typ.MethodSet() | |
670 for i, n := 0, vset.Len(); i < n; i++ { | |
671 m := vset.At(i) | |
672 if m.Obj().IsExported() { | |
673 w.emitMethod(m) | |
674 if methodNames == nil { | |
675 methodNames = make(map[string]bool) | |
676 } | |
677 methodNames[m.Obj().Name()] = true | |
678 } | |
679 } | |
680 | |
681 // emit methods with pointer receiver; exclude | |
682 // methods that we have emitted already | |
683 // (the method set of *T includes the methods of T) | |
684 pset := types.NewPointer(typ).MethodSet() | |
685 for i, n := 0, pset.Len(); i < n; i++ { | |
686 m := pset.At(i) | |
687 if m.Obj().IsExported() && !methodNames[m.Obj().Name()] { | |
688 w.emitMethod(m) | |
689 } | |
686 } | 690 } |
687 } | 691 } |
688 | 692 |
689 func (w *Walker) emitStructType(name string, typ *types.Struct) { | 693 func (w *Walker) emitStructType(name string, typ *types.Struct) { |
690 typeStruct := fmt.Sprintf("type %s struct", name) | 694 typeStruct := fmt.Sprintf("type %s struct", name) |
691 w.emitf(typeStruct) | 695 w.emitf(typeStruct) |
692 defer w.pushScope(typeStruct)() | 696 defer w.pushScope(typeStruct)() |
693 | 697 |
694 for i := 0; i < typ.NumFields(); i++ { | 698 for i := 0; i < typ.NumFields(); i++ { |
695 f := typ.Field(i) | 699 f := typ.Field(i) |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 | 783 |
780 if _, dup := w.features[f]; dup { | 784 if _, dup := w.features[f]; dup { |
781 panic("duplicate feature inserted: " + f) | 785 panic("duplicate feature inserted: " + f) |
782 } | 786 } |
783 w.features[f] = true | 787 w.features[f] = true |
784 | 788 |
785 if *verbose { | 789 if *verbose { |
786 log.Printf("feature: %s", f) | 790 log.Printf("feature: %s", f) |
787 } | 791 } |
788 } | 792 } |
LEFT | RIGHT |