stmt.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package main
  2. import (
  3. "fmt"
  4. "go/ast"
  5. )
  6. func parseStmt(loc string, s ast.Stmt) {
  7. switch s := s.(type) {
  8. case *ast.CaseClause:
  9. parseCaseClause(loc, s)
  10. case *ast.DeclStmt:
  11. parseDeclStmt(loc, s)
  12. case *ast.ExprStmt, *ast.AssignStmt, *ast.ReturnStmt,
  13. *ast.BranchStmt: // break, continue, fallthrough, goto,
  14. // fmt.Printf("%s/(%T)\n", loc, s)
  15. case *ast.IfStmt:
  16. parseIfStmt(loc, s)
  17. case *ast.RangeStmt:
  18. parseRangeStmt(loc, s)
  19. case *ast.TypeSwitchStmt:
  20. parseTypeSwitchStmt(loc, s)
  21. default:
  22. fmt.Printf("Unhandled type %T\n", s)
  23. }
  24. }
  25. func parseCaseClause(loc string, s *ast.CaseClause) {
  26. loc += "/case"
  27. if s.Body == nil {
  28. // fmt.Printf("%s/(nil case)\n", loc)
  29. return
  30. }
  31. for _, rs := range s.Body {
  32. parseStmt(loc, rs)
  33. }
  34. }
  35. func parseDeclStmt(loc string, s *ast.DeclStmt) {
  36. loc += "/decl"
  37. switch d := s.Decl.(type) {
  38. case *ast.GenDecl:
  39. parseGenDecl(loc, d)
  40. default:
  41. fmt.Printf("DeclStmt: %T\n", d)
  42. }
  43. }
  44. func parseIfStmt(loc string, s *ast.IfStmt) {
  45. loc += "/if"
  46. // fmt.Println(loc)
  47. if s.Body == nil {
  48. fmt.Printf("%s/(nil if)\n", loc)
  49. } else {
  50. thenLoc := loc + "/then"
  51. for _, rs := range s.Body.List {
  52. parseStmt(thenLoc, rs)
  53. }
  54. }
  55. if s.Else == nil {
  56. // fmt.Printf("%s/(nil else)\n", loc)
  57. return
  58. } else {
  59. elseLoc := loc + "/else"
  60. for _, rs := range s.Else.(*ast.BlockStmt).List {
  61. parseStmt(elseLoc, rs)
  62. }
  63. }
  64. }
  65. func parseRangeStmt(loc string, s *ast.RangeStmt) {
  66. loc += "/range"
  67. // fmt.Println(loc)
  68. if s.Body == nil {
  69. fmt.Printf("%s/(nil range)\n", loc)
  70. return
  71. }
  72. for _, rs := range s.Body.List {
  73. parseStmt(loc, rs)
  74. }
  75. }
  76. func parseTypeSwitchStmt(loc string, s *ast.TypeSwitchStmt) {
  77. loc += "/(type)"
  78. // fmt.Println(loc)
  79. if s.Body == nil {
  80. fmt.Printf("%s/(nil body)\n", loc)
  81. return
  82. }
  83. for _, clause := range s.Body.List {
  84. body := clause.(*ast.CaseClause).Body
  85. if body == nil {
  86. // fmt.Printf("%s/empty clause\n", loc)
  87. continue
  88. }
  89. for _, rs := range body {
  90. parseStmt(loc, rs)
  91. }
  92. }
  93. }