100 lines
1.9 KiB
Go
100 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
)
|
|
|
|
func parseStmt(loc string, s ast.Stmt) {
|
|
switch s := s.(type) {
|
|
case *ast.CaseClause:
|
|
parseCaseClause(loc, s)
|
|
case *ast.DeclStmt:
|
|
parseDeclStmt(loc, s)
|
|
case *ast.ExprStmt, *ast.AssignStmt, *ast.ReturnStmt,
|
|
*ast.BranchStmt: // break, continue, fallthrough, goto,
|
|
// fmt.Printf("%s/(%T)\n", loc, s)
|
|
case *ast.IfStmt:
|
|
parseIfStmt(loc, s)
|
|
case *ast.RangeStmt:
|
|
parseRangeStmt(loc, s)
|
|
case *ast.TypeSwitchStmt:
|
|
parseTypeSwitchStmt(loc, s)
|
|
default:
|
|
fmt.Printf("Unhandled type %T\n", s)
|
|
}
|
|
}
|
|
|
|
func parseCaseClause(loc string, s *ast.CaseClause) {
|
|
loc += "/case"
|
|
if s.Body == nil {
|
|
// fmt.Printf("%s/(nil case)\n", loc)
|
|
return
|
|
}
|
|
for _, rs := range s.Body {
|
|
parseStmt(loc, rs)
|
|
}
|
|
}
|
|
|
|
func parseDeclStmt(loc string, s *ast.DeclStmt) {
|
|
loc += "/decl"
|
|
switch d := s.Decl.(type) {
|
|
case *ast.GenDecl:
|
|
parseGenDecl(loc, d)
|
|
default:
|
|
fmt.Printf("DeclStmt: %T\n", d)
|
|
}
|
|
}
|
|
|
|
func parseIfStmt(loc string, s *ast.IfStmt) {
|
|
loc += "/if"
|
|
// fmt.Println(loc)
|
|
if s.Body == nil {
|
|
fmt.Printf("%s/(nil if)\n", loc)
|
|
} else {
|
|
thenLoc := loc + "/then"
|
|
for _, rs := range s.Body.List {
|
|
parseStmt(thenLoc, rs)
|
|
}
|
|
}
|
|
if s.Else == nil {
|
|
// fmt.Printf("%s/(nil else)\n", loc)
|
|
return
|
|
} else {
|
|
elseLoc := loc + "/else"
|
|
for _, rs := range s.Else.(*ast.BlockStmt).List {
|
|
parseStmt(elseLoc, rs)
|
|
}
|
|
}
|
|
}
|
|
|
|
func parseRangeStmt(loc string, s *ast.RangeStmt) {
|
|
loc += "/range"
|
|
// fmt.Println(loc)
|
|
if s.Body == nil {
|
|
fmt.Printf("%s/(nil range)\n", loc)
|
|
return
|
|
}
|
|
for _, rs := range s.Body.List {
|
|
parseStmt(loc, rs)
|
|
}
|
|
}
|
|
|
|
func parseTypeSwitchStmt(loc string, s *ast.TypeSwitchStmt) {
|
|
loc += "/(type)"
|
|
// fmt.Println(loc)
|
|
if s.Body == nil {
|
|
fmt.Printf("%s/(nil body)\n", loc)
|
|
return
|
|
}
|
|
for _, clause := range s.Body.List {
|
|
body := clause.(*ast.CaseClause).Body
|
|
if body == nil {
|
|
// fmt.Printf("%s/empty clause\n", loc)
|
|
continue
|
|
}
|
|
for _, rs := range body {
|
|
parseStmt(loc, rs)
|
|
}
|
|
}
|
|
}
|