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

     1  package kmgGoParser
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/bronze1man/kmg/kmgFile"
     6  	"github.com/bronze1man/kmg/kmgGoSource/kmgGoReader"
     7  	"unicode"
     8  )
     9  
    10  // 暂时忽略任何测试包. 此处不做编译检查,认为所有输入的go文件都是正常的.
    11  func MustParsePackage(gopath string, pkgPath string) *Package {
    12  	return NewProgram([]string{gopath}).GetPackage(pkgPath)
    13  }
    14  
    15  //再多解析一个文件,path 是绝对路径
    16  func (pkg *Package) mustAddFile(path string) {
    17  	//fmt.Println(path)
    18  	file := parseFile(pkg.PkgPath, path, pkg)
    19  	for imp := range file.ImportMap {
    20  		pkg.AddImport(imp)
    21  	}
    22  	for _, funcDecl := range file.FuncList {
    23  		pkg.FuncList = append(pkg.FuncList, funcDecl)
    24  	}
    25  	for _, funcDecl := range file.MethodList {
    26  		pkg.MethodList = append(pkg.MethodList, funcDecl)
    27  	}
    28  	for _, namedType := range file.NamedTypeList {
    29  		pkg.NamedTypeList = append(pkg.NamedTypeList, namedType)
    30  	}
    31  }
    32  
    33  func (pkg *Package) LookupNamedType(name string) *NamedType {
    34  	for i := range pkg.NamedTypeList {
    35  		if pkg.NamedTypeList[i].Name == name {
    36  			return pkg.NamedTypeList[i]
    37  		}
    38  	}
    39  	return nil
    40  }
    41  
    42  func parseFile(pkgPath string, path string, pkg *Package) *File {
    43  	gofile := &File{
    44  		PackagePath:    pkgPath,
    45  		ImportMap:      map[string]bool{},
    46  		AliasImportMap: map[string]string{},
    47  		Pkg:            pkg,
    48  	}
    49  	content := kmgFile.MustReadFile(path)
    50  	posFile := kmgGoReader.NewPosFile(path, content)
    51  	content = goSourceRemoveComment(content, posFile)
    52  	r := kmgGoReader.NewReader(content, posFile)
    53  
    54  	r.ReadAllSpace()
    55  	r.MustReadMatch(tokenPackage)
    56  	r.ReadUntilByte('\n')
    57  	for {
    58  		if r.IsEof() {
    59  			return gofile //没有 import 正确情况
    60  		}
    61  		r.ReadAllSpace()
    62  		if r.IsMatchAfter(tokenImport) {
    63  			gofile.readImport(r)
    64  			continue
    65  		}
    66  		break
    67  	}
    68  	for {
    69  		switch {
    70  		case r.IsEof():
    71  			return gofile
    72  		case r.IsMatchAfter(tokenFunc):
    73  			funcDecl := gofile.readGoFunc(r)
    74  			if funcDecl.GetKind() == Func {
    75  				gofile.FuncList = append(gofile.FuncList, funcDecl)
    76  			} else {
    77  				gofile.MethodList = append(gofile.MethodList, funcDecl)
    78  			}
    79  		case r.IsMatchAfter(tokenType):
    80  			//r.ReadUntilByte('\n')
    81  			gofile.readGoType(r)
    82  		case r.IsMatchAfter(tokenVar):
    83  			gofile.readGoVar(r)
    84  		case r.IsMatchAfter(tokenConst):
    85  			gofile.readGoConst(r)
    86  		// 有一些没有分析的代码,里面可能包含import,此处先简单绕过.
    87  		case r.IsMatchAfter(tokenDoubleQuate) || r.IsMatchAfter(tokenGraveAccent):
    88  			MustReadGoString(r)
    89  			//fmt.Println(string(ret))
    90  		case r.IsMatchAfter(tokenSingleQuate):
    91  			mustReadGoChar(r)
    92  		default:
    93  			r.ReadByte()
    94  		}
    95  	}
    96  }
    97  
    98  func readIdentifier(r *kmgGoReader.Reader) []byte {
    99  	buf := &bytes.Buffer{}
   100  	if r.IsEof() {
   101  		panic(r.GetFileLineInfo() + " unexcept EOF")
   102  	}
   103  	b := r.ReadRune()
   104  	if b == '_' || unicode.IsLetter(b) {
   105  		buf.WriteRune(b)
   106  	} else {
   107  		r.UnreadRune()
   108  		return nil
   109  	}
   110  	for {
   111  		if r.IsEof() {
   112  			return buf.Bytes()
   113  		}
   114  		b := r.ReadRune()
   115  		if b == '_' || unicode.IsLetter(b) || unicode.IsDigit(b) {
   116  			buf.WriteRune(b)
   117  		} else {
   118  			r.UnreadRune()
   119  			return buf.Bytes() // 不是Identifier的东西留个调用者处理
   120  		}
   121  	}
   122  }
   123  
   124  // 跳过 "{" "}",默认当前已经有第一层了(已经读入一个"{"了)
   125  func readMatchBigParantheses(r *kmgGoReader.Reader) []byte {
   126  	return readMatchChar(r, '{', '}')
   127  }
   128  
   129  // 跳过 "[" "]",默认当前已经有第一层了(已经读入一个"["了)
   130  func readMatchMiddleParantheses(r *kmgGoReader.Reader) []byte {
   131  	return readMatchChar(r, '[', ']')
   132  }
   133  
   134  // 跳过 "(" ")",默认当前已经有第一层了(已经读入一个"("了)
   135  func readMatchSmallParantheses(r *kmgGoReader.Reader) []byte {
   136  	return readMatchChar(r, '(', ')')
   137  }
   138  
   139  func readMatchChar(r *kmgGoReader.Reader, starter byte, ender byte) []byte {
   140  	startPos := r.Pos()
   141  	level := 1
   142  	for {
   143  		if r.IsEof() {
   144  			panic(r.GetFileLineInfo() + " unexcept EOF")
   145  		}
   146  		b := r.ReadByte()
   147  		if b == '"' || b == '`' {
   148  			r.UnreadByte()
   149  			MustReadGoString(r)
   150  		} else if b == '\'' {
   151  			r.UnreadByte()
   152  			mustReadGoChar(r)
   153  		} else if b == starter {
   154  			level++
   155  		} else if b == ender {
   156  			level--
   157  			if level == 0 {
   158  				return r.BufToCurrent(startPos)
   159  			}
   160  		}
   161  	}
   162  }