summaryrefslogtreecommitdiff
path: root/libgo/go/go/printer
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-01-12 01:31:45 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-01-12 01:31:45 +0000
commit9a0e3259f44ad2de9c65f14f756dab01b3598391 (patch)
tree86a3b8019380d5fad53258c4baba3dd9e1e7c736 /libgo/go/go/printer
parentc6135f063335419e4b5df0b4e1caf145882c8a4b (diff)
libgo: Update to weekly.2011-12-14.
From-SVN: r183118
Diffstat (limited to 'libgo/go/go/printer')
-rw-r--r--libgo/go/go/printer/printer.go88
-rw-r--r--libgo/go/go/printer/printer_test.go2
2 files changed, 80 insertions, 10 deletions
diff --git a/libgo/go/go/printer/printer.go b/libgo/go/go/printer/printer.go
index f8c22f1419d..8538236c2c9 100644
--- a/libgo/go/go/printer/printer.go
+++ b/libgo/go/go/printer/printer.go
@@ -807,13 +807,75 @@ func (p *printer) flush(next token.Position, tok token.Token) (droppedFF bool) {
return
}
+// getNode returns the ast.CommentGroup associated with n, if any.
+func getDoc(n ast.Node) *ast.CommentGroup {
+ switch n := n.(type) {
+ // *ast.Fields cannot be printed separately - ignore for now
+ case *ast.ImportSpec:
+ return n.Doc
+ case *ast.ValueSpec:
+ return n.Doc
+ case *ast.TypeSpec:
+ return n.Doc
+ case *ast.GenDecl:
+ return n.Doc
+ case *ast.FuncDecl:
+ return n.Doc
+ case *ast.File:
+ return n.Doc
+ }
+ return nil
+}
+
func (p *printer) printNode(node interface{}) error {
+ // unpack *CommentedNode, if any
+ var comments []*ast.CommentGroup
+ if cnode, ok := node.(*CommentedNode); ok {
+ node = cnode.Node
+ comments = cnode.Comments
+ }
+
+ if comments != nil {
+ // commented node - restrict comment list to relevant range
+ n, ok := node.(ast.Node)
+ if !ok {
+ goto unsupported
+ }
+ beg := n.Pos()
+ end := n.End()
+ // if the node has associated documentation,
+ // include that commentgroup in the range
+ // (the comment list is sorted in the order
+ // of the comment appearance in the source code)
+ if doc := getDoc(n); doc != nil {
+ beg = doc.Pos()
+ }
+ // token.Pos values are global offsets, we can
+ // compare them directly
+ i := 0
+ for i < len(comments) && comments[i].End() < beg {
+ i++
+ }
+ j := i
+ for j < len(comments) && comments[j].Pos() < end {
+ j++
+ }
+ if i < j {
+ p.comments = comments[i:j]
+ }
+ } else if n, ok := node.(*ast.File); ok {
+ // use ast.File comments, if any
+ p.comments = n.Comments
+ }
+
+ // if there are no comments, use node comments
+ p.useNodeComments = p.comments == nil
+
+ // format node
switch n := node.(type) {
case ast.Expr:
- p.useNodeComments = true
p.expr(n, ignoreMultiLine)
case ast.Stmt:
- p.useNodeComments = true
// A labeled statement will un-indent to position the
// label. Set indent to 1 so we don't get indent "underflow".
if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt {
@@ -821,19 +883,19 @@ func (p *printer) printNode(node interface{}) error {
}
p.stmt(n, false, ignoreMultiLine)
case ast.Decl:
- p.useNodeComments = true
p.decl(n, ignoreMultiLine)
case ast.Spec:
- p.useNodeComments = true
p.spec(n, 1, false, ignoreMultiLine)
case *ast.File:
- p.comments = n.Comments
- p.useNodeComments = n.Comments == nil
p.file(n)
default:
- return fmt.Errorf("go/printer: unsupported node type %T", n)
+ goto unsupported
}
+
return nil
+
+unsupported:
+ return fmt.Errorf("go/printer: unsupported node type %T", node)
}
// ----------------------------------------------------------------------------
@@ -1001,10 +1063,18 @@ func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node interface{
return
}
+// A CommentedNode bundles an AST node and corresponding comments.
+// It may be provided as argument to any of the FPrint functions.
+//
+type CommentedNode struct {
+ Node interface{} // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt
+ Comments []*ast.CommentGroup
+}
+
// Fprint "pretty-prints" an AST node to output for a given configuration cfg.
// Position information is interpreted relative to the file set fset.
-// The node type must be *ast.File, or assignment-compatible to ast.Expr,
-// ast.Decl, ast.Spec, or ast.Stmt.
+// The node type must be *ast.File, *CommentedNode, or assignment-compatible
+// to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt.
//
func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{}) error {
return cfg.fprint(output, fset, node, make(map[ast.Node]int))
diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go
index 924d4dfdb29..45477d40f6e 100644
--- a/libgo/go/go/printer/printer_test.go
+++ b/libgo/go/go/printer/printer_test.go
@@ -107,7 +107,7 @@ func check(t *testing.T, source, golden string, mode checkMode) {
// start a timer to produce a time-out signal
tc := make(chan int)
go func() {
- time.Sleep(10e9) // plenty of a safety margin, even for very slow machines
+ time.Sleep(10 * time.Second) // plenty of a safety margin, even for very slow machines
tc <- 0
}()