// 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 for single-line for-loops.
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
}


// Formatting of for-statement headers for multi-line for-loops.
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 range []int{} {
	println("foo")}
	for x := range []int{} {
	use(x) }
	for x := range (([]int{})) {
	use(x) }  // no parens printed
}


// Formatting of selected short single- and multi-line statements.
func _() {
	if cond {}
	if cond {
	} // multiple lines
	if cond {} else {} // else clause always requires multiple lines

	for {}
	for i := 0; i < len(a); 1++ {}
	for i := 0; i < len(a); 1++ { a[i] = i }
	for i := 0; i < len(a); 1++ { a[i] = i
	} // multiple lines

	for range a{}
	for _ = range a{}
	for _, _ = range a{}
	for i := range a {}
	for i := range a { a[i] = i }
	for i := range a { a[i] = i
	} // multiple lines

	go func() { for { a <- <-b } }()
	defer func() { if x := recover(); x != nil { err = fmt.Sprintf("error: %s", x.msg) } }()
}


// 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()
}


// Formatting of empty statements.
func _() {
	;;;;;;;;;;;;;;;;;;;;;;;;;
}

func _() {;;;;;;;;;;;;;;;;;;;;;;;;;
}

func _() {;;;;;;;;;;;;;;;;;;;;;;;;;}

func _() {
f();;;;;;;;;;;;;;;;;;;;;;;;;
}

func _() {
L:;;;;;;;;;;;;
}

func _() {
L:;;;;;;;;;;;;
	f()
}
