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

package statements

var expr bool

func use(x interface{})	{}

// Formatting of multi-line return statements.
func _f() {
	return
	return x, y, z
	return T{}
	return T{1, 2, 3},
		x, y, z
	return T{1, 2, 3},
		x, y,
		z
	return T{1,
		2,
		3}
	return T{1,
		2,
		3,
	}
	return T{
		1,
		2,
		3}
	return T{
		1,
		2,
		3,
	}
	return T{
		1,
		T{1, 2, 3},
		3,
	}
	return T{
		1,
		T{1,
			2, 3},
		3,
	}
	return T{
		1,
		T{1,
			2,
			3},
		3,
	}
	return T{
		1,
		2,
	}, nil
	return T{
			1,
			2,
		},
		T{
			x:	3,
			y:	4,
		}, nil
	return T{
			1,
			2,
		},
		nil
	return T{
			1,
			2,
		},
		T{
			x:	3,
			y:	4,
		},
		nil
	return x + y +
		z
	return func() {}
	return func() {
			_ = 0
		}, T{
			1, 2,
		}
	return func() {
		_ = 0
	}
	return func() T {
		return T{
			1, 2,
		}
	}
}

// Formatting of multi-line returns: test cases from issue 1207.
func F() (*T, os.Error) {
	return &T{
			X:	1,
			Y:	2,
		},
		nil
}

func G() (*T, *T, os.Error) {
	return &T{
			X:	1,
			Y:	2,
		},
		&T{
			X:	3,
			Y:	4,
		},
		nil
}

func _() interface{} {
	return &fileStat{
		name:		basename(file.name),
		size:		mkSize(d.FileSizeHigh, d.FileSizeLow),
		modTime:	mkModTime(d.LastWriteTime),
		mode:		mkMode(d.FileAttributes),
		sys:		mkSysFromFI(&d),
	}, nil
}

// Formatting of if-statement headers.
func _() {
	if true {
	}
	if true {
	}	// no semicolon printed
	if expr {
	}
	if expr {
	}	// no semicolon printed
	if expr {
	}	// no parens printed
	if expr {
	}	// no semicolon and parens printed
	if x := expr; true {
		use(x)
	}
	if x := expr; expr {
		use(x)
	}
}

// Formatting of switch-statement headers.
func _() {
	switch {
	}
	switch {
	}	// no semicolon printed
	switch expr {
	}
	switch expr {
	}	// no semicolon printed
	switch expr {
	}	// no parens printed
	switch expr {
	}	// no semicolon and parens printed
	switch x := expr; {
	default:
		use(
			x)
	}
	switch x := expr; expr {
	default:
		use(x)
	}
}

// Formatting of switch statement bodies.
func _() {
	switch {
	}

	switch x := 0; x {
	case 1:
		use(x)
		use(x)	// followed by an empty line

	case 2:	// followed by an empty line

		use(x)	// followed by an empty line

	case 3:	// no empty lines
		use(x)
		use(x)
	}

	switch x {
	case 0:
		use(x)
	case 1:	// this comment should have no effect on the previous or next line
		use(x)
	}

	switch x := 0; x {
	case 1:
		x = 0
		// this comment should be indented
	case 2:
		x = 0
	// this comment should not be indented, it is aligned with the next case
	case 3:
		x = 0
		/* indented comment
		   aligned
		   aligned
		*/
		// bla
		/* and more */
	case 4:
		x = 0
	/* not indented comment
	   aligned
	   aligned
	*/
	// bla
	/* and more */
	case 5:
	}
}

// Formatting of selected select statements.
func _() {
	select {}
	select { /* this comment should not be tab-aligned because the closing } is on the same line */
	}
	select {	/* this comment should be tab-aligned */
	}
	select {	// this comment should be tab-aligned
	}
	select {
	case <-c:
	}
}

// Formatting of for-statement headers.
func _() {
	for {
	}
	for expr {
	}
	for expr {
	}	// no parens printed
	for {
	}	// no semicolons printed
	for x := expr; ; {
		use(x)
	}
	for expr {
	}	// no semicolons printed
	for expr {
	}	// no semicolons and parens printed
	for ; ; expr = false {
	}
	for x := expr; expr; {
		use(x)
	}
	for x := expr; ; expr = false {
		use(x)
	}
	for ; expr; expr = false {
	}
	for x := expr; expr; expr = false {
		use(x)
	}
	for x := range []int{} {
		use(x)
	}
	for x := range []int{} {
		use(x)
	}	// no parens printed
}

// Don't remove mandatory parentheses around composite literals in control clauses.
func _() {
	// strip parentheses - no composite literals or composite literals don't start with a type name
	if x {
	}
	if x {
	}
	if []T{} {
	}
	if []T{} {
	}
	if []T{} {
	}

	for x {
	}
	for x {
	}
	for []T{} {
	}
	for []T{} {
	}
	for []T{} {
	}

	switch x {
	}
	switch x {
	}
	switch []T{} {
	}
	switch []T{} {
	}

	for _ = range []T{T{42}} {
	}

	// leave parentheses - composite literals start with a type name
	if (T{}) {
	}
	if (T{}) {
	}
	if (T{}) {
	}

	for (T{}) {
	}
	for (T{}) {
	}
	for (T{}) {
	}

	switch (T{}) {
	}
	switch (T{}) {
	}

	for _ = range (T1{T{42}}) {
	}

	if x == (T{42}[0]) {
	}
	if (x == T{42}[0]) {
	}
	if x == (T{42}[0]) {
	}
	if x == (T{42}[0]) {
	}
	if x == (T{42}[0]) {
	}
	if x == a+b*(T{42}[0]) {
	}
	if (x == a+b*T{42}[0]) {
	}
	if x == a+b*(T{42}[0]) {
	}
	if x == a+(b * (T{42}[0])) {
	}
	if x == a+b*(T{42}[0]) {
	}
	if (a + b*(T{42}[0])) == x {
	}
	if (a + b*(T{42}[0])) == x {
	}

	if struct{ x bool }{false}.x {
	}
	if (struct{ x bool }{false}.x) == false {
	}
	if struct{ x bool }{false}.x == false {
	}
}

// Extra empty lines inside functions. Do respect source code line
// breaks between statement boundaries but print at most one empty
// line at a time.
func _() {

	const _ = 0

	const _ = 1
	type _ int
	type _ float

	var _ = 0
	var x = 1

	// Each use(x) call below should have at most one empty line before and after.
	// Known bug: The first use call may have more than one empty line before
	//            (see go/printer/nodes.go, func linebreak).

	use(x)

	if x < x {

		use(x)

	} else {

		use(x)

	}
}

// Formatting around labels.
func _() {
L:
}

func _() {
	// this comment should be indented
L:	// no semicolon needed
}

func _() {
	switch 0 {
	case 0:
	L0:
		;	// semicolon required
	case 1:
	L1:
		;	// semicolon required
	default:
	L2:	// no semicolon needed
	}
}

func _() {
	f()
L1:
	f()
L2:
	;
L3:
}

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

func _() {
L:
	_ = 0
}

func _() {
	// this comment should be indented
L:
	_ = 0
}

func _() {
	for {
	L1:
		_ = 0
	L2:
		_ = 0
	}
}

func _() {
	// this comment should be indented
	for {
	L1:
		_ = 0
	L2:
		_ = 0
	}
}

func _() {
	if true {
		_ = 0
	}
	_ = 0	// the indentation here should not be affected by the long label name
AnOverlongLabel:
	_ = 0

	if true {
		_ = 0
	}
	_ = 0

L:
	_ = 0
}

func _() {
	for {
		goto L
	}
L:

	MoreCode()
}

func _() {
	for {
		goto L
	}
L:	// A comment on the same line as the label, followed by a single empty line.
	// Known bug: There may be more than one empty line before MoreCode()
	//            (see go/printer/nodes.go, func linebreak).

	MoreCode()
}

func _() {
	for {
		goto L
	}
L:

	// There should be a single empty line before this comment.
	MoreCode()
}

func _() {
	for {
		goto AVeryLongLabelThatShouldNotAffectFormatting
	}
AVeryLongLabelThatShouldNotAffectFormatting:
	// There should be a single empty line after this comment.

	// There should be a single empty line before this comment.
	MoreCode()
}
