// 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.

// This is a package for testing comment placement by go/printer.
//
package main

import "fmt"	// fmt

const c0 = 0	// zero
const (
	c1	= iota	// c1
	c2		// c2
)

// Alignment of comments in declarations>
const (
	_	T	= iota	// comment
	_			// comment
	_			// comment
	_	= iota + 10
	_	// comments

	_	= 10		// comment
	_	T	= 20	// comment
)

const (
	_____	= iota	// foo
	_		// bar
	_	= 0	// bal
	_		// bat
)

const (
	_	T	= iota	// comment
	_			// comment
	_			// comment
	_	= iota + 10
	_	// comment
	_	= 10
	_	= 20		// comment
	_	T	= 0	// comment
)

// The SZ struct; it is empty.
type SZ struct{}

// The S0 struct; no field is exported.
type S0 struct {
	int
	x, y, z	int	// 3 unexported fields
}

// The S1 struct; some fields are not exported.
type S1 struct {
	S0
	A, B, C	float	// 3 exported fields
	D, b, c	int	// 2 unexported fields
}

// The S2 struct; all fields are exported.
type S2 struct {
	S1
	A, B, C	float	// 3 exported fields
}

// The IZ interface; it is empty.
type SZ interface{}

// The I0 interface; no method is exported.
type I0 interface {
	f(x int) int	// unexported method
}

// The I1 interface; some methods are not exported.
type I1 interface {
	I0
	F(x float) float	// exported methods
	g(x int) int		// unexported method
}

// The I2 interface; all methods are exported.
type I2 interface {
	I0
	F(x float) float	// exported method
	G(x float) float	// exported method
}

// The S3 struct; all comments except for the last one must appear in the export.
type S3 struct {
	// lead comment for F1
	F1	int	// line comment for F1
	// lead comment for F2
	F2	int	// line comment for F2
	f3	int	// f3 is not exported
}

// This comment group should be separated
// with a newline from the next comment
// group.

// This comment should NOT be associated with the next declaration.

var x int	// x
var ()


// This comment SHOULD be associated with the next declaration.
func f0() {
	const pi = 3.14	// pi
	var s1 struct{}	/* an empty struct */	/* foo */
	// a struct constructor
	// --------------------
	var s2 struct{} = struct{}{}
	x := pi
}
//
// NO SPACE HERE
//
func f1() {
	f0()
	/* 1 */
	// 2
	/* 3 */
	/* 4 */
	f0()
}


func _() {
	// this comment should be properly indented
}


func _(x int) int {
	if x < 0 {	// the tab printed before this comment's // must not affect the remaining lines
		return -x	// this statement should be properly indented
	}
	if x < 0 {	/* the tab printed before this comment's /* must not affect the remaining lines */
		return -x	// this statement should be properly indented
	}
	return x
}


func typeswitch(x interface{}) {
	switch v := x.(type) {
	case bool, int, float:
	case string:
	default:
	}

	switch x.(type) {
	}

	switch v0, ok := x.(int); v := x.(type) {
	}

	switch v0, ok := x.(int); x.(type) {
	case byte:	// this comment should be on the same line as the keyword
		// this comment should be normally indented
		_ = 0
	case bool, int, float:
		// this comment should be indented
	case string:
	default:
		// this comment should be indented
	}
	// this comment should not be indented
}

func _() {
	/* freestanding comment
	   aligned		line
	   aligned line
	*/
}

func _() {
	/* freestanding comment
	   aligned		line
	   aligned line
	*/
}

func _() {
	/* freestanding comment
	   aligned		line
	   aligned line */
}

func _() {
	/*	freestanding comment
		aligned		line
		aligned line
	*/
}

func _() {
	/*	freestanding comment
		aligned		line
		aligned line
	*/
}

func _() {
	/*	freestanding comment
		aligned		line
		aligned line */
}


func _() {
	/*
	   freestanding comment
	   aligned		line
	   aligned line
	*/
}

func _() {
	/*
	   freestanding comment
	   aligned		line
	   aligned line
	*/
}

func _() {
	/*
	   freestanding comment
	   aligned		line
	   aligned line */
}

func _() {
	/*
		freestanding comment
		aligned		line
		aligned line
	*/
}

func _() {
	/*
		freestanding comment
		aligned		line
		aligned line
	*/
}

func _() {
	/*
		freestanding comment
		aligned		line
		aligned line */
}

func _() {
	/* freestanding comment
	   aligned line
	*/
}

func _() {
	/* freestanding comment
	   aligned line
	*/
}

func _() {
	/* freestanding comment
	   aligned line */
}

func _() {
	/*	freestanding comment
		aligned line
	*/
}

func _() {
	/*	freestanding comment
		aligned line
	*/
}

func _() {
	/*	freestanding comment
		aligned line */
}


func _() {
	/*
	   freestanding comment
	   aligned line
	*/
}

func _() {
	/*
	   freestanding comment
	   aligned line
	*/
}

func _() {
	/*
	   freestanding comment
	   aligned line */
}

func _() {
	/*
		freestanding comment
		aligned line
	*/
}

func _() {
	/*
		freestanding comment
		aligned line
	*/
}

func _() {
	/*
		freestanding comment
		aligned line */
}

/*
 * line
 * of
 * stars
 */

/* another line
 * of
 * stars */

/*	and another line
 *	of
 *	stars */

/* a line of
 * stars */

/*	and another line of
 *	stars */

/* a line of stars
 */

/*	and another line of
 */

/* a line of stars
 */

/*	and another line of
 */

/*
aligned in middle
here
        not here
*/

/*
blank line in middle:

with no leading spaces on blank line.
*/

/*
   aligned in middle
   here
           not here
*/

/*
	blank line in middle:

	with no leading spaces on blank line.
*/

func _() {
	/*
	 * line
	 * of
	 * stars
	 */

	/*
		aligned in middle
		here
			not here
	*/

	/*
		blank line in middle:

		with no leading spaces on blank line.
	*/
}


// Some interesting interspersed comments
func _( /* this */ x /* is */ /* an */ int) {
}

func _( /* no params */ )	{}

func _() {
	f( /* no args */ )
}

func ( /* comment1 */ T /* comment2 */ ) _()	{}

func _() { /* one-line functions with comments are formatted as multi-line functions */
}

func _() {
	_ = 0
	/* closing curly brace should be on new line */
}

func _() {
	_ = []int{0, 1 /* don't introduce a newline after this comment - was issue 1365 */ }
}


// Comments immediately adjacent to punctuation (for which the go/printer
// may obly have estimated position information) must remain after the punctuation.
func _() {
	_ = T{
		1,	// comment after comma
		2,	/* comment after comma */
		3,	// comment after comma
	}
	_ = T{
		1,	// comment after comma
		2,	/* comment after comma */
		3,	// comment after comma
	}
	_ = T{
		/* comment before literal */ 1,
		2,	/* comment before comma - ok to move after comma */
		3,	/* comment before comma - ok to move after comma */
	}

	for i = 0;	// comment after semicolon
	i < 9;		/* comment after semicolon */
	i++ {		// comment after opening curly brace
	}

	// TODO(gri) the last comment in this example should be aligned */
	for i = 0;	// comment after semicolon
	i < 9;		/* comment before semicolon - ok to move after semicolon */
	i++ /* comment before opening curly brace */ {
	}
}


// Line comments with tabs
func _() {
	var finput *bufio.Reader	// input file
	var stderr *bufio.Writer
	var ftable *bufio.Writer	// y.go file
	var foutput *bufio.Writer	// y.output file

	var oflag string	// -o [y.go]		- y.go file
	var vflag string	// -v [y.output]	- y.output file
	var lflag bool		// -l			- disable line directives
}


/* This comment is the last entry in this file. It must be printed and should be followed by a newline */
