代码拉取完成,页面将自动刷新
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
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。