Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
7e525928
Commit
7e525928
authored
Sep 18, 2012
by
Andrew Gerrand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
go/doc: synthesize "package main" for examples
R=gri CC=golang-dev
https://golang.org/cl/6525046
parent
cc8cfefd
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
92 additions
and
0 deletions
+92
-0
example.go
src/pkg/go/doc/example.go
+92
-0
No files found.
src/pkg/go/doc/example.go
View file @
7e525928
...
...
@@ -9,8 +9,10 @@ package doc
import
(
"go/ast"
"go/token"
"path"
"regexp"
"sort"
"strconv"
"strings"
"unicode"
"unicode/utf8"
...
...
@@ -20,6 +22,7 @@ type Example struct {
Name
string
// name of the item being exemplified
Doc
string
// example function doc string
Code
ast
.
Node
Play
*
ast
.
File
// a whole program version of the example
Comments
[]
*
ast
.
CommentGroup
Output
string
// expected output
}
...
...
@@ -56,6 +59,7 @@ func Examples(files ...*ast.File) []*Example {
Name
:
name
[
len
(
"Example"
)
:
],
Doc
:
doc
,
Code
:
f
.
Body
,
Play
:
playExample
(
file
,
f
.
Body
),
Comments
:
file
.
Comments
,
Output
:
exampleOutput
(
f
,
file
.
Comments
),
})
...
...
@@ -115,3 +119,91 @@ type exampleByName []*Example
func
(
s
exampleByName
)
Len
()
int
{
return
len
(
s
)
}
func
(
s
exampleByName
)
Swap
(
i
,
j
int
)
{
s
[
i
],
s
[
j
]
=
s
[
j
],
s
[
i
]
}
func
(
s
exampleByName
)
Less
(
i
,
j
int
)
bool
{
return
s
[
i
]
.
Name
<
s
[
j
]
.
Name
}
// playExample synthesizes a new *ast.File based on the provided
// file with the provided function body as the body of main.
func
playExample
(
file
*
ast
.
File
,
body
*
ast
.
BlockStmt
)
*
ast
.
File
{
if
!
strings
.
HasSuffix
(
file
.
Name
.
Name
,
"_test"
)
{
// We don't support examples that are part of the
// greater package (yet).
return
nil
}
// Determine the imports we need based on unresolved identifiers.
// This is a heuristic that presumes package names match base import paths.
// (Should be good enough most of the time.)
var
unresolved
[]
*
ast
.
Ident
ast
.
Inspect
(
body
,
func
(
n
ast
.
Node
)
bool
{
if
e
,
ok
:=
n
.
(
*
ast
.
SelectorExpr
);
ok
{
if
id
,
ok
:=
e
.
X
.
(
*
ast
.
Ident
);
ok
&&
id
.
Obj
==
nil
{
unresolved
=
append
(
unresolved
,
id
)
}
}
return
true
})
imports
:=
make
(
map
[
string
]
string
)
// [name]path
for
_
,
s
:=
range
file
.
Imports
{
p
,
err
:=
strconv
.
Unquote
(
s
.
Path
.
Value
)
if
err
!=
nil
{
continue
}
n
:=
path
.
Base
(
p
)
if
s
.
Name
!=
nil
{
if
s
.
Name
.
Name
==
"."
{
// We can't resolve dot imports (yet).
return
nil
}
n
=
s
.
Name
.
Name
}
for
_
,
id
:=
range
unresolved
{
if
n
==
id
.
Name
{
imports
[
n
]
=
p
break
}
}
}
// TODO(adg): look for other unresolved identifiers and, if found, give up.
// Synthesize new imports.
importDecl
:=
&
ast
.
GenDecl
{
Tok
:
token
.
IMPORT
,
Lparen
:
1
,
// Need non-zero Lparen and Rparen so that printer
Rparen
:
1
,
// treats this as a factored import.
}
for
n
,
p
:=
range
imports
{
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
)
}
// Synthesize main function.
funcDecl
:=
&
ast
.
FuncDecl
{
Name
:
ast
.
NewIdent
(
"main"
),
Type
:
&
ast
.
FuncType
{},
Body
:
body
,
}
// Filter out comments that are outside the function body.
var
comments
[]
*
ast
.
CommentGroup
for
_
,
c
:=
range
file
.
Comments
{
if
c
.
Pos
()
<
body
.
Pos
()
||
c
.
Pos
()
>=
body
.
End
()
{
continue
}
comments
=
append
(
comments
,
c
)
}
// Synthesize file.
f
:=
&
ast
.
File
{
Name
:
ast
.
NewIdent
(
"main"
),
Decls
:
[]
ast
.
Decl
{
importDecl
,
funcDecl
},
Comments
:
comments
,
}
// TODO(adg): look for resolved identifiers declared outside function scope
// and include their declarations in the new file.
return
f
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment