Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.0.1-2020.1.5 / pattern / convert.go
1 package pattern
2
3 import (
4         "fmt"
5         "go/ast"
6         "go/token"
7         "go/types"
8         "reflect"
9 )
10
11 var astTypes = map[string]reflect.Type{
12         "Ellipsis":       reflect.TypeOf(ast.Ellipsis{}),
13         "RangeStmt":      reflect.TypeOf(ast.RangeStmt{}),
14         "AssignStmt":     reflect.TypeOf(ast.AssignStmt{}),
15         "IndexExpr":      reflect.TypeOf(ast.IndexExpr{}),
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
56 func ASTToNode(node interface{}) Node {
57         switch node := node.(type) {
58         case *ast.File:
59                 panic("cannot convert *ast.File to Node")
60         case nil:
61                 return Nil{}
62         case string:
63                 return String(node)
64         case token.Token:
65                 return Token(node)
66         case *ast.ExprStmt:
67                 return ASTToNode(node.X)
68         case *ast.BlockStmt:
69                 if node == nil {
70                         return Nil{}
71                 }
72                 return ASTToNode(node.List)
73         case *ast.FieldList:
74                 if node == nil {
75                         return Nil{}
76                 }
77                 return ASTToNode(node.List)
78         case *ast.BasicLit:
79                 if node == nil {
80                         return Nil{}
81                 }
82         case *ast.ParenExpr:
83                 return ASTToNode(node.X)
84         }
85
86         if node, ok := node.(ast.Node); ok {
87                 name := reflect.TypeOf(node).Elem().Name()
88                 T, ok := structNodes[name]
89                 if !ok {
90                         panic(fmt.Sprintf("internal error: unhandled type %T", node))
91                 }
92
93                 if reflect.ValueOf(node).IsNil() {
94                         return Nil{}
95                 }
96                 v := reflect.ValueOf(node).Elem()
97                 objs := make([]Node, T.NumField())
98                 for i := 0; i < T.NumField(); i++ {
99                         f := v.FieldByName(T.Field(i).Name)
100                         objs[i] = ASTToNode(f.Interface())
101                 }
102
103                 n, err := populateNode(name, objs, false)
104                 if err != nil {
105                         panic(fmt.Sprintf("internal error: %s", err))
106                 }
107                 return n
108         }
109
110         s := reflect.ValueOf(node)
111         if s.Kind() == reflect.Slice {
112                 if s.Len() == 0 {
113                         return List{}
114                 }
115                 if s.Len() == 1 {
116                         return ASTToNode(s.Index(0).Interface())
117                 }
118
119                 tail := List{}
120                 for i := s.Len() - 1; i >= 0; i-- {
121                         head := ASTToNode(s.Index(i).Interface())
122                         l := List{
123                                 Head: head,
124                                 Tail: tail,
125                         }
126                         tail = l
127                 }
128                 return tail
129         }
130
131         panic(fmt.Sprintf("internal error: unhandled type %T", node))
132 }
133
134 func NodeToAST(node Node, state State) interface{} {
135         switch node := node.(type) {
136         case Binding:
137                 v, ok := state[node.Name]
138                 if !ok {
139                         // really we want to return an error here
140                         panic("XXX")
141                 }
142                 switch v := v.(type) {
143                 case types.Object:
144                         return &ast.Ident{Name: v.Name()}
145                 default:
146                         return v
147                 }
148         case Builtin, Any, Object, Function, Not, Or:
149                 panic("XXX")
150         case List:
151                 if (node == List{}) {
152                         return []ast.Node{}
153                 }
154                 x := []ast.Node{NodeToAST(node.Head, state).(ast.Node)}
155                 x = append(x, NodeToAST(node.Tail, state).([]ast.Node)...)
156                 return x
157         case Token:
158                 return token.Token(node)
159         case String:
160                 return string(node)
161         case Nil:
162                 return nil
163         }
164
165         name := reflect.TypeOf(node).Name()
166         T, ok := astTypes[name]
167         if !ok {
168                 panic(fmt.Sprintf("internal error: unhandled type %T", node))
169         }
170         v := reflect.ValueOf(node)
171         out := reflect.New(T)
172         for i := 0; i < T.NumField(); i++ {
173                 fNode := v.FieldByName(T.Field(i).Name)
174                 if (fNode == reflect.Value{}) {
175                         continue
176                 }
177                 fAST := out.Elem().FieldByName(T.Field(i).Name)
178                 switch fAST.Type().Kind() {
179                 case reflect.Slice:
180                         c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state))
181                         if c.Kind() != reflect.Slice {
182                                 // it's a single node in the pattern, we have to wrap
183                                 // it in a slice
184                                 slice := reflect.MakeSlice(fAST.Type(), 1, 1)
185                                 slice.Index(0).Set(c)
186                                 c = slice
187                         }
188                         switch fAST.Interface().(type) {
189                         case []ast.Node:
190                                 switch cc := c.Interface().(type) {
191                                 case []ast.Node:
192                                         fAST.Set(c)
193                                 case []ast.Expr:
194                                         var slice []ast.Node
195                                         for _, el := range cc {
196                                                 slice = append(slice, el)
197                                         }
198                                         fAST.Set(reflect.ValueOf(slice))
199                                 default:
200                                         panic("XXX")
201                                 }
202                         case []ast.Expr:
203                                 switch cc := c.Interface().(type) {
204                                 case []ast.Node:
205                                         var slice []ast.Expr
206                                         for _, el := range cc {
207                                                 slice = append(slice, el.(ast.Expr))
208                                         }
209                                         fAST.Set(reflect.ValueOf(slice))
210                                 case []ast.Expr:
211                                         fAST.Set(c)
212                                 default:
213                                         panic("XXX")
214                                 }
215                         default:
216                                 panic("XXX")
217                         }
218                 case reflect.Int:
219                         c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state))
220                         switch c.Kind() {
221                         case reflect.String:
222                                 tok, ok := tokensByString[c.Interface().(string)]
223                                 if !ok {
224                                         // really we want to return an error here
225                                         panic("XXX")
226                                 }
227                                 fAST.SetInt(int64(tok))
228                         case reflect.Int:
229                                 fAST.Set(c)
230                         default:
231                                 panic(fmt.Sprintf("internal error: unexpected kind %s", c.Kind()))
232                         }
233                 default:
234                         r := NodeToAST(fNode.Interface().(Node), state)
235                         if r != nil {
236                                 fAST.Set(reflect.ValueOf(r))
237                         }
238                 }
239         }
240
241         return out.Interface().(ast.Node)
242 }