// 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 issue22111() {
_ = x[:]
_ = x[:b]
_ = x[:b+1]
_ = x[a:]
_ = x[a+1:]
_ = x[a:b]
_ = x[a+1 : b]
_ = x[a : b+1]
_ = x[a+1 : b+1]
_ = x[:b:c]
_ = x[: b+1 : c]
_ = x[: b : c+1]
_ = x[: b+1 : c+1]
_ = x[a:b:c]
_ = x[a+1 : b : c]
_ = x[a : b+1 : c]
_ = x[a+1 : b+1 : c]
_ = x[a : b : c+1]
_ = x[a+1 : b : c+1]
_ = x[a : b+1 : c+1]
_ = x[a+1 : b+1 : c+1]
}
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}}
_ = (interface{})(nil)
_ = (interface{ String() string })(nil)
_ = (interface {
String() string
})(nil)
_ = (interface{ fmt.Stringer })(nil)
_ = (interface {
fmt.Stringer
})(nil)
}
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()
},
)
}
|