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

Side by Side Diff: src/pkg/go/doc/example.go

Issue 6813061: go/doc: fix identifier blank import handling for examples (Closed)
Patch Set: diff -r 126c37a9e33c https://code.google.com/p/go/ 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 | « src/cmd/godoc/godoc.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Extract example functions from file ASTs. 5 // Extract example functions from file ASTs.
6 6
7 package doc 7 package doc
8 8
9 import ( 9 import (
10 "go/ast" 10 "go/ast"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // Remove predeclared identifiers from unresolved list. 139 // Remove predeclared identifiers from unresolved list.
140 for n := range unresolved { 140 for n := range unresolved {
141 if predeclaredTypes[n] || predeclaredConstants[n] || predeclared Funcs[n] { 141 if predeclaredTypes[n] || predeclaredConstants[n] || predeclared Funcs[n] {
142 delete(unresolved, n) 142 delete(unresolved, n)
143 } 143 }
144 } 144 }
145 145
146 // Use unresolved identifiers to determine the imports used by this 146 // Use unresolved identifiers to determine the imports used by this
147 // example. The heuristic assumes package names match base import 147 // example. The heuristic assumes package names match base import
148 // paths. (Should be good enough most of the time.) 148 // paths. (Should be good enough most of the time.)
149 » imports := make(map[string]string) // [name]path 149 » imports := make(map[string]string) // [name]path
gri 2012/11/16 19:52:23 Please call the first map say "namedImports" so it
150 » blankImports := []*ast.ImportSpec{} // _ imports
150 for _, s := range file.Imports { 151 for _, s := range file.Imports {
151 p, err := strconv.Unquote(s.Path.Value) 152 p, err := strconv.Unquote(s.Path.Value)
152 if err != nil { 153 if err != nil {
153 continue 154 continue
154 } 155 }
155 n := path.Base(p) 156 n := path.Base(p)
156 if s.Name != nil { 157 if s.Name != nil {
157 if s.Name.Name == "." { 158 if s.Name.Name == "." {
158 // We can't resolve dot imports (yet). 159 // We can't resolve dot imports (yet).
159 return nil 160 return nil
160 } 161 }
161 n = s.Name.Name 162 n = s.Name.Name
162 } 163 }
163 if unresolved[n] { 164 if unresolved[n] {
164 imports[n] = p 165 imports[n] = p
165 delete(unresolved, n) 166 delete(unresolved, n)
166 } 167 }
168 if n == "_" {
gri 2012/11/16 19:52:23 This should be "else if", but better: switch { ca
169 blankImports = append(blankImports, s)
170 }
167 } 171 }
168 172
169 // If there are other unresolved identifiers, give up because this 173 // If there are other unresolved identifiers, give up because this
170 // synthesized file is not going to build. 174 // synthesized file is not going to build.
171 if len(unresolved) > 0 { 175 if len(unresolved) > 0 {
172 return nil 176 return nil
173 } 177 }
174 178
175 // Filter out comments that are outside the function body. 179 // Filter out comments that are outside the function body.
gri 2012/11/16 19:52:23 This is too complicated. The comments associated w
176 var comments []*ast.CommentGroup 180 var comments []*ast.CommentGroup
177 for _, c := range file.Comments { 181 for _, c := range file.Comments {
178 » » if c.Pos() < body.Pos() || c.Pos() >= body.End() { 182 » » incl := false
179 » » » continue 183 » » for _, p := range blankImports {
adg 2012/11/13 11:50:48 I think this code is getting complex enough that w
minux1 2012/11/15 11:04:09 Will do that after I figure out why the formatting
184 » » » if p.Doc != nil && c.Pos() >= p.Doc.Pos() && c.Pos() < p .Doc.End() {
185 » » » » incl = true
186 » » » » break
187 » » » }
180 } 188 }
181 » » comments = append(comments, c) 189 » » if c.Pos() >= body.Pos() && c.Pos() < body.End() {
190 » » » incl = true
191 » » }
192 » » if incl {
193 » » » comments = append(comments, c)
194 » » }
182 } 195 }
183 196
184 // Strip "Output:" commment and adjust body end position. 197 // Strip "Output:" commment and adjust body end position.
185 body, comments = stripOutputComment(body, comments) 198 body, comments = stripOutputComment(body, comments)
186 199
187 // Synthesize import declaration. 200 // Synthesize import declaration.
188 importDecl := &ast.GenDecl{ 201 importDecl := &ast.GenDecl{
189 Tok: token.IMPORT, 202 Tok: token.IMPORT,
190 Lparen: 1, // Need non-zero Lparen and Rparen so that printer 203 Lparen: 1, // Need non-zero Lparen and Rparen so that printer
191 Rparen: 1, // treats this as a factored import. 204 Rparen: 1, // treats this as a factored import.
192 } 205 }
193 for n, p := range imports { 206 for n, p := range imports {
gri 2012/11/16 19:52:23 s/imports/namedImports/
194 s := &ast.ImportSpec{Path: &ast.BasicLit{Value: strconv.Quote(p) }} 207 s := &ast.ImportSpec{Path: &ast.BasicLit{Value: strconv.Quote(p) }}
195 if path.Base(p) != n { 208 if path.Base(p) != n {
196 s.Name = ast.NewIdent(n) 209 s.Name = ast.NewIdent(n)
197 } 210 }
198 importDecl.Specs = append(importDecl.Specs, s) 211 importDecl.Specs = append(importDecl.Specs, s)
199 } 212 }
213 for _, p := range blankImports {
gri 2012/11/16 19:52:23 this becomes: importDecl.Specs = append(importDec
214 importDecl.Specs = append(importDecl.Specs, p)
215 }
200 216
201 // Synthesize main function. 217 // Synthesize main function.
202 funcDecl := &ast.FuncDecl{ 218 funcDecl := &ast.FuncDecl{
203 Name: ast.NewIdent("main"), 219 Name: ast.NewIdent("main"),
204 Type: &ast.FuncType{}, 220 Type: &ast.FuncType{},
205 Body: body, 221 Body: body,
206 } 222 }
207 223
208 // Synthesize file. 224 // Synthesize file.
209 return &ast.File{ 225 return &ast.File{
210 Name: ast.NewIdent("main"), 226 Name: ast.NewIdent("main"),
211 Decls: []ast.Decl{importDecl, funcDecl}, 227 Decls: []ast.Decl{importDecl, funcDecl},
212 Comments: comments, 228 Comments: comments,
213 } 229 }
214 } 230 }
215 231
216 // playExample takes a whole file example and synthesizes a new *ast.File 232 // playExampleFile takes a whole file example and synthesizes a new *ast.File
217 // such that the example is function main in package main. 233 // such that the example is function main in package main.
218 func playExampleFile(file *ast.File) *ast.File { 234 func playExampleFile(file *ast.File) *ast.File {
219 // Strip copyright comment if present. 235 // Strip copyright comment if present.
220 comments := file.Comments 236 comments := file.Comments
221 if len(comments) > 0 && strings.HasPrefix(comments[0].Text(), "Copyright ") { 237 if len(comments) > 0 && strings.HasPrefix(comments[0].Text(), "Copyright ") {
222 comments = comments[1:] 238 comments = comments[1:]
223 } 239 }
224 240
225 // Copy declaration slice, rewriting the ExampleX function to main. 241 // Copy declaration slice, rewriting the ExampleX function to main.
226 var decls []ast.Decl 242 var decls []ast.Decl
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 if cg.Pos() < pos { 287 if cg.Pos() < pos {
272 continue 288 continue
273 } 289 }
274 if cg.End() > end { 290 if cg.End() > end {
275 break 291 break
276 } 292 }
277 i, last = j, cg 293 i, last = j, cg
278 } 294 }
279 return 295 return
280 } 296 }
OLDNEW
« no previous file with comments | « src/cmd/godoc/godoc.go ('k') | no next file » | no next file with comments »

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