diff options
author | Robert Griesemer <gri@golang.org> | 2010-05-14 15:38:25 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2010-05-14 15:38:25 -0700 |
commit | 5083900ab517513e26de4d6ecf36a16176bb0b09 (patch) | |
tree | b95e6a8f392692cc55d2199a370c0a7a02d4af01 /src/pkg/go | |
parent | 69eb90832f67ff3d0cb79a8f50a9e986d580b1b8 (diff) | |
download | golang-5083900ab517513e26de4d6ecf36a16176bb0b09.tar.gz |
go/printer (gofmt): don't lose mandatory semicolons
Fixes issue 779.
R=r
CC=golang-dev
http://codereview.appspot.com/1218042
Diffstat (limited to 'src/pkg/go')
-rw-r--r-- | src/pkg/go/printer/nodes.go | 36 | ||||
-rw-r--r-- | src/pkg/go/printer/printer.go | 4 | ||||
-rw-r--r-- | src/pkg/go/printer/testdata/statements.golden | 18 | ||||
-rw-r--r-- | src/pkg/go/printer/testdata/statements.input | 18 |
4 files changed, 59 insertions, 17 deletions
diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go index dd2b497f5..044a08a21 100644 --- a/src/pkg/go/printer/nodes.go +++ b/src/pkg/go/printer/nodes.go @@ -491,7 +491,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isIncomplete bool, ctxt exprC type exprContext uint const ( - compositeLit = 1 << iota + compositeLit exprContext = 1 << iota structType ) @@ -922,7 +922,7 @@ const maxStmtNewlines = 2 // maximum number of newlines between statements // Print the statement list indented, but without a newline after the last statement. // Extra line breaks between statements in the source are respected but at most one // empty line is printed between statements. -func (p *printer) stmtList(list []ast.Stmt, _indent int) { +func (p *printer) stmtList(list []ast.Stmt, _indent int, nextIsRBrace bool) { // TODO(gri): fix _indent code if _indent > 0 { p.print(indent) @@ -933,7 +933,7 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int) { // in those cases each clause is a new section p.linebreak(s.Pos().Line, 1, maxStmtNewlines, ignore, i == 0 || _indent == 0 || multiLine) multiLine = false - p.stmt(s, &multiLine) + p.stmt(s, nextIsRBrace && i == len(list)-1, &multiLine) } if _indent > 0 { p.print(unindent) @@ -944,7 +944,7 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int) { // block prints an *ast.BlockStmt; it always spans at least two lines. func (p *printer) block(s *ast.BlockStmt, indent int) { p.print(s.Pos(), token.LBRACE) - p.stmtList(s.List, indent) + p.stmtList(s.List, indent, true) p.linebreak(s.Rbrace.Line, 1, maxStmtNewlines, ignore, true) p.print(s.Rbrace, token.RBRACE) } @@ -990,7 +990,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po // all semicolons required // (they are not separators, print them explicitly) if init != nil { - p.stmt(init, ignoreMultiLine) + p.stmt(init, false, ignoreMultiLine) } p.print(token.SEMICOLON, blank) if expr != nil { @@ -1001,7 +1001,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po p.print(token.SEMICOLON, blank) needsBlank = false if post != nil { - p.stmt(post, ignoreMultiLine) + p.stmt(post, false, ignoreMultiLine) needsBlank = true } } @@ -1013,7 +1013,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po // Sets multiLine to true if the statements spans multiple lines. -func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) { +func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) { p.print(stmt.Pos()) switch s := stmt.(type) { @@ -1033,8 +1033,12 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) { p.print(unindent) p.expr(s.Label, multiLine) p.print(token.COLON, vtab, indent) + if _, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty && !nextIsRBrace { + p.print(token.SEMICOLON) + break + } p.linebreak(s.Stmt.Pos().Line, 0, 1, ignore, true) - p.stmt(s.Stmt, multiLine) + p.stmt(s.Stmt, nextIsRBrace, multiLine) case *ast.ExprStmt: const depth = 1 @@ -1088,10 +1092,10 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) { p.print(blank, token.ELSE, blank) switch s.Else.(type) { case *ast.BlockStmt, *ast.IfStmt: - p.stmt(s.Else, ignoreMultiLine) + p.stmt(s.Else, nextIsRBrace, ignoreMultiLine) default: p.print(token.LBRACE, indent, formfeed) - p.stmt(s.Else, ignoreMultiLine) + p.stmt(s.Else, true, ignoreMultiLine) p.print(unindent, formfeed, token.RBRACE) } } @@ -1104,7 +1108,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) { p.print(token.DEFAULT) } p.print(s.Colon, token.COLON) - p.stmtList(s.Body, 1) + p.stmtList(s.Body, 1, nextIsRBrace) case *ast.SwitchStmt: p.print(token.SWITCH) @@ -1120,17 +1124,17 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) { p.print(token.DEFAULT) } p.print(s.Colon, token.COLON) - p.stmtList(s.Body, 1) + p.stmtList(s.Body, 1, nextIsRBrace) case *ast.TypeSwitchStmt: p.print(token.SWITCH) if s.Init != nil { p.print(blank) - p.stmt(s.Init, ignoreMultiLine) + p.stmt(s.Init, false, ignoreMultiLine) p.print(token.SEMICOLON) } p.print(blank) - p.stmt(s.Assign, ignoreMultiLine) + p.stmt(s.Assign, false, ignoreMultiLine) p.print(blank) p.block(s.Body, 0) *multiLine = true @@ -1147,7 +1151,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) { p.print(token.DEFAULT) } p.print(s.Colon, token.COLON) - p.stmtList(s.Body, 1) + p.stmtList(s.Body, 1, nextIsRBrace) case *ast.SelectStmt: p.print(token.SELECT, blank) @@ -1359,7 +1363,7 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi if i > 0 { p.print(token.SEMICOLON, blank) } - p.stmt(s, ignoreMultiLine) + p.stmt(s, i == len(b.List)-1, ignoreMultiLine) } p.print(blank) } diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go index 745ecd4cc..8e59089a6 100644 --- a/src/pkg/go/printer/printer.go +++ b/src/pkg/go/printer/printer.go @@ -767,6 +767,7 @@ func (p *printer) print(args ...interface{}) { } else { data = []byte(x.Name()) } + tok = token.IDENT case *ast.BasicLit: if p.Styler != nil { data, tag = p.Styler.BasicLit(x) @@ -778,6 +779,7 @@ func (p *printer) print(args ...interface{}) { // bytes since they do not appear in legal UTF-8 sequences) // TODO(gri): do this more efficiently. data = []byte("\xff" + string(data) + "\xff") + tok = token.INT // representing all literal tokens case token.Token: if p.Styler != nil { data, tag = p.Styler.Token(x) @@ -1011,7 +1013,7 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) { if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt { p.indent = 1 } - p.stmt(n, ignoreMultiLine) + p.stmt(n, false, ignoreMultiLine) case ast.Decl: p.useNodeComments = true p.decl(n, atTop, ignoreMultiLine) diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden index f3dc8fe74..eec4ae08d 100644 --- a/src/pkg/go/printer/testdata/statements.golden +++ b/src/pkg/go/printer/testdata/statements.golden @@ -253,6 +253,24 @@ L: func _() { // this comment should be indented +L: // no semicolon needed +} + + +func _() { + switch 0 { + case 0: + L0: ; // semicolon required + case 1: + L1: ; // semicolon required + default: + L2: // no semicolon needed + } +} + + +func _() { + // this comment should be indented L: } diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input index a92911a36..42d6a8780 100644 --- a/src/pkg/go/printer/testdata/statements.input +++ b/src/pkg/go/printer/testdata/statements.input @@ -189,6 +189,24 @@ func _() { func _() { // this comment should be indented + L: ; // no semicolon needed +} + + +func _() { + switch 0 { + case 0: + L0: ; // semicolon required + case 1: + L1: ; // semicolon required + default: + L2: ; // no semicolon needed + } +} + + +func _() { + // this comment should be indented L: } |