From 9ff4565e2b300c0fc6fdf9bcaa45f0baa789bf36 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 27 Sep 2010 15:03:15 -0700 Subject: [PATCH] gofmt: stability improvement There are a variety of token pairs that if printed without separating blank may combine into a different token sequence. Most of these (except for INT + .) don't happen at the moment due to the spacing introduced between expression operands. However, this will prevent errors should the expression spacing change. R=rsc CC=golang-dev https://golang.org/cl/2207044 --- src/pkg/go/printer/nodes.go | 7 +++-- src/pkg/go/printer/printer.go | 29 +++++++++++++++++-- .../go/printer/testdata/expressions.golden | 11 +++++++ src/pkg/go/printer/testdata/expressions.input | 11 +++++++ src/pkg/go/printer/testdata/expressions.raw | 11 +++++++ 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go index 2451116fdb6..3e8f12100b1 100644 --- a/src/pkg/go/printer/nodes.go +++ b/src/pkg/go/printer/nodes.go @@ -543,7 +543,7 @@ func walkBinary(e *ast.BinaryExpr) (has5, has6 bool, maxProblem int) { case *ast.UnaryExpr: switch e.Op.String() + r.Op.String() { - case "/*": + case "/*", "&&", "&^": maxProblem = 6 case "++", "--": if maxProblem < 5 { @@ -612,11 +612,14 @@ func reduceDepth(depth int) int { // 1) If there is a binary operator with a right side unary operand // that would clash without a space, the cutoff must be (in order): // -// &^ 7 // /* 7 +// && 7 +// &^ 7 // ++ 6 // -- 6 // +// (Comparison operators always have spaces around them.) +// // 2) If there is a mix of level 6 and level 5 operators, then the cutoff // is 6 (use spaces to distinguish precedence) in Normal mode // and 5 (never use spaces) in Compact mode. diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go index b985f6ed3e2..cdc8cf518d2 100644 --- a/src/pkg/go/printer/printer.go +++ b/src/pkg/go/printer/printer.go @@ -746,6 +746,26 @@ func (p *printer) writeWhitespace(n int) { // ---------------------------------------------------------------------------- // Printing interface + +func mayCombine(prev token.Token, next byte) (b bool) { + switch prev { + case token.INT: + b = next == '.' // 1. + case token.ADD: + b = next == '+' // ++ + case token.SUB: + b = next == '-' // -- + case token.QUO: + b = next == '*' // /* + case token.LSS: + b = next == '-' || next == '<' // <- or << + case token.AND: + b = next == '&' || next == '^' // && or &^ + } + return +} + + // print prints a list of "items" (roughly corresponding to syntactic // tokens, but also including whitespace and formatting information). // It is the only print function that should be called directly from @@ -803,8 +823,13 @@ func (p *printer) print(args ...interface{}) { tok = x.Kind case token.Token: s := x.String() - if p.lastTok == token.INT && s[0] == '.' { - // separate int with blank from '.' so it doesn't become a float + if mayCombine(p.lastTok, s[0]) { + // the previous and the current token must be + // separated by a blank otherwise they combine + // into a different incorrect token sequence + // (except for token.INT followed by a '.' this + // should never happen because it is taken care + // of via binary expression formatting) if len(p.buffer) != 0 { p.internalError("whitespace buffer not empty") } diff --git a/src/pkg/go/printer/testdata/expressions.golden b/src/pkg/go/printer/testdata/expressions.golden index 02bae49b48d..b5dac45a7bb 100644 --- a/src/pkg/go/printer/testdata/expressions.golden +++ b/src/pkg/go/printer/testdata/expressions.golden @@ -194,6 +194,17 @@ func f(x int, args ...int) { _ = .42.x _ = 42e0.x _ = 42e0.x + + // a blank must remain between the binary operator and the 2nd operand + _ = x / *y + _ = x < -1 + _ = x < <-1 + _ = x + +1 + _ = x - -1 + _ = x & &x + _ = x & ^x + + _ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x) } diff --git a/src/pkg/go/printer/testdata/expressions.input b/src/pkg/go/printer/testdata/expressions.input index 7d5889b064b..3eb1629317a 100644 --- a/src/pkg/go/printer/testdata/expressions.input +++ b/src/pkg/go/printer/testdata/expressions.input @@ -194,6 +194,17 @@ func f(x int, args ...int) { _ = .42.x _ = 42e0 .x _ = 42e0.x + + // a blank must remain between the binary operator and the 2nd operand + _ = x/ *y + _ = x< -1 + _ = x< <-1 + _ = x+ +1 + _ = x- -1 + _ = x& &x + _ = x& ^x + + _ = f(x/ *y, x< -1, x< <-1, x+ +1, x- -1, x& &x, x& ^x) } diff --git a/src/pkg/go/printer/testdata/expressions.raw b/src/pkg/go/printer/testdata/expressions.raw index 9e83892e87b..e571d08284c 100644 --- a/src/pkg/go/printer/testdata/expressions.raw +++ b/src/pkg/go/printer/testdata/expressions.raw @@ -194,6 +194,17 @@ func f(x int, args ...int) { _ = .42.x _ = 42e0.x _ = 42e0.x + + // a blank must remain between the binary operator and the 2nd operand + _ = x / *y + _ = x < -1 + _ = x < <-1 + _ = x + +1 + _ = x - -1 + _ = x & &x + _ = x & ^x + + _ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x) }