Пример #1
0
func readIdentifier(r *kmgGoReader.Reader) []byte {
	buf := &bytes.Buffer{}
	if r.IsEof() {
		panic(r.GetFileLineInfo() + " unexcept EOF")
	}
	b := r.ReadRune()
	if b == '_' || unicode.IsLetter(b) {
		buf.WriteRune(b)
	} else {
		r.UnreadRune()
		return nil
	}
	for {
		if r.IsEof() {
			return buf.Bytes()
		}
		b := r.ReadRune()
		if b == '_' || unicode.IsLetter(b) || unicode.IsDigit(b) {
			buf.WriteRune(b)
		} else {
			r.UnreadRune()
			return buf.Bytes() // 不是Identifier的东西留个调用者处理
		}
	}
}
Пример #2
0
/*
第一个字符可能为
	letter -> identifier(单独的类型名,带package的类型的package部分)
	"struct" struct类型开头
	"func" func类型开头
	"interface" interface类型开头
	"*" 指针开头
	"[" (数组,slice) 开头
	"map[" map开头
	"chan " chan开头
	"chan<- " chan<- 开头
	"<-chan" chan<- 开头
*/
func (gofile *File) readType(r *kmgGoReader.Reader) Type {
	id := readIdentifier(r)
	if len(id) == 0 {
		if r.IsMatchAfter([]byte("<-chan")) {
			r.MustReadMatch([]byte("<-chan"))
			r.ReadAllSpace()
			return ChanType{
				Dir:  RecvDir,
				Elem: gofile.readType(r),
			}
		}
		b := r.ReadByte()
		if b == '*' {
			return PointerType{
				Elem: gofile.readType(r),
			}
		} else if b == '[' {
			content := readMatchMiddleParantheses(r)
			if len(content) == 1 {
				return SliceType{
					Elem: gofile.readType(r),
				}
			} else {
				// 仅跳过
				return ArrayType{
					Elem: gofile.readType(r),
				}
			}
		} else if b == '(' {
			typ := gofile.readType(r)
			r.MustReadMatch([]byte(")"))
			return typ
		} else {
			panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
		}
	}
	if bytes.Equal(id, []byte("struct")) {
		return gofile.readStruct(r)
	} else if bytes.Equal(id, []byte("interface")) {
		// 仅跳过
		r.ReadAllSpace()
		b := r.ReadByte()
		if b != '{' {
			panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
		}
		readMatchBigParantheses(r)
		return InterfaceType{}
	} else if bytes.Equal(id, []byte("map")) {
		b := r.ReadByte()
		m := MapType{}
		if b != '[' {
			panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
		}
		m.Key = gofile.readType(r)
		r.MustReadMatch([]byte("]"))
		m.Value = gofile.readType(r)
		return m
	} else if bytes.Equal(id, []byte("func")) {
		// 仅跳过
		r.ReadAllSpace()
		b := r.ReadByte()
		if b != '(' {
			panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
		}
		readMatchSmallParantheses(r) //跳过输入参数
		r.ReadAllSpaceWithoutLineBreak()
		run := r.ReadRune() //跳过输出参数
		if run == '(' {
			readMatchSmallParantheses(r)
		} else if run == '\n' { //换行符可以标识这个函数定义结束了.
			return FuncType{}
		} else if unicode.IsLetter(run) || run == '[' || run == '*' || run == '<' {
			r.UnreadRune() //输出参数只有一个类型
			gofile.readType(r)
		} else {
			r.UnreadRune() //读到了其他东西,退回.
		}
		return FuncType{}
	} else if bytes.Equal(id, []byte("chan")) {
		if r.IsMatchAfter([]byte("<-")) {
			r.MustReadMatch([]byte("<-"))
			r.ReadAllSpace()
			return ChanType{
				Dir:  SendDir,
				Elem: gofile.readType(r),
			}
		} else {
			r.ReadAllSpace()
			return ChanType{
				Dir:  BothDir,
				Elem: gofile.readType(r),
			}
		}
	} else {
		b := r.ReadByte()
		if b == '.' {
			pkgPath := string(id)
			pkgPath, err := gofile.LookupFullPackagePath(pkgPath)
			if err != nil {
				fmt.Println(r.GetFileLineInfo(), err.Error()) //TODO 以目前的复杂度暂时无解.需要把所有相关的package都看一遍才能正确.
			}
			id2 := readIdentifier(r)
			return &NamedType{
				PackagePath: pkgPath,
				Name:        string(id2),
				Pkg:         gofile.Pkg,
			}
		} else {
			r.UnreadByte()
			name := string(id)
			if builtinTypeMap[BuiltinType(name)] != Invalid {
				return BuiltinType(name)
			} else {
				return &NamedType{
					PackagePath: gofile.PackagePath,
					Name:        string(id),
					Pkg:         gofile.Pkg,
				}
			}
		}
	}
	/*
		}else if r.IsMatchAfter([]byte("struct")) { //TODO 解决struct后面必须有一个空格的问题.
			r.ReadAllSpace()
			b := r.ReadByte()
			if b!='{' {
				panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
			}
			readMatchBigParantheses(r)
			return StructType{}
		}else if r.IsMatchAfter([]byte("interface")) {
			r.ReadAllSpace()
			b := r.ReadByte()
			if b!='{' {
				panic(fmt.Errorf("%s unexcept %s", r.GetFileLineInfo(), string(rune(b))))
			}
			readMatchBigParantheses(r)
			return InterfaceType{}
		}else if r.IsMatchAfter([]byte("map[")){

		}else if r.IsMatchAfter([]byte("func")){
			//TODO finish it.
		}
	*/
}