LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2012 The Go Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 package main | |
6 | |
7 import ( | |
8 "fmt" | |
9 "go/ast" | |
10 "log" | |
11 "reflect" | |
12 ) | |
13 | |
14 const debugClone = false | |
15 | |
16 // TODO(bradfitz): delete this function (and whole file) once | |
17 // http://golang.org/issue/4380 is fixed. | |
18 func clone(i interface{}) (cloned interface{}) { | |
19 if debugClone { | |
20 defer func() { | |
21 if !reflect.DeepEqual(i, cloned) { | |
22 log.Printf("cloned %T doesn't match: in=%#v out=
%#v", i, i, cloned) | |
23 } | |
24 }() | |
25 } | |
26 switch v := i.(type) { | |
27 case nil: | |
28 return nil | |
29 case *ast.File: | |
30 o := &ast.File{ | |
31 Doc: v.Doc, // shallow | |
32 Package: v.Package, | |
33 Comments: v.Comments, // shallow | |
34 Name: v.Name, | |
35 Scope: v.Scope, | |
36 } | |
37 for _, x := range v.Decls { | |
38 o.Decls = append(o.Decls, clone(x).(ast.Decl)) | |
39 } | |
40 for _, x := range v.Imports { | |
41 o.Imports = append(o.Imports, clone(x).(*ast.ImportSpec)
) | |
42 } | |
43 for _, x := range v.Unresolved { | |
44 o.Unresolved = append(o.Unresolved, x) | |
45 } | |
46 return o | |
47 case *ast.GenDecl: | |
48 o := new(ast.GenDecl) | |
49 *o = *v | |
50 o.Specs = nil | |
51 for _, x := range v.Specs { | |
52 o.Specs = append(o.Specs, clone(x).(ast.Spec)) | |
53 } | |
54 return o | |
55 case *ast.TypeSpec: | |
56 o := new(ast.TypeSpec) | |
57 *o = *v | |
58 o.Type = cloneExpr(v.Type) | |
59 return o | |
60 case *ast.InterfaceType: | |
61 o := new(ast.InterfaceType) | |
62 *o = *v | |
63 o.Methods = clone(v.Methods).(*ast.FieldList) | |
64 return o | |
65 case *ast.FieldList: | |
66 if v == nil { | |
67 return v | |
68 } | |
69 o := new(ast.FieldList) | |
70 *o = *v | |
71 o.List = nil | |
72 for _, x := range v.List { | |
73 o.List = append(o.List, clone(x).(*ast.Field)) | |
74 } | |
75 return o | |
76 case *ast.Field: | |
77 o := &ast.Field{ | |
78 Doc: v.Doc, // shallow | |
79 Type: cloneExpr(v.Type), | |
80 Tag: clone(v.Tag).(*ast.BasicLit), | |
81 Comment: v.Comment, // shallow | |
82 } | |
83 for _, x := range v.Names { | |
84 o.Names = append(o.Names, clone(x).(*ast.Ident)) | |
85 } | |
86 return o | |
87 case *ast.FuncType: | |
88 if v == nil { | |
89 return v | |
90 } | |
91 return &ast.FuncType{ | |
92 Func: v.Func, | |
93 Params: clone(v.Params).(*ast.FieldList), | |
94 Results: clone(v.Results).(*ast.FieldList), | |
95 } | |
96 case *ast.FuncDecl: | |
97 if v == nil { | |
98 return v | |
99 } | |
100 return &ast.FuncDecl{ | |
101 Recv: clone(v.Recv).(*ast.FieldList), | |
102 Name: v.Name, | |
103 Type: clone(v.Type).(*ast.FuncType), | |
104 Body: v.Body, // shallow | |
105 } | |
106 case *ast.ValueSpec: | |
107 if v == nil { | |
108 return v | |
109 } | |
110 o := &ast.ValueSpec{ | |
111 Type: cloneExpr(v.Type), | |
112 } | |
113 for _, x := range v.Names { | |
114 o.Names = append(o.Names, x) | |
115 } | |
116 for _, x := range v.Values { | |
117 o.Values = append(o.Values, cloneExpr(x)) | |
118 } | |
119 return o | |
120 case *ast.CallExpr: | |
121 if v == nil { | |
122 return v | |
123 } | |
124 o := &ast.CallExpr{} | |
125 *o = *v | |
126 o.Args = cloneExprs(v.Args) | |
127 o.Fun = cloneExpr(v.Fun) | |
128 return o | |
129 case *ast.SelectorExpr: | |
130 if v == nil { | |
131 return nil | |
132 } | |
133 return &ast.SelectorExpr{ | |
134 X: cloneExpr(v.X), | |
135 Sel: v.Sel, | |
136 } | |
137 case *ast.ArrayType: | |
138 return &ast.ArrayType{ | |
139 Lbrack: v.Lbrack, | |
140 Len: cloneExpr(v.Len), | |
141 Elt: cloneExpr(v.Elt), | |
142 } | |
143 case *ast.StructType: | |
144 return &ast.StructType{ | |
145 Struct: v.Struct, | |
146 Fields: clone(v.Fields).(*ast.FieldList), | |
147 Incomplete: v.Incomplete, | |
148 } | |
149 case *ast.StarExpr: | |
150 return &ast.StarExpr{ | |
151 Star: v.Star, | |
152 X: cloneExpr(v.X), | |
153 } | |
154 case *ast.CompositeLit: | |
155 return &ast.CompositeLit{ | |
156 Type: cloneExpr(v.Type), | |
157 Lbrace: v.Lbrace, | |
158 Elts: cloneExprs(v.Elts), | |
159 Rbrace: v.Rbrace, | |
160 } | |
161 case *ast.UnaryExpr: | |
162 return &ast.UnaryExpr{ | |
163 OpPos: v.OpPos, | |
164 Op: v.Op, | |
165 X: cloneExpr(v.X), | |
166 } | |
167 case *ast.BinaryExpr: | |
168 return &ast.BinaryExpr{ | |
169 OpPos: v.OpPos, | |
170 Op: v.Op, | |
171 X: cloneExpr(v.X), | |
172 Y: cloneExpr(v.Y), | |
173 } | |
174 case *ast.Ellipsis: | |
175 return &ast.Ellipsis{ | |
176 Ellipsis: v.Ellipsis, | |
177 Elt: cloneExpr(v.Elt), | |
178 } | |
179 case *ast.KeyValueExpr: | |
180 return &ast.KeyValueExpr{ | |
181 Key: cloneExpr(v.Key), | |
182 Colon: v.Colon, | |
183 Value: cloneExpr(v.Value), | |
184 } | |
185 case *ast.FuncLit: | |
186 return &ast.FuncLit{ | |
187 Type: clone(v.Type).(*ast.FuncType), | |
188 Body: v.Body, // shallow | |
189 } | |
190 case *ast.MapType: | |
191 return &ast.MapType{ | |
192 Map: v.Map, | |
193 Key: cloneExpr(v.Key), | |
194 Value: cloneExpr(v.Value), | |
195 } | |
196 case *ast.ParenExpr: | |
197 return &ast.ParenExpr{ | |
198 Lparen: v.Lparen, | |
199 X: cloneExpr(v.X), | |
200 Rparen: v.Rparen, | |
201 } | |
202 case *ast.Ident, *ast.BasicLit: | |
203 return v | |
204 case *ast.ImportSpec: | |
205 return &ast.ImportSpec{ | |
206 Doc: v.Doc, // shallow | |
207 Name: v.Name, | |
208 Path: clone(v.Path).(*ast.BasicLit), | |
209 Comment: v.Comment, // shallow | |
210 EndPos: v.EndPos, | |
211 } | |
212 case *ast.ChanType: | |
213 return &ast.ChanType{ | |
214 Begin: v.Begin, | |
215 Arrow: v.Arrow, | |
216 Dir: v.Dir, | |
217 Value: cloneExpr(v.Value), | |
218 } | |
219 case *ast.TypeAssertExpr: | |
220 return &ast.TypeAssertExpr{ | |
221 X: cloneExpr(v.X), | |
222 Type: cloneExpr(v.Type), | |
223 } | |
224 case *ast.IndexExpr: | |
225 return &ast.IndexExpr{ | |
226 X: cloneExpr(v.X), | |
227 Index: cloneExpr(v.Index), | |
228 Lbrack: v.Lbrack, | |
229 Rbrack: v.Rbrack, | |
230 } | |
231 } | |
232 panic(fmt.Sprintf("Uncloneable type %T", i)) | |
233 } | |
234 | |
235 func cloneExpr(x ast.Expr) ast.Expr { | |
236 if x == nil { | |
237 return nil | |
238 } | |
239 return clone(x).(ast.Expr) | |
240 } | |
241 | |
242 func cloneExprs(x []ast.Expr) []ast.Expr { | |
243 if x == nil { | |
244 return nil | |
245 } | |
246 o := make([]ast.Expr, len(x)) | |
247 for i, x := range x { | |
248 o[i] = cloneExpr(x) | |
249 } | |
250 return o | |
251 } | |
LEFT | RIGHT |