| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package expressions |
| |
| type T struct { |
| x, y, z int |
| } |
| |
| var ( |
| a, b, c, d, e int |
| under_bar int |
| longIdentifier1, longIdentifier2, longIdentifier3 int |
| t0, t1, t2 T |
| s string |
| p *int |
| ) |
| |
| func _() { |
| // no spaces around simple or parenthesized expressions |
| _ = (a + 0) |
| _ = a + b |
| _ = a + b + c |
| _ = a + b - c |
| _ = a - b - c |
| _ = a + (b * c) |
| _ = a + (b / c) |
| _ = a - (b % c) |
| _ = 1 + a |
| _ = a + 1 |
| _ = a + b + 1 |
| _ = s[a] |
| _ = s[a:] |
| _ = s[:b] |
| _ = s[1:2] |
| _ = s[a:b] |
| _ = s[0:len(s)] |
| _ = s[0] << 1 |
| _ = (s[0] << 1) & 0xf |
| _ = s[0]<<2 | s[1]>>4 |
| _ = "foo" + s |
| _ = s + "foo" |
| _ = 'a' + 'b' |
| _ = len(s) / 2 |
| _ = len(t0.x) / a |
| |
| // spaces around expressions of different precedence or expressions containing spaces |
| _ = a + -b |
| _ = a - ^b |
| _ = a / *p |
| _ = a + b*c |
| _ = 1 + b*c |
| _ = a + 2*c |
| _ = a + c*2 |
| _ = 1 + 2*3 |
| _ = s[1 : 2*3] |
| _ = s[a : b-c] |
| _ = s[0:] |
| _ = s[a+b] |
| _ = s[:b-c] |
| _ = s[a+b:] |
| _ = a[a<<b+1] |
| _ = a[a<<b+1:] |
| _ = s[a+b : len(s)] |
| _ = s[len(s):-a] |
| _ = s[a : len(s)+1] |
| _ = s[a:len(s)+1] + s |
| |
| // spaces around operators with equal or lower precedence than comparisons |
| _ = a == b |
| _ = a != b |
| _ = a > b |
| _ = a >= b |
| _ = a < b |
| _ = a <= b |
| _ = a < b && c > d |
| _ = a < b || c > d |
| |
| // spaces around "long" operands |
| _ = a + longIdentifier1 |
| _ = longIdentifier1 + a |
| _ = longIdentifier1 + longIdentifier2*longIdentifier3 |
| _ = s + "a longer string" |
| |
| // some selected cases |
| _ = a + t0.x |
| _ = a + t0.x + t1.x*t2.x |
| _ = a + b + c + d + e + 2*3 |
| _ = a + b + c + 2*3 + d + e |
| _ = (a + b + c) * 2 |
| _ = a - b + c - d + (a + b + c) + d&e |
| _ = under_bar - 1 |
| _ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666) |
| _ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx) |
| |
| // test case for issue 8021 |
| // want: |
| // ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]] |
| _ = ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]] |
| |
| // the parser does not restrict expressions that may appear as statements |
| true |
| 42 |
| "foo" |
| x |
| (x) |
| a + b |
| a + b + c |
| a + (b * c) |
| a + (b / c) |
| 1 + a |
| a + 1 |
| s[a] |
| x << 1 |
| (s[0] << 1) & 0xf |
| "foo" + s |
| x == y |
| x < y || z > 42 |
| } |
| |
| // slice expressions with cap |
| func _() { |
| _ = x[a:b:c] |
| _ = x[a:b : c+d] |
| _ = x[a : b+d : c] |
| _ = x[a : b+d : c+d] |
| _ = x[a+d : b:c] |
| _ = x[a+d : b : c+d] |
| _ = x[a+d : b+d : c] |
| _ = x[a+d : b+d : c+d] |
| |
| _ = x[:b:c] |
| _ = x[:b : c+d] |
| _ = x[:b+d : c] |
| _ = x[:b+d : c+d] |
| } |
| |
| func _() { |
| _ = a + b |
| _ = a + b + c |
| _ = a + b*c |
| _ = a + (b * c) |
| _ = (a + b) * c |
| _ = a + (b * c * d) |
| _ = a + (b*c + d) |
| |
| _ = 1 << x |
| _ = -1 << x |
| _ = 1<<x - 1 |
| _ = -1<<x - 1 |
| |
| _ = f(a + b) |
| _ = f(a + b + c) |
| _ = f(a + b*c) |
| _ = f(a + (b * c)) |
| _ = f(1<<x-1, 1<<x-2) |
| |
| _ = 1<<d.logWindowSize - 1 |
| |
| buf = make(x, 2*cap(b.buf)+n) |
| |
| dst[i*3+2] = dbuf[0] << 2 |
| dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4 |
| |
| b.buf = b.buf[0 : b.off+m+n] |
| b.buf = b.buf[0 : b.off+m*n] |
| f(b.buf[0 : b.off+m+n]) |
| |
| signed += ' ' * 8 |
| tw.octal(header[148:155], chksum) |
| |
| _ = x > 0 && i >= 0 |
| |
| x1, x0 := x>>w2, x&m2 |
| z0 = t1<<w2 + t0 |
| z1 = (t1 + t0>>w2) >> w2 |
| q1, r1 := x1/d1, x1%d1 |
| r1 = r1*b2 | x0>>w2 |
| x1 = (x1 << z) | (x0 >> (uint(w) - z)) |
| x1 = x1<<z | x0>>(uint(w)-z) |
| |
| _ = buf[0 : len(buf)+1] |
| _ = buf[0 : n+1] |
| |
| a, b = b, a |
| a = b + c |
| a = b*c + d |
| _ = a*b + c |
| _ = a - b - c |
| _ = a - (b - c) |
| _ = a - b*c |
| _ = a - (b * c) |
| _ = a * b / c |
| _ = a / *b |
| _ = x[a|^b] |
| _ = x[a / *b] |
| _ = a & ^b |
| _ = a + +b |
| _ = a - -b |
| _ = x[a*-b] |
| _ = x[a + +b] |
| _ = x ^ y ^ z |
| _ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF] |
| _ = len(longVariableName) * 2 |
| |
| _ = token(matchType + xlength<<lengthShift + xoffset) |
| } |
| |
| func f(x int, args ...int) { |
| f(0, args...) |
| f(1, args) |
| f(2, args[0]) |
| |
| // make sure syntactically legal code remains syntactically legal |
| f(3, 42 ...) // a blank must remain between 42 and ... |
| f(4, 42....) |
| f(5, 42....) |
| f(6, 42.0...) |
| f(7, 42.0...) |
| f(8, .42...) |
| f(9, .42...) |
| f(10, 42e0...) |
| f(11, 42e0...) |
| |
| _ = 42 .x // a blank must remain between 42 and .x |
| _ = 42..x |
| _ = 42..x |
| _ = 42.0.x |
| _ = 42.0.x |
| _ = .42.x |
| _ = .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) |
| } |
| |
| func _() { |
| _ = T{} |
| _ = struct{}{} |
| _ = [10]T{} |
| _ = [...]T{} |
| _ = []T{} |
| _ = map[int]T{} |
| } |
| |
| // one-line structs/interfaces in composite literals (up to a threshold) |
| func _() { |
| _ = struct{}{} |
| _ = struct{ x int }{0} |
| _ = struct{ x, y, z int }{0, 1, 2} |
| _ = struct{ int }{0} |
| _ = struct{ s struct{ int } }{struct{ int }{0}} |
| } |
| |
| func _() { |
| // do not modify literals |
| _ = "tab1 tab2 tab3 end" // string contains 3 tabs |
| _ = "tab1 tab2 tab3 end" // same string with 3 blanks - may be unaligned because editors see tabs in strings |
| _ = "" // this comment should be aligned with the one on the previous line |
| _ = `` |
| _ = ` |
| ` |
| _ = `foo |
| bar` |
| _ = `three spaces before the end of the line starting here: |
| they must not be removed` |
| } |
| |
| func _() { |
| // smart handling of indentation for multi-line raw strings |
| var _ = `` |
| var _ = `foo` |
| var _ = `foo |
| bar` |
| |
| var _ = `` |
| var _ = `foo` |
| var _ = |
| // the next line should remain indented |
| `foo |
| bar` |
| |
| var _ = // comment |
| `` |
| var _ = // comment |
| `foo` |
| var _ = // comment |
| // the next line should remain indented |
| `foo |
| bar` |
| |
| var _ = /* comment */ `` |
| var _ = /* comment */ `foo` |
| var _ = /* comment */ `foo |
| bar` |
| |
| var _ = /* comment */ |
| `` |
| var _ = /* comment */ |
| `foo` |
| var _ = /* comment */ |
| // the next line should remain indented |
| `foo |
| bar` |
| |
| var board = []int( |
| `........... |
| ........... |
| ....●●●.... |
| ....●●●.... |
| ..●●●●●●●.. |
| ..●●●○●●●.. |
| ..●●●●●●●.. |
| ....●●●.... |
| ....●●●.... |
| ........... |
| ........... |
| `) |
| |
| var state = S{ |
| "foo", |
| // the next line should remain indented |
| `........... |
| ........... |
| ....●●●.... |
| ....●●●.... |
| ..●●●●●●●.. |
| ..●●●○●●●.. |
| ..●●●●●●●.. |
| ....●●●.... |
| ....●●●.... |
| ........... |
| ........... |
| `, |
| "bar", |
| } |
| } |
| |
| func _() { |
| // one-line function literals (body is on a single line) |
| _ = func() {} |
| _ = func() int { return 0 } |
| _ = func(x, y int) bool { m := (x + y) / 2; return m < 0 } |
| |
| // multi-line function literals (body is not on one line) |
| _ = func() { |
| } |
| _ = func() int { |
| return 0 |
| } |
| _ = func(x, y int) bool { |
| m := (x + y) / 2 |
| return x < y |
| } |
| |
| f(func() { |
| }) |
| f(func() int { |
| return 0 |
| }) |
| f(func(x, y int) bool { |
| m := (x + y) / 2 |
| return x < y |
| }) |
| } |
| |
| func _() { |
| _ = [][]int{ |
| []int{1}, |
| []int{1, 2}, |
| []int{1, 2, 3}, |
| } |
| _ = [][]int{ |
| {1}, |
| []int{1, 2}, |
| []int{1, 2, 3}, |
| } |
| _ = [][]int{ |
| {1}, |
| {1, 2}, |
| {1, 2, 3}, |
| } |
| _ = [][]int{{1}, {1, 2}, {1, 2, 3}} |
| } |
| |
| // various multi-line expressions |
| func _() { |
| // do not add extra indentation to multi-line string lists |
| _ = "foo" + "bar" |
| _ = "foo" + |
| "bar" + |
| "bah" |
| _ = []string{ |
| "abc" + |
| "def", |
| "foo" + |
| "bar", |
| } |
| } |
| |
| const _ = F1 + |
| `string = "%s";` + |
| `ptr = *;` + |
| `datafmt.T2 = s ["-" p "-"];` |
| |
| const _ = `datafmt "datafmt";` + |
| `default = "%v";` + |
| `array = *;` + |
| `datafmt.T3 = s {" " a a / ","};` |
| |
| const _ = `datafmt "datafmt";` + |
| `default = "%v";` + |
| `array = *;` + |
| `datafmt.T3 = s {" " a a / ","};` |
| |
| func _() { |
| _ = F1 + |
| `string = "%s";` + |
| `ptr = *;` + |
| `datafmt.T2 = s ["-" p "-"];` |
| |
| _ = |
| `datafmt "datafmt";` + |
| `default = "%v";` + |
| `array = *;` + |
| `datafmt.T3 = s {" " a a / ","};` |
| |
| _ = `datafmt "datafmt";` + |
| `default = "%v";` + |
| `array = *;` + |
| `datafmt.T3 = s {" " a a / ","};` |
| } |
| |
| func _() { |
| // respect source lines in multi-line expressions |
| _ = a + |
| b + |
| c |
| _ = a < b || |
| b < a |
| _ = "933262154439441526816992388562667004907159682643816214685929" + |
| "638952175999932299156089414639761565182862536979208272237582" + |
| "51185210916864000000000000000000000000" // 100! |
| _ = "170141183460469231731687303715884105727" // prime |
| } |
| |
| // Alignment after overlong lines |
| const ( |
| _ = "991" |
| _ = "2432902008176640000" // 20! |
| _ = "933262154439441526816992388562667004907159682643816214685929" + |
| "638952175999932299156089414639761565182862536979208272237582" + |
| "51185210916864000000000000000000000000" // 100! |
| _ = "170141183460469231731687303715884105727" // prime |
| ) |
| |
| // Correct placement of operators and comments in multi-line expressions |
| func _() { |
| _ = a + // comment |
| b + // comment |
| c |
| _ = "a" + |
| "b" + // comment |
| "c" |
| _ = "ba0408" + "7265717569726564" // field 71, encoding 2, string "required" |
| } |
| |
| // Correct placement of terminating comma/closing parentheses in multi-line calls. |
| func _() { |
| f(1, |
| 2, |
| 3) |
| f(1, |
| 2, |
| 3, |
| ) |
| f(1, |
| 2, |
| 3) // comment |
| f(1, |
| 2, |
| 3, // comment |
| ) |
| f(1, |
| 2, |
| 3) // comment |
| f(1, |
| 2, |
| 3, // comment |
| ) |
| } |
| |
| // Align comments in multi-line lists of single-line expressions. |
| var txpix = [NCOL]draw.Color{ |
| draw.Yellow, // yellow |
| draw.Cyan, // cyan |
| draw.Green, // lime green |
| draw.GreyBlue, // slate |
| draw.Red, /* red */ |
| draw.GreyGreen, /* olive green */ |
| draw.Blue, /* blue */ |
| draw.Color(0xFF55AAFF), /* pink */ |
| draw.Color(0xFFAAFFFF), /* lavender */ |
| draw.Color(0xBB005DFF), /* maroon */ |
| } |
| |
| func same(t, u *Time) bool { |
| // respect source lines in multi-line expressions |
| return t.Year == u.Year && |
| t.Month == u.Month && |
| t.Day == u.Day && |
| t.Hour == u.Hour && |
| t.Minute == u.Minute && |
| t.Second == u.Second && |
| t.Weekday == u.Weekday && |
| t.ZoneOffset == u.ZoneOffset && |
| t.Zone == u.Zone |
| } |
| |
| func (p *parser) charClass() { |
| // respect source lines in multi-line expressions |
| if cc.negate && len(cc.ranges) == 2 && |
| cc.ranges[0] == '\n' && cc.ranges[1] == '\n' { |
| nl := new(_NotNl) |
| p.re.add(nl) |
| } |
| } |
| |
| func addState(s []state, inst instr, match []int) { |
| // handle comments correctly in multi-line expressions |
| for i := 0; i < l; i++ { |
| if s[i].inst.index() == index && // same instruction |
| s[i].match[0] < pos { // earlier match already going; leftmost wins |
| return s |
| } |
| } |
| } |
| |
| func (self *T) foo(x int) *T { return self } |
| |
| func _() { module.Func1().Func2() } |
| |
| func _() { |
| _ = new(T). |
| foo(1). |
| foo(2). |
| foo(3) |
| |
| _ = new(T). |
| foo(1). |
| foo(2). // inline comments |
| foo(3) |
| |
| _ = new(T).foo(1).foo(2).foo(3) |
| |
| // handle multiline argument list correctly |
| _ = new(T). |
| foo( |
| 1). |
| foo(2) |
| |
| _ = new(T).foo( |
| 1).foo(2) |
| |
| _ = Array[3+ |
| 4] |
| |
| _ = Method(1, 2, |
| 3) |
| |
| _ = new(T). |
| foo(). |
| bar().(*Type) |
| |
| _ = new(T). |
| foo(). |
| bar().(*Type). |
| baz() |
| |
| _ = new(T). |
| foo(). |
| bar()["idx"] |
| |
| _ = new(T). |
| foo(). |
| bar()["idx"]. |
| baz() |
| |
| _ = new(T). |
| foo(). |
| bar()[1:2] |
| |
| _ = new(T). |
| foo(). |
| bar()[1:2]. |
| baz() |
| |
| _ = new(T). |
| Field. |
| Array[3+ |
| 4]. |
| Table["foo"]. |
| Blob.(*Type). |
| Slices[1:4]. |
| Method(1, 2, |
| 3). |
| Thingy |
| |
| _ = a.b.c |
| _ = a. |
| b. |
| c |
| _ = a.b().c |
| _ = a. |
| b(). |
| c |
| _ = a.b[0].c |
| _ = a. |
| b[0]. |
| c |
| _ = a.b[0:].c |
| _ = a. |
| b[0:]. |
| c |
| _ = a.b.(T).c |
| _ = a. |
| b.(T). |
| c |
| } |
| |
| // Don't introduce extra newlines in strangely formatted expression lists. |
| func f() { |
| // os.Open parameters should remain on two lines |
| if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE| |
| os.O_TRUNC, 0666); err != nil { |
| log.Fatal(err) |
| } |
| } |
| |
| // Handle multi-line argument lists ending in ... correctly. |
| // Was issue 3130. |
| func _() { |
| _ = append(s, a...) |
| _ = append( |
| s, a...) |
| _ = append(s, |
| a...) |
| _ = append( |
| s, |
| a...) |
| _ = append(s, a..., |
| ) |
| _ = append(s, |
| a..., |
| ) |
| _ = append( |
| s, |
| a..., |
| ) |
| } |
| |
| // Literal function types in conversions must be parenthesized; |
| // for now go/parser accepts the unparenthesized form where it |
| // is non-ambiguous. |
| func _() { |
| // these conversions should be rewritten to look |
| // the same as the parenthesized conversions below |
| _ = (func())(nil) |
| _ = (func(x int) float)(nil) |
| _ = (func() func() func())(nil) |
| |
| _ = (func())(nil) |
| _ = (func(x int) float)(nil) |
| _ = (func() func() func())(nil) |
| } |
| |
| func _() { |
| _ = f(). |
| f(func() { |
| f() |
| }). |
| f(map[int]int{ |
| 1: 2, |
| 3: 4, |
| }) |
| |
| _ = f(). |
| f( |
| func() { |
| f() |
| }, |
| ) |
| } |