Commit 6474eda4 authored by Robert Griesemer's avatar Robert Griesemer

go/printer: simpler exprList code, more tests

Except for the tests, this is mostly deleting code:

- removed several exprListModes:
  blankStart: easily done explicitly, and trailing blanks
    are cleaned up by the trimmer post-pass
  blankEnd: never used
  commaSep: all exprLists calls had this set

- added test cases for multi-line returns
(for a later fix of issue 1207)

- no formatting changes

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5672062
parent de7361bf
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"bytes" "bytes"
"go/ast" "go/ast"
"go/token" "go/token"
"unicode/utf8"
) )
// Other formatting issues: // Other formatting issues:
...@@ -82,11 +83,8 @@ func (p *printer) setComment(g *ast.CommentGroup) { ...@@ -82,11 +83,8 @@ func (p *printer) setComment(g *ast.CommentGroup) {
type exprListMode uint type exprListMode uint
const ( const (
blankStart exprListMode = 1 << iota // print a blank before a non-empty list commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma
blankEnd // print a blank after a non-empty list noIndent // no extra indentation in multi-line lists
commaSep // elements are separated by commas
commaTerm // list is optionally terminated by a comma
noIndent // no extra indentation in multi-line lists
) )
// If indent is set, a multi-line identifier list is indented after the // If indent is set, a multi-line identifier list is indented after the
...@@ -97,9 +95,9 @@ func (p *printer) identList(list []*ast.Ident, indent bool) { ...@@ -97,9 +95,9 @@ func (p *printer) identList(list []*ast.Ident, indent bool) {
for i, x := range list { for i, x := range list {
xlist[i] = x xlist[i] = x
} }
mode := commaSep var mode exprListMode
if !indent { if !indent {
mode |= noIndent mode = noIndent
} }
p.exprList(token.NoPos, xlist, 1, mode, token.NoPos) p.exprList(token.NoPos, xlist, 1, mode, token.NoPos)
} }
...@@ -116,10 +114,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp ...@@ -116,10 +114,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
return return
} }
if mode&blankStart != 0 {
p.print(blank)
}
prev := p.posFor(prev0) prev := p.posFor(prev0)
next := p.posFor(next0) next := p.posFor(next0)
line := p.lineFor(list[0].Pos()) line := p.lineFor(list[0].Pos())
...@@ -129,18 +123,12 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp ...@@ -129,18 +123,12 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
// all list entries on a single line // all list entries on a single line
for i, x := range list { for i, x := range list {
if i > 0 { if i > 0 {
if mode&commaSep != 0 { // use position of expression following the comma as
// use position of expression following the comma as // comma position for correct comment placement
// comma position for correct comment placement p.print(x.Pos(), token.COMMA, blank)
p.print(x.Pos(), token.COMMA)
}
p.print(blank)
} }
p.expr0(x, depth) p.expr0(x, depth)
} }
if mode&blankEnd != 0 {
p.print(blank)
}
return return
} }
...@@ -212,15 +200,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp ...@@ -212,15 +200,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
if i > 0 { if i > 0 {
needsLinebreak := prevLine < line && prevLine > 0 && line > 0 needsLinebreak := prevLine < line && prevLine > 0 && line > 0
if mode&commaSep != 0 { // use position of expression following the comma as
// use position of expression following the comma as // comma position for correct comment placement, but
// comma position for correct comment placement, but // only if the expression is on the same line
// only if the expression is on the same line if !needsLinebreak {
if !needsLinebreak { p.print(x.Pos())
p.print(x.Pos())
}
p.print(token.COMMA)
} }
p.print(token.COMMA)
needsBlank := true needsBlank := true
if needsLinebreak { if needsLinebreak {
// lines are broken using newlines so comments remain aligned // lines are broken using newlines so comments remain aligned
...@@ -260,10 +246,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp ...@@ -260,10 +246,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
return return
} }
if mode&blankEnd != 0 {
p.print(blank)
}
if ws == ignore && mode&noIndent == 0 { if ws == ignore && mode&noIndent == 0 {
// unindent if we indented // unindent if we indented
p.print(unindent) p.print(unindent)
...@@ -350,9 +332,9 @@ func (p *printer) signature(params, result *ast.FieldList) { ...@@ -350,9 +332,9 @@ func (p *printer) signature(params, result *ast.FieldList) {
func identListSize(list []*ast.Ident, maxSize int) (size int) { func identListSize(list []*ast.Ident, maxSize int) (size int) {
for i, x := range list { for i, x := range list {
if i > 0 { if i > 0 {
size += 2 // ", " size += len(", ")
} }
size += len(x.Name) size += utf8.RuneCountInString(x.Name)
if size >= maxSize { if size >= maxSize {
break break
} }
...@@ -798,13 +780,13 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { ...@@ -798,13 +780,13 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
p.expr1(x.Fun, token.HighestPrec, depth) p.expr1(x.Fun, token.HighestPrec, depth)
p.print(x.Lparen, token.LPAREN) p.print(x.Lparen, token.LPAREN)
if x.Ellipsis.IsValid() { if x.Ellipsis.IsValid() {
p.exprList(x.Lparen, x.Args, depth, commaSep, x.Ellipsis) p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis)
p.print(x.Ellipsis, token.ELLIPSIS) p.print(x.Ellipsis, token.ELLIPSIS)
if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) { if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) {
p.print(token.COMMA, formfeed) p.print(token.COMMA, formfeed)
} }
} else { } else {
p.exprList(x.Lparen, x.Args, depth, commaSep|commaTerm, x.Rparen) p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen)
} }
p.print(x.Rparen, token.RPAREN) p.print(x.Rparen, token.RPAREN)
...@@ -814,7 +796,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { ...@@ -814,7 +796,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
p.expr1(x.Type, token.HighestPrec, depth) p.expr1(x.Type, token.HighestPrec, depth)
} }
p.print(x.Lbrace, token.LBRACE) p.print(x.Lbrace, token.LBRACE)
p.exprList(x.Lbrace, x.Elts, 1, commaSep|commaTerm, x.Rbrace) p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace)
// do not insert extra line breaks because of comments before // do not insert extra line breaks because of comments before
// the closing '}' as it might break the code if there is no // the closing '}' as it might break the code if there is no
// trailing ',' // trailing ','
...@@ -1032,9 +1014,9 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) { ...@@ -1032,9 +1014,9 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
if len(s.Lhs) > 1 && len(s.Rhs) > 1 { if len(s.Lhs) > 1 && len(s.Rhs) > 1 {
depth++ depth++
} }
p.exprList(s.Pos(), s.Lhs, depth, commaSep, s.TokPos) p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos)
p.print(blank, s.TokPos, s.Tok) p.print(blank, s.TokPos, s.Tok, blank)
p.exprList(s.TokPos, s.Rhs, depth, blankStart|commaSep, token.NoPos) p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos)
case *ast.GoStmt: case *ast.GoStmt:
p.print(token.GO, blank) p.print(token.GO, blank)
...@@ -1047,7 +1029,8 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) { ...@@ -1047,7 +1029,8 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
case *ast.ReturnStmt: case *ast.ReturnStmt:
p.print(token.RETURN) p.print(token.RETURN)
if s.Results != nil { if s.Results != nil {
p.exprList(s.Pos(), s.Results, 1, blankStart|commaSep, token.NoPos) p.print(blank)
p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
} }
case *ast.BranchStmt: case *ast.BranchStmt:
...@@ -1078,8 +1061,8 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) { ...@@ -1078,8 +1061,8 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
case *ast.CaseClause: case *ast.CaseClause:
if s.List != nil { if s.List != nil {
p.print(token.CASE) p.print(token.CASE, blank)
p.exprList(s.Pos(), s.List, 1, blankStart|commaSep, s.Colon) p.exprList(s.Pos(), s.List, 1, 0, s.Colon)
} else { } else {
p.print(token.DEFAULT) p.print(token.DEFAULT)
} }
...@@ -1229,8 +1212,8 @@ func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool) { ...@@ -1229,8 +1212,8 @@ func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool) {
p.expr(s.Type) p.expr(s.Type)
} }
if s.Values != nil { if s.Values != nil {
p.print(vtab, token.ASSIGN) p.print(vtab, token.ASSIGN, blank)
p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, token.NoPos) p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
extraTabs-- extraTabs--
} }
if s.Comment != nil { if s.Comment != nil {
...@@ -1268,8 +1251,8 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) { ...@@ -1268,8 +1251,8 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
p.expr(s.Type) p.expr(s.Type)
} }
if s.Values != nil { if s.Values != nil {
p.print(blank, token.ASSIGN) p.print(blank, token.ASSIGN, blank)
p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, token.NoPos) p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
} }
p.setComment(s.Comment) p.setComment(s.Comment)
......
...@@ -8,6 +8,82 @@ var expr bool ...@@ -8,6 +8,82 @@ var expr bool
func use(x interface{}) {} func use(x interface{}) {}
// Formatting of multi-line return statements.
func _f() {
return
return x, y, z
return T{}
return T{1, 2, 3},
x, y, z
return T{1, 2, 3},
x, y,
z
return T{1,
2,
3}
return T{1,
2,
3,
}
return T{
1,
2,
3}
return T{
1,
2,
3,
}
return T{
1,
T{1, 2, 3},
3,
}
return T{
1,
T{1,
2, 3},
3,
}
return T{
1,
T{1,
2,
3},
3,
}
return T{
1,
2,
},
nil
return T{
1,
2,
},
T{
x: 3,
y: 4,
},
nil
return x + y +
z
return func() {}
return func() {
_ = 0
}, T{
1, 2,
}
return func() {
_ = 0
}
return func() T {
return T{
1, 2,
}
}
}
// Formatting of if-statement headers. // Formatting of if-statement headers.
func _() { func _() {
if true { if true {
......
...@@ -8,6 +8,82 @@ var expr bool ...@@ -8,6 +8,82 @@ var expr bool
func use(x interface{}) {} func use(x interface{}) {}
// Formatting of multi-line return statements.
func _f() {
return
return x, y, z
return T{}
return T{1, 2, 3},
x, y, z
return T{1, 2, 3},
x, y,
z
return T{1,
2,
3}
return T{1,
2,
3,
}
return T{
1,
2,
3}
return T{
1,
2,
3,
}
return T{
1,
T{1, 2, 3},
3,
}
return T{
1,
T{1,
2, 3},
3,
}
return T{
1,
T{1,
2,
3},
3,
}
return T{
1,
2,
},
nil
return T{
1,
2,
},
T{
x: 3,
y: 4,
},
nil
return x + y +
z
return func() {}
return func() {
_ = 0
}, T{
1, 2,
}
return func() {
_ = 0
}
return func() T {
return T {
1, 2,
}
}
}
// Formatting of if-statement headers. // Formatting of if-statement headers.
func _() { func _() {
if true {} if true {}
......
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