Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(113)

Delta Between Two Patch Sets: src/cmd/api/clone.go

Issue 12300043: code review 12300043: cmd/api: rewrite using go/types (Closed)
Left Patch Set: diff -r 619bcb1a0254 https://code.google.com/p/go Created 11 years, 7 months ago
Right Patch Set: diff -r f53cee5f15de https://code.google.com/p/go Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « api/next.txt ('k') | src/cmd/api/goapi.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(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 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b