summaryrefslogtreecommitdiff
path: root/libgo/go/go/printer/nodes.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/go/printer/nodes.go')
-rw-r--r--libgo/go/go/printer/nodes.go109
1 files changed, 66 insertions, 43 deletions
diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go
index 583c6c3709..d5a69349be 100644
--- a/libgo/go/go/printer/nodes.go
+++ b/libgo/go/go/printer/nodes.go
@@ -163,8 +163,8 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
size := 0
// print all list elements
+ prevLine := prev.Line
for i, x := range list {
- prevLine := line
line = p.lineFor(x.Pos())
// determine if the next linebreak, if any, needs to use formfeed:
@@ -207,8 +207,8 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
}
}
+ needsLinebreak := 0 < prevLine && prevLine < line
if i > 0 {
- needsLinebreak := prevLine < line && prevLine > 0 && line > 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
@@ -232,16 +232,20 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
}
}
- if isPair && size > 0 && len(list) > 1 {
- // 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
+ if len(list) > 1 && isPair && size > 0 && needsLinebreak {
+ // we have a key:value expression that fits onto one line
+ // and it's not on the same line as the prior expression:
+ // use a column for the key such that consecutive entries
+ // can align if possible
+ // (needsLinebreak is set if we started a new line before)
p.expr(pair.Key)
p.print(pair.Colon, token.COLON, vtab)
p.expr(pair.Value)
} else {
p.expr0(x, depth)
}
+
+ prevLine = line
}
if mode&commaTerm != 0 && next.IsValid() && p.pos.Line < next.Line {
@@ -378,10 +382,6 @@ 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()) > 0
-}
-
func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
lbrace := fields.Opening
list := fields.List
@@ -428,13 +428,14 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
if len(list) == 1 {
sep = blank
}
- newSection := false
+ var line int
for i, f := range list {
if i > 0 {
- p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection)
+ p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
}
extraTabs := 0
p.setComment(f.Doc)
+ p.recordLine(&line)
if len(f.Names) > 0 {
// named fields
p.identList(f.Names, false)
@@ -460,7 +461,6 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
}
p.setComment(f.Comment)
}
- newSection = p.isMultiLine(f)
}
if isIncomplete {
if len(list) > 0 {
@@ -472,12 +472,13 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
} else { // interface
- newSection := false
+ var line int
for i, f := range list {
if i > 0 {
- p.linebreak(p.lineFor(f.Pos()), 1, ignore, newSection)
+ p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
}
p.setComment(f.Doc)
+ p.recordLine(&line)
if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
// method
p.expr(f.Names[0])
@@ -487,7 +488,6 @@ func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool)
p.expr(f.Type)
}
p.setComment(f.Comment)
- newSection = p.isMultiLine(f)
}
if isIncomplete {
if len(list) > 0 {
@@ -736,7 +736,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
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)) // parentheses undo one level of depth
+ p.expr0(x.X, depth)
} else {
p.print(token.LPAREN)
p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
@@ -826,10 +826,16 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
}
p.print(x.Lbrace, token.LBRACE)
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 ','
- p.print(noExtraLinebreak, x.Rbrace, token.RBRACE, noExtraLinebreak)
+ // do not insert extra line break following a /*-style comment
+ // before the closing '}' as it might break the code if there
+ // is no trailing ','
+ mode := noExtraLinebreak
+ // do not insert extra blank following a /*-style comment
+ // before the closing '}' unless the literal is empty
+ if len(x.Elts) > 0 {
+ mode |= noExtraBlank
+ }
+ p.print(mode, x.Rbrace, token.RBRACE, mode)
case *ast.Ellipsis:
p.print(token.ELLIPSIS)
@@ -901,20 +907,31 @@ func (p *printer) stmtList(list []ast.Stmt, nindent int, nextIsRBrace bool) {
if nindent > 0 {
p.print(indent)
}
- multiLine := false
+ var line int
i := 0
for _, s := range list {
// ignore empty statements (was issue 3466)
if _, isEmpty := s.(*ast.EmptyStmt); !isEmpty {
- // _indent == 0 only for lists of switch/select case clauses;
+ // nindent == 0 only for lists of switch/select case clauses;
// in those cases each clause is a new section
if len(p.output) > 0 {
// only print line break if we are not at the beginning of the output
// (i.e., we are not printing only a partial program)
- p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || nindent == 0 || multiLine)
+ p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || nindent == 0 || p.linesFrom(line) > 0)
}
+ p.recordLine(&line)
p.stmt(s, nextIsRBrace && i == len(list)-1)
- multiLine = p.isMultiLine(s)
+ // labeled statements put labels on a separate line, but here
+ // we only care about the start line of the actual statement
+ // without label - correct line for each label
+ for t := s; ; {
+ lt, _ := t.(*ast.LabeledStmt)
+ if lt == nil {
+ break
+ }
+ line++
+ t = lt.Stmt
+ }
i++
}
}
@@ -1203,14 +1220,17 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
case *ast.RangeStmt:
p.print(token.FOR, blank)
- 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)
- }
- p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank)
+ if s.Key != nil {
+ 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)
+ }
+ p.print(blank, s.TokPos, s.Tok, blank)
+ }
+ p.print(token.RANGE, blank)
p.expr(stripParens(s.X))
p.print(blank)
p.block(s.Body, 1)
@@ -1375,22 +1395,22 @@ func (p *printer) genDecl(d *ast.GenDecl) {
// two or more grouped const/var declarations:
// determine if the type column must be kept
keepType := keepTypeColumn(d.Specs)
- newSection := false
+ var line int
for i, s := range d.Specs {
if i > 0 {
- p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
+ p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0)
}
+ p.recordLine(&line)
p.valueSpec(s.(*ast.ValueSpec), keepType[i])
- newSection = p.isMultiLine(s)
}
} else {
- newSection := false
+ var line int
for i, s := range d.Specs {
if i > 0 {
- p.linebreak(p.lineFor(s.Pos()), 1, ignore, newSection)
+ p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0)
}
+ p.recordLine(&line)
p.spec(s, n, false)
- newSection = p.isMultiLine(s)
}
}
p.print(unindent, formfeed)
@@ -1448,13 +1468,16 @@ func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
// opening and closing brace are on different lines - don't make it a one-liner
return maxSize + 1
}
- if len(b.List) > 5 || p.commentBefore(p.posFor(pos2)) {
- // too many statements or there is a comment inside - don't make it a one-liner
+ if len(b.List) > 5 {
+ // too many statements - don't make it a one-liner
return maxSize + 1
}
// otherwise, estimate body size
- bodySize := 0
+ bodySize := p.commentSizeBefore(p.posFor(pos2))
for i, s := range b.List {
+ if bodySize > maxSize {
+ break // no need to continue
+ }
if i > 0 {
bodySize += 2 // space for a semicolon and blank
}
@@ -1488,7 +1511,7 @@ func (p *printer) adjBlock(headerSize int, sep whiteSpace, b *ast.BlockStmt) {
}
p.print(blank)
}
- p.print(b.Rbrace, token.RBRACE)
+ p.print(noExtraLinebreak, b.Rbrace, token.RBRACE, noExtraLinebreak)
return
}