package main
import (
"flag"
"fmt"
"github.com/golang/glog"
"io/ioutil"
"os"
"strings"
"text/scanner"
)
type ScanInfo struct {
Line int
IsClose bool
}
func main() {
filePath := flag.String("filePath", "", "filePath")
if strings.HasSuffix(*filePath, ".go") {
ScanFile(*filePath)
return
}
gopath := make([]string, 0)
allGoPath, err := getAllFile(*filePath, gopath)
if err != nil {
glog.Error("打开文件夹失败", err)
return
}
for _, fi := range allGoPath {
ScanFile(fi)
}
}
func getAllFile(pathname string, gopath []string) ([]string, error) {
rd, err := ioutil.ReadDir(pathname)
if err != nil {
return nil, err
}
for _, fi := range rd {
if fi.IsDir() {
gopath, err = getAllFile(pathname+fi.Name()+"/", gopath)
if err != nil {
return nil, err
}
} else if strings.HasSuffix(fi.Name(), ".go") {
gopath = append(gopath, pathname+fi.Name())
}
}
return gopath, nil
}
func ScanFile(filePath string) []ScanInfo {
fileInfo, err := os.Open(filePath)
defer fileInfo.Close()
if err != nil {
glog.Error("文件打开错误", err)
return nil
}
scanInfos := make([]ScanInfo, 0)
scan := &scanner.Scanner{}
scan.Init(fileInfo)
shouldNext := true
for i := scan.Scan(); i != scanner.EOF; {
if scan.TokenText() == "func" {
shouldNext = false
i = scan.Scan()
allLettle := make([]string, 0)
shouldClosePre := make(map[string]*ScanInfo)
shouldCloseRow := make(map[string]*ScanInfo)
for scan.TokenText() != "func" {
allLettle = append(allLettle, scan.TokenText())
if scan.TokenText() == "Prepare" {
closeName := getParam(allLettle)
if len(closeName) > 0 {
if shouldClosePre[closeName] != nil {
fmt.Printf("%s:第%d行,有Prepare创建的句柄变量%s和前面的同名了\n", filePath, scan.Line, closeName)
}
shouldClosePre[closeName] = &ScanInfo{
Line: scan.Line,
}
}
}
for k := range shouldClosePre {
if k == scan.TokenText() {
scan.Scan()
allLettle = append(allLettle, scan.TokenText())
scan.Scan()
allLettle = append(allLettle, scan.TokenText())
if strings.Contains(scan.TokenText(), "Query") {
closeName := getParam(allLettle)
if len(closeName) > 0 {
if shouldClosePre[closeName] != nil {
fmt.Printf("%s:第%d行,有row变量%s和前面的同名了\n", filePath, scan.Line, closeName)
}
shouldCloseRow[closeName] = &ScanInfo{
Line: scan.Line,
}
}
}
}
}
if scan.TokenText() == "Close" && len(allLettle) >= 3 {
closeName := allLettle[len(allLettle)-3]
if shouldClosePre[closeName] != nil {
shouldClosePre[closeName].IsClose = true
}
if shouldCloseRow[closeName] != nil {
shouldCloseRow[closeName].IsClose = true
}
}
i = scan.Scan()
if i == scanner.EOF {
break
}
}
for k, v := range shouldClosePre {
if !v.IsClose {
fmt.Printf("%s:第%d的句柄:%s没有关闭\n", filePath, v.Line, k)
}
}
for k, v := range shouldCloseRow {
if !v.IsClose {
fmt.Printf("%s:第%d的row:%s没有关闭\n", filePath, v.Line, k)
}
}
}
if shouldNext {
i = scan.Scan()
} else {
shouldNext = true
}
}
return scanInfos
}
func getParam(params []string) string {
for i := len(params) - 1; i > 0; i-- {
if params[i] == "," && i-1 >= 0 {
return params[i-1]
}
}
return ""
}
网友评论