github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgGoSource/kmgReflectV2.go (about)

     1  package kmgGoSource
     2  
     3  import (
     4  	"fmt"
     5  	"go/doc"
     6  	"reflect"
     7  )
     8  
     9  type Kind string
    10  
    11  const (
    12  	Struct Kind = "Struct"
    13  	Ptr    Kind = "Ptr"
    14  )
    15  
    16  //表示一个指针类型
    17  type TypePointer struct {
    18  	Elem Type
    19  }
    20  
    21  func (p TypePointer) Kind() Kind {
    22  	return Ptr
    23  }
    24  func (p TypePointer) Method() []Method {
    25  	return p.Elem.Method()
    26  }
    27  func (p TypePointer) WriteInPkgPath(currentPkgPath string) (str string, importPathList []string) {
    28  	str, importPathList = p.Elem.WriteInPkgPath(currentPkgPath)
    29  	return "*" + str, importPathList
    30  }
    31  
    32  //表示一个struct类型
    33  type TypeStruct struct {
    34  	docType     *doc.Type
    35  	pkg         *Package
    36  	reflectType reflect.Type
    37  }
    38  
    39  func (p TypeStruct) Kind() Kind {
    40  	return Struct
    41  }
    42  func (p TypeStruct) Package() *Package {
    43  	return p.pkg
    44  }
    45  func (p TypeStruct) Method() []Method {
    46  	numMethod := p.reflectType.NumMethod()
    47  	if numMethod == 0 {
    48  		return nil
    49  	}
    50  	out := make([]Method, numMethod)
    51  	for i := 0; i < numMethod; i++ {
    52  		refletMethod := p.reflectType.Method(i)
    53  		method := Method{
    54  			Recv: p,
    55  			Func: Func{
    56  				Name: refletMethod.Name,
    57  			},
    58  		}
    59  
    60  		out[i] = method
    61  	}
    62  	return out
    63  }
    64  
    65  func (p TypeStruct) WriteInPkgPath(currentPkgPath string) (str string, importPathList []string) {
    66  	thisPkgPath := p.Package().PkgPath()
    67  	if thisPkgPath == "" || currentPkgPath == thisPkgPath {
    68  		return p.docType.Name, nil
    69  	}
    70  	return p.Package().Name() + "." + p.docType.Name, []string{thisPkgPath}
    71  }
    72  
    73  //表示一种golang的类型
    74  type Type interface {
    75  	Kind() Kind
    76  	Method() []Method
    77  	//在这个pkgPath里面的表示方法
    78  	WriteInPkgPath(currentPkgPath string) (str string, importPathList []string)
    79  }
    80  
    81  type Method struct {
    82  	Recv Type
    83  	Func
    84  }
    85  
    86  type Func struct {
    87  	Name       string
    88  	InArgList  []FuncArgument
    89  	OutArgList []FuncArgument
    90  }
    91  
    92  type FuncArgument struct {
    93  	Name string
    94  	Type Type
    95  }
    96  
    97  //从反射的类型获取一个Type
    98  // 主要: 需要运行时有源代码,需要使用kmg配置GOPATH
    99  func MustNewTypeFromReflectType(typ reflect.Type) Type {
   100  	switch typ.Kind() {
   101  	case reflect.Ptr:
   102  		return TypePointer{
   103  			Elem: MustNewTypeFromReflectType(typ.Elem()),
   104  		}
   105  	case reflect.Struct:
   106  		pkgPath := typ.PkgPath()
   107  		if pkgPath == "" {
   108  			panic(`TODO Handle pkgPath==""`)
   109  		}
   110  		pkg := MustNewPackageFromImportPath(pkgPath)
   111  		docType := pkg.getDocTypeByName(typ.Name())
   112  		return TypeStruct{
   113  			docType:     docType,
   114  			pkg:         pkg,
   115  			reflectType: typ,
   116  		}
   117  	default:
   118  		panic(fmt.Errorf("not process kind:%s", typ.Kind()))
   119  	}
   120  
   121  }