blob: 8c523b60221c9d6e5b39b993fd71ee3208d5fb14 [file] [log] [blame]
// 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()
},
)
}