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