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

import "io"

import (
	_ "io"
)

import _ "io"

import (
	"io"
	"io"
	"io"
)

import (
	"io"
	aLongRename "io"

	b "io"
)

// no newlines between consecutive single imports, but
// respect extra line breaks in the source (at most one empty line)
import _ "io"
import _ "io"
import _ "io"

import _ "os"
import _ "os"
import _ "os"


import _ "fmt"
import _ "fmt"
import _ "fmt"

// make sure a comment doesn't cause semicolons to be inserted
import _ "foo"	// a comment
import		// a comment
"bar"
import "foo"	// a comment
import "bar"	// a comment

import (
	_ "foo" +	// a comment
		// a comment
		"bar" +
		"foo" +	// a comment
		"bar"	// a comment
)

// a case that caused problems in the past (comment placement)
import (
	. "fmt"
	"io"
	"malloc"	// for the malloc count test only
	"math"
	"strings"
	"testing"
)


// at least one empty line between declarations of different kind
import _ "io"

var _ int


func _() {
	// the following decls need a semicolon at the end
	type _ int
	type _ *int
	type _ []int
	type _ map[string]int
	type _ chan int
	type _ func() int

	var _ int
	var _ *int
	var _ []int
	var _ map[string]int
	var _ chan int
	var _ func() int

	// the following decls don't need a semicolon at the end
	type _ struct{}
	type _ *struct{}
	type _ []struct{}
	type _ map[string]struct{}
	type _ chan struct{}
	type _ func() struct{}

	type _ interface{}
	type _ *interface{}
	type _ []interface{}
	type _ map[string]interface{}
	type _ chan interface{}
	type _ func() interface{}

	var _ struct{}
	var _ *struct{}
	var _ []struct{}
	var _ map[string]struct{}
	var _ chan struct{}
	var _ func() struct{}

	var _ interface{}
	var _ *interface{}
	var _ []interface{}
	var _ map[string]interface{}
	var _ chan interface{}
	var _ func() interface{}
}


// don't lose blank lines in grouped declarations
const (
	_	int	= 0
	_	float	= 1

	_	string	= "foo"

	_	= iota
	_

	// a comment
	_

	_
)


type (
	_	int
	_	struct{}

	_	interface{}

	// a comment
	_	map[string]int
)


var (
	_	int	= 0
	_	float	= 1

	_	string	= "foo"

	_	bool

	// a comment
	_	bool
)


// don't lose blank lines in this struct
type _ struct {
	String	struct {
		Str, Len int
	}
	Slice	struct {
		Array, Len, Cap int
	}
	Eface	struct {
		Typ, Ptr int
	}

	UncommonType	struct {
		Name, PkgPath int
	}
	CommonType	struct {
		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
	}
	Type	struct {
		Typ, Ptr int
	}
	StructField	struct {
		Name, PkgPath, Typ, Tag, Offset int
	}
	StructType	struct {
		Fields int
	}
	PtrType	struct {
		Elem int
	}
	SliceType	struct {
		Elem int
	}
	ArrayType	struct {
		Elem, Len int
	}

	Stktop	struct {
		Stackguard, Stackbase, Gobuf int
	}
	Gobuf	struct {
		Sp, Pc, G int
	}
	G	struct {
		Stackbase, Sched, Status, Alllink int
	}
}


// no tabs for single or ungrouped decls
func _() {
	const xxxxxx = 0
	type x int
	var xxx int
	var yyyy float = 3.14
	var zzzzz = "bar"

	const (
		xxxxxx = 0
	)
	type (
		x int
	)
	var (
		xxx int
	)
	var (
		yyyy float = 3.14
	)
	var (
		zzzzz = "bar"
	)
}

// tabs for multiple or grouped decls
func _() {
	// no entry has a type
	const (
		zzzzzz	= 1
		z	= 2
		zzz	= 3
	)
	// some entries have a type
	const (
		xxxxxx			= 1
		x			= 2
		xxx			= 3
		yyyyyyyy	float	= iota
		yyyy			= "bar"
		yyy
		yy	= 2
	)
}

func _() {
	// no entry has a type
	var (
		zzzzzz	= 1
		z	= 2
		zzz	= 3
	)
	// no entry has a value
	var (
		_	int
		_	float
		_	string

		_	int	// comment
		_	float	// comment
		_	string	// comment
	)
	// some entries have a type
	var (
		xxxxxx		int
		x		float
		xxx		string
		yyyyyyyy	int	= 1234
		y		float	= 3.14
		yyyy			= "bar"
		yyy		string	= "foo"
	)
	// mixed entries - all comments should be aligned
	var (
		a, b, c			int
		x				= 10
		d			int	// comment
		y				= 20		// comment
		f, ff, fff, ffff	int	= 0, 1, 2, 3	// comment
	)
	// respect original line breaks
	var _ = []T{
		T{0x20, "Telugu"},
	}
	var _ = []T{
		// respect original line breaks
		T{0x20, "Telugu"},
	}
}

func _() {
	type (
		xxxxxx	int
		x	float
		xxx	string
		xxxxx	[]x
		xx	struct{}
		xxxxxxx	struct {
			_, _	int
			_	float
		}
		xxxx	chan<- string
	)
}


// formatting of structs
type _ struct{}

type _ struct { /* this comment should be visible */ }

type _ struct {
	// this comment should be visible and properly indented
}

type _ struct {	// this comment must not change indentation
	f			int
	f, ff, fff, ffff	int
}

type _ struct {
	string
}

type _ struct {
	string	// comment
}

type _ struct {
	string "tag"
}

type _ struct {
	string "tag"	// comment
}

type _ struct {
	f int
}

type _ struct {
	f int	// comment
}

type _ struct {
	f int "tag"
}

type _ struct {
	f int "tag"	// comment
}

type _ struct {
	bool
	a, b, c			int
	int			"tag"
	ES				// comment
	float			"tag"	// comment
	f			int	// comment
	f, ff, fff, ffff	int	// comment
	g			float	"tag"
	h			float	"tag"	// comment
}


// difficult cases
type _ struct {
	bool		// comment
	text	[]byte	// comment
}


// formatting of interfaces
type EI interface{}

type _ interface {
	EI
}

type _ interface {
	f()
	fffff()
}

type _ interface {
	EI
	f()
	fffffg()
}

type _ interface {	// this comment must not change indentation
	EI				// here's a comment
	f()				// no blank between identifier and ()
	fffff()				// no blank between identifier and ()
	gggggggggggg(x, y, z int)	// hurray
}

// formatting of variable declarations
func _() {
	type day struct {
		n		int
		short, long	string
	}
	var (
		Sunday		= day{0, "SUN", "Sunday"}
		Monday		= day{1, "MON", "Monday"}
		Tuesday		= day{2, "TUE", "Tuesday"}
		Wednesday	= day{3, "WED", "Wednesday"}
		Thursday	= day{4, "THU", "Thursday"}
		Friday		= day{5, "FRI", "Friday"}
		Saturday	= day{6, "SAT", "Saturday"}
	)
}


func _() {
	var Universe = Scope{
		Names: map[string]*Ident{
			// basic types
			"bool": nil,
			"byte": nil,
			"int8": nil,
			"int16": nil,
			"int32": nil,
			"int64": nil,
			"uint8": nil,
			"uint16": nil,
			"uint32": nil,
			"uint64": nil,
			"float32": nil,
			"float64": nil,
			"string": nil,

			// convenience types
			"int": nil,
			"uint": nil,
			"uintptr": nil,
			"float": nil,

			// constants
			"false": nil,
			"true": nil,
			"iota": nil,
			"nil": nil,

			// functions
			"cap": nil,
			"len": nil,
			"new": nil,
			"make": nil,
			"panic": nil,
			"panicln": nil,
			"print": nil,
			"println": nil,
		},
	}
}


func _() {
	var _ = T{
		a,	// must introduce trailing comma
	}
}


// formatting of consecutive single-line functions
func _()	{}
func _()	{}
func _()	{}

func _()	{}	// an empty line before this function
func _()	{}
func _()	{}

func _()		{ f(1, 2, 3) }
func _(x int) int	{ return x + 1 }
func _() int		{ type T struct{} }


// making function declarations safe for new semicolon rules
func _() { /* one-line func */ }

func _() {	// opening "{" must move up
	/* one-line func */ }

func _() {	// opening "{" must move up
	// multi-line func

	// in the following declarations, a comment must not
	// introduce a newline and thus cause a semicolon to
	// be inserted
	const _ T = x	// comment
	const _ = x	// comment

	type _ T	// comment
	type _ struct // comment
	{

	}
	type _ interface // comment
	{

	}
	type _ * // comment
	T
	type _ [ // comment
	]T
	type _ [ // comment
	10]T
	type _ chan // comment
	T
	type _ map // comment
	[T]T

	var _ T		// comment
	var _ T = x	// comment
	var _ struct // comment
	{

	}
	var _ interface // comment
	{

	}
	var _ * // comment
	T
	var _ [ // comment
	]T
	var _ [ // comment
	10]T
	var _ chan // comment
	T
	var _ map // comment
	[T]T

	var _ = x	// comment
}
