1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package expressions
6
7type T struct {
8 x, y, z int
9}
10
11var (
12 a, b, c, d, e int
13 under_bar int
14 longIdentifier1, longIdentifier2, longIdentifier3 int
15 t0, t1, t2 T
16 s string
17 p *int
18)
19
20func _() {
21 // no spaces around simple or parenthesized expressions
22 _ = (a + 0)
23 _ = a + b
24 _ = a + b + c
25 _ = a + b - c
26 _ = a - b - c
27 _ = a + (b * c)
28 _ = a + (b / c)
29 _ = a - (b % c)
30 _ = 1 + a
31 _ = a + 1
32 _ = a + b + 1
33 _ = s[a]
34 _ = s[a:]
35 _ = s[:b]
36 _ = s[1:2]
37 _ = s[a:b]
38 _ = s[0:len(s)]
39 _ = s[0] << 1
40 _ = (s[0] << 1) & 0xf
41 _ = s[0]<<2 | s[1]>>4
42 _ = "foo" + s
43 _ = s + "foo"
44 _ = 'a' + 'b'
45 _ = len(s) / 2
46 _ = len(t0.x) / a
47
48 // spaces around expressions of different precedence or expressions containing spaces
49 _ = a + -b
50 _ = a - ^b
51 _ = a / *p
52 _ = a + b*c
53 _ = 1 + b*c
54 _ = a + 2*c
55 _ = a + c*2
56 _ = 1 + 2*3
57 _ = s[1 : 2*3]
58 _ = s[a : b-c]
59 _ = s[0:]
60 _ = s[a+b]
61 _ = s[:b-c]
62 _ = s[a+b:]
63 _ = a[a<<b+1]
64 _ = a[a<<b+1:]
65 _ = s[a+b : len(s)]
66 _ = s[len(s):-a]
67 _ = s[a : len(s)+1]
68 _ = s[a:len(s)+1] + s
69
70 // spaces around operators with equal or lower precedence than comparisons
71 _ = a == b
72 _ = a != b
73 _ = a > b
74 _ = a >= b
75 _ = a < b
76 _ = a <= b
77 _ = a < b && c > d
78 _ = a < b || c > d
79
80 // spaces around "long" operands
81 _ = a + longIdentifier1
82 _ = longIdentifier1 + a
83 _ = longIdentifier1 + longIdentifier2*longIdentifier3
84 _ = s + "a longer string"
85
86 // some selected cases
87 _ = a + t0.x
88 _ = a + t0.x + t1.x*t2.x
89 _ = a + b + c + d + e + 2*3
90 _ = a + b + c + 2*3 + d + e
91 _ = (a + b + c) * 2
92 _ = a - b + c - d + (a + b + c) + d&e
93 _ = under_bar - 1
94 _ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666)
95 _ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
96
97 // test case for issue 8021
98 // want:
99 // ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
100 _ = ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
101
102 // the parser does not restrict expressions that may appear as statements
103 true
104 42
105 "foo"
106 x
107 (x)
108 a + b
109 a + b + c
110 a + (b * c)
111 a + (b / c)
112 1 + a
113 a + 1
114 s[a]
115 x << 1
116 (s[0] << 1) & 0xf
117 "foo" + s
118 x == y
119 x < y || z > 42
120}
121
122// slice expressions with cap
123func _() {
124 _ = x[a:b:c]
125 _ = x[a : b : c+d]
126 _ = x[a : b+d : c]
127 _ = x[a : b+d : c+d]
128 _ = x[a+d : b : c]
129 _ = x[a+d : b : c+d]
130 _ = x[a+d : b+d : c]
131 _ = x[a+d : b+d : c+d]
132
133 _ = x[:b:c]
134 _ = x[: b : c+d]
135 _ = x[: b+d : c]
136 _ = x[: b+d : c+d]
137}
138
139func issue22111() {
140 _ = x[:]
141
142 _ = x[:b]
143 _ = x[:b+1]
144
145 _ = x[a:]
146 _ = x[a+1:]
147
148 _ = x[a:b]
149 _ = x[a+1 : b]
150 _ = x[a : b+1]
151 _ = x[a+1 : b+1]
152
153 _ = x[:b:c]
154 _ = x[: b+1 : c]
155 _ = x[: b : c+1]
156 _ = x[: b+1 : c+1]
157
158 _ = x[a:b:c]
159 _ = x[a+1 : b : c]
160 _ = x[a : b+1 : c]
161 _ = x[a+1 : b+1 : c]
162 _ = x[a : b : c+1]
163 _ = x[a+1 : b : c+1]
164 _ = x[a : b+1 : c+1]
165 _ = x[a+1 : b+1 : c+1]
166}
167
168func _() {
169 _ = a + b
170 _ = a + b + c
171 _ = a + b*c
172 _ = a + (b * c)
173 _ = (a + b) * c
174 _ = a + (b * c * d)
175 _ = a + (b*c + d)
176
177 _ = 1 << x
178 _ = -1 << x
179 _ = 1<<x - 1
180 _ = -1<<x - 1
181
182 _ = f(a + b)
183 _ = f(a + b + c)
184 _ = f(a + b*c)
185 _ = f(a + (b * c))
186 _ = f(1<<x-1, 1<<x-2)
187
188 _ = 1<<d.logWindowSize - 1
189
190 buf = make(x, 2*cap(b.buf)+n)
191
192 dst[i*3+2] = dbuf[0] << 2
193 dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
194
195 b.buf = b.buf[0 : b.off+m+n]
196 b.buf = b.buf[0 : b.off+m*n]
197 f(b.buf[0 : b.off+m+n])
198
199 signed += ' ' * 8
200 tw.octal(header[148:155], chksum)
201
202 _ = x > 0 && i >= 0
203
204 x1, x0 := x>>w2, x&m2
205 z0 = t1<<w2 + t0
206 z1 = (t1 + t0>>w2) >> w2
207 q1, r1 := x1/d1, x1%d1
208 r1 = r1*b2 | x0>>w2
209 x1 = (x1 << z) | (x0 >> (uint(w) - z))
210 x1 = x1<<z | x0>>(uint(w)-z)
211
212 _ = buf[0 : len(buf)+1]
213 _ = buf[0 : n+1]
214
215 a, b = b, a
216 a = b + c
217 a = b*c + d
218 _ = a*b + c
219 _ = a - b - c
220 _ = a - (b - c)
221 _ = a - b*c
222 _ = a - (b * c)
223 _ = a * b / c
224 _ = a / *b
225 _ = x[a|^b]
226 _ = x[a / *b]
227 _ = a & ^b
228 _ = a + +b
229 _ = a - -b
230 _ = x[a*-b]
231 _ = x[a + +b]
232 _ = x ^ y ^ z
233 _ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
234 _ = len(longVariableName) * 2
235
236 _ = token(matchType + xlength<<lengthShift + xoffset)
237}
238
239func f(x int, args ...int) {
240 f(0, args...)
241 f(1, args)
242 f(2, args[0])
243
244 // make sure syntactically legal code remains syntactically legal
245 f(3, 42 ...) // a blank must remain between 42 and ...
246 f(4, 42....)
247 f(5, 42....)
248 f(6, 42.0...)
249 f(7, 42.0...)
250 f(8, .42...)
251 f(9, .42...)
252 f(10, 42e0...)
253 f(11, 42e0...)
254
255 _ = 42 .x // a blank must remain between 42 and .x
256 _ = 42..x
257 _ = 42..x
258 _ = 42.0.x
259 _ = 42.0.x
260 _ = .42.x
261 _ = .42.x
262 _ = 42e0.x
263 _ = 42e0.x
264
265 // a blank must remain between the binary operator and the 2nd operand
266 _ = x / *y
267 _ = x < -1
268 _ = x < <-1
269 _ = x + +1
270 _ = x - -1
271 _ = x & &x
272 _ = x & ^x
273
274 _ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x)
275}
276
277func _() {
278 _ = T{}
279 _ = struct{}{}
280 _ = [10]T{}
281 _ = [...]T{}
282 _ = []T{}
283 _ = map[int]T{}
284}
285
286// one-line structs/interfaces in composite literals (up to a threshold)
287func _() {
288 _ = struct{}{}
289 _ = struct{ x int }{0}
290 _ = struct{ x, y, z int }{0, 1, 2}
291 _ = struct{ int }{0}
292 _ = struct{ s struct{ int } }{struct{ int }{0}}
293
294 _ = (interface{})(nil)
295 _ = (interface{ String() string })(nil)
296 _ = (interface {
297 String() string
298 })(nil)
299 _ = (interface{ fmt.Stringer })(nil)
300 _ = (interface {
301 fmt.Stringer
302 })(nil)
303}
304
305func _() {
306 // do not modify literals
307 _ = "tab1 tab2 tab3 end" // string contains 3 tabs
308 _ = "tab1 tab2 tab3 end" // same string with 3 blanks - may be unaligned because editors see tabs in strings
309 _ = "" // this comment should be aligned with the one on the previous line
310 _ = ``
311 _ = `
312`
313 _ = `foo
314 bar`
315 _ = `three spaces before the end of the line starting here:
316they must not be removed`
317}
318
319func _() {
320 // smart handling of indentation for multi-line raw strings
321 var _ = ``
322 var _ = `foo`
323 var _ = `foo
324bar`
325
326 var _ = ``
327 var _ = `foo`
328 var _ =
329 // the next line should remain indented
330 `foo
331bar`
332
333 var _ = // comment
334 ``
335 var _ = // comment
336 `foo`
337 var _ = // comment
338 // the next line should remain indented
339 `foo
340bar`
341
342 var _ = /* comment */ ``
343 var _ = /* comment */ `foo`
344 var _ = /* comment */ `foo
345bar`
346
347 var _ = /* comment */
348 ``
349 var _ = /* comment */
350 `foo`
351 var _ = /* comment */
352 // the next line should remain indented
353 `foo
354bar`
355
356 var board = []int(
357 `...........
358...........
359....●●●....
360....●●●....
361..●●●●●●●..
362..●●●○●●●..
363..●●●●●●●..
364....●●●....
365....●●●....
366...........
367...........
368`)
369
370 var state = S{
371 "foo",
372 // the next line should remain indented
373 `...........
374...........
375....●●●....
376....●●●....
377..●●●●●●●..
378..●●●○●●●..
379..●●●●●●●..
380....●●●....
381....●●●....
382...........
383...........
384`,
385 "bar",
386 }
387}
388
389func _() {
390 // one-line function literals (body is on a single line)
391 _ = func() {}
392 _ = func() int { return 0 }
393 _ = func(x, y int) bool { m := (x + y) / 2; return m < 0 }
394
395 // multi-line function literals (body is not on one line)
396 _ = func() {
397 }
398 _ = func() int {
399 return 0
400 }
401 _ = func(x, y int) bool {
402 m := (x + y) / 2
403 return x < y
404 }
405
406 f(func() {
407 })
408 f(func() int {
409 return 0
410 })
411 f(func(x, y int) bool {
412 m := (x + y) / 2
413 return x < y
414 })
415}
416
417func _() {
418 _ = [][]int{
419 []int{1},
420 []int{1, 2},
421 []int{1, 2, 3},
422 }
423 _ = [][]int{
424 {1},
425 []int{1, 2},
426 []int{1, 2, 3},
427 }
428 _ = [][]int{
429 {1},
430 {1, 2},
431 {1, 2, 3},
432 }
433 _ = [][]int{{1}, {1, 2}, {1, 2, 3}}
434}
435
436// various multi-line expressions
437func _() {
438 // do not add extra indentation to multi-line string lists
439 _ = "foo" + "bar"
440 _ = "foo" +
441 "bar" +
442 "bah"
443 _ = []string{
444 "abc" +
445 "def",
446 "foo" +
447 "bar",
448 }
449}
450
451const _ = F1 +
452 `string = "%s";` +
453 `ptr = *;` +
454 `datafmt.T2 = s ["-" p "-"];`
455
456const _ = `datafmt "datafmt";` +
457 `default = "%v";` +
458 `array = *;` +
459 `datafmt.T3 = s {" " a a / ","};`
460
461const _ = `datafmt "datafmt";` +
462 `default = "%v";` +
463 `array = *;` +
464 `datafmt.T3 = s {" " a a / ","};`
465
466func _() {
467 _ = F1 +
468 `string = "%s";` +
469 `ptr = *;` +
470 `datafmt.T2 = s ["-" p "-"];`
471
472 _ =
473 `datafmt "datafmt";` +
474 `default = "%v";` +
475 `array = *;` +
476 `datafmt.T3 = s {" " a a / ","};`
477
478 _ = `datafmt "datafmt";` +
479 `default = "%v";` +
480 `array = *;` +
481 `datafmt.T3 = s {" " a a / ","};`
482}
483
484func _() {
485 // respect source lines in multi-line expressions
486 _ = a +
487 b +
488 c
489 _ = a < b ||
490 b < a
491 _ = "933262154439441526816992388562667004907159682643816214685929" +
492 "638952175999932299156089414639761565182862536979208272237582" +
493 "51185210916864000000000000000000000000" // 100!
494 _ = "170141183460469231731687303715884105727" // prime
495}
496
497// Alignment after overlong lines
498const (
499 _ = "991"
500 _ = "2432902008176640000" // 20!
501 _ = "933262154439441526816992388562667004907159682643816214685929" +
502 "638952175999932299156089414639761565182862536979208272237582" +
503 "51185210916864000000000000000000000000" // 100!
504 _ = "170141183460469231731687303715884105727" // prime
505)
506
507// Correct placement of operators and comments in multi-line expressions
508func _() {
509 _ = a + // comment
510 b + // comment
511 c
512 _ = "a" +
513 "b" + // comment
514 "c"
515 _ = "ba0408" + "7265717569726564" // field 71, encoding 2, string "required"
516}
517
518// Correct placement of terminating comma/closing parentheses in multi-line calls.
519func _() {
520 f(1,
521 2,
522 3)
523 f(1,
524 2,
525 3,
526 )
527 f(1,
528 2,
529 3) // comment
530 f(1,
531 2,
532 3, // comment
533 )
534 f(1,
535 2,
536 3) // comment
537 f(1,
538 2,
539 3, // comment
540 )
541}
542
543// Align comments in multi-line lists of single-line expressions.
544var txpix = [NCOL]draw.Color{
545 draw.Yellow, // yellow
546 draw.Cyan, // cyan
547 draw.Green, // lime green
548 draw.GreyBlue, // slate
549 draw.Red, /* red */
550 draw.GreyGreen, /* olive green */
551 draw.Blue, /* blue */
552 draw.Color(0xFF55AAFF), /* pink */
553 draw.Color(0xFFAAFFFF), /* lavender */
554 draw.Color(0xBB005DFF), /* maroon */
555}
556
557func same(t, u *Time) bool {
558 // respect source lines in multi-line expressions
559 return t.Year == u.Year &&
560 t.Month == u.Month &&
561 t.Day == u.Day &&
562 t.Hour == u.Hour &&
563 t.Minute == u.Minute &&
564 t.Second == u.Second &&
565 t.Weekday == u.Weekday &&
566 t.ZoneOffset == u.ZoneOffset &&
567 t.Zone == u.Zone
568}
569
570func (p *parser) charClass() {
571 // respect source lines in multi-line expressions
572 if cc.negate && len(cc.ranges) == 2 &&
573 cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
574 nl := new(_NotNl)
575 p.re.add(nl)
576 }
577}
578
579func addState(s []state, inst instr, match []int) {
580 // handle comments correctly in multi-line expressions
581 for i := 0; i < l; i++ {
582 if s[i].inst.index() == index && // same instruction
583 s[i].match[0] < pos { // earlier match already going; leftmost wins
584 return s
585 }
586 }
587}
588
589func (self *T) foo(x int) *T { return self }
590
591func _() { module.Func1().Func2() }
592
593func _() {
594 _ = new(T).
595 foo(1).
596 foo(2).
597 foo(3)
598
599 _ = new(T).
600 foo(1).
601 foo(2). // inline comments
602 foo(3)
603
604 _ = new(T).foo(1).foo(2).foo(3)
605
606 // handle multiline argument list correctly
607 _ = new(T).
608 foo(
609 1).
610 foo(2)
611
612 _ = new(T).foo(
613 1).foo(2)
614
615 _ = Array[3+
616 4]
617
618 _ = Method(1, 2,
619 3)
620
621 _ = new(T).
622 foo().
623 bar().(*Type)
624
625 _ = new(T).
626 foo().
627 bar().(*Type).
628 baz()
629
630 _ = new(T).
631 foo().
632 bar()["idx"]
633
634 _ = new(T).
635 foo().
636 bar()["idx"].
637 baz()
638
639 _ = new(T).
640 foo().
641 bar()[1:2]
642
643 _ = new(T).
644 foo().
645 bar()[1:2].
646 baz()
647
648 _ = new(T).
649 Field.
650 Array[3+
651 4].
652 Table["foo"].
653 Blob.(*Type).
654 Slices[1:4].
655 Method(1, 2,
656 3).
657 Thingy
658
659 _ = a.b.c
660 _ = a.
661 b.
662 c
663 _ = a.b().c
664 _ = a.
665 b().
666 c
667 _ = a.b[0].c
668 _ = a.
669 b[0].
670 c
671 _ = a.b[0:].c
672 _ = a.
673 b[0:].
674 c
675 _ = a.b.(T).c
676 _ = a.
677 b.(T).
678 c
679}
680
681// Don't introduce extra newlines in strangely formatted expression lists.
682func f() {
683 // os.Open parameters should remain on two lines
684 if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
685 os.O_TRUNC, 0666); err != nil {
686 log.Fatal(err)
687 }
688}
689
690// Handle multi-line argument lists ending in ... correctly.
691// Was issue 3130.
692func _() {
693 _ = append(s, a...)
694 _ = append(
695 s, a...)
696 _ = append(s,
697 a...)
698 _ = append(
699 s,
700 a...)
701 _ = append(s, a...,
702 )
703 _ = append(s,
704 a...,
705 )
706 _ = append(
707 s,
708 a...,
709 )
710}
711
712// Literal function types in conversions must be parenthesized;
713// for now go/parser accepts the unparenthesized form where it
714// is non-ambiguous.
715func _() {
716 // these conversions should be rewritten to look
717 // the same as the parenthesized conversions below
718 _ = (func())(nil)
719 _ = (func(x int) float)(nil)
720 _ = (func() func() func())(nil)
721
722 _ = (func())(nil)
723 _ = (func(x int) float)(nil)
724 _ = (func() func() func())(nil)
725}
726
727func _() {
728 _ = f().
729 f(func() {
730 f()
731 }).
732 f(map[int]int{
733 1: 2,
734 3: 4,
735 })
736
737 _ = f().
738 f(
739 func() {
740 f()
741 },
742 )
743}
View as plain text