Commit 9809d738 authored by Robert Griesemer's avatar Robert Griesemer

- print comments associated with declarations

- fix a bug w/ optional semicolons

R=rsc
DELTA=46  (24 added, 0 deleted, 22 changed)
OCL=31306
CL=31311
parent 42af8034
...@@ -521,7 +521,7 @@ func (p *printer) expr(x ast.Expr) bool { ...@@ -521,7 +521,7 @@ func (p *printer) expr(x ast.Expr) bool {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Statements // 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. // Print the statement list indented, but without a newline after the last statement.
func (p *printer) stmtList(list []ast.Stmt) { func (p *printer) stmtList(list []ast.Stmt) {
...@@ -607,7 +607,16 @@ func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) { ...@@ -607,7 +607,16 @@ func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) {
p.print("BadStmt"); p.print("BadStmt");
case *ast.DeclStmt: 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: case *ast.EmptyStmt:
// nothing to do // nothing to do
...@@ -757,8 +766,9 @@ func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) { ...@@ -757,8 +766,9 @@ func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Declarations // Declarations
// Returns true if a separating semicolon is optional. // Returns trailing comment, if any, and whether a separating semicolon is optional.
func (p *printer) spec(spec ast.Spec) (optSemi bool) { //
func (p *printer) spec(spec ast.Spec) (comment *ast.Comment, optSemi bool) {
switch s := spec.(type) { switch s := spec.(type) {
case *ast.ImportSpec: case *ast.ImportSpec:
p.doc(s.Doc); p.doc(s.Doc);
...@@ -767,35 +777,39 @@ func (p *printer) spec(spec ast.Spec) (optSemi bool) { ...@@ -767,35 +777,39 @@ func (p *printer) spec(spec ast.Spec) (optSemi bool) {
} }
// TODO fix for longer package names // TODO fix for longer package names
p.print(tab, s.Path[0].Pos(), s.Path[0].Value); p.print(tab, s.Path[0].Pos(), s.Path[0].Value);
comment = s.Comment;
case *ast.ValueSpec: case *ast.ValueSpec:
p.doc(s.Doc); p.doc(s.Doc);
p.identList(s.Names); p.identList(s.Names);
if s.Type != nil { if s.Type != nil {
p.print(blank); // TODO switch to tab? (indent problem with structs) p.print(blank); // TODO switch to tab? (indent problem with structs)
p.expr(s.Type); optSemi = p.expr(s.Type);
} }
if s.Values != nil { if s.Values != nil {
p.print(tab, token.ASSIGN, blank); p.print(tab, token.ASSIGN, blank);
p.exprList(s.Values); p.exprList(s.Values);
optSemi = false;
} }
comment = s.Comment;
case *ast.TypeSpec: case *ast.TypeSpec:
p.doc(s.Doc); p.doc(s.Doc);
p.expr(s.Name); p.expr(s.Name);
p.print(blank); // TODO switch to tab? (but indent problem with structs) p.print(blank); // TODO switch to tab? (but indent problem with structs)
optSemi = p.expr(s.Type); optSemi = p.expr(s.Type);
comment = s.Comment;
default: default:
panic("unreachable"); panic("unreachable");
} }
return optSemi; return comment, optSemi;
} }
// Returns true if a separating semicolon is optional. // 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) { switch d := decl.(type) {
case *ast.BadDecl: case *ast.BadDecl:
p.print(d.Pos(), "BadDecl"); p.print(d.Pos(), "BadDecl");
...@@ -806,22 +820,30 @@ func (p *printer) decl(decl ast.Decl) (optSemi bool) { ...@@ -806,22 +820,30 @@ func (p *printer) decl(decl ast.Decl) (optSemi bool) {
if d.Lparen.IsValid() { if d.Lparen.IsValid() {
// group of parenthesized declarations // group of parenthesized declarations
p.print(d.Lparen, token.LPAREN, +1, newline); p.print(d.Lparen, token.LPAREN);
if len(d.Specs) > 0 {
p.print(+1, newline);
for i, s := range d.Specs { for i, s := range d.Specs {
if i > 0 { if i > 0 {
p.print(token.SEMICOLON, newline); p.print(token.SEMICOLON);
p.comment(comment);
p.print(newline);
} }
p.spec(s); comment, optSemi = p.spec(s);
} }
if p.optSemis() { if p.optSemis() {
p.print(token.SEMICOLON); p.print(token.SEMICOLON);
} }
p.print(-1, newline, d.Rparen, token.RPAREN); p.comment(comment);
p.print(-1, newline);
}
p.print(d.Rparen, token.RPAREN);
comment = nil; // comment was already printed
optSemi = true; optSemi = true;
} else { } else {
// single declaration // single declaration
optSemi = p.spec(d.Specs[0]); comment, optSemi = p.spec(d.Specs[0]);
} }
case *ast.FuncDecl: case *ast.FuncDecl:
...@@ -850,7 +872,7 @@ func (p *printer) decl(decl ast.Decl) (optSemi bool) { ...@@ -850,7 +872,7 @@ func (p *printer) decl(decl ast.Decl) (optSemi bool) {
panic("unreachable"); panic("unreachable");
} }
return optSemi; return comment, optSemi;
} }
...@@ -868,10 +890,11 @@ func (p *printer) program(prog *ast.Program) { ...@@ -868,10 +890,11 @@ func (p *printer) program(prog *ast.Program) {
for _, d := range prog.Decls { for _, d := range prog.Decls {
p.print(newline, newline); p.print(newline, newline);
p.decl(d); comment, _ := p.decl(d);
if p.optSemis() { if p.optSemis() {
p.print(token.SEMICOLON); p.print(token.SEMICOLON);
} }
p.comment(comment);
} }
p.print(newline); p.print(newline);
...@@ -898,7 +921,8 @@ func Fprint(output io.Writer, node interface{}, mode uint) (int, os.Error) { ...@@ -898,7 +921,8 @@ func Fprint(output io.Writer, node interface{}, mode uint) (int, os.Error) {
case ast.Stmt: case ast.Stmt:
p.stmt(n); p.stmt(n);
case ast.Decl: case ast.Decl:
p.decl(n); comment, _ := p.decl(n);
p.comment(comment);
case *ast.Program: case *ast.Program:
p.program(n); p.program(n);
default: default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment