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// This is a package for testing comment placement by go/printer.
6package main
7
8import "fmt"	// fmt
9
10const c0 = 0	// zero
11const (
12	c1	= iota	// c1
13	c2		// c2
14)
15
16// Alignment of comments in declarations>
17const (
18	_	T	= iota	// comment
19	_			// comment
20	_			// comment
21	_	= iota + 10
22	_	// comments
23
24	_		= 10	// comment
25	_	T	= 20	// comment
26)
27
28const (
29	_____	= iota	// foo
30	_		// bar
31	_	= 0	// bal
32	_		// bat
33)
34
35const (
36	_	T	= iota	// comment
37	_			// comment
38	_			// comment
39	_	= iota + 10
40	_		// comment
41	_		= 10
42	_		= 20	// comment
43	_	T	= 0	// comment
44)
45
46// The SZ struct; it is empty.
47type SZ struct{}
48
49// The S0 struct; no field is exported.
50type S0 struct {
51	int
52	x, y, z	int	// 3 unexported fields
53}
54
55// The S1 struct; some fields are not exported.
56type S1 struct {
57	S0
58	A, B, C	float	// 3 exported fields
59	D, b, c	int	// 2 unexported fields
60}
61
62// The S2 struct; all fields are exported.
63type S2 struct {
64	S1
65	A, B, C	float	// 3 exported fields
66}
67
68// The IZ interface; it is empty.
69type SZ interface{}
70
71// The I0 interface; no method is exported.
72type I0 interface {
73	f(x int) int	// unexported method
74}
75
76// The I1 interface; some methods are not exported.
77type I1 interface {
78	I0
79	F(x float) float	// exported methods
80	g(x int) int		// unexported method
81}
82
83// The I2 interface; all methods are exported.
84type I2 interface {
85	I0
86	F(x float) float	// exported method
87	G(x float) float	// exported method
88}
89
90// The S3 struct; all comments except for the last one must appear in the export.
91type S3 struct {
92	// lead comment for F1
93	F1	int	// line comment for F1
94	// lead comment for F2
95	F2	int	// line comment for F2
96	f3	int	// f3 is not exported
97}
98
99// Here is a comment.
100// Here is an accidentally unindented line.
101// More comment.
102//
103//dir:ect ive
104type directiveCheck struct{}
105
106// This comment group should be separated
107// with a newline from the next comment
108// group.
109
110// This comment should NOT be associated with the next declaration.
111
112var x int	// x
113var ()
114
115// This comment SHOULD be associated with f0.
116func f0() {
117	const pi = 3.14	// pi
118	var s1 struct{}	/* an empty struct */	/* foo */
119	// a struct constructor
120	// --------------------
121	var s2 struct{} = struct{}{}
122	x := pi
123}
124
125// This comment should be associated with f1, with one blank line before the comment.
126func f1() {
127	f0()
128	/* 1 */
129	// 2
130	/* 3 */
131	/* 4 */
132	f0()
133}
134
135func _() {
136	// this comment should be properly indented
137}
138
139func _(x int) int {
140	if x < 0 {	// the tab printed before this comment's // must not affect the remaining lines
141		return -x	// this statement should be properly indented
142	}
143	if x < 0 {	/* the tab printed before this comment's /* must not affect the remaining lines */
144		return -x	// this statement should be properly indented
145	}
146	return x
147}
148
149func typeswitch(x interface{}) {
150	switch v := x.(type) {
151	case bool, int, float:
152	case string:
153	default:
154	}
155
156	switch x.(type) {
157	}
158
159	switch v0, ok := x.(int); v := x.(type) {
160	}
161
162	switch v0, ok := x.(int); x.(type) {
163	case byte:	// this comment should be on the same line as the keyword
164		// this comment should be normally indented
165		_ = 0
166	case bool, int, float:
167		// this comment should be indented
168	case string:
169	default:
170		// this comment should be indented
171	}
172	// this comment should not be indented
173}
174
175//
176// Indentation of comments after possibly indented multi-line constructs
177// (test cases for issue 3147).
178//
179
180func _() {
181	s := 1 +
182		2
183	// should be indented like s
184}
185
186func _() {
187	s := 1 +
188		2	// comment
189	// should be indented like s
190}
191
192func _() {
193	s := 1 +
194		2	// comment
195	// should be indented like s
196	_ = 0
197}
198
199func _() {
200	s := 1 +
201		2
202	// should be indented like s
203	_ = 0
204}
205
206func _() {
207	s := 1 +
208		2
209
210	// should be indented like s
211}
212
213func _() {
214	s := 1 +
215		2	// comment
216
217	// should be indented like s
218}
219
220func _() {
221	s := 1 +
222		2	// comment
223
224	// should be indented like s
225	_ = 0
226}
227
228func _() {
229	s := 1 +
230		2
231
232	// should be indented like s
233	_ = 0
234}
235
236// Test case from issue 3147.
237func f() {
238	templateText := "a" +	// A
239		"b" +	// B
240		"c"	// C
241
242	// should be aligned with f()
243	f()
244}
245
246// Modified test case from issue 3147.
247func f() {
248	templateText := "a" +	// A
249		"b" +	// B
250		"c"	// C
251
252		// may not be aligned with f() (source is not aligned)
253	f()
254}
255
256//
257// Test cases for alignment of lines in general comments.
258//
259
260func _() {
261	/* freestanding comment
262	   aligned		line
263	   aligned line
264	*/
265}
266
267func _() {
268	/* freestanding comment
269	   aligned		line
270	   aligned line
271	*/
272}
273
274func _() {
275	/* freestanding comment
276	   aligned		line
277	   aligned line */
278}
279
280func _() {
281	/*	freestanding comment
282		aligned		line
283		aligned line
284	*/
285}
286
287func _() {
288	/*	freestanding comment
289		aligned		line
290		aligned line
291	*/
292}
293
294func _() {
295	/*	freestanding comment
296		aligned		line
297		aligned line */
298}
299
300func _() {
301	/*
302	   freestanding comment
303	   aligned		line
304	   aligned line
305	*/
306}
307
308func _() {
309	/*
310	   freestanding comment
311	   aligned		line
312	   aligned line
313	*/
314}
315
316func _() {
317	/*
318	   freestanding comment
319	   aligned		line
320	   aligned line */
321}
322
323func _() {
324	/*
325		freestanding comment
326		aligned		line
327		aligned line
328	*/
329}
330
331func _() {
332	/*
333		freestanding comment
334		aligned		line
335		aligned line
336	*/
337}
338
339func _() {
340	/*
341		freestanding comment
342		aligned		line
343		aligned line */
344}
345
346func _() {
347	/* freestanding comment
348	   aligned line
349	*/
350}
351
352func _() {
353	/* freestanding comment
354	   aligned line
355	*/
356}
357
358func _() {
359	/* freestanding comment
360	   aligned line */
361}
362
363func _() {
364	/*	freestanding comment
365		aligned line
366	*/
367}
368
369func _() {
370	/*	freestanding comment
371		aligned line
372	*/
373}
374
375func _() {
376	/*	freestanding comment
377		aligned line */
378}
379
380func _() {
381	/*
382	   freestanding comment
383	   aligned line
384	*/
385}
386
387func _() {
388	/*
389	   freestanding comment
390	   aligned line
391	*/
392}
393
394func _() {
395	/*
396	   freestanding comment
397	   aligned line */
398}
399
400func _() {
401	/*
402		freestanding comment
403		aligned line
404	*/
405}
406
407func _() {
408	/*
409		freestanding comment
410		aligned line
411	*/
412}
413
414func _() {
415	/*
416		freestanding comment
417		aligned line */
418}
419
420// Issue 9751.
421func _() {
422	/*a string
423
424	b string*/
425
426	/*A string
427
428
429
430	Z string*/
431
432	/*a string
433
434	b string
435
436	c string*/
437
438	{
439		/*a string
440		b string*/
441
442		/*a string
443
444		b string*/
445
446		/*a string
447
448		b string
449
450		c string*/
451	}
452
453	{
454		/*a string
455		b string*/
456
457		/*a string
458
459		b string*/
460
461		/*a string
462
463		b string
464
465		c string*/
466	}
467
468	/*
469	 */
470
471	/*
472
473	 */
474
475	/*
476
477	 * line
478
479	 */
480}
481
482/*
483 * line
484 * of
485 * stars
486 */
487
488/* another line
489 * of
490 * stars */
491
492/*	and another line
493 *	of
494 *	stars */
495
496/* a line of
497 * stars */
498
499/*	and another line of
500 *	stars */
501
502/* a line of stars
503 */
504
505/*	and another line of
506 */
507
508/* a line of stars
509 */
510
511/*	and another line of
512 */
513
514/*
515aligned in middle
516here
517        not here
518*/
519
520/*
521blank line in middle:
522
523with no leading spaces on blank line.
524*/
525
526/*
527   aligned in middle
528   here
529           not here
530*/
531
532/*
533	blank line in middle:
534
535	with no leading spaces on blank line.
536*/
537
538func _() {
539	/*
540	 * line
541	 * of
542	 * stars
543	 */
544
545	/*
546		aligned in middle
547		here
548			not here
549	*/
550
551	/*
552		blank line in middle:
553
554		with no leading spaces on blank line.
555	*/
556}
557
558// Some interesting interspersed comments.
559// See below for more common cases.
560func _( /* this */ x /* is */ /* an */ int) {
561}
562
563func _( /* no params - extra blank before and after comment */ )	{}
564func _(a, b int /* params - no extra blank after comment */)		{}
565
566func _()	{ f( /* no args - extra blank before and after comment */ ) }
567func _()	{ f(a, b /* args - no extra blank after comment */) }
568
569func _() {
570	f( /* no args - extra blank before and after comment */ )
571	f(a, b /* args - no extra blank after comment */)
572}
573
574func ( /* comment1 */ T /* comment2 */) _()	{}
575
576func _()	{ /* "short-ish one-line functions with comments are formatted as multi-line functions */ }
577func _()	{ x := 0; /* comment */ y = x /* comment */ }
578
579func _() {
580	_ = 0
581	/* closing curly brace should be on new line */
582}
583
584func _() {
585	_ = []int{0, 1 /* don't introduce a newline after this comment - was issue 1365 */}
586}
587
588// Test cases from issue 1542:
589// Comments must not be placed before commas and cause invalid programs.
590func _() {
591	var a = []int{1, 2	/*jasldf*/}
592	_ = a
593}
594
595func _() {
596	var a = []int{1, 2}/*jasldf
597	 */
598
599	_ = a
600}
601
602func _() {
603	var a = []int{1, 2}// jasldf
604
605	_ = a
606}
607
608// Test cases from issues 11274, 15137:
609// Semicolon must not be lost when multiple statements are on the same line with a comment.
610func _() {
611	x := 0 /**/
612	y := 1
613}
614
615func _() {
616	f()
617	f()
618	f() /* comment */
619	f()
620	f() /* comment */
621	f()
622	f() /* a */ /* b */
623	f()
624	f() /* a */ /* b */
625	f()
626	f() /* a */ /* b */
627	f()
628}
629
630func _() {
631	f() /* a */ /* b */
632}
633
634// Comments immediately adjacent to punctuation followed by a newline
635// remain after the punctuation (looks better and permits alignment of
636// comments).
637func _() {
638	_ = T{
639		1,	// comment after comma
640		2,	/* comment after comma */
641		3,	// comment after comma
642	}
643	_ = T{
644		1,	// comment after comma
645		2,	/* comment after comma */
646		3,	// comment after comma
647	}
648	_ = T{
649		/* comment before literal */ 1,
650		2,	/* comment before comma - ok to move after comma */
651		3,	/* comment before comma - ok to move after comma */
652	}
653
654	for i = 0;	// comment after semicolon
655	i < 9;		/* comment after semicolon */
656	i++ {		// comment after opening curly brace
657	}
658
659	// TODO(gri) the last comment in this example should be aligned */
660	for i = 0;	// comment after semicolon
661	i < 9;		/* comment before semicolon - ok to move after semicolon */
662	i++ /* comment before opening curly brace */ {
663	}
664}
665
666// If there is no newline following punctuation, commas move before the punctuation.
667// This way, commas interspersed in lists stay with the respective expression.
668func f(x /* comment */, y int, z int /* comment */, u, v, w int /* comment */) {
669	f(x /* comment */, y)
670	f(x,	/* comment */
671		y)
672	f(
673		x,	/* comment */
674	)
675}
676
677func g(
678	x int,	/* comment */
679) {
680}
681
682type _ struct {
683	a, b /* comment */, c int
684}
685
686type _ struct {
687	a, b /* comment */, c int
688}
689
690func _() {
691	for a /* comment */, b := range x {
692	}
693}
694
695//extern foo
696func foo()	{}
697
698//export bar
699func bar()	{}
700
701// Print line directives correctly.
702
703// The following is a legal line directive.
704//
705//line foo:1
706func _() {
707	_ = 0
708	// The following is a legal line directive. It must not be indented:
709//line foo:2
710	_ = 1
711
712	// The following is not a legal line directive (it doesn't start in column 1):
713	//line foo:2
714	_ = 2
715
716	// The following is not a legal line directive (missing colon):
717//line foo -3
718	_ = 3
719}
720
721// Line comments with tabs
722func _() {
723	var finput *bufio.Reader	// input file
724	var stderr *bufio.Writer
725	var ftable *bufio.Writer	// y.go file
726	var foutput *bufio.Writer	// y.output file
727
728	var oflag string	// -o [y.go]		- y.go file
729	var vflag string	// -v [y.output]	- y.output file
730	var lflag bool		// -l			- disable line directives
731}
732
733// Trailing white space in comments should be trimmed
734func _() {
735	// This comment has 4 blanks following that should be trimmed:
736	/* Each line of this comment has blanks or tabs following that should be trimmed:
737	   line 2:
738	   line 3:
739	*/
740}
741
742var _ = []T{ /* lone comment */ }
743
744var _ = []T{
745	/* lone comment */
746}
747
748var _ = []T{
749	// lone comments
750	// in composite lit
751}
752
753var _ = [][]T{
754	{
755		// lone comments
756		// in composite lit
757	},
758}
759
760// TODO: gofmt doesn't add these tabs; make it so that these golden
761// tests run the printer in a way that it's exactly like gofmt.
762
763var _ = []T{	// lone comment
764}
765
766var _ = []T{	// lone comments
767	// in composite lit
768}
769
770func _()	{}
771
772func _()	{}
773
774/* This comment is the last entry in this file. It must be printed and should be followed by a newline */
775