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 }