]> Cypherpunks repositories - gostls13.git/commitdiff
go/doc: don't synthesize code for examples that are not self-contained
authorAndrew Gerrand <adg@golang.org>
Thu, 20 Dec 2012 20:06:38 +0000 (07:06 +1100)
committerAndrew Gerrand <adg@golang.org>
Thu, 20 Dec 2012 20:06:38 +0000 (07:06 +1100)
Fixes #4309.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6974045

src/pkg/go/doc/example.go

index e5752bb15a16ee22124f6a9bd37cd0f36c82994d..9fc0b415f0d4ab98bf73e5cec1a9d0ec158a5222 100644 (file)
@@ -119,8 +119,29 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
                return nil
        }
 
-       // Find unresolved identifiers
+       // Find top-level declarations in the file.
+       topDecls := make(map[*ast.Object]bool)
+       for _, decl := range file.Decls {
+               switch d := decl.(type) {
+               case *ast.FuncDecl:
+                       topDecls[d.Name.Obj] = true
+               case *ast.GenDecl:
+                       for _, spec := range d.Specs {
+                               switch s := spec.(type) {
+                               case *ast.TypeSpec:
+                                       topDecls[s.Name.Obj] = true
+                               case *ast.ValueSpec:
+                                       for _, id := range s.Names {
+                                               topDecls[id.Obj] = true
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // Find unresolved identifiers and uses of top-level declarations.
        unresolved := make(map[string]bool)
+       usesTopDecl := false
        ast.Inspect(body, func(n ast.Node) bool {
                // For an expression like fmt.Println, only add "fmt" to the
                // set of unresolved names.
@@ -130,11 +151,19 @@ func playExample(file *ast.File, body *ast.BlockStmt) *ast.File {
                        }
                        return false
                }
-               if id, ok := n.(*ast.Ident); ok && id.Obj == nil {
-                       unresolved[id.Name] = true
+               if id, ok := n.(*ast.Ident); ok {
+                       if id.Obj == nil {
+                               unresolved[id.Name] = true
+                       } else if topDecls[id.Obj] {
+                               usesTopDecl = true
+                       }
                }
                return true
        })
+       if usesTopDecl {
+               // We don't support examples that are not self-contained (yet).
+               return nil
+       }
 
        // Remove predeclared identifiers from unresolved list.
        for n := range unresolved {