1 Star 0 Fork 0

lonely / gometalinter

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
golang.go 7.10 KB
一键复制 编辑 原始数据 按行查看 历史
package golang
import (
"go/ast"
"go/parser"
"go/token"
"github.com/mibk/dupl/syntax"
)
const (
BadNode = iota
File
ArrayType
AssignStmt
BasicLit
BinaryExpr
BlockStmt
BranchStmt
CallExpr
CaseClause
ChanType
CommClause
CompositeLit
DeclStmt
DeferStmt
Ellipsis
EmptyStmt
ExprStmt
Field
FieldList
ForStmt
FuncDecl
FuncLit
FuncType
GenDecl
GoStmt
Ident
IfStmt
IncDecStmt
IndexExpr
InterfaceType
KeyValueExpr
LabeledStmt
MapType
ParenExpr
RangeStmt
ReturnStmt
SelectStmt
SelectorExpr
SendStmt
SliceExpr
StarExpr
StructType
SwitchStmt
TypeAssertExpr
TypeSpec
TypeSwitchStmt
UnaryExpr
ValueSpec
)
// Parse the given file and return uniform syntax tree.
func Parse(filename string) (*syntax.Node, error) {
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, filename, nil, 0)
if err != nil {
return nil, err
}
t := &transformer{
fileset: fset,
filename: filename,
}
return t.trans(file), nil
}
type transformer struct {
fileset *token.FileSet
filename string
}
// trans transforms given golang AST to uniform tree structure.
func (t *transformer) trans(node ast.Node) (o *syntax.Node) {
o = syntax.NewNode()
o.Filename = t.filename
st, end := node.Pos(), node.End()
o.Pos, o.End = t.fileset.File(st).Offset(st), t.fileset.File(end).Offset(end)
switch n := node.(type) {
case *ast.ArrayType:
o.Type = ArrayType
if n.Len != nil {
o.AddChildren(t.trans(n.Len))
}
o.AddChildren(t.trans(n.Elt))
case *ast.AssignStmt:
o.Type = AssignStmt
for _, e := range n.Rhs {
o.AddChildren(t.trans(e))
}
for _, e := range n.Lhs {
o.AddChildren(t.trans(e))
}
case *ast.BasicLit:
o.Type = BasicLit
case *ast.BinaryExpr:
o.Type = BinaryExpr
o.AddChildren(t.trans(n.X), t.trans(n.Y))
case *ast.BlockStmt:
o.Type = BlockStmt
for _, stmt := range n.List {
o.AddChildren(t.trans(stmt))
}
case *ast.BranchStmt:
o.Type = BranchStmt
if n.Label != nil {
o.AddChildren(t.trans(n.Label))
}
case *ast.CallExpr:
o.Type = CallExpr
o.AddChildren(t.trans(n.Fun))
for _, arg := range n.Args {
o.AddChildren(t.trans(arg))
}
case *ast.CaseClause:
o.Type = CaseClause
for _, e := range n.List {
o.AddChildren(t.trans(e))
}
for _, stmt := range n.Body {
o.AddChildren(t.trans(stmt))
}
case *ast.ChanType:
o.Type = ChanType
o.AddChildren(t.trans(n.Value))
case *ast.CommClause:
o.Type = CommClause
if n.Comm != nil {
o.AddChildren(t.trans(n.Comm))
}
for _, stmt := range n.Body {
o.AddChildren(t.trans(stmt))
}
case *ast.CompositeLit:
o.Type = CompositeLit
if n.Type != nil {
o.AddChildren(t.trans(n.Type))
}
for _, e := range n.Elts {
o.AddChildren(t.trans(e))
}
case *ast.DeclStmt:
o.Type = DeclStmt
o.AddChildren(t.trans(n.Decl))
case *ast.DeferStmt:
o.Type = DeferStmt
o.AddChildren(t.trans(n.Call))
case *ast.Ellipsis:
o.Type = Ellipsis
if n.Elt != nil {
o.AddChildren(t.trans(n.Elt))
}
case *ast.EmptyStmt:
o.Type = EmptyStmt
case *ast.ExprStmt:
o.Type = ExprStmt
o.AddChildren(t.trans(n.X))
case *ast.Field:
o.Type = Field
for _, name := range n.Names {
o.AddChildren(t.trans(name))
}
o.AddChildren(t.trans(n.Type))
case *ast.FieldList:
o.Type = FieldList
for _, field := range n.List {
o.AddChildren(t.trans(field))
}
case *ast.File:
o.Type = File
for _, decl := range n.Decls {
if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT {
// skip import declarations
continue
}
o.AddChildren(t.trans(decl))
}
case *ast.ForStmt:
o.Type = ForStmt
if n.Init != nil {
o.AddChildren(t.trans(n.Init))
}
if n.Cond != nil {
o.AddChildren(t.trans(n.Cond))
}
if n.Post != nil {
o.AddChildren(t.trans(n.Post))
}
o.AddChildren(t.trans(n.Body))
case *ast.FuncDecl:
o.Type = FuncDecl
if n.Recv != nil {
o.AddChildren(t.trans(n.Recv))
}
o.AddChildren(t.trans(n.Name), t.trans(n.Type))
if n.Body != nil {
o.AddChildren(t.trans(n.Body))
}
case *ast.FuncLit:
o.Type = FuncLit
o.AddChildren(t.trans(n.Type), t.trans(n.Body))
case *ast.FuncType:
o.Type = FuncType
o.AddChildren(t.trans(n.Params))
if n.Results != nil {
o.AddChildren(t.trans(n.Results))
}
case *ast.GenDecl:
o.Type = GenDecl
for _, spec := range n.Specs {
o.AddChildren(t.trans(spec))
}
case *ast.GoStmt:
o.Type = GoStmt
o.AddChildren(t.trans(n.Call))
case *ast.Ident:
o.Type = Ident
case *ast.IfStmt:
o.Type = IfStmt
if n.Init != nil {
o.AddChildren(t.trans(n.Init))
}
o.AddChildren(t.trans(n.Cond), t.trans(n.Body))
if n.Else != nil {
o.AddChildren(t.trans(n.Else))
}
case *ast.IncDecStmt:
o.Type = IncDecStmt
o.AddChildren(t.trans(n.X))
case *ast.IndexExpr:
o.Type = IndexExpr
o.AddChildren(t.trans(n.X), t.trans(n.Index))
case *ast.InterfaceType:
o.Type = InterfaceType
o.AddChildren(t.trans(n.Methods))
case *ast.KeyValueExpr:
o.Type = KeyValueExpr
o.AddChildren(t.trans(n.Key), t.trans(n.Value))
case *ast.LabeledStmt:
o.Type = LabeledStmt
o.AddChildren(t.trans(n.Label), t.trans(n.Stmt))
case *ast.MapType:
o.Type = MapType
o.AddChildren(t.trans(n.Key), t.trans(n.Value))
case *ast.ParenExpr:
o.Type = ParenExpr
o.AddChildren(t.trans(n.X))
case *ast.RangeStmt:
o.Type = RangeStmt
if n.Key != nil {
o.AddChildren(t.trans(n.Key))
}
if n.Value != nil {
o.AddChildren(t.trans(n.Value))
}
o.AddChildren(t.trans(n.X), t.trans(n.Body))
case *ast.ReturnStmt:
o.Type = ReturnStmt
for _, e := range n.Results {
o.AddChildren(t.trans(e))
}
case *ast.SelectStmt:
o.Type = SelectStmt
o.AddChildren(t.trans(n.Body))
case *ast.SelectorExpr:
o.Type = SelectorExpr
o.AddChildren(t.trans(n.X), t.trans(n.Sel))
case *ast.SendStmt:
o.Type = SendStmt
o.AddChildren(t.trans(n.Chan), t.trans(n.Value))
case *ast.SliceExpr:
o.Type = SliceExpr
o.AddChildren(t.trans(n.X))
if n.Low != nil {
o.AddChildren(t.trans(n.Low))
}
if n.High != nil {
o.AddChildren(t.trans(n.High))
}
if n.Max != nil {
o.AddChildren(t.trans(n.Max))
}
case *ast.StarExpr:
o.Type = StarExpr
o.AddChildren(t.trans(n.X))
case *ast.StructType:
o.Type = StructType
o.AddChildren(t.trans(n.Fields))
case *ast.SwitchStmt:
o.Type = SwitchStmt
if n.Init != nil {
o.AddChildren(t.trans(n.Init))
}
if n.Tag != nil {
o.AddChildren(t.trans(n.Tag))
}
o.AddChildren(t.trans(n.Body))
case *ast.TypeAssertExpr:
o.Type = TypeAssertExpr
o.AddChildren(t.trans(n.X))
if n.Type != nil {
o.AddChildren(t.trans(n.Type))
}
case *ast.TypeSpec:
o.Type = TypeSpec
o.AddChildren(t.trans(n.Name), t.trans(n.Type))
case *ast.TypeSwitchStmt:
o.Type = TypeSwitchStmt
if n.Init != nil {
o.AddChildren(t.trans(n.Init))
}
o.AddChildren(t.trans(n.Assign), t.trans(n.Body))
case *ast.UnaryExpr:
o.Type = UnaryExpr
o.AddChildren(t.trans(n.X))
case *ast.ValueSpec:
o.Type = ValueSpec
for _, name := range n.Names {
o.AddChildren(t.trans(name))
}
if n.Type != nil {
o.AddChildren(t.trans(n.Type))
}
for _, val := range n.Values {
o.AddChildren(t.trans(val))
}
default:
o.Type = BadNode
}
return o
}
1
https://gitee.com/lonely0422/gometalinter.git
git@gitee.com:lonely0422/gometalinter.git
lonely0422
gometalinter
gometalinter
v3.0.0

搜索帮助