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

     1  package kmgGoSource
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  //it is func decl with reflect func
     9  //if a field not have a name
    10  //only actual params ,not include recv
    11  type ReflectFuncDecl struct {
    12  	Params         []*ReflectFuncDeclField
    13  	Results        []*ReflectFuncDeclField
    14  	ParamMap       map[string]*ReflectFuncDeclField
    15  	ResultMap      map[string]*ReflectFuncDeclField
    16  	ResultHasNames bool
    17  }
    18  
    19  type ReflectFuncDeclField struct {
    20  	Name  string //may not have name
    21  	Type  reflect.Type
    22  	Index int //place in origin param or result ,method include recv ,start from 0
    23  }
    24  
    25  //reflectType may not match funcDecl
    26  func NewReflectFuncDecl(funcDecl *FuncDecl, rFunc reflect.Type, isMethod bool) (*ReflectFuncDecl, error) {
    27  	decl := &ReflectFuncDecl{
    28  		ParamMap:  make(map[string]*ReflectFuncDeclField),
    29  		ResultMap: make(map[string]*ReflectFuncDeclField),
    30  	}
    31  	paramIndex := 0
    32  	if isMethod {
    33  		paramIndex = 1
    34  	}
    35  	if len(funcDecl.ParamNames) != rFunc.NumIn()-paramIndex {
    36  		return nil, fmt.Errorf("NewReflectFuncDecl(): Param num not match FuncDecl: %d,reflectType: %d",
    37  			len(funcDecl.ParamNames),
    38  			rFunc.NumIn()-paramIndex,
    39  		)
    40  	}
    41  	for _, name := range funcDecl.ParamNames {
    42  		field := &ReflectFuncDeclField{Name: name, Type: rFunc.In(paramIndex), Index: paramIndex}
    43  		decl.Params = append(decl.Params, field)
    44  		paramIndex++
    45  	}
    46  	//result not have name
    47  	if len(funcDecl.ResultName) == 0 {
    48  		decl.ResultHasNames = false
    49  		for i := 0; i < rFunc.NumOut(); i++ {
    50  			decl.Results = append(decl.Results, &ReflectFuncDeclField{Type: rFunc.In(paramIndex), Index: i})
    51  		}
    52  	} else {
    53  		decl.ResultHasNames = true
    54  		if len(funcDecl.ResultName) != rFunc.NumOut() {
    55  			return nil, fmt.Errorf("NewReflectFuncDecl(): Result num not match FuncDecl: %d,reflectType: %d",
    56  				len(funcDecl.ResultName),
    57  				rFunc.NumOut(),
    58  			)
    59  		}
    60  		resultIndex := 0
    61  		//result have name
    62  		for _, name := range funcDecl.ResultName {
    63  			field := &ReflectFuncDeclField{Name: name, Type: rFunc.Out(resultIndex), Index: resultIndex}
    64  			decl.Results = append(decl.Results, field)
    65  			resultIndex++
    66  		}
    67  	}
    68  	for _, field := range decl.Params {
    69  		decl.ParamMap[field.Name] = field
    70  	}
    71  	if decl.ResultHasNames {
    72  		for _, field := range decl.Results {
    73  			decl.ResultMap[field.Name] = field
    74  		}
    75  	}
    76  	return decl, nil
    77  }