mirror of https://github.com/golang/go.git
gofmt: fix some linebreak issues
- don't lose empty lines after labels - canonicalize number of line breaks - gofmt src misc, fixes a couple of irregular breaks R=rsc CC=golang-dev https://golang.org/cl/1843044
This commit is contained in:
parent
199e17ba1f
commit
8f9aeb5a66
|
|
@ -270,7 +270,6 @@ func (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Somethings is wrong if at the end, the top level is null or hasn't used
|
||||
// all of the leaves.
|
||||
if top.lastChain.leafCount != n {
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ func (h *huffmanDecoder) init(bits []int) bool {
|
|||
h.min = min
|
||||
h.max = max
|
||||
|
||||
|
||||
// For each code range, compute
|
||||
// nextcode (first code of that length),
|
||||
// limit (last code of that length), and
|
||||
|
|
|
|||
|
|
@ -224,7 +224,6 @@ func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) {
|
|||
italics = false // don't italicize URLs
|
||||
}
|
||||
|
||||
|
||||
// write match
|
||||
if len(url) > 0 {
|
||||
w.Write(html_a)
|
||||
|
|
|
|||
|
|
@ -28,32 +28,30 @@ import (
|
|||
// ----------------------------------------------------------------------------
|
||||
// Common AST nodes.
|
||||
|
||||
// Print as many newlines as necessary (but at least min and and at most
|
||||
// max newlines) to get to the current line. ws is printed before the first
|
||||
// line break. If newSection is set, the first line break is printed as
|
||||
// formfeed. Returns true if any line break was printed; returns false otherwise.
|
||||
// Print as many newlines as necessary (but at least min newlines) to get to
|
||||
// the current line. ws is printed before the first line break. If newSection
|
||||
// is set, the first line break is printed as formfeed. Returns true if any
|
||||
// line break was printed; returns false otherwise.
|
||||
//
|
||||
// TODO(gri): Reconsider signature (provide position instead of line)
|
||||
// TODO(gri): linebreak may add too many lines if the next statement at "line"
|
||||
// is preceeded by comments because the computation of n assumes
|
||||
// the current position before the comment and the target position
|
||||
// after the comment. Thus, after interspersing such comments, the
|
||||
// space taken up by them is not considered to reduce the number of
|
||||
// linebreaks. At the moment there is no easy way to know about
|
||||
// future (not yet interspersed) comments in this function.
|
||||
//
|
||||
func (p *printer) linebreak(line, min, max int, ws whiteSpace, newSection bool) (printedBreak bool) {
|
||||
n := line - p.pos.Line
|
||||
switch {
|
||||
case n < min:
|
||||
n = min
|
||||
case n > max:
|
||||
n = max
|
||||
}
|
||||
|
||||
func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (printedBreak bool) {
|
||||
n := p.nlines(line-p.pos.Line, min)
|
||||
if n > 0 {
|
||||
p.print(ws)
|
||||
if newSection {
|
||||
p.print(formfeed)
|
||||
n--
|
||||
printedBreak = true
|
||||
}
|
||||
}
|
||||
for ; n > 0; n-- {
|
||||
p.print(newline)
|
||||
for ; n > 0; n-- {
|
||||
p.print(newline)
|
||||
}
|
||||
printedBreak = true
|
||||
}
|
||||
return
|
||||
|
|
@ -190,7 +188,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, depth int, mode
|
|||
// lines for them.
|
||||
linebreakMin = 0
|
||||
}
|
||||
if prev.IsValid() && prev.Line < line && p.linebreak(line, linebreakMin, 2, ws, true) {
|
||||
if prev.IsValid() && prev.Line < line && p.linebreak(line, linebreakMin, ws, true) {
|
||||
ws = ignore
|
||||
*multiLine = true
|
||||
prevBreak = 0
|
||||
|
|
@ -252,7 +250,7 @@ func (p *printer) exprList(prev token.Position, list []ast.Expr, depth int, mode
|
|||
// unless forceFF is set or there are multiple expressions on
|
||||
// the same line in which case formfeed is used
|
||||
// broken with a formfeed
|
||||
if p.linebreak(line, linebreakMin, 2, ws, useFF || prevBreak+1 < i) {
|
||||
if p.linebreak(line, linebreakMin, ws, useFF || prevBreak+1 < i) {
|
||||
ws = ignore
|
||||
*multiLine = true
|
||||
prevBreak = i
|
||||
|
|
@ -371,6 +369,11 @@ func (p *printer) setLineComment(text string) {
|
|||
|
||||
|
||||
func (p *printer) fieldList(fields *ast.FieldList, isIncomplete bool, ctxt exprContext) {
|
||||
p.nesting++
|
||||
defer func() {
|
||||
p.nesting--
|
||||
}()
|
||||
|
||||
lbrace := fields.Opening
|
||||
list := fields.List
|
||||
rbrace := fields.Closing
|
||||
|
|
@ -413,7 +416,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isIncomplete bool, ctxt exprC
|
|||
var ml bool
|
||||
for i, f := range list {
|
||||
if i > 0 {
|
||||
p.linebreak(f.Pos().Line, 1, 2, ignore, ml)
|
||||
p.linebreak(f.Pos().Line, 1, ignore, ml)
|
||||
}
|
||||
ml = false
|
||||
extraTabs := 0
|
||||
|
|
@ -457,7 +460,7 @@ func (p *printer) fieldList(fields *ast.FieldList, isIncomplete bool, ctxt exprC
|
|||
var ml bool
|
||||
for i, f := range list {
|
||||
if i > 0 {
|
||||
p.linebreak(f.Pos().Line, 1, 2, ignore, ml)
|
||||
p.linebreak(f.Pos().Line, 1, ignore, ml)
|
||||
}
|
||||
ml = false
|
||||
p.setComment(f.Doc)
|
||||
|
|
@ -648,7 +651,7 @@ func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int, multiL
|
|||
if xline != yline && xline > 0 && yline > 0 {
|
||||
// at least one line break, but respect an extra empty line
|
||||
// in the source
|
||||
if p.linebreak(yline, 1, 2, ws, true) {
|
||||
if p.linebreak(yline, 1, ws, true) {
|
||||
ws = ignore
|
||||
*multiLine = true
|
||||
printBlank = false // no blank after line break
|
||||
|
|
@ -917,8 +920,6 @@ func (p *printer) expr(x ast.Expr, multiLine *bool) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// Statements
|
||||
|
||||
const maxStmtNewlines = 2 // maximum number of newlines between statements
|
||||
|
||||
// Print the statement list indented, but without a newline after the last statement.
|
||||
// Extra line breaks between statements in the source are respected but at most one
|
||||
// empty line is printed between statements.
|
||||
|
|
@ -931,7 +932,7 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int, nextIsRBrace bool) {
|
|||
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(s.Pos().Line, 1, maxStmtNewlines, ignore, i == 0 || _indent == 0 || multiLine)
|
||||
p.linebreak(s.Pos().Line, 1, ignore, i == 0 || _indent == 0 || multiLine)
|
||||
multiLine = false
|
||||
p.stmt(s, nextIsRBrace && i == len(list)-1, &multiLine)
|
||||
}
|
||||
|
|
@ -945,7 +946,7 @@ func (p *printer) stmtList(list []ast.Stmt, _indent int, nextIsRBrace bool) {
|
|||
func (p *printer) block(s *ast.BlockStmt, indent int) {
|
||||
p.print(s.Pos(), token.LBRACE)
|
||||
p.stmtList(s.List, indent, true)
|
||||
p.linebreak(s.Rbrace.Line, 1, maxStmtNewlines, ignore, true)
|
||||
p.linebreak(s.Rbrace.Line, 1, ignore, true)
|
||||
p.print(s.Rbrace, token.RBRACE)
|
||||
}
|
||||
|
||||
|
|
@ -1039,7 +1040,7 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
|
|||
break
|
||||
}
|
||||
} else {
|
||||
p.print(newline)
|
||||
p.linebreak(s.Stmt.Pos().Line, 1, ignore, true)
|
||||
}
|
||||
p.stmt(s.Stmt, nextIsRBrace, multiLine)
|
||||
|
||||
|
|
@ -1271,7 +1272,7 @@ func (p *printer) genDecl(d *ast.GenDecl, multiLine *bool) {
|
|||
var ml bool
|
||||
for i, s := range d.Specs {
|
||||
if i > 0 {
|
||||
p.linebreak(s.Pos().Line, 1, 2, ignore, ml)
|
||||
p.linebreak(s.Pos().Line, 1, ignore, ml)
|
||||
}
|
||||
ml = false
|
||||
p.spec(s, len(d.Specs), false, &ml)
|
||||
|
|
@ -1345,6 +1346,11 @@ func (p *printer) funcBody(b *ast.BlockStmt, headerSize int, isLit bool, multiLi
|
|||
return
|
||||
}
|
||||
|
||||
p.nesting++
|
||||
defer func() {
|
||||
p.nesting--
|
||||
}()
|
||||
|
||||
if p.isOneLineFunc(b, headerSize) {
|
||||
sep := vtab
|
||||
if isLit {
|
||||
|
|
@ -1414,8 +1420,6 @@ func (p *printer) decl(decl ast.Decl, multiLine *bool) {
|
|||
// ----------------------------------------------------------------------------
|
||||
// Files
|
||||
|
||||
const maxDeclNewlines = 3 // maximum number of newlines between declarations
|
||||
|
||||
func declToken(decl ast.Decl) (tok token.Token) {
|
||||
tok = token.ILLEGAL
|
||||
switch d := decl.(type) {
|
||||
|
|
@ -1444,7 +1448,7 @@ func (p *printer) file(src *ast.File) {
|
|||
if prev != tok {
|
||||
min = 2
|
||||
}
|
||||
p.linebreak(d.Pos().Line, min, maxDeclNewlines, ignore, false)
|
||||
p.linebreak(d.Pos().Line, min, ignore, false)
|
||||
p.decl(d, ignoreMultiLine)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ import (
|
|||
)
|
||||
|
||||
|
||||
const (
|
||||
debug = false // enable for debugging
|
||||
maxNewlines = 3 // maximum vertical white space
|
||||
)
|
||||
const debug = false // enable for debugging
|
||||
|
||||
|
||||
type whiteSpace int
|
||||
|
|
@ -41,8 +38,8 @@ var (
|
|||
esc = []byte{tabwriter.Escape}
|
||||
htab = []byte{'\t'}
|
||||
htabs = []byte("\t\t\t\t\t\t\t\t")
|
||||
newlines = []byte("\n\n\n\n\n\n\n\n") // more than maxNewlines
|
||||
formfeeds = []byte("\f\f\f\f\f\f\f\f") // more than maxNewlines
|
||||
newlines = []byte("\n\n\n\n\n\n\n\n") // more than the max determined by nlines
|
||||
formfeeds = []byte("\f\f\f\f\f\f\f\f") // more than the max determined by nlines
|
||||
|
||||
esc_quot = []byte(""") // shorter than """
|
||||
esc_apos = []byte("'") // shorter than "'"
|
||||
|
|
@ -68,6 +65,7 @@ type printer struct {
|
|||
errors chan os.Error
|
||||
|
||||
// Current state
|
||||
nesting int // nesting level (0: top-level (package scope), >0: functions/decls.)
|
||||
written int // number of bytes written
|
||||
indent int // current indentation
|
||||
escape bool // true if in escape sequence
|
||||
|
|
@ -112,6 +110,25 @@ func (p *printer) internalError(msg ...interface{}) {
|
|||
}
|
||||
|
||||
|
||||
// nlines returns the adjusted number of linebreaks given the desired number
|
||||
// of breaks n such that min <= result <= max where max depends on the current
|
||||
// nesting level.
|
||||
//
|
||||
func (p *printer) nlines(n, min int) int {
|
||||
if n < min {
|
||||
return min
|
||||
}
|
||||
max := 3 // max. number of newlines at the top level (p.nesting == 0)
|
||||
if p.nesting > 0 {
|
||||
max = 2 // max. number of newlines everywhere else
|
||||
}
|
||||
if n > max {
|
||||
return max
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
// write0 writes raw (uninterpreted) data to p.output and handles errors.
|
||||
// write0 does not indent after newlines, and does not HTML-escape or update p.pos.
|
||||
//
|
||||
|
|
@ -207,9 +224,7 @@ func (p *printer) write(data []byte) {
|
|||
|
||||
func (p *printer) writeNewlines(n int, useFF bool) {
|
||||
if n > 0 {
|
||||
if n > maxNewlines {
|
||||
n = maxNewlines
|
||||
}
|
||||
n = p.nlines(n, 0)
|
||||
if useFF {
|
||||
p.write(formfeeds[0:n])
|
||||
} else {
|
||||
|
|
@ -292,8 +307,8 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor
|
|||
}
|
||||
|
||||
if pos.IsValid() && pos.Filename != p.last.Filename {
|
||||
// comment in a different file - separate with newlines
|
||||
p.writeNewlines(maxNewlines, true)
|
||||
// comment in a different file - separate with newlines (writeNewlines will limit the number)
|
||||
p.writeNewlines(10, true)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -1004,9 +1019,11 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
|
|||
go func() {
|
||||
switch n := node.(type) {
|
||||
case ast.Expr:
|
||||
p.nesting = 1
|
||||
p.useNodeComments = true
|
||||
p.expr(n, ignoreMultiLine)
|
||||
case ast.Stmt:
|
||||
p.nesting = 1
|
||||
p.useNodeComments = true
|
||||
// A labeled statement will un-indent to position the
|
||||
// label. Set indent to 1 so we don't get indent "underflow".
|
||||
|
|
@ -1015,12 +1032,15 @@ func (cfg *Config) Fprint(output io.Writer, node interface{}) (int, os.Error) {
|
|||
}
|
||||
p.stmt(n, false, ignoreMultiLine)
|
||||
case ast.Decl:
|
||||
p.nesting = 1
|
||||
p.useNodeComments = true
|
||||
p.decl(n, ignoreMultiLine)
|
||||
case ast.Spec:
|
||||
p.nesting = 1
|
||||
p.useNodeComments = true
|
||||
p.spec(n, 1, false, ignoreMultiLine)
|
||||
case *ast.File:
|
||||
p.nesting = 0
|
||||
p.comments = n.Comments
|
||||
p.useNodeComments = n.Comments == nil
|
||||
p.file(n)
|
||||
|
|
|
|||
|
|
@ -227,7 +227,8 @@ func _() {
|
|||
var x = 1
|
||||
|
||||
// Each use(x) call below should have at most one empty line before and after.
|
||||
|
||||
// Known bug: The first use call may have more than one empty line before
|
||||
// (see go/printer/nodes.go, func linebreak).
|
||||
|
||||
|
||||
use(x)
|
||||
|
|
@ -336,3 +337,49 @@ AnOverlongLabel:
|
|||
L:
|
||||
_ = 0
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto L
|
||||
}
|
||||
L:
|
||||
|
||||
MoreCode()
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto L
|
||||
}
|
||||
L: // A comment on the same line as the label, followed by a single empty line.
|
||||
// Known bug: There may be more than one empty line before MoreCode()
|
||||
// (see go/printer/nodes.go, func linebreak).
|
||||
|
||||
|
||||
MoreCode()
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto L
|
||||
}
|
||||
L:
|
||||
|
||||
// There should be a single empty line before this comment.
|
||||
MoreCode()
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto AVeryLongLabelThatShouldNotAffectFormatting
|
||||
}
|
||||
AVeryLongLabelThatShouldNotAffectFormatting:
|
||||
// There should be a single empty line after this comment.
|
||||
|
||||
// There should be a single empty line before this comment.
|
||||
MoreCode()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ func _() {
|
|||
var x = 1
|
||||
|
||||
// Each use(x) call below should have at most one empty line before and after.
|
||||
// Known bug: The first use call may have more than one empty line before
|
||||
// (see go/printer/nodes.go, func linebreak).
|
||||
|
||||
|
||||
|
||||
|
|
@ -266,3 +268,54 @@ AnOverlongLabel:
|
|||
|
||||
L: _ = 0
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto L
|
||||
}
|
||||
L:
|
||||
|
||||
MoreCode()
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto L
|
||||
}
|
||||
L: // A comment on the same line as the label, followed by a single empty line.
|
||||
// Known bug: There may be more than one empty line before MoreCode()
|
||||
// (see go/printer/nodes.go, func linebreak).
|
||||
|
||||
|
||||
|
||||
|
||||
MoreCode()
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto L
|
||||
}
|
||||
L:
|
||||
|
||||
|
||||
|
||||
|
||||
// There should be a single empty line before this comment.
|
||||
MoreCode()
|
||||
}
|
||||
|
||||
|
||||
func _() {
|
||||
for {
|
||||
goto AVeryLongLabelThatShouldNotAffectFormatting
|
||||
}
|
||||
AVeryLongLabelThatShouldNotAffectFormatting:
|
||||
// There should be a single empty line after this comment.
|
||||
|
||||
// There should be a single empty line before this comment.
|
||||
MoreCode()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ Body.
|
|||
t.Fatal("newnews should work: " + err.String())
|
||||
}
|
||||
|
||||
|
||||
// NewGroups
|
||||
if _, err = conn.NewGroups(tt); err != nil {
|
||||
t.Fatal("newgroups shouldn't error " + err.String())
|
||||
|
|
|
|||
Loading…
Reference in New Issue