1 Star 16 Fork 3

A-涛/protoc-go-valid

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
parse.go 1.96 KB
一键复制 编辑 原始数据 按行查看 历史
A-涛 提交于 2021-12-03 22:00 . update
package file
import (
"go/ast"
"go/parser"
"go/token"
"regexp"
"runtime"
"strings"
)
const (
InjectTagFlag = "@tag" // 注入 tag 的标识
)
var (
rComment = regexp.MustCompile(`@tag (.*)`) // 匹配注入 tag
rInject = regexp.MustCompile("`.+`$")
rTags = regexp.MustCompile(`\w+:"[^"]+"`) // 匹配 tag
)
// textArea
type textArea struct {
Start int // 开始位置
End int // 截止位置
CurrentTag string // 已有 tag
InjectTag string // 注入的 tag
}
// HandlePath 处理最后一个的路径服务
func HandlePath(path string) string {
lastSymbol := "/"
if runtime.GOOS == "windows" {
lastSymbol = "\\\\"
}
if strings.LastIndex(path, lastSymbol) != len(path)-1 {
path += lastSymbol
}
return path
}
// ParseFile 解析文件
func ParseFile(inputPath string) (areas []textArea, err error) {
fSet := token.NewFileSet()
f, err := parser.ParseFile(fSet, inputPath, nil, parser.ParseComments)
if err != nil {
return
}
for _, decl := range f.Decls {
genDecl, ok := decl.(*ast.GenDecl)
if !ok {
continue
}
var typeSpec *ast.TypeSpec // 类型
for _, spec := range genDecl.Specs {
if ts, tsOK := spec.(*ast.TypeSpec); tsOK {
typeSpec = ts
break
}
}
// 空就跳过
if typeSpec == nil {
continue
}
// 不是结构体就跳过
structDecl, ok := typeSpec.Type.(*ast.StructType)
if !ok {
continue
}
for _, field := range structDecl.Fields.List {
var comments []*ast.Comment
// 字段的注释
if field.Comment != nil {
comments = append(comments, field.Comment.List...)
}
// 组装数据
for _, comment := range comments {
tag := tagFromComment(comment.Text)
if tag == "" {
continue
}
currentTag := field.Tag.Value
area := textArea{
Start: int(field.Pos()),
End: int(field.End()),
CurrentTag: currentTag[1 : len(currentTag)-1], // 去掉 ``
InjectTag: tag,
}
areas = append(areas, area)
}
}
}
return
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/xuesongtao/protoc-go-valid.git
git@gitee.com:xuesongtao/protoc-go-valid.git
xuesongtao
protoc-go-valid
protoc-go-valid
v1.6.6

搜索帮助