diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-12 01:31:45 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-12 01:31:45 +0000 |
commit | 9a0e3259f44ad2de9c65f14f756dab01b3598391 (patch) | |
tree | 86a3b8019380d5fad53258c4baba3dd9e1e7c736 /libgo/go/go/printer | |
parent | c6135f063335419e4b5df0b4e1caf145882c8a4b (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.go | 88 | ||||
-rw-r--r-- | libgo/go/go/printer/printer_test.go | 2 |
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 }() |