summaryrefslogtreecommitdiff
path: root/libgo/go/go/printer
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-03-06 17:57:23 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-03-06 17:57:23 +0000
commit593f74bbab63d34c7060918088bcbad686c31c66 (patch)
tree4ce83ca433796a728e9fdd00af105bce158532b5 /libgo/go/go/printer
parent46402cbe0ba3ea92be9642cf18eedaefe57a414c (diff)
libgo: Update to weekly.2012-03-04 release.
From-SVN: r185010
Diffstat (limited to 'libgo/go/go/printer')
-rw-r--r--libgo/go/go/printer/nodes.go361
-rw-r--r--libgo/go/go/printer/printer.go75
-rw-r--r--libgo/go/go/printer/printer_test.go5
-rw-r--r--libgo/go/go/printer/testdata/comments.golden85
-rw-r--r--libgo/go/go/printer/testdata/comments.input85
-rw-r--r--libgo/go/go/printer/testdata/declarations.golden10
-rw-r--r--libgo/go/go/printer/testdata/declarations.input6
-rw-r--r--libgo/go/go/printer/testdata/expressions.golden22
-rw-r--r--libgo/go/go/printer/testdata/expressions.input22
-rw-r--r--libgo/go/go/printer/testdata/expressions.raw22
-rw-r--r--libgo/go/go/printer/testdata/parser.go2
-rw-r--r--libgo/go/go/printer/testdata/statements.golden76
-rw-r--r--libgo/go/go/printer/testdata/statements.input76
13 files changed, 598 insertions, 249 deletions
diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go
index cd5e075c16c..05b4ef59a2d 100644
--- a/libgo/go/go/printer/nodes.go
+++ b/libgo/go/go/printer/nodes.go
@@ -12,6 +12,7 @@ import (
"bytes"
"go/ast"
"go/token"
+ "unicode/utf8"
)
// Other formatting issues:
@@ -82,46 +83,37 @@ func (p *printer) setComment(g *ast.CommentGroup) {
type exprListMode uint
const (
- blankStart exprListMode = 1 << iota // print a blank before a non-empty list
- blankEnd // print a blank after a non-empty list
- commaSep // elements are separated by commas
- commaTerm // list is optionally terminated by a comma
- noIndent // no extra indentation in multi-line lists
+ commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma
+ noIndent // no extra indentation in multi-line lists
)
-// Sets multiLine to true if the identifier list spans multiple lines.
// If indent is set, a multi-line identifier list is indented after the
// first linebreak encountered.
-func (p *printer) identList(list []*ast.Ident, indent bool, multiLine *bool) {
+func (p *printer) identList(list []*ast.Ident, indent bool) {
// convert into an expression list so we can re-use exprList formatting
xlist := make([]ast.Expr, len(list))
for i, x := range list {
xlist[i] = x
}
- mode := commaSep
+ var mode exprListMode
if !indent {
- mode |= noIndent
+ mode = noIndent
}
- p.exprList(token.NoPos, xlist, 1, mode, multiLine, token.NoPos)
+ p.exprList(token.NoPos, xlist, 1, mode, token.NoPos)
}
// Print a list of expressions. If the list spans multiple
// source lines, the original line breaks are respected between
-// expressions. Sets multiLine to true if the list spans multiple
-// lines.
+// expressions.
//
// TODO(gri) Consider rewriting this to be independent of []ast.Expr
// so that we can use the algorithm for any kind of list
// (e.g., pass list via a channel over which to range).
-func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, multiLine *bool, next0 token.Pos) {
+func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, next0 token.Pos) {
if len(list) == 0 {
return
}
- if mode&blankStart != 0 {
- p.print(blank)
- }
-
prev := p.posFor(prev0)
next := p.posFor(next0)
line := p.lineFor(list[0].Pos())
@@ -131,17 +123,11 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
// all list entries on a single line
for i, x := range list {
if i > 0 {
- if mode&commaSep != 0 {
- // use position of expression following the comma as
- // comma position for correct comment placement
- p.print(x.Pos(), token.COMMA)
- }
- p.print(blank)
+ // use position of expression following the comma as
+ // comma position for correct comment placement
+ p.print(x.Pos(), token.COMMA, blank)
}
- p.expr0(x, depth, multiLine)
- }
- if mode&blankEnd != 0 {
- p.print(blank)
+ p.expr0(x, depth)
}
return
}
@@ -161,7 +147,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
prevBreak := -1 // index of last expression that was followed by a linebreak
if prev.IsValid() && prev.Line < line && p.linebreak(line, 0, ws, true) {
ws = ignore
- *multiLine = true
prevBreak = 0
}
@@ -215,15 +200,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
if i > 0 {
needsLinebreak := prevLine < line && prevLine > 0 && line > 0
- if mode&commaSep != 0 {
- // use position of expression following the comma as
- // comma position for correct comment placement, but
- // only if the expression is on the same line
- if !needsLinebreak {
- p.print(x.Pos())
- }
- p.print(token.COMMA)
+ // use position of expression following the comma as
+ // comma position for correct comment placement, but
+ // only if the expression is on the same line
+ if !needsLinebreak {
+ p.print(x.Pos())
}
+ p.print(token.COMMA)
needsBlank := true
if needsLinebreak {
// lines are broken using newlines so comments remain aligned
@@ -231,7 +214,6 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
// the same line in which case formfeed is used
if p.linebreak(line, 0, ws, useFF || prevBreak+1 < i) {
ws = ignore
- *multiLine = true
prevBreak = i
needsBlank = false // we got a line break instead
}
@@ -245,11 +227,11 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
// we have a key:value expression that fits onto one line and
// is in a list with more then one entry: use a column for the
// key such that consecutive entries can align if possible
- p.expr(pair.Key, multiLine)
+ p.expr(pair.Key)
p.print(pair.Colon, token.COLON, vtab)
- p.expr(pair.Value, multiLine)
+ p.expr(pair.Value)
} else {
- p.expr0(x, depth, multiLine)
+ p.expr0(x, depth)
}
}
@@ -264,18 +246,13 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
return
}
- if mode&blankEnd != 0 {
- p.print(blank)
- }
-
if ws == ignore && mode&noIndent == 0 {
// unindent if we indented
p.print(unindent)
}
}
-// Sets multiLine to true if the the parameter list spans multiple lines.
-func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
+func (p *printer) parameters(fields *ast.FieldList) {
p.print(fields.Opening, token.LPAREN)
if len(fields.List) > 0 {
prevLine := p.lineFor(fields.Opening)
@@ -306,7 +283,6 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) {
// break line if the opening "(" or previous parameter ended on a different line
ws = ignore
- *multiLine = true
} else if i > 0 {
p.print(blank)
}
@@ -318,11 +294,11 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
// again at the end (and still ws == indent). Thus, a subsequent indent
// by a linebreak call after a type, or in the next multi-line identList
// will do the right thing.
- p.identList(par.Names, ws == indent, multiLine)
+ p.identList(par.Names, ws == indent)
p.print(blank)
}
// parameter type
- p.expr(par.Type, multiLine)
+ p.expr(par.Type)
prevLine = parLineEnd
}
// if the closing ")" is on a separate line from the last parameter,
@@ -339,27 +315,26 @@ func (p *printer) parameters(fields *ast.FieldList, multiLine *bool) {
p.print(fields.Closing, token.RPAREN)
}
-// Sets multiLine to true if the signature spans multiple lines.
-func (p *printer) signature(params, result *ast.FieldList, multiLine *bool) {
- p.parameters(params, multiLine)
+func (p *printer) signature(params, result *ast.FieldList) {
+ p.parameters(params)
n := result.NumFields()
if n > 0 {
p.print(blank)
if n == 1 && result.List[0].Names == nil {
// single anonymous result; no ()'s
- p.expr(result.List[0].Type, multiLine)
+ p.expr(result.List[0].Type)
return
}
- p.parameters(result, multiLine)
+ p.parameters(result)
}
}
func identListSize(list []*ast.Ident, maxSize int) (size int) {
for i, x := range list {
if i > 0 {
- size += 2 // ", "
+ size += len(", ")
}
- size += len(x.Name)
+ size += utf8.RuneCountInString(x.Name)
if size >= maxSize {
break
}
@@ -389,6 +364,10 @@ func (p *printer) setLineComment(text string) {
p.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: text}}})
}
+func (p *printer) isMultiLine(n ast.Node) bool {
+ return p.lineFor(n.End())-p.lineFor(n.Pos()) > 1
+}
+
func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
lbrace := fields.Opening
list := fields.List
@@ -412,12 +391,12 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
// no comments so no need for comma position
p.print(token.COMMA, blank)
}
- p.expr(x, ignoreMultiLine)
+ p.expr(x)
}
if len(f.Names) > 0 {
p.print(blank)
}
- p.expr(f.Type, ignoreMultiLine)
+ p.expr(f.Type)
p.print(blank, rbrace, token.RBRACE)
return
}
@@ -435,23 +414,22 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
if len(list) == 1 {
sep = blank
}
- var ml bool
+ newSection := false
for i, f := range list {
if i > 0 {
- p.linebreak(p.lineFor(f.Pos()), 1, ignore, ml)
+ p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection)
}
- ml = false
extraTabs := 0
p.setComment(f.Doc)
if len(f.Names) > 0 {
// named fields
- p.identList(f.Names, false, &ml)
+ p.identList(f.Names, false)
p.print(sep)
- p.expr(f.Type, &ml)
+ p.expr(f.Type)
extraTabs = 1
} else {
// anonymous field
- p.expr(f.Type, &ml)
+ p.expr(f.Type)
extraTabs = 2
}
if f.Tag != nil {
@@ -459,7 +437,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
p.print(sep)
}
p.print(sep)
- p.expr(f.Tag, &ml)
+ p.expr(f.Tag)
extraTabs = 0
}
if f.Comment != nil {
@@ -468,6 +446,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
}
p.setComment(f.Comment)
}
+ newSection = p.isMultiLine(f)
}
if isIncomplete {
if len(list) > 0 {
@@ -479,22 +458,22 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
} else { // interface
- var ml bool
+ newSection := false
for i, f := range list {
if i > 0 {
- p.linebreak(p.lineFor(f.Pos()), 1, ignore, ml)
+ p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection)
}
- ml = false
p.setComment(f.Doc)
if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
// method
- p.expr(f.Names[0], &ml)
- p.signature(ftyp.Params, ftyp.Results, &ml)
+ p.expr(f.Names[0])
+ p.signature(ftyp.Params, ftyp.Results)
} else {
// embedded interface
- p.expr(f.Type, &ml)
+ p.expr(f.Type)
}
p.setComment(f.Comment)
+ newSection = p.isMultiLine(f)
}
if isIncomplete {
if len(list) > 0 {
@@ -635,15 +614,14 @@ func reduceDepth(depth int) int {
// cutoff is 6 (always use spaces) in Normal mode
// and 4 (never use spaces) in Compact mode.
//
-// Sets multiLine to true if the binary expression spans multiple lines.
-func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiLine *bool) {
+func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) {
prec := x.Op.Precedence()
if prec < prec1 {
// parenthesis needed
// Note: The parser inserts an ast.ParenExpr node; thus this case
// can only occur if the AST is created in a different way.
p.print(token.LPAREN)
- p.expr0(x, reduceDepth(depth), multiLine) // parentheses undo one level of depth
+ p.expr0(x, reduceDepth(depth)) // parentheses undo one level of depth
p.print(token.RPAREN)
return
}
@@ -651,7 +629,7 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL
printBlank := prec < cutoff
ws := indent
- p.expr1(x.X, prec, depth+diffPrec(x.X, prec), multiLine)
+ p.expr1(x.X, prec, depth+diffPrec(x.X, prec))
if printBlank {
p.print(blank)
}
@@ -663,14 +641,13 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL
// in the source
if p.linebreak(yline, 1, ws, true) {
ws = ignore
- *multiLine = true
printBlank = false // no blank after line break
}
}
if printBlank {
p.print(blank)
}
- p.expr1(x.Y, prec+1, depth+1, multiLine)
+ p.expr1(x.Y, prec+1, depth+1)
if ws == ignore {
p.print(unindent)
}
@@ -681,8 +658,7 @@ func isBinary(expr ast.Expr) bool {
return ok
}
-// Sets multiLine to true if the expression spans multiple lines.
-func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
+func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
p.print(expr.Pos())
switch x := expr.(type) {
@@ -697,12 +673,12 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
p.internalError("depth < 1:", depth)
depth = 1
}
- p.binaryExpr(x, prec1, cutoff(x, depth), depth, multiLine)
+ p.binaryExpr(x, prec1, cutoff(x, depth), depth)
case *ast.KeyValueExpr:
- p.expr(x.Key, multiLine)
+ p.expr(x.Key)
p.print(x.Colon, token.COLON, blank)
- p.expr(x.Value, multiLine)
+ p.expr(x.Value)
case *ast.StarExpr:
const prec = token.UnaryPrec
@@ -710,12 +686,12 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
// parenthesis needed
p.print(token.LPAREN)
p.print(token.MUL)
- p.expr(x.X, multiLine)
+ p.expr(x.X)
p.print(token.RPAREN)
} else {
// no parenthesis needed
p.print(token.MUL)
- p.expr(x.X, multiLine)
+ p.expr(x.X)
}
case *ast.UnaryExpr:
@@ -723,7 +699,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
if prec < prec1 {
// parenthesis needed
p.print(token.LPAREN)
- p.expr(x, multiLine)
+ p.expr(x)
p.print(token.RPAREN)
} else {
// no parenthesis needed
@@ -732,42 +708,41 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
// TODO(gri) Remove this code if it cannot be reached.
p.print(blank)
}
- p.expr1(x.X, prec, depth, multiLine)
+ p.expr1(x.X, prec, depth)
}
case *ast.BasicLit:
p.print(x)
case *ast.FuncLit:
- p.expr(x.Type, multiLine)
- p.funcBody(x.Body, p.distance(x.Type.Pos(), p.pos), true, multiLine)
+ p.expr(x.Type)
+ p.funcBody(x.Body, p.distance(x.Type.Pos(), p.pos), true)
case *ast.ParenExpr:
if _, hasParens := x.X.(*ast.ParenExpr); hasParens {
// don't print parentheses around an already parenthesized expression
// TODO(gri) consider making this more general and incorporate precedence levels
- p.expr0(x.X, reduceDepth(depth), multiLine) // parentheses undo one level of depth
+ p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
} else {
p.print(token.LPAREN)
- p.expr0(x.X, reduceDepth(depth), multiLine) // parentheses undo one level of depth
+ p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
p.print(x.Rparen, token.RPAREN)
}
case *ast.SelectorExpr:
- p.expr1(x.X, token.HighestPrec, depth, multiLine)
+ p.expr1(x.X, token.HighestPrec, depth)
p.print(token.PERIOD)
if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
p.print(indent, newline, x.Sel.Pos(), x.Sel, unindent)
- *multiLine = true
} else {
p.print(x.Sel.Pos(), x.Sel)
}
case *ast.TypeAssertExpr:
- p.expr1(x.X, token.HighestPrec, depth, multiLine)
+ p.expr1(x.X, token.HighestPrec, depth)
p.print(token.PERIOD, token.LPAREN)
if x.Type != nil {
- p.expr(x.Type, multiLine)
+ p.expr(x.Type)
} else {
p.print(token.TYPE)
}
@@ -775,17 +750,17 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
case *ast.IndexExpr:
// TODO(gri): should treat[] like parentheses and undo one level of depth
- p.expr1(x.X, token.HighestPrec, 1, multiLine)
+ p.expr1(x.X, token.HighestPrec, 1)
p.print(x.Lbrack, token.LBRACK)
- p.expr0(x.Index, depth+1, multiLine)
+ p.expr0(x.Index, depth+1)
p.print(x.Rbrack, token.RBRACK)
case *ast.SliceExpr:
// TODO(gri): should treat[] like parentheses and undo one level of depth
- p.expr1(x.X, token.HighestPrec, 1, multiLine)
+ p.expr1(x.X, token.HighestPrec, 1)
p.print(x.Lbrack, token.LBRACK)
if x.Low != nil {
- p.expr0(x.Low, depth+1, multiLine)
+ p.expr0(x.Low, depth+1)
}
// blanks around ":" if both sides exist and either side is a binary expression
if depth <= 1 && x.Low != nil && x.High != nil && (isBinary(x.Low) || isBinary(x.High)) {
@@ -794,7 +769,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
p.print(token.COLON)
}
if x.High != nil {
- p.expr0(x.High, depth+1, multiLine)
+ p.expr0(x.High, depth+1)
}
p.print(x.Rbrack, token.RBRACK)
@@ -802,21 +777,26 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
if len(x.Args) > 1 {
depth++
}
- p.expr1(x.Fun, token.HighestPrec, depth, multiLine)
+ p.expr1(x.Fun, token.HighestPrec, depth)
p.print(x.Lparen, token.LPAREN)
- p.exprList(x.Lparen, x.Args, depth, commaSep|commaTerm, multiLine, x.Rparen)
if x.Ellipsis.IsValid() {
+ p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis)
p.print(x.Ellipsis, token.ELLIPSIS)
+ if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) {
+ p.print(token.COMMA, formfeed)
+ }
+ } else {
+ p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen)
}
p.print(x.Rparen, token.RPAREN)
case *ast.CompositeLit:
// composite literal elements that are composite literals themselves may have the type omitted
if x.Type != nil {
- p.expr1(x.Type, token.HighestPrec, depth, multiLine)
+ p.expr1(x.Type, token.HighestPrec, depth)
}
p.print(x.Lbrace, token.LBRACE)
- p.exprList(x.Lbrace, x.Elts, 1, commaSep|commaTerm, multiLine, x.Rbrace)
+ p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace)
// do not insert extra line breaks because of comments before
// the closing '}' as it might break the code if there is no
// trailing ','
@@ -825,16 +805,16 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
case *ast.Ellipsis:
p.print(token.ELLIPSIS)
if x.Elt != nil {
- p.expr(x.Elt, multiLine)
+ p.expr(x.Elt)
}
case *ast.ArrayType:
p.print(token.LBRACK)
if x.Len != nil {
- p.expr(x.Len, multiLine)
+ p.expr(x.Len)
}
p.print(token.RBRACK)
- p.expr(x.Elt, multiLine)
+ p.expr(x.Elt)
case *ast.StructType:
p.print(token.STRUCT)
@@ -842,7 +822,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
case *ast.FuncType:
p.print(token.FUNC)
- p.signature(x.Params, x.Results, multiLine)
+ p.signature(x.Params, x.Results)
case *ast.InterfaceType:
p.print(token.INTERFACE)
@@ -850,9 +830,9 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
case *ast.MapType:
p.print(token.MAP, token.LBRACK)
- p.expr(x.Key, multiLine)
+ p.expr(x.Key)
p.print(token.RBRACK)
- p.expr(x.Value, multiLine)
+ p.expr(x.Value)
case *ast.ChanType:
switch x.Dir {
@@ -864,7 +844,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
p.print(token.CHAN, token.ARROW)
}
p.print(blank)
- p.expr(x.Value, multiLine)
+ p.expr(x.Value)
default:
panic("unreachable")
@@ -873,14 +853,13 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, multiLine *bool) {
return
}
-func (p *printer) expr0(x ast.Expr, depth int, multiLine *bool) {
- p.expr1(x, token.LowestPrec, depth, multiLine)
+func (p *printer) expr0(x ast.Expr, depth int) {
+ p.expr1(x, token.LowestPrec, depth)
}
-// Sets multiLine to true if the expression spans multiple lines.
-func (p *printer) expr(x ast.Expr, multiLine *bool) {
+func (p *printer) expr(x ast.Expr) {
const depth = 1
- p.expr1(x, token.LowestPrec, depth, multiLine)
+ p.expr1(x, token.LowestPrec, depth)
}
// ----------------------------------------------------------------------------
@@ -894,13 +873,13 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int, nextIsRBrace bool) {
if _indent > 0 {
p.print(indent)
}
- var multiLine bool
+ multiLine := false
for i, s := range list {
// _indent == 0 only for lists of switch/select case clauses;
// in those cases each clause is a new section
p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || _indent == 0 || multiLine)
- multiLine = false
- p.stmt(s, nextIsRBrace && i == len(list)-1, &multiLine)
+ p.stmt(s, nextIsRBrace && i == len(list)-1)
+ multiLine = p.isMultiLine(s)
}
if _indent > 0 {
p.print(unindent)
@@ -957,25 +936,25 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
if init == nil && post == nil {
// no semicolons required
if expr != nil {
- p.expr(stripParens(expr), ignoreMultiLine)
+ p.expr(stripParens(expr))
needsBlank = true
}
} else {
// all semicolons required
// (they are not separators, print them explicitly)
if init != nil {
- p.stmt(init, false, ignoreMultiLine)
+ p.stmt(init, false)
}
p.print(token.SEMICOLON, blank)
if expr != nil {
- p.expr(stripParens(expr), ignoreMultiLine)
+ p.expr(stripParens(expr))
needsBlank = true
}
if isForStmt {
p.print(token.SEMICOLON, blank)
needsBlank = false
if post != nil {
- p.stmt(post, false, ignoreMultiLine)
+ p.stmt(post, false)
needsBlank = true
}
}
@@ -985,8 +964,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, nextIsRBrace bool, multiLine *bool) {
+func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
p.print(stmt.Pos())
switch s := stmt.(type) {
@@ -994,7 +972,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
p.print("BadStmt")
case *ast.DeclStmt:
- p.decl(s.Decl, multiLine)
+ p.decl(s.Decl)
case *ast.EmptyStmt:
// nothing to do
@@ -1004,7 +982,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
// is applied before the line break if there is no comment
// between (see writeWhitespace)
p.print(unindent)
- p.expr(s.Label, multiLine)
+ p.expr(s.Label)
p.print(s.Colon, token.COLON, indent)
if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty {
if !nextIsRBrace {
@@ -1014,21 +992,21 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
} else {
p.linebreak(p.lineFor(s.Stmt.Pos()), 1, ignore, true)
}
- p.stmt(s.Stmt, nextIsRBrace, multiLine)
+ p.stmt(s.Stmt, nextIsRBrace)
case *ast.ExprStmt:
const depth = 1
- p.expr0(s.X, depth, multiLine)
+ p.expr0(s.X, depth)
case *ast.SendStmt:
const depth = 1
- p.expr0(s.Chan, depth, multiLine)
+ p.expr0(s.Chan, depth)
p.print(blank, s.Arrow, token.ARROW, blank)
- p.expr0(s.Value, depth, multiLine)
+ p.expr0(s.Value, depth)
case *ast.IncDecStmt:
const depth = 1
- p.expr0(s.X, depth+1, multiLine)
+ p.expr0(s.X, depth+1)
p.print(s.TokPos, s.Tok)
case *ast.AssignStmt:
@@ -1036,56 +1014,55 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
if len(s.Lhs) > 1 && len(s.Rhs) > 1 {
depth++
}
- p.exprList(s.Pos(), s.Lhs, depth, commaSep, multiLine, s.TokPos)
- p.print(blank, s.TokPos, s.Tok)
- p.exprList(s.TokPos, s.Rhs, depth, blankStart|commaSep, multiLine, token.NoPos)
+ p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos)
+ p.print(blank, s.TokPos, s.Tok, blank)
+ p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos)
case *ast.GoStmt:
p.print(token.GO, blank)
- p.expr(s.Call, multiLine)
+ p.expr(s.Call)
case *ast.DeferStmt:
p.print(token.DEFER, blank)
- p.expr(s.Call, multiLine)
+ p.expr(s.Call)
case *ast.ReturnStmt:
p.print(token.RETURN)
if s.Results != nil {
- p.exprList(s.Pos(), s.Results, 1, blankStart|commaSep, multiLine, token.NoPos)
+ p.print(blank)
+ p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
}
case *ast.BranchStmt:
p.print(s.Tok)
if s.Label != nil {
p.print(blank)
- p.expr(s.Label, multiLine)
+ p.expr(s.Label)
}
case *ast.BlockStmt:
p.block(s, 1)
- *multiLine = true
case *ast.IfStmt:
p.print(token.IF)
p.controlClause(false, s.Init, s.Cond, nil)
p.block(s.Body, 1)
- *multiLine = true
if s.Else != nil {
p.print(blank, token.ELSE, blank)
switch s.Else.(type) {
case *ast.BlockStmt, *ast.IfStmt:
- p.stmt(s.Else, nextIsRBrace, ignoreMultiLine)
+ p.stmt(s.Else, nextIsRBrace)
default:
p.print(token.LBRACE, indent, formfeed)
- p.stmt(s.Else, true, ignoreMultiLine)
+ p.stmt(s.Else, true)
p.print(unindent, formfeed, token.RBRACE)
}
}
case *ast.CaseClause:
if s.List != nil {
- p.print(token.CASE)
- p.exprList(s.Pos(), s.List, 1, blankStart|commaSep, multiLine, s.Colon)
+ p.print(token.CASE, blank)
+ p.exprList(s.Pos(), s.List, 1, 0, s.Colon)
} else {
p.print(token.DEFAULT)
}
@@ -1096,25 +1073,23 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
p.print(token.SWITCH)
p.controlClause(false, s.Init, s.Tag, nil)
p.block(s.Body, 0)
- *multiLine = true
case *ast.TypeSwitchStmt:
p.print(token.SWITCH)
if s.Init != nil {
p.print(blank)
- p.stmt(s.Init, false, ignoreMultiLine)
+ p.stmt(s.Init, false)
p.print(token.SEMICOLON)
}
p.print(blank)
- p.stmt(s.Assign, false, ignoreMultiLine)
+ p.stmt(s.Assign, false)
p.print(blank)
p.block(s.Body, 0)
- *multiLine = true
case *ast.CommClause:
if s.Comm != nil {
p.print(token.CASE, blank)
- p.stmt(s.Comm, false, ignoreMultiLine)
+ p.stmt(s.Comm, false)
} else {
p.print(token.DEFAULT)
}
@@ -1129,29 +1104,26 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE)
} else {
p.block(body, 0)
- *multiLine = true
}
case *ast.ForStmt:
p.print(token.FOR)
p.controlClause(true, s.Init, s.Cond, s.Post)
p.block(s.Body, 1)
- *multiLine = true
case *ast.RangeStmt:
p.print(token.FOR, blank)
- p.expr(s.Key, multiLine)
+ p.expr(s.Key)
if s.Value != nil {
// use position of value following the comma as
// comma position for correct comment placement
p.print(s.Value.Pos(), token.COMMA, blank)
- p.expr(s.Value, multiLine)
+ p.expr(s.Value)
}
p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank)
- p.expr(stripParens(s.X), multiLine)
+ p.expr(stripParens(s.X))
p.print(blank)
p.block(s.Body, 1)
- *multiLine = true
default:
panic("unreachable")
@@ -1228,20 +1200,20 @@ func keepTypeColumn(specs []ast.Spec) []bool {
return m
}
-func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool, multiLine *bool) {
+func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool) {
p.setComment(s.Doc)
- p.identList(s.Names, doIndent, multiLine) // always present
+ p.identList(s.Names, doIndent) // always present
extraTabs := 3
if s.Type != nil || keepType {
p.print(vtab)
extraTabs--
}
if s.Type != nil {
- p.expr(s.Type, multiLine)
+ p.expr(s.Type)
}
if s.Values != nil {
- p.print(vtab, token.ASSIGN)
- p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, multiLine, token.NoPos)
+ p.print(vtab, token.ASSIGN, blank)
+ p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
extraTabs--
}
if s.Comment != nil {
@@ -1255,17 +1227,16 @@ func (p *printer) valueSpec(s *ast.ValueSpec, keepType, doIndent bool, multiLine
// The parameter n is the number of specs in the group. If doIndent is set,
// multi-line identifier lists in the spec are indented when the first
// linebreak is encountered.
-// Sets multiLine to true if the spec spans multiple lines.
//
-func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
+func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
switch s := spec.(type) {
case *ast.ImportSpec:
p.setComment(s.Doc)
if s.Name != nil {
- p.expr(s.Name, multiLine)
+ p.expr(s.Name)
p.print(blank)
}
- p.expr(s.Path, multiLine)
+ p.expr(s.Path)
p.setComment(s.Comment)
p.print(s.EndPos)
@@ -1274,26 +1245,26 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
p.internalError("expected n = 1; got", n)
}
p.setComment(s.Doc)
- p.identList(s.Names, doIndent, multiLine) // always present
+ p.identList(s.Names, doIndent) // always present
if s.Type != nil {
p.print(blank)
- p.expr(s.Type, multiLine)
+ p.expr(s.Type)
}
if s.Values != nil {
- p.print(blank, token.ASSIGN)
- p.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, multiLine, token.NoPos)
+ p.print(blank, token.ASSIGN, blank)
+ p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
}
p.setComment(s.Comment)
case *ast.TypeSpec:
p.setComment(s.Doc)
- p.expr(s.Name, multiLine)
+ p.expr(s.Name)
if n == 1 {
p.print(blank)
} else {
p.print(vtab)
}
- p.expr(s.Type, multiLine)
+ p.expr(s.Type)
p.setComment(s.Comment)
default:
@@ -1301,8 +1272,7 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
}
}
-// Sets multiLine to true if the declaration spans multiple lines.
-func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) {
+func (p *printer) genDecl(d *ast.GenDecl) {
p.setComment(d.Doc)
p.print(d.Pos(), d.Tok, blank)
@@ -1315,32 +1285,31 @@ func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) {
// two or more grouped const/var declarations:
// determine if the type column must be kept
keepType := keepTypeColumn(d.Specs)
- var ml bool
+ newSection := false
for i, s := range d.Specs {
if i > 0 {
- p.linebreak(p.lineFor(s.Pos()), 1, ignore, ml)
+ p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
}
- ml = false
- p.valueSpec(s.(*ast.ValueSpec), keepType[i], false, &ml)
+ p.valueSpec(s.(*ast.ValueSpec), keepType[i], false)
+ newSection = p.isMultiLine(s)
}
} else {
- var ml bool
+ newSection := false
for i, s := range d.Specs {
if i > 0 {
- p.linebreak(p.lineFor(s.Pos()), 1, ignore, ml)
+ p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
}
- ml = false
- p.spec(s, n, false, &ml)
+ p.spec(s, n, false)
+ newSection = p.isMultiLine(s)
}
}
p.print(unindent, formfeed)
- *multiLine = true
}
p.print(d.Rparen, token.RPAREN)
} else {
// single declaration
- p.spec(d.Specs[0], 1, true, multiLine)
+ p.spec(d.Specs[0], 1, true)
}
}
@@ -1404,8 +1373,7 @@ func (p *printer) isOneLineFunc(b *ast.BlockStmt, headerSize int) bool {
return headerSize+bodySize <= maxSize
}
-// Sets multiLine to true if the function body spans multiple lines.
-func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLine *bool) {
+func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool) {
if b == nil {
return
}
@@ -1422,7 +1390,7 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi
if i > 0 {
p.print(token.SEMICOLON, blank)
}
- p.stmt(s, i == len(b.List)-1, ignoreMultiLine)
+ p.stmt(s, i == len(b.List)-1)
}
p.print(blank)
}
@@ -1432,7 +1400,6 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi
p.print(blank)
p.block(b, 1)
- *multiLine = true
}
// distance returns the column difference between from and to if both
@@ -1446,28 +1413,26 @@ func (p *printer) distance(from0 token.Pos, to token.Position) int {
return infinity
}
-// Sets multiLine to true if the declaration spans multiple lines.
-func (p *printer) funcDecl(d *ast.FuncDecl, multiLine *bool) {
+func (p *printer) funcDecl(d *ast.FuncDecl) {
p.setComment(d.Doc)
p.print(d.Pos(), token.FUNC, blank)
if d.Recv != nil {
- p.parameters(d.Recv, multiLine) // method: print receiver
+ p.parameters(d.Recv) // method: print receiver
p.print(blank)
}
- p.expr(d.Name, multiLine)
- p.signature(d.Type.Params, d.Type.Results, multiLine)
- p.funcBody(d.Body, p.distance(d.Pos(), p.pos), false, multiLine)
+ p.expr(d.Name)
+ p.signature(d.Type.Params, d.Type.Results)
+ p.funcBody(d.Body, p.distance(d.Pos(), p.pos), false)
}
-// Sets multiLine to true if the declaration spans multiple lines.
-func (p *printer) decl(decl ast.Decl, multiLine *bool) {
+func (p *printer) decl(decl ast.Decl) {
switch d := decl.(type) {
case *ast.BadDecl:
p.print(d.Pos(), "BadDecl")
case *ast.GenDecl:
- p.genDecl(d, multiLine)
+ p.genDecl(d)
case *ast.FuncDecl:
- p.funcDecl(d, multiLine)
+ p.funcDecl(d)
default:
panic("unreachable")
}
@@ -1490,7 +1455,7 @@ func declToken(decl ast.Decl) (tok token.Token) {
func (p *printer) file(src *ast.File) {
p.setComment(src.Doc)
p.print(src.Pos(), token.PACKAGE, blank)
- p.expr(src.Name, ignoreMultiLine)
+ p.expr(src.Name)
if len(src.Decls) > 0 {
tok := token.ILLEGAL
@@ -1509,7 +1474,7 @@ func (p *printer) file(src *ast.File) {
min = 2
}
p.linebreak(p.lineFor(d.Pos()), min, ignore, false)
- p.decl(d, ignoreMultiLine)
+ p.decl(d)
}
}
diff --git a/libgo/go/go/printer/printer.go b/libgo/go/go/printer/printer.go
index 72f65a1d852..a027d32da89 100644
--- a/libgo/go/go/printer/printer.go
+++ b/libgo/go/go/printer/printer.go
@@ -34,9 +34,6 @@ const (
unindent = whiteSpace('<')
)
-// Use ignoreMultiLine if the multiLine information is not important.
-var ignoreMultiLine = new(bool)
-
// A pmode value represents the current printer mode.
type pmode int
@@ -280,10 +277,9 @@ func (p *printer) writeString(pos token.Position, s string, isLit bool) {
// it as is likely to help position the comment nicely.
// pos is the comment position, next the position of the item
// after all pending comments, prev is the previous comment in
-// a group of comments (or nil), and isKeyword indicates if the
-// next item is a keyword.
+// a group of comments (or nil), and tok is the next token.
//
-func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, isKeyword bool) {
+func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *ast.Comment, tok token.Token) {
if len(p.output) == 0 {
// the comment is the first item to be printed - don't write any whitespace
return
@@ -338,38 +334,41 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, prev, comment *as
// comment on a different line:
// separate with at least one line break
droppedLinebreak := false
- if prev == nil {
- // first comment of a comment group
- j := 0
- for i, ch := range p.wsbuf {
- switch ch {
- case blank, vtab:
- // ignore any horizontal whitespace before line breaks
- p.wsbuf[i] = ignore
+ j := 0
+ for i, ch := range p.wsbuf {
+ switch ch {
+ case blank, vtab:
+ // ignore any horizontal whitespace before line breaks
+ p.wsbuf[i] = ignore
+ continue
+ case indent:
+ // apply pending indentation
+ continue
+ case unindent:
+ // if this is not the last unindent, apply it
+ // as it is (likely) belonging to the last
+ // construct (e.g., a multi-line expression list)
+ // and is not part of closing a block
+ if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent {
continue
- case indent:
- // apply pending indentation
+ }
+ // if the next token is not a closing }, apply the unindent
+ // if it appears that the comment is aligned with the
+ // token; otherwise assume the unindent is part of a
+ // closing block and stop (this scenario appears with
+ // comments before a case label where the comments
+ // apply to the next case instead of the current one)
+ if tok != token.RBRACE && pos.Column == next.Column {
continue
- case unindent:
- // if the next token is a keyword, apply the outdent
- // if it appears that the comment is aligned with the
- // keyword; otherwise assume the outdent is part of a
- // closing block and stop (this scenario appears with
- // comments before a case label where the comments
- // apply to the next case instead of the current one)
- if isKeyword && pos.Column == next.Column {
- continue
- }
- case newline, formfeed:
- // TODO(gri): may want to keep formfeed info in some cases
- p.wsbuf[i] = ignore
- droppedLinebreak = true
}
- j = i
- break
+ case newline, formfeed:
+ p.wsbuf[i] = ignore
+ droppedLinebreak = prev == nil // record only if first comment of a group
}
- p.writeWhitespace(j)
+ j = i
+ break
}
+ p.writeWhitespace(j)
// determine number of linebreaks before the comment
n := 0
@@ -678,7 +677,7 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
var last *ast.Comment
for p.commentBefore(next) {
for _, c := range p.comment.List {
- p.writeCommentPrefix(p.posFor(c.Pos()), next, last, c, tok.IsKeyword())
+ p.writeCommentPrefix(p.posFor(c.Pos()), next, last, c, tok)
p.writeComment(c)
last = c
}
@@ -1011,18 +1010,18 @@ func (p *printer) printNode(node interface{}) error {
// format node
switch n := node.(type) {
case ast.Expr:
- p.expr(n, ignoreMultiLine)
+ p.expr(n)
case ast.Stmt:
// 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 {
p.indent = 1
}
- p.stmt(n, false, ignoreMultiLine)
+ p.stmt(n, false)
case ast.Decl:
- p.decl(n, ignoreMultiLine)
+ p.decl(n)
case ast.Spec:
- p.spec(n, 1, false, ignoreMultiLine)
+ p.spec(n, 1, false)
case *ast.File:
p.file(n)
default:
diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go
index 2d4f61356c1..497d671f240 100644
--- a/libgo/go/go/printer/printer_test.go
+++ b/libgo/go/go/printer/printer_test.go
@@ -154,15 +154,12 @@ var data = []entry{
}
func TestFiles(t *testing.T) {
- for i, e := range data {
+ for _, e := range data {
source := filepath.Join(dataDir, e.source)
golden := filepath.Join(dataDir, e.golden)
check(t, source, golden, e.mode)
// TODO(gri) check that golden is idempotent
//check(t, golden, golden, e.mode)
- if testing.Short() && i >= 3 {
- break
- }
}
}
diff --git a/libgo/go/go/printer/testdata/comments.golden b/libgo/go/go/printer/testdata/comments.golden
index 4c6f1ab8274..d9aa2d82f7d 100644
--- a/libgo/go/go/printer/testdata/comments.golden
+++ b/libgo/go/go/printer/testdata/comments.golden
@@ -168,6 +168,91 @@ func typeswitch(x interface{}) {
// this comment should not be indented
}
+//
+// Indentation of comments after possibly indented multi-line constructs
+// (test cases for issue 3147).
+//
+
+func _() {
+ s := 1 +
+ 2
+ // should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+ // should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+ // should be indented like s
+ _ = 0
+}
+
+func _() {
+ s := 1 +
+ 2
+ // should be indented like s
+ _ = 0
+}
+
+func _() {
+ s := 1 +
+ 2
+
+ // should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+
+ // should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+
+ // should be indented like s
+ _ = 0
+}
+
+func _() {
+ s := 1 +
+ 2
+
+ // should be indented like s
+ _ = 0
+}
+
+// Test case from issue 3147.
+func f() {
+ templateText := "a" + // A
+ "b" + // B
+ "c" // C
+
+ // should be aligned with f()
+ f()
+}
+
+// Modified test case from issue 3147.
+func f() {
+ templateText := "a" + // A
+ "b" + // B
+ "c" // C
+
+ // may not be aligned with f() (source is not aligned)
+ f()
+}
+
+//
+// Test cases for alignment of lines in general comments.
+//
+
func _() {
/* freestanding comment
aligned line
diff --git a/libgo/go/go/printer/testdata/comments.input b/libgo/go/go/printer/testdata/comments.input
index c0f8cca3a92..6084b3fe450 100644
--- a/libgo/go/go/printer/testdata/comments.input
+++ b/libgo/go/go/printer/testdata/comments.input
@@ -171,6 +171,91 @@ func typeswitch(x interface{}) {
// this comment should not be indented
}
+//
+// Indentation of comments after possibly indented multi-line constructs
+// (test cases for issue 3147).
+//
+
+func _() {
+ s := 1 +
+ 2
+// should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+ // should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+ // should be indented like s
+ _ = 0
+}
+
+func _() {
+ s := 1 +
+ 2
+ // should be indented like s
+ _ = 0
+}
+
+func _() {
+ s := 1 +
+ 2
+
+// should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+
+ // should be indented like s
+}
+
+func _() {
+ s := 1 +
+ 2 // comment
+
+ // should be indented like s
+ _ = 0
+}
+
+func _() {
+ s := 1 +
+ 2
+
+ // should be indented like s
+ _ = 0
+}
+
+// Test case from issue 3147.
+func f() {
+ templateText := "a" + // A
+ "b" + // B
+ "c" // C
+
+ // should be aligned with f()
+ f()
+}
+
+// Modified test case from issue 3147.
+func f() {
+ templateText := "a" + // A
+ "b" + // B
+ "c" // C
+
+ // may not be aligned with f() (source is not aligned)
+ f()
+}
+
+//
+// Test cases for alignment of lines in general comments.
+//
+
func _() {
/* freestanding comment
aligned line
diff --git a/libgo/go/go/printer/testdata/declarations.golden b/libgo/go/go/printer/testdata/declarations.golden
index 928b8ce0a9f..7ed7cb61ae5 100644
--- a/libgo/go/go/printer/testdata/declarations.golden
+++ b/libgo/go/go/printer/testdata/declarations.golden
@@ -83,13 +83,13 @@ import (
// more import examples
import (
"xxx"
- "much longer name" // comment
- "short name" // comment
+ "much_longer_name" // comment
+ "short_name" // comment
)
import (
_ "xxx"
- "much longer name" // comment
+ "much_longer_name" // comment
)
import (
@@ -500,7 +500,7 @@ type _ struct {
type _ struct {
a, b,
- c, d int // this line should be indented
+ c, d int // this line should be indented
u, v, w, x float // this line should be indented
p, q,
r, s float // this line should be indented
@@ -562,7 +562,7 @@ var a2, b2,
var (
a3, b3,
- c3, d3 int // this line should be indented
+ c3, d3 int // this line should be indented
a4, b4, c4 int // this line should be indented
)
diff --git a/libgo/go/go/printer/testdata/declarations.input b/libgo/go/go/printer/testdata/declarations.input
index 68f90308a36..df8c2b167e1 100644
--- a/libgo/go/go/printer/testdata/declarations.input
+++ b/libgo/go/go/printer/testdata/declarations.input
@@ -84,13 +84,13 @@ import (
// more import examples
import (
"xxx"
- "much longer name" // comment
- "short name" // comment
+ "much_longer_name" // comment
+ "short_name" // comment
)
import (
_ "xxx"
- "much longer name" // comment
+ "much_longer_name" // comment
)
import (
diff --git a/libgo/go/go/printer/testdata/expressions.golden b/libgo/go/go/printer/testdata/expressions.golden
index 95fdd95ffbb..45fa4d97a4a 100644
--- a/libgo/go/go/printer/testdata/expressions.golden
+++ b/libgo/go/go/printer/testdata/expressions.golden
@@ -625,3 +625,25 @@ func f() {
log.Fatal(err)
}
}
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+ _ = append(s, a...)
+ _ = append(
+ s, a...)
+ _ = append(s,
+ a...)
+ _ = append(
+ s,
+ a...)
+ _ = append(s, a...,
+ )
+ _ = append(s,
+ a...,
+ )
+ _ = append(
+ s,
+ a...,
+ )
+}
diff --git a/libgo/go/go/printer/testdata/expressions.input b/libgo/go/go/printer/testdata/expressions.input
index d1131498352..f545c66057c 100644
--- a/libgo/go/go/printer/testdata/expressions.input
+++ b/libgo/go/go/printer/testdata/expressions.input
@@ -654,3 +654,25 @@ func f() {
log.Fatal(err)
}
}
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+ _ = append(s, a...)
+ _ = append(
+ s, a...)
+ _ = append(s,
+ a...)
+ _ = append(
+ s,
+ a...)
+ _ = append(s, a...,
+ )
+ _ = append(s,
+ a...,
+ )
+ _ = append(
+ s,
+ a...,
+ )
+}
diff --git a/libgo/go/go/printer/testdata/expressions.raw b/libgo/go/go/printer/testdata/expressions.raw
index 3442ba9b950..87a4b00836d 100644
--- a/libgo/go/go/printer/testdata/expressions.raw
+++ b/libgo/go/go/printer/testdata/expressions.raw
@@ -625,3 +625,25 @@ func f() {
log.Fatal(err)
}
}
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+ _ = append(s, a...)
+ _ = append(
+ s, a...)
+ _ = append(s,
+ a...)
+ _ = append(
+ s,
+ a...)
+ _ = append(s, a...,
+ )
+ _ = append(s,
+ a...,
+ )
+ _ = append(
+ s,
+ a...,
+ )
+}
diff --git a/libgo/go/go/printer/testdata/parser.go b/libgo/go/go/printer/testdata/parser.go
index c85297f5831..dba8bbd4351 100644
--- a/libgo/go/go/printer/testdata/parser.go
+++ b/libgo/go/go/printer/testdata/parser.go
@@ -52,7 +52,7 @@ type parser struct {
// Non-syntactic parser control
exprLev int // < 0: in control clause, >= 0: in expression
- // Ordinary identifer scopes
+ // Ordinary identifier scopes
pkgScope *ast.Scope // pkgScope.Outer == nil
topScope *ast.Scope // top-most scope; may be pkgScope
unresolved []*ast.Ident // unresolved identifiers
diff --git a/libgo/go/go/printer/testdata/statements.golden b/libgo/go/go/printer/testdata/statements.golden
index 90e1743557d..ffca21edba9 100644
--- a/libgo/go/go/printer/testdata/statements.golden
+++ b/libgo/go/go/printer/testdata/statements.golden
@@ -8,6 +8,82 @@ var expr bool
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.
func _() {
if true {
diff --git a/libgo/go/go/printer/testdata/statements.input b/libgo/go/go/printer/testdata/statements.input
index 86a753c5ad9..99945e9551a 100644
--- a/libgo/go/go/printer/testdata/statements.input
+++ b/libgo/go/go/printer/testdata/statements.input
@@ -8,6 +8,82 @@ var expr bool
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.
func _() {
if true {}