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

Side by Side Diff: src/cmd/api/clone.go

Issue 6845058: code review 6845058: cmd/api: speed up API check by 2x, caching parser.Parse... (Closed)
Patch Set: diff -r a26a8ada8f6e https://go.googlecode.com/hg/ Created 11 years, 4 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:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/cmd/api/goapi.go » ('j') | src/cmd/api/goapi.go » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 if i == nil {
remyoudompheng 2012/11/17 19:19:59 why not put case nil: return nil in the switch?
bradfitz 2012/11/17 22:13:09 Done.
27 return nil
28 }
29 switch v := i.(type) {
30 case *ast.File:
31 o := &ast.File{
32 Doc: v.Doc, // shallow
33 Package: v.Package,
34 Comments: v.Comments, // shallow
35 Name: v.Name,
36 Scope: v.Scope,
37 }
38 for _, x := range v.Decls {
39 o.Decls = append(o.Decls, clone(x).(ast.Decl))
40 }
41 for _, x := range v.Imports {
42 o.Imports = append(o.Imports, clone(x).(*ast.ImportSpec) )
43 }
44 for _, x := range v.Unresolved {
45 o.Unresolved = append(o.Unresolved, x)
46 }
47 return o
48 case *ast.GenDecl:
49 o := new(ast.GenDecl)
50 *o = *v
51 o.Specs = nil
52 for _, x := range v.Specs {
53 o.Specs = append(o.Specs, clone(x).(ast.Spec))
54 }
55 return o
56 case *ast.TypeSpec:
57 o := new(ast.TypeSpec)
58 *o = *v
59 o.Type = cloneExpr(v.Type)
60 return o
61 case *ast.InterfaceType:
62 o := new(ast.InterfaceType)
63 *o = *v
64 o.Methods = clone(v.Methods).(*ast.FieldList)
65 return o
66 case *ast.FieldList:
67 if v == nil {
68 return v
69 }
70 o := new(ast.FieldList)
71 *o = *v
72 o.List = nil
73 for _, x := range v.List {
74 o.List = append(o.List, clone(x).(*ast.Field))
75 }
76 return o
77 case *ast.Field:
78 o := &ast.Field{
79 Doc: v.Doc, // shallow
80 Type: cloneExpr(v.Type),
81 Tag: clone(v.Tag).(*ast.BasicLit),
82 Comment: v.Comment, // shallow
83 }
84 for _, x := range v.Names {
85 o.Names = append(o.Names, clone(x).(*ast.Ident))
86 }
87 return o
88 case *ast.FuncType:
89 if v == nil {
90 return v
91 }
92 return &ast.FuncType{
93 Func: v.Func,
94 Params: clone(v.Params).(*ast.FieldList),
95 Results: clone(v.Results).(*ast.FieldList),
96 }
97 case *ast.FuncDecl:
98 if v == nil {
99 return v
100 }
101 return &ast.FuncDecl{
102 Recv: clone(v.Recv).(*ast.FieldList),
103 Name: v.Name,
104 Type: clone(v.Type).(*ast.FuncType),
105 Body: v.Body, // shallow
106 }
107 case *ast.ValueSpec:
108 if v == nil {
109 return v
110 }
111 o := &ast.ValueSpec{
112 Type: cloneExpr(v.Type),
113 }
114 for _, x := range v.Names {
115 o.Names = append(o.Names, x)
116 }
117 for _, x := range v.Values {
118 o.Values = append(o.Values, cloneExpr(x))
119 }
120 return o
121 case *ast.CallExpr:
122 if v == nil {
123 return v
124 }
125 o := &ast.CallExpr{}
126 *o = *v
127 o.Args = cloneExprs(v.Args)
128 o.Fun = cloneExpr(v.Fun)
129 return o
130 case *ast.SelectorExpr:
131 if v == nil {
132 return nil
133 }
134 return &ast.SelectorExpr{
135 X: cloneExpr(v.X),
136 Sel: v.Sel,
137 }
138 case *ast.ArrayType:
139 return &ast.ArrayType{
140 Lbrack: v.Lbrack,
141 Len: cloneExpr(v.Len),
142 Elt: cloneExpr(v.Elt),
143 }
144 case *ast.StructType:
145 return &ast.StructType{
146 Struct: v.Struct,
147 Fields: clone(v.Fields).(*ast.FieldList),
148 Incomplete: v.Incomplete,
149 }
150 case *ast.StarExpr:
151 return &ast.StarExpr{
152 Star: v.Star,
153 X: cloneExpr(v.X),
154 }
155 case *ast.CompositeLit:
156 return &ast.CompositeLit{
157 Type: cloneExpr(v.Type),
158 Lbrace: v.Lbrace,
159 Elts: cloneExprs(v.Elts),
160 Rbrace: v.Rbrace,
161 }
162 case *ast.UnaryExpr:
163 return &ast.UnaryExpr{
164 OpPos: v.OpPos,
165 Op: v.Op,
166 X: cloneExpr(v.X),
167 }
168 case *ast.BinaryExpr:
169 return &ast.BinaryExpr{
170 OpPos: v.OpPos,
171 Op: v.Op,
172 X: cloneExpr(v.X),
173 Y: cloneExpr(v.Y),
174 }
175 case *ast.Ellipsis:
176 return &ast.Ellipsis{
177 Ellipsis: v.Ellipsis,
178 Elt: cloneExpr(v.Elt),
179 }
180 case *ast.KeyValueExpr:
181 return &ast.KeyValueExpr{
182 Key: cloneExpr(v.Key),
183 Colon: v.Colon,
184 Value: cloneExpr(v.Value),
185 }
186 case *ast.FuncLit:
187 return &ast.FuncLit{
188 Type: clone(v.Type).(*ast.FuncType),
189 Body: v.Body, // shallow
190 }
191 case *ast.MapType:
192 return &ast.MapType{
193 Map: v.Map,
194 Key: cloneExpr(v.Key),
195 Value: cloneExpr(v.Value),
196 }
197 case *ast.ParenExpr:
198 return &ast.ParenExpr{
199 Lparen: v.Lparen,
200 X: cloneExpr(v.X),
201 Rparen: v.Rparen,
202 }
203 case *ast.Ident, *ast.BasicLit:
204 return v
205 case *ast.ImportSpec:
206 return &ast.ImportSpec{
207 Doc: v.Doc, // shallow
208 Name: v.Name,
209 Path: clone(v.Path).(*ast.BasicLit),
210 Comment: v.Comment, // shallow
211 EndPos: v.EndPos,
212 }
213 case *ast.ChanType:
214 return &ast.ChanType{
215 Begin: v.Begin,
216 Arrow: v.Arrow,
217 Dir: v.Dir,
218 Value: cloneExpr(v.Value),
219 }
220 case *ast.TypeAssertExpr:
221 return &ast.TypeAssertExpr{
222 X: cloneExpr(v.X),
223 Type: cloneExpr(v.Type),
224 }
225 case *ast.IndexExpr:
226 return &ast.IndexExpr{
227 X: cloneExpr(v.X),
228 Index: cloneExpr(v.Index),
229 Lbrack: v.Lbrack,
230 Rbrack: v.Rbrack,
231 }
232 }
233 panic(fmt.Sprintf("Uncloneable type %T", i))
234 }
235
236 func cloneExpr(x ast.Expr) ast.Expr {
237 if x == nil {
238 return nil
239 }
240 return clone(x).(ast.Expr)
241 }
242
243 func cloneExprs(x []ast.Expr) []ast.Expr {
244 if x == nil {
245 return nil
246 }
247 o := make([]ast.Expr, len(x))
248 for i, x := range x {
249 o[i] = cloneExpr(x)
250 }
251 return o
252 }
OLDNEW
« no previous file with comments | « no previous file | src/cmd/api/goapi.go » ('j') | src/cmd/api/goapi.go » ('J')

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