]>
Commit | Line | Data |
---|---|---|
7a938933 ILT |
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 | ||
5 | package expressions | |
6 | ||
7 | type T struct { | |
8 | x, y, z int | |
9 | } | |
10 | ||
11 | var ( | |
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 | ||
7a938933 ILT |
20 | func _() { |
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) | |
7a938933 | 96 | |
9ff56c95 ILT |
97 | // the parser does not restrict expressions that may appear as statements |
98 | true | |
99 | 42 | |
100 | "foo" | |
101 | x | |
102 | (x) | |
7a938933 ILT |
103 | a + b |
104 | a + b + c | |
7a938933 | 105 | a + (b * c) |
9ff56c95 ILT |
106 | a + (b / c) |
107 | 1 + a | |
108 | a + 1 | |
109 | s[a] | |
110 | x << 1 | |
111 | (s[0] << 1) & 0xf | |
112 | "foo" + s | |
113 | x == y | |
114 | x < y || z > 42 | |
115 | } | |
116 | ||
9ff56c95 ILT |
117 | func _() { |
118 | _ = a + b | |
119 | _ = a + b + c | |
120 | _ = a + b*c | |
121 | _ = a + (b * c) | |
122 | _ = (a + b) * c | |
123 | _ = a + (b * c * d) | |
124 | _ = a + (b*c + d) | |
7a938933 | 125 | |
9ff56c95 ILT |
126 | _ = 1 << x |
127 | _ = -1 << x | |
128 | _ = 1<<x - 1 | |
129 | _ = -1<<x - 1 | |
7a938933 | 130 | |
9ff56c95 ILT |
131 | _ = f(a + b) |
132 | _ = f(a + b + c) | |
133 | _ = f(a + b*c) | |
134 | _ = f(a + (b * c)) | |
135 | _ = f(1<<x-1, 1<<x-2) | |
7a938933 | 136 | |
9ff56c95 | 137 | _ = 1<<d.logWindowSize - 1 |
7a938933 ILT |
138 | |
139 | buf = make(x, 2*cap(b.buf)+n) | |
140 | ||
141 | dst[i*3+2] = dbuf[0] << 2 | |
142 | dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4 | |
143 | ||
144 | b.buf = b.buf[0 : b.off+m+n] | |
145 | b.buf = b.buf[0 : b.off+m*n] | |
146 | f(b.buf[0 : b.off+m+n]) | |
147 | ||
148 | signed += ' ' * 8 | |
149 | tw.octal(header[148:155], chksum) | |
150 | ||
9ff56c95 | 151 | _ = x > 0 && i >= 0 |
7a938933 ILT |
152 | |
153 | x1, x0 := x>>w2, x&m2 | |
154 | z0 = t1<<w2 + t0 | |
155 | z1 = (t1 + t0>>w2) >> w2 | |
156 | q1, r1 := x1/d1, x1%d1 | |
157 | r1 = r1*b2 | x0>>w2 | |
158 | x1 = (x1 << z) | (x0 >> (uint(w) - z)) | |
159 | x1 = x1<<z | x0>>(uint(w)-z) | |
160 | ||
9ff56c95 ILT |
161 | _ = buf[0 : len(buf)+1] |
162 | _ = buf[0 : n+1] | |
7a938933 ILT |
163 | |
164 | a, b = b, a | |
165 | a = b + c | |
166 | a = b*c + d | |
9ff56c95 ILT |
167 | _ = a*b + c |
168 | _ = a - b - c | |
169 | _ = a - (b - c) | |
170 | _ = a - b*c | |
171 | _ = a - (b * c) | |
172 | _ = a * b / c | |
173 | _ = a / *b | |
174 | _ = x[a|^b] | |
175 | _ = x[a / *b] | |
176 | _ = a & ^b | |
177 | _ = a + +b | |
178 | _ = a - -b | |
179 | _ = x[a*-b] | |
180 | _ = x[a + +b] | |
181 | _ = x ^ y ^ z | |
182 | _ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF] | |
183 | _ = len(longVariableName) * 2 | |
184 | ||
185 | _ = token(matchType + xlength<<lengthShift + xoffset) | |
7a938933 ILT |
186 | } |
187 | ||
7a938933 ILT |
188 | func f(x int, args ...int) { |
189 | f(0, args...) | |
190 | f(1, args) | |
191 | f(2, args[0]) | |
192 | ||
193 | // make sure syntactically legal code remains syntactically legal | |
194 | f(3, 42 ...) // a blank must remain between 42 and ... | |
195 | f(4, 42....) | |
196 | f(5, 42....) | |
197 | f(6, 42.0...) | |
198 | f(7, 42.0...) | |
199 | f(8, .42...) | |
200 | f(9, .42...) | |
201 | f(10, 42e0...) | |
202 | f(11, 42e0...) | |
203 | ||
204 | _ = 42 .x // a blank must remain between 42 and .x | |
205 | _ = 42..x | |
206 | _ = 42..x | |
207 | _ = 42.0.x | |
208 | _ = 42.0.x | |
209 | _ = .42.x | |
210 | _ = .42.x | |
211 | _ = 42e0.x | |
212 | _ = 42e0.x | |
213 | ||
214 | // a blank must remain between the binary operator and the 2nd operand | |
215 | _ = x / *y | |
216 | _ = x < -1 | |
217 | _ = x < <-1 | |
218 | _ = x + +1 | |
219 | _ = x - -1 | |
220 | _ = x & &x | |
221 | _ = x & ^x | |
222 | ||
223 | _ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x) | |
224 | } | |
225 | ||
7a938933 ILT |
226 | func _() { |
227 | _ = T{} | |
228 | _ = struct{}{} | |
229 | _ = [10]T{} | |
230 | _ = [...]T{} | |
231 | _ = []T{} | |
232 | _ = map[int]T{} | |
233 | } | |
234 | ||
7a938933 ILT |
235 | // one-line structs/interfaces in composite literals (up to a threshold) |
236 | func _() { | |
237 | _ = struct{}{} | |
238 | _ = struct{ x int }{0} | |
239 | _ = struct{ x, y, z int }{0, 1, 2} | |
240 | _ = struct{ int }{0} | |
8039ca76 | 241 | _ = struct{ s struct{ int } }{struct{ int }{0}} |
7a938933 ILT |
242 | } |
243 | ||
7a938933 ILT |
244 | func _() { |
245 | // do not modify literals | |
246 | _ = "tab1 tab2 tab3 end" // string contains 3 tabs | |
247 | _ = "tab1 tab2 tab3 end" // same string with 3 blanks - may be unaligned because editors see tabs in strings | |
248 | _ = "" // this comment should be aligned with the one on the previous line | |
249 | _ = `` | |
250 | _ = ` | |
251 | ` | |
252 | _ = `foo | |
253 | bar` | |
254 | _ = `three spaces before the end of the line starting here: | |
f72f4169 ILT |
255 | they must not be removed` |
256 | } | |
5133f00e | 257 | |
5133f00e ILT |
258 | func _() { |
259 | // smart handling of indentation for multi-line raw strings | |
260 | var _ = `` | |
261 | var _ = `foo` | |
262 | var _ = `foo | |
263 | bar` | |
264 | ||
265 | var _ = `` | |
266 | var _ = `foo` | |
267 | var _ = | |
f72f4169 ILT |
268 | // the next line should remain indented |
269 | `foo | |
5133f00e ILT |
270 | bar` |
271 | ||
272 | var _ = // comment | |
273 | `` | |
274 | var _ = // comment | |
275 | `foo` | |
276 | var _ = // comment | |
f72f4169 ILT |
277 | // the next line should remain indented |
278 | `foo | |
5133f00e ILT |
279 | bar` |
280 | ||
281 | var _ = /* comment */ `` | |
282 | var _ = /* comment */ `foo` | |
283 | var _ = /* comment */ `foo | |
284 | bar` | |
285 | ||
286 | var _ = /* comment */ | |
287 | `` | |
288 | var _ = /* comment */ | |
289 | `foo` | |
290 | var _ = /* comment */ | |
f72f4169 ILT |
291 | // the next line should remain indented |
292 | `foo | |
5133f00e ILT |
293 | bar` |
294 | ||
295 | var board = []int( | |
f72f4169 | 296 | `........... |
5133f00e ILT |
297 | ........... |
298 | ....●●●.... | |
299 | ....●●●.... | |
300 | ..●●●●●●●.. | |
301 | ..●●●○●●●.. | |
302 | ..●●●●●●●.. | |
303 | ....●●●.... | |
304 | ....●●●.... | |
305 | ........... | |
306 | ........... | |
307 | `) | |
308 | ||
309 | var state = S{ | |
310 | "foo", | |
f72f4169 ILT |
311 | // the next line should remain indented |
312 | `........... | |
5133f00e ILT |
313 | ........... |
314 | ....●●●.... | |
315 | ....●●●.... | |
316 | ..●●●●●●●.. | |
317 | ..●●●○●●●.. | |
318 | ..●●●●●●●.. | |
319 | ....●●●.... | |
320 | ....●●●.... | |
321 | ........... | |
322 | ........... | |
323 | `, | |
324 | "bar", | |
325 | } | |
7a938933 ILT |
326 | } |
327 | ||
7a938933 ILT |
328 | func _() { |
329 | // one-line function literals (body is on a single line) | |
330 | _ = func() {} | |
331 | _ = func() int { return 0 } | |
332 | _ = func(x, y int) bool { m := (x + y) / 2; return m < 0 } | |
333 | ||
334 | // multi-line function literals (body is not on one line) | |
335 | _ = func() { | |
336 | } | |
337 | _ = func() int { | |
338 | return 0 | |
339 | } | |
340 | _ = func(x, y int) bool { | |
341 | m := (x + y) / 2 | |
342 | return x < y | |
343 | } | |
344 | ||
345 | f(func() { | |
346 | }) | |
347 | f(func() int { | |
348 | return 0 | |
349 | }) | |
350 | f(func(x, y int) bool { | |
351 | m := (x + y) / 2 | |
352 | return x < y | |
353 | }) | |
354 | } | |
355 | ||
7a938933 ILT |
356 | func _() { |
357 | _ = [][]int{ | |
358 | []int{1}, | |
359 | []int{1, 2}, | |
360 | []int{1, 2, 3}, | |
361 | } | |
362 | _ = [][]int{ | |
363 | {1}, | |
364 | []int{1, 2}, | |
365 | []int{1, 2, 3}, | |
366 | } | |
367 | _ = [][]int{ | |
368 | {1}, | |
369 | {1, 2}, | |
370 | {1, 2, 3}, | |
371 | } | |
372 | _ = [][]int{{1}, {1, 2}, {1, 2, 3}} | |
373 | } | |
374 | ||
7a938933 ILT |
375 | // various multi-line expressions |
376 | func _() { | |
377 | // do not add extra indentation to multi-line string lists | |
378 | _ = "foo" + "bar" | |
379 | _ = "foo" + | |
380 | "bar" + | |
381 | "bah" | |
382 | _ = []string{ | |
383 | "abc" + | |
384 | "def", | |
385 | "foo" + | |
386 | "bar", | |
387 | } | |
388 | } | |
389 | ||
7a938933 ILT |
390 | const _ = F1 + |
391 | `string = "%s";` + | |
392 | `ptr = *;` + | |
393 | `datafmt.T2 = s ["-" p "-"];` | |
394 | ||
7a938933 ILT |
395 | const _ = `datafmt "datafmt";` + |
396 | `default = "%v";` + | |
397 | `array = *;` + | |
398 | `datafmt.T3 = s {" " a a / ","};` | |
399 | ||
7a938933 ILT |
400 | const _ = `datafmt "datafmt";` + |
401 | `default = "%v";` + | |
402 | `array = *;` + | |
403 | `datafmt.T3 = s {" " a a / ","};` | |
404 | ||
7a938933 ILT |
405 | func _() { |
406 | _ = F1 + | |
407 | `string = "%s";` + | |
408 | `ptr = *;` + | |
409 | `datafmt.T2 = s ["-" p "-"];` | |
410 | ||
411 | _ = | |
412 | `datafmt "datafmt";` + | |
413 | `default = "%v";` + | |
414 | `array = *;` + | |
415 | `datafmt.T3 = s {" " a a / ","};` | |
416 | ||
417 | _ = `datafmt "datafmt";` + | |
418 | `default = "%v";` + | |
419 | `array = *;` + | |
420 | `datafmt.T3 = s {" " a a / ","};` | |
421 | } | |
422 | ||
7a938933 ILT |
423 | func _() { |
424 | // respect source lines in multi-line expressions | |
425 | _ = a + | |
426 | b + | |
427 | c | |
428 | _ = a < b || | |
429 | b < a | |
430 | _ = "933262154439441526816992388562667004907159682643816214685929" + | |
431 | "638952175999932299156089414639761565182862536979208272237582" + | |
432 | "51185210916864000000000000000000000000" // 100! | |
433 | _ = "170141183460469231731687303715884105727" // prime | |
434 | } | |
435 | ||
7a938933 ILT |
436 | // Alignment after overlong lines |
437 | const ( | |
438 | _ = "991" | |
439 | _ = "2432902008176640000" // 20! | |
440 | _ = "933262154439441526816992388562667004907159682643816214685929" + | |
441 | "638952175999932299156089414639761565182862536979208272237582" + | |
442 | "51185210916864000000000000000000000000" // 100! | |
443 | _ = "170141183460469231731687303715884105727" // prime | |
444 | ) | |
445 | ||
7a938933 ILT |
446 | // Correct placement of operators and comments in multi-line expressions |
447 | func _() { | |
448 | _ = a + // comment | |
449 | b + // comment | |
450 | c | |
451 | _ = "a" + | |
452 | "b" + // comment | |
453 | "c" | |
454 | _ = "ba0408" + "7265717569726564" // field 71, encoding 2, string "required" | |
455 | } | |
456 | ||
7a938933 ILT |
457 | // Correct placement of terminating comma/closing parentheses in multi-line calls. |
458 | func _() { | |
459 | f(1, | |
460 | 2, | |
461 | 3) | |
462 | f(1, | |
463 | 2, | |
464 | 3, | |
465 | ) | |
466 | f(1, | |
467 | 2, | |
468 | 3) // comment | |
469 | f(1, | |
470 | 2, | |
471 | 3, // comment | |
472 | ) | |
473 | f(1, | |
474 | 2, | |
475 | 3) // comment | |
476 | f(1, | |
477 | 2, | |
478 | 3, // comment | |
479 | ) | |
480 | } | |
481 | ||
7a938933 ILT |
482 | // Align comments in multi-line lists of single-line expressions. |
483 | var txpix = [NCOL]draw.Color{ | |
484 | draw.Yellow, // yellow | |
485 | draw.Cyan, // cyan | |
486 | draw.Green, // lime green | |
487 | draw.GreyBlue, // slate | |
488 | draw.Red, /* red */ | |
489 | draw.GreyGreen, /* olive green */ | |
490 | draw.Blue, /* blue */ | |
491 | draw.Color(0xFF55AAFF), /* pink */ | |
492 | draw.Color(0xFFAAFFFF), /* lavender */ | |
493 | draw.Color(0xBB005DFF), /* maroon */ | |
494 | } | |
495 | ||
7a938933 ILT |
496 | func same(t, u *Time) bool { |
497 | // respect source lines in multi-line expressions | |
498 | return t.Year == u.Year && | |
499 | t.Month == u.Month && | |
500 | t.Day == u.Day && | |
501 | t.Hour == u.Hour && | |
502 | t.Minute == u.Minute && | |
503 | t.Second == u.Second && | |
504 | t.Weekday == u.Weekday && | |
505 | t.ZoneOffset == u.ZoneOffset && | |
506 | t.Zone == u.Zone | |
507 | } | |
508 | ||
7a938933 ILT |
509 | func (p *parser) charClass() { |
510 | // respect source lines in multi-line expressions | |
511 | if cc.negate && len(cc.ranges) == 2 && | |
512 | cc.ranges[0] == '\n' && cc.ranges[1] == '\n' { | |
513 | nl := new(_NotNl) | |
514 | p.re.add(nl) | |
515 | } | |
516 | } | |
517 | ||
7a938933 ILT |
518 | func addState(s []state, inst instr, match []int) { |
519 | // handle comments correctly in multi-line expressions | |
520 | for i := 0; i < l; i++ { | |
521 | if s[i].inst.index() == index && // same instruction | |
522 | s[i].match[0] < pos { // earlier match already going; leftmost wins | |
523 | return s | |
524 | } | |
525 | } | |
526 | } | |
527 | ||
528 | func (self *T) foo(x int) *T { return self } | |
529 | ||
530 | func _() { module.Func1().Func2() } | |
531 | ||
532 | func _() { | |
533 | _ = new(T). | |
534 | foo(1). | |
535 | foo(2). | |
536 | foo(3) | |
537 | ||
538 | _ = new(T). | |
539 | foo(1). | |
540 | foo(2). // inline comments | |
541 | foo(3) | |
542 | ||
543 | _ = new(T).foo(1).foo(2).foo(3) | |
544 | ||
545 | // handle multiline argument list correctly | |
546 | _ = new(T). | |
547 | foo( | |
501699af | 548 | 1). |
7a938933 ILT |
549 | foo(2) |
550 | ||
551 | _ = new(T).foo( | |
552 | 1).foo(2) | |
553 | ||
554 | _ = Array[3+ | |
555 | 4] | |
556 | ||
557 | _ = Method(1, 2, | |
558 | 3) | |
559 | ||
560 | _ = new(T). | |
561 | foo(). | |
562 | bar().(*Type) | |
563 | ||
564 | _ = new(T). | |
565 | foo(). | |
566 | bar().(*Type). | |
567 | baz() | |
568 | ||
569 | _ = new(T). | |
570 | foo(). | |
571 | bar()["idx"] | |
572 | ||
573 | _ = new(T). | |
574 | foo(). | |
575 | bar()["idx"]. | |
576 | baz() | |
577 | ||
578 | _ = new(T). | |
579 | foo(). | |
580 | bar()[1:2] | |
581 | ||
582 | _ = new(T). | |
583 | foo(). | |
584 | bar()[1:2]. | |
585 | baz() | |
586 | ||
587 | _ = new(T). | |
588 | Field. | |
589 | Array[3+ | |
501699af | 590 | 4]. |
7a938933 ILT |
591 | Table["foo"]. |
592 | Blob.(*Type). | |
593 | Slices[1:4]. | |
594 | Method(1, 2, | |
501699af | 595 | 3). |
7a938933 ILT |
596 | Thingy |
597 | ||
598 | _ = a.b.c | |
599 | _ = a. | |
600 | b. | |
601 | c | |
602 | _ = a.b().c | |
603 | _ = a. | |
604 | b(). | |
605 | c | |
606 | _ = a.b[0].c | |
607 | _ = a. | |
608 | b[0]. | |
609 | c | |
610 | _ = a.b[0:].c | |
611 | _ = a. | |
612 | b[0:]. | |
613 | c | |
614 | _ = a.b.(T).c | |
615 | _ = a. | |
616 | b.(T). | |
617 | c | |
618 | } | |
f72f4169 | 619 | |
f72f4169 ILT |
620 | // Don't introduce extra newlines in strangely formatted expression lists. |
621 | func f() { | |
622 | // os.Open parameters should remain on two lines | |
623 | if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE| | |
adb0401d | 624 | os.O_TRUNC, 0666); err != nil { |
f72f4169 ILT |
625 | log.Fatal(err) |
626 | } | |
627 | } | |
593f74bb ILT |
628 | |
629 | // Handle multi-line argument lists ending in ... correctly. | |
630 | // Was issue 3130. | |
631 | func _() { | |
632 | _ = append(s, a...) | |
633 | _ = append( | |
634 | s, a...) | |
635 | _ = append(s, | |
636 | a...) | |
637 | _ = append( | |
638 | s, | |
639 | a...) | |
640 | _ = append(s, a..., | |
641 | ) | |
642 | _ = append(s, | |
643 | a..., | |
644 | ) | |
645 | _ = append( | |
646 | s, | |
647 | a..., | |
648 | ) | |
649 | } | |
4ccad563 ILT |
650 | |
651 | // Literal function types in conversions must be parenthesized; | |
652 | // for now go/parser accepts the unparenthesized form where it | |
653 | // is non-ambiguous. | |
654 | func _() { | |
655 | // these conversions should be rewritten to look | |
656 | // the same as the parenthesized conversions below | |
657 | _ = (func())(nil) | |
658 | _ = (func(x int) float)(nil) | |
659 | _ = (func() func() func())(nil) | |
660 | ||
661 | _ = (func())(nil) | |
662 | _ = (func(x int) float)(nil) | |
663 | _ = (func() func() func())(nil) | |
664 | } |