]> Cypherpunks repositories - gostls13.git/commitdiff
- print comments associated with declarations
authorRobert Griesemer <gri@golang.org>
Tue, 7 Jul 2009 23:07:34 +0000 (16:07 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 7 Jul 2009 23:07:34 +0000 (16:07 -0700)
- fix a bug w/ optional semicolons

R=rsc
DELTA=46  (24 added, 0 deleted, 22 changed)
OCL=31306
CL=31311

src/pkg/go/printer/printer.go

index e2898c518f420ea5e912356fdd24e5ecafbfdbe6..f91a14c05a3ad59067dea68578b6d131fc6e52a4 100644 (file)
@@ -521,7 +521,7 @@ func (p *printer) expr(x ast.Expr) bool {
 // ----------------------------------------------------------------------------
 // Statements
 
-func (p *printer) decl(decl ast.Decl) (optSemi bool)
+func (p *printer) decl(decl ast.Decl) (comment *ast.Comment, optSemi bool)
 
 // Print the statement list indented, but without a newline after the last statement.
 func (p *printer) stmtList(list []ast.Stmt) {
@@ -607,7 +607,16 @@ func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) {
                p.print("BadStmt");
 
        case *ast.DeclStmt:
-               optSemi = p.decl(s.Decl);
+               var comment *ast.Comment;
+               comment, optSemi = p.decl(s.Decl);
+               if comment != nil {
+                       // Trailing comments of declarations in statement lists
+                       // are not associated with the declaration in the parser;
+                       // this case should never happen. Print anyway to continue
+                       // gracefully.
+                       p.comment(comment);
+                       p.print(newline);
+               }
 
        case *ast.EmptyStmt:
                // nothing to do
@@ -757,8 +766,9 @@ func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) {
 // ----------------------------------------------------------------------------
 // Declarations
 
-// Returns true if a separating semicolon is optional.
-func (p *printer) spec(spec ast.Spec) (optSemi bool) {
+// Returns trailing comment, if any, and whether a separating semicolon is optional.
+//
+func (p *printer) spec(spec ast.Spec) (comment *ast.Comment, optSemi bool) {
        switch s := spec.(type) {
        case *ast.ImportSpec:
                p.doc(s.Doc);
@@ -767,35 +777,39 @@ func (p *printer) spec(spec ast.Spec) (optSemi bool) {
                }
                // TODO fix for longer package names
                p.print(tab, s.Path[0].Pos(), s.Path[0].Value);
+               comment = s.Comment;
 
        case *ast.ValueSpec:
                p.doc(s.Doc);
                p.identList(s.Names);
                if s.Type != nil {
                        p.print(blank);  // TODO switch to tab? (indent problem with structs)
-                       p.expr(s.Type);
+                       optSemi = p.expr(s.Type);
                }
                if s.Values != nil {
                        p.print(tab, token.ASSIGN, blank);
                        p.exprList(s.Values);
+                       optSemi = false;
                }
+               comment = s.Comment;
 
        case *ast.TypeSpec:
                p.doc(s.Doc);
                p.expr(s.Name);
                p.print(blank);  // TODO switch to tab? (but indent problem with structs)
                optSemi = p.expr(s.Type);
+               comment = s.Comment;
 
        default:
                panic("unreachable");
        }
 
-       return optSemi;
+       return comment, optSemi;
 }
 
 
 // Returns true if a separating semicolon is optional.
-func (p *printer) decl(decl ast.Decl) (optSemi bool) {
+func (p *printer) decl(decl ast.Decl) (comment *ast.Comment, optSemi bool) {
        switch d := decl.(type) {
        case *ast.BadDecl:
                p.print(d.Pos(), "BadDecl");
@@ -806,22 +820,30 @@ func (p *printer) decl(decl ast.Decl) (optSemi bool) {
 
                if d.Lparen.IsValid() {
                        // group of parenthesized declarations
-                       p.print(d.Lparen, token.LPAREN, +1, newline);
-                       for i, s := range d.Specs {
-                               if i > 0 {
-                                       p.print(token.SEMICOLON, newline);
+                       p.print(d.Lparen, token.LPAREN);
+                       if len(d.Specs) > 0 {
+                               p.print(+1, newline);
+                               for i, s := range d.Specs {
+                                       if i > 0 {
+                                               p.print(token.SEMICOLON);
+                                               p.comment(comment);
+                                               p.print(newline);
+                                       }
+                                       comment, optSemi = p.spec(s);
                                }
-                               p.spec(s);
-                       }
-                       if p.optSemis() {
-                               p.print(token.SEMICOLON);
+                               if p.optSemis() {
+                                       p.print(token.SEMICOLON);
+                               }
+                               p.comment(comment);
+                               p.print(-1, newline);
                        }
-                       p.print(-1, newline, d.Rparen, token.RPAREN);
+                       p.print(d.Rparen, token.RPAREN);
+                       comment = nil;  // comment was already printed
                        optSemi = true;
 
                } else {
                        // single declaration
-                       optSemi = p.spec(d.Specs[0]);
+                       comment, optSemi = p.spec(d.Specs[0]);
                }
 
        case *ast.FuncDecl:
@@ -850,7 +872,7 @@ func (p *printer) decl(decl ast.Decl) (optSemi bool) {
                panic("unreachable");
        }
 
-       return optSemi;
+       return comment, optSemi;
 }
 
 
@@ -868,10 +890,11 @@ func (p *printer) program(prog *ast.Program) {
 
        for _, d := range prog.Decls {
                p.print(newline, newline);
-               p.decl(d);
+               comment, _ := p.decl(d);
                if p.optSemis() {
                        p.print(token.SEMICOLON);
                }
+               p.comment(comment);
        }
 
        p.print(newline);
@@ -898,7 +921,8 @@ func Fprint(output io.Writer, node interface{}, mode uint) (int, os.Error) {
                case ast.Stmt:
                        p.stmt(n);
                case ast.Decl:
-                       p.decl(n);
+                       comment, _ := p.decl(n);
+                       p.comment(comment);
                case *ast.Program:
                        p.program(n);
                default: