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

     1  package kmgGoParser
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/bronze1man/kmg/kmgGoSource/kmgGoReader"
     6  )
     7  
     8  // 此处仅跳过函数
     9  func (gofile *File) readGoFunc(r *kmgGoReader.Reader) *FuncOrMethodDeclaration {
    10  	funcDecl := &FuncOrMethodDeclaration{}
    11  	r.MustReadMatch([]byte("func"))
    12  	// 读函数头,至少要有括号
    13  	r.ReadAllSpace()
    14  	b := r.ReadByte()
    15  	if b == '(' {
    16  		r.UnreadByte()
    17  		receiver := gofile.readParameters(r)
    18  		if len(receiver) != 1 {
    19  			panic(fmt.Errorf("%s receiver must have one parameter", r.GetFileLineInfo()))
    20  		}
    21  		funcDecl.ReceiverType = receiver[0].Type
    22  		r.ReadAllSpace()
    23  		// 暂不处理方法
    24  	} else {
    25  		r.UnreadByte()
    26  	}
    27  	id := readIdentifier(r)
    28  	funcDecl.Name = string(id)
    29  	if funcDecl.Name == "" {
    30  		panic(fmt.Errorf("%s need function name", r.GetFileLineInfo()))
    31  	}
    32  	r.ReadAllSpace()
    33  	b = r.ReadByte()
    34  	if b != '(' {
    35  		panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
    36  	}
    37  	r.UnreadByte()
    38  	funcDecl.InParameter = gofile.readParameters(r)
    39  	r.ReadAllSpaceWithoutLineBreak()
    40  	b = r.ReadByte()
    41  	if b == '\n' { //没有body
    42  		return funcDecl
    43  	} else if b != '{' {
    44  		r.UnreadByte()
    45  		funcDecl.OutParameter = gofile.readParameters(r)
    46  		r.ReadAllSpaceWithoutLineBreak()
    47  		b = r.ReadByte()
    48  	}
    49  	if b == '\n' { //没有body
    50  		return funcDecl
    51  	}
    52  	if b != '{' {
    53  		panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
    54  	}
    55  
    56  	//跳过函数体
    57  	readMatchBigParantheses(r)
    58  	return funcDecl
    59  }
    60  
    61  func (gofile *File) readParameters(r *kmgGoReader.Reader) (output []FuncParameter) {
    62  
    63  	b := r.ReadByte()
    64  	if b != '(' {
    65  		// 处理 int 这种类型
    66  		r.UnreadByte()
    67  		return []FuncParameter{
    68  			{
    69  				Type: gofile.readType(r),
    70  			},
    71  		}
    72  	}
    73  	parameterPartList := []*astParameterPart{}
    74  	lastPart := &astParameterPart{}
    75  	for {
    76  		r.ReadAllSpace()
    77  		b := r.ReadByte()
    78  		if b == ')' || b == ',' {
    79  			if lastPart.partList[0].originByte != nil {
    80  				parameterPartList = append(parameterPartList, lastPart)
    81  				lastPart = &astParameterPart{}
    82  			}
    83  			if b == ')' {
    84  				break
    85  			}
    86  			if b == ',' {
    87  				continue
    88  			}
    89  		}
    90  
    91  		r.UnreadByte()
    92  		if r.IsMatchAfter([]byte("...")) {
    93  			r.MustReadMatch([]byte("..."))
    94  			lastPart.isVariadic = true
    95  		}
    96  		startPos := r.Pos()
    97  		typ := gofile.readType(r)
    98  		buf := r.BufToCurrent(startPos)
    99  		//fmt.Println(string(buf))
   100  		hasSet := false
   101  		for i := range lastPart.partList {
   102  			if lastPart.partList[i].originByte == nil {
   103  				lastPart.partList[i].originByte = buf
   104  				lastPart.partList[i].typ = typ
   105  				hasSet = true
   106  				break
   107  			}
   108  		}
   109  		if !hasSet {
   110  			panic(r.GetFileLineInfo() + " unexcept func parameterList.")
   111  		}
   112  	}
   113  
   114  	output = make([]FuncParameter, len(parameterPartList))
   115  	onlyHavePart1Num := 0
   116  	for i := range parameterPartList {
   117  		if parameterPartList[i].partList[1].originByte == nil {
   118  			onlyHavePart1Num++
   119  		}
   120  	}
   121  	//重新分析出函数参数来. 处理(int,int) 这种类型.
   122  	if onlyHavePart1Num == len(parameterPartList) {
   123  		for i := range parameterPartList {
   124  			output[i].Type = parameterPartList[i].partList[0].typ
   125  			output[i].IsVariadic = parameterPartList[i].isVariadic
   126  		}
   127  		return output
   128  	}
   129  	// 处理 (x,y int) (x int,y int) 这种类型.
   130  	for i, parameterPart := range parameterPartList {
   131  		output[i].Name = string(parameterPart.partList[0].originByte)
   132  		if parameterPart.partList[1].typ != nil {
   133  			output[i].Type = parameterPart.partList[1].typ
   134  		}
   135  		output[i].IsVariadic = parameterPart.isVariadic
   136  	}
   137  	// 补全 (x,y int) 里面 x的类型.
   138  	for i := range parameterPartList {
   139  		if output[i].Type == nil {
   140  			for j := i + 1; j < len(parameterPartList); j++ {
   141  				if output[j].Type != nil {
   142  					output[i].Type = output[j].Type
   143  				}
   144  			}
   145  		}
   146  	}
   147  	return output
   148  }
   149  
   150  type astParameterPart struct {
   151  	partList [2]struct {
   152  		originByte []byte
   153  		typ        Type
   154  	}
   155  	isVariadic bool //是否有3个点
   156  }