convert.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package pattern
  2. import (
  3. "fmt"
  4. "go/ast"
  5. "go/token"
  6. "go/types"
  7. "reflect"
  8. "golang.org/x/exp/typeparams"
  9. )
  10. var astTypes = map[string]reflect.Type{
  11. "Ellipsis": reflect.TypeOf(ast.Ellipsis{}),
  12. "RangeStmt": reflect.TypeOf(ast.RangeStmt{}),
  13. "AssignStmt": reflect.TypeOf(ast.AssignStmt{}),
  14. "IndexExpr": reflect.TypeOf(ast.IndexExpr{}),
  15. "IndexListExpr": reflect.TypeOf(typeparams.IndexListExpr{}),
  16. "Ident": reflect.TypeOf(ast.Ident{}),
  17. "ValueSpec": reflect.TypeOf(ast.ValueSpec{}),
  18. "GenDecl": reflect.TypeOf(ast.GenDecl{}),
  19. "BinaryExpr": reflect.TypeOf(ast.BinaryExpr{}),
  20. "ForStmt": reflect.TypeOf(ast.ForStmt{}),
  21. "ArrayType": reflect.TypeOf(ast.ArrayType{}),
  22. "DeferStmt": reflect.TypeOf(ast.DeferStmt{}),
  23. "MapType": reflect.TypeOf(ast.MapType{}),
  24. "ReturnStmt": reflect.TypeOf(ast.ReturnStmt{}),
  25. "SliceExpr": reflect.TypeOf(ast.SliceExpr{}),
  26. "StarExpr": reflect.TypeOf(ast.StarExpr{}),
  27. "UnaryExpr": reflect.TypeOf(ast.UnaryExpr{}),
  28. "SendStmt": reflect.TypeOf(ast.SendStmt{}),
  29. "SelectStmt": reflect.TypeOf(ast.SelectStmt{}),
  30. "ImportSpec": reflect.TypeOf(ast.ImportSpec{}),
  31. "IfStmt": reflect.TypeOf(ast.IfStmt{}),
  32. "GoStmt": reflect.TypeOf(ast.GoStmt{}),
  33. "Field": reflect.TypeOf(ast.Field{}),
  34. "SelectorExpr": reflect.TypeOf(ast.SelectorExpr{}),
  35. "StructType": reflect.TypeOf(ast.StructType{}),
  36. "KeyValueExpr": reflect.TypeOf(ast.KeyValueExpr{}),
  37. "FuncType": reflect.TypeOf(ast.FuncType{}),
  38. "FuncLit": reflect.TypeOf(ast.FuncLit{}),
  39. "FuncDecl": reflect.TypeOf(ast.FuncDecl{}),
  40. "ChanType": reflect.TypeOf(ast.ChanType{}),
  41. "CallExpr": reflect.TypeOf(ast.CallExpr{}),
  42. "CaseClause": reflect.TypeOf(ast.CaseClause{}),
  43. "CommClause": reflect.TypeOf(ast.CommClause{}),
  44. "CompositeLit": reflect.TypeOf(ast.CompositeLit{}),
  45. "EmptyStmt": reflect.TypeOf(ast.EmptyStmt{}),
  46. "SwitchStmt": reflect.TypeOf(ast.SwitchStmt{}),
  47. "TypeSwitchStmt": reflect.TypeOf(ast.TypeSwitchStmt{}),
  48. "TypeAssertExpr": reflect.TypeOf(ast.TypeAssertExpr{}),
  49. "TypeSpec": reflect.TypeOf(ast.TypeSpec{}),
  50. "InterfaceType": reflect.TypeOf(ast.InterfaceType{}),
  51. "BranchStmt": reflect.TypeOf(ast.BranchStmt{}),
  52. "IncDecStmt": reflect.TypeOf(ast.IncDecStmt{}),
  53. "BasicLit": reflect.TypeOf(ast.BasicLit{}),
  54. }
  55. func ASTToNode(node interface{}) Node {
  56. switch node := node.(type) {
  57. case *ast.File:
  58. panic("cannot convert *ast.File to Node")
  59. case nil:
  60. return Nil{}
  61. case string:
  62. return String(node)
  63. case token.Token:
  64. return Token(node)
  65. case *ast.ExprStmt:
  66. return ASTToNode(node.X)
  67. case *ast.BlockStmt:
  68. if node == nil {
  69. return Nil{}
  70. }
  71. return ASTToNode(node.List)
  72. case *ast.FieldList:
  73. if node == nil {
  74. return Nil{}
  75. }
  76. return ASTToNode(node.List)
  77. case *ast.BasicLit:
  78. if node == nil {
  79. return Nil{}
  80. }
  81. case *ast.ParenExpr:
  82. return ASTToNode(node.X)
  83. }
  84. if node, ok := node.(ast.Node); ok {
  85. name := reflect.TypeOf(node).Elem().Name()
  86. T, ok := structNodes[name]
  87. if !ok {
  88. panic(fmt.Sprintf("internal error: unhandled type %T", node))
  89. }
  90. if reflect.ValueOf(node).IsNil() {
  91. return Nil{}
  92. }
  93. v := reflect.ValueOf(node).Elem()
  94. objs := make([]Node, T.NumField())
  95. for i := 0; i < T.NumField(); i++ {
  96. f := v.FieldByName(T.Field(i).Name)
  97. objs[i] = ASTToNode(f.Interface())
  98. }
  99. n, err := populateNode(name, objs, false)
  100. if err != nil {
  101. panic(fmt.Sprintf("internal error: %s", err))
  102. }
  103. return n
  104. }
  105. s := reflect.ValueOf(node)
  106. if s.Kind() == reflect.Slice {
  107. if s.Len() == 0 {
  108. return List{}
  109. }
  110. if s.Len() == 1 {
  111. return ASTToNode(s.Index(0).Interface())
  112. }
  113. tail := List{}
  114. for i := s.Len() - 1; i >= 0; i-- {
  115. head := ASTToNode(s.Index(i).Interface())
  116. l := List{
  117. Head: head,
  118. Tail: tail,
  119. }
  120. tail = l
  121. }
  122. return tail
  123. }
  124. panic(fmt.Sprintf("internal error: unhandled type %T", node))
  125. }
  126. func NodeToAST(node Node, state State) interface{} {
  127. switch node := node.(type) {
  128. case Binding:
  129. v, ok := state[node.Name]
  130. if !ok {
  131. // really we want to return an error here
  132. panic("XXX")
  133. }
  134. switch v := v.(type) {
  135. case types.Object:
  136. return &ast.Ident{Name: v.Name()}
  137. default:
  138. return v
  139. }
  140. case Builtin, Any, Object, Function, Not, Or:
  141. panic("XXX")
  142. case List:
  143. if (node == List{}) {
  144. return []ast.Node{}
  145. }
  146. x := []ast.Node{NodeToAST(node.Head, state).(ast.Node)}
  147. x = append(x, NodeToAST(node.Tail, state).([]ast.Node)...)
  148. return x
  149. case Token:
  150. return token.Token(node)
  151. case String:
  152. return string(node)
  153. case Nil:
  154. return nil
  155. }
  156. name := reflect.TypeOf(node).Name()
  157. T, ok := astTypes[name]
  158. if !ok {
  159. panic(fmt.Sprintf("internal error: unhandled type %T", node))
  160. }
  161. v := reflect.ValueOf(node)
  162. out := reflect.New(T)
  163. for i := 0; i < T.NumField(); i++ {
  164. fNode := v.FieldByName(T.Field(i).Name)
  165. if (fNode == reflect.Value{}) {
  166. continue
  167. }
  168. fAST := out.Elem().FieldByName(T.Field(i).Name)
  169. switch fAST.Type().Kind() {
  170. case reflect.Slice:
  171. c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state))
  172. if c.Kind() != reflect.Slice {
  173. // it's a single node in the pattern, we have to wrap
  174. // it in a slice
  175. slice := reflect.MakeSlice(fAST.Type(), 1, 1)
  176. slice.Index(0).Set(c)
  177. c = slice
  178. }
  179. switch fAST.Interface().(type) {
  180. case []ast.Node:
  181. switch cc := c.Interface().(type) {
  182. case []ast.Node:
  183. fAST.Set(c)
  184. case []ast.Expr:
  185. var slice []ast.Node
  186. for _, el := range cc {
  187. slice = append(slice, el)
  188. }
  189. fAST.Set(reflect.ValueOf(slice))
  190. default:
  191. panic("XXX")
  192. }
  193. case []ast.Expr:
  194. switch cc := c.Interface().(type) {
  195. case []ast.Node:
  196. var slice []ast.Expr
  197. for _, el := range cc {
  198. slice = append(slice, el.(ast.Expr))
  199. }
  200. fAST.Set(reflect.ValueOf(slice))
  201. case []ast.Expr:
  202. fAST.Set(c)
  203. default:
  204. panic("XXX")
  205. }
  206. default:
  207. panic("XXX")
  208. }
  209. case reflect.Int:
  210. c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state))
  211. switch c.Kind() {
  212. case reflect.String:
  213. tok, ok := tokensByString[c.Interface().(string)]
  214. if !ok {
  215. // really we want to return an error here
  216. panic("XXX")
  217. }
  218. fAST.SetInt(int64(tok))
  219. case reflect.Int:
  220. fAST.Set(c)
  221. default:
  222. panic(fmt.Sprintf("internal error: unexpected kind %s", c.Kind()))
  223. }
  224. default:
  225. r := NodeToAST(fNode.Interface().(Node), state)
  226. if r != nil {
  227. fAST.Set(reflect.ValueOf(r))
  228. }
  229. }
  230. }
  231. return out.Interface().(ast.Node)
  232. }