aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2010-09-27 15:03:15 -0700
committerRobert Griesemer <gri@golang.org>2010-09-27 15:03:15 -0700
commit9ff4565e2b300c0fc6fdf9bcaa45f0baa789bf36 (patch)
tree733020a66e500a95813cd4567f5f4f79df16bf85
parent20430f03bc621a42750ea6df14e56e4ed5632e89 (diff)
downloadgo-9ff4565e2b300c0fc6fdf9bcaa45f0baa789bf36.tar.gz
go-9ff4565e2b300c0fc6fdf9bcaa45f0baa789bf36.zip
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
-rw-r--r--src/pkg/go/printer/nodes.go7
-rw-r--r--src/pkg/go/printer/printer.go29
-rw-r--r--src/pkg/go/printer/testdata/expressions.golden11
-rw-r--r--src/pkg/go/printer/testdata/expressions.input11
-rw-r--r--src/pkg/go/printer/testdata/expressions.raw11
5 files changed, 65 insertions, 4 deletions
diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go
index 2451116fdb..3e8f12100b 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 b985f6ed3e..cdc8cf518d 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 02bae49b48..b5dac45a7b 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 7d5889b064..3eb1629317 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 9e83892e87..e571d08284 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)
}