]> Cypherpunks repositories - gostls13.git/commitdiff
go/printer: replace multiline logic
authorRobert Griesemer <gri@golang.org>
Wed, 29 Feb 2012 16:38:31 +0000 (08:38 -0800)
committerRobert Griesemer <gri@golang.org>
Wed, 29 Feb 2012 16:38:31 +0000 (08:38 -0800)
This CL mostly deletes code.

Using existing position information is
just as good to determine if a new section
is needed; no need to track exact multi-
line information. Eliminates the need to
carry around a multiLine parameter with
practically every function.

Applied gofmt -w src misc resulting in only
a minor change to godoc.go. In return, a couple
of test cases are now formatted better.

Not Go1-required, but nice-to-have as it will
simplify fixes going forward.

R=rsc
CC=golang-dev
https://golang.org/cl/5706055

src/cmd/godoc/godoc.go
src/pkg/go/printer/nodes.go
src/pkg/go/printer/printer.go
src/pkg/go/printer/testdata/declarations.golden

index 72496589561d007e4c08cbe6b9ab1e79537d7278..1f212a0bcd66dd70852be7737f2e6e5fe8b083c5 100644 (file)
@@ -69,7 +69,7 @@ var (
        // search index
        indexEnabled = flag.Bool("index", false, "enable search index")
        indexFiles   = flag.String("index_files", "", "glob pattern specifying index files;"+
-               "if not empty, the index is read from these files in sorted order")
+                       "if not empty, the index is read from these files in sorted order")
        maxResults    = flag.Int("maxresults", 10000, "maximum number of full text search results shown")
        indexThrottle = flag.Float64("index_throttle", 0.75, "index throttle value; 0.0 = no time allocated, 1.0 = full throttle")
 
index 2205f633f1d502b0d0f774fde7f5557f35bb95f5..16fc9de1ee62e2cb5f5244e56c4f76ec89acc408 100644 (file)
@@ -89,10 +89,9 @@ const (
        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 {
@@ -102,18 +101,17 @@ func (p *printer) identList(list []*ast.Ident, indent bool, multiLine *bool) {
        if !indent {
                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
        }
@@ -138,7 +136,7 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
                                }
                                p.print(blank)
                        }
-                       p.expr0(x, depth, multiLine)
+                       p.expr0(x, depth)
                }
                if mode&blankEnd != 0 {
                        p.print(blank)
@@ -161,7 +159,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
        }
 
@@ -231,7 +228,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 +241,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)
                }
        }
 
@@ -274,8 +270,7 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
        }
 }
 
-// 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 +301,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 +312,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,18 +333,17 @@ 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)
        }
 }
 
@@ -389,6 +382,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 +409,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 +432,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 +455,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 +464,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 +476,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 +632,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 +647,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 +659,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 +676,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 +691,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 +704,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 +717,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 +726,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 +768,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 +787,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,26 +795,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)
                if x.Ellipsis.IsValid() {
-                       p.exprList(x.Lparen, x.Args, depth, commaSep, multiLine, x.Ellipsis)
+                       p.exprList(x.Lparen, x.Args, depth, commaSep, 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, commaSep|commaTerm, multiLine, x.Rparen)
+                       p.exprList(x.Lparen, x.Args, depth, commaSep|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, commaSep|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 ','
@@ -830,16 +823,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)
@@ -847,7 +840,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)
@@ -855,9 +848,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 {
@@ -869,7 +862,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")
@@ -878,14 +871,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)
 }
 
 // ----------------------------------------------------------------------------
@@ -899,13 +891,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)
@@ -962,25 +954,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
                        }
                }
@@ -990,8 +982,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) {
@@ -999,7 +990,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
@@ -1009,7 +1000,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 {
@@ -1019,21 +1010,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:
@@ -1041,48 +1032,46 @@ 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.exprList(s.Pos(), s.Lhs, depth, commaSep, s.TokPos)
                p.print(blank, s.TokPos, s.Tok)
-               p.exprList(s.TokPos, s.Rhs, depth, blankStart|commaSep, multiLine, token.NoPos)
+               p.exprList(s.TokPos, s.Rhs, depth, blankStart|commaSep, 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.exprList(s.Pos(), s.Results, 1, blankStart|commaSep, 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)
                        }
                }
@@ -1090,7 +1079,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
        case *ast.CaseClause:
                if s.List != nil {
                        p.print(token.CASE)
-                       p.exprList(s.Pos(), s.List, 1, blankStart|commaSep, multiLine, s.Colon)
+                       p.exprList(s.Pos(), s.List, 1, blankStart|commaSep, s.Colon)
                } else {
                        p.print(token.DEFAULT)
                }
@@ -1101,25 +1090,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)
                }
@@ -1134,29 +1121,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")
@@ -1233,20 +1217,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.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, token.NoPos)
                extraTabs--
        }
        if s.Comment != nil {
@@ -1260,17 +1244,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)
 
@@ -1279,26 +1262,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.exprList(token.NoPos, s.Values, 1, blankStart|commaSep, 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:
@@ -1306,8 +1289,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)
 
@@ -1320,32 +1302,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)
        }
 }
 
@@ -1409,8 +1390,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
        }
@@ -1427,7 +1407,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)
                }
@@ -1437,7 +1417,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
@@ -1451,28 +1430,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")
        }
@@ -1495,7 +1472,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
@@ -1514,7 +1491,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)
                }
        }
 
index 72f65a1d8526637fd1c56dcfcaf1d9e4a02f005c..1ab4456e832291e6622db4d60f81cf444e175b88 100644 (file)
@@ -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
 
@@ -1011,18 +1008,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:
index a46463e56e6609476710cce8fa83b00b97351d5e..7ed7cb61ae5cddbeea5d076f8e23419b6f0f2515 100644 (file)
@@ -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
 )