1
0
mirror of https://github.com/golang/go synced 2024-11-22 23:50:03 -07:00

go/doc: fix identifier blank import handling for examples

Replacement CL for 6813061; thanks to minux for prototyping.

Fixes #4300.

R=minux.ma
CC=golang-dev
https://golang.org/cl/6782082
This commit is contained in:
Robert Griesemer 2012-11-17 10:40:11 -08:00
parent 792e664ee4
commit 80dcc434a8
2 changed files with 25 additions and 12 deletions

View File

@ -356,6 +356,7 @@ func example_htmlFunc(funcName string, examples []*doc.Example, fset *token.File
// (use tabs, no comment highlight, etc).
play := ""
if eg.Play != nil && *showPlayground {
ast.SortImports(fset, eg.Play)
var buf bytes.Buffer
err := (&printer.Config{Mode: printer.TabIndent, Tabwidth: 8}).Fprint(&buf, fset, eg.Play)
if err != nil {

View File

@ -145,8 +145,9 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
// Use unresolved identifiers to determine the imports used by this
// example. The heuristic assumes package names match base import
// paths. (Should be good enough most of the time.)
imports := make(map[string]string) // [name]path
// paths for imports w/o renames (should be good enough most of the time).
namedImports := make(map[string]string) // [name]path
var blankImports []ast.Spec // _ imports
for _, s := range file.Imports {
p, err := strconv.Unquote(s.Path.Value)
if err != nil {
@ -154,14 +155,18 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
}
n := path.Base(p)
if s.Name != nil {
if s.Name.Name == "." {
n = s.Name.Name
switch n {
case "_":
blankImports = append(blankImports, s)
continue
case ".":
// We can't resolve dot imports (yet).
return nil
}
n = s.Name.Name
}
if unresolved[n] {
imports[n] = p
namedImports[n] = p
delete(unresolved, n)
}
}
@ -172,14 +177,20 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
return nil
}
// Filter out comments that are outside the function body.
// Include documentation belonging to blank imports.
var comments []*ast.CommentGroup
for _, c := range file.Comments {
if c.Pos() < body.Pos() || c.Pos() >= body.End() {
continue
}
for _, s := range blankImports {
if c := s.(*ast.ImportSpec).Doc; c != nil {
comments = append(comments, c)
}
}
// Include comments that are inside the function body.
for _, c := range file.Comments {
if body.Pos() <= c.Pos() && c.End() <= body.End() {
comments = append(comments, c)
}
}
// Strip "Output:" commment and adjust body end position.
body, comments = stripOutputComment(body, comments)
@ -190,13 +201,14 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
Lparen: 1, // Need non-zero Lparen and Rparen so that printer
Rparen: 1, // treats this as a factored import.
}
for n, p := range imports {
for n, p := range namedImports {
s := &ast.ImportSpec{Path: &ast.BasicLit{Value: strconv.Quote(p)}}
if path.Base(p) != n {
s.Name = ast.NewIdent(n)
}
importDecl.Specs = append(importDecl.Specs, s)
}
importDecl.Specs = append(importDecl.Specs, blankImports...)
// Synthesize main function.
funcDecl := &ast.FuncDecl{
@ -213,7 +225,7 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
}
}
// playExample takes a whole file example and synthesizes a new *ast.File
// playExampleFile takes a whole file example and synthesizes a new *ast.File
// such that the example is function main in package main.
func playExampleFile(file *ast.File) *ast.File {
// Strip copyright comment if present.