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

import (
	"go/ast"
	"go/token"
	"log"
)


/*
 * Type compiler
 */

type typeCompiler struct {
	*compiler
	block *block
	// Check to be performed after a type declaration is compiled.
	//
	// TODO(austin) This will probably have to change after we
	// eliminate forward declarations.
	lateCheck func() bool
}

func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type {
	_, _, def := a.block.Lookup(x.Name)
	if def == nil {
		a.diagAt(x.Pos(), "%s: undefined", x.Name)
		return nil
	}
	switch def := def.(type) {
	case *Constant:
		a.diagAt(x.Pos(), "constant %v used as type", x.Name)
		return nil
	case *Variable:
		a.diagAt(x.Pos(), "variable %v used as type", x.Name)
		return nil
	case *NamedType:
		if !allowRec && def.incomplete {
			a.diagAt(x.Pos(), "illegal recursive type")
			return nil
		}
		if !def.incomplete && def.Def == nil {
			// Placeholder type from an earlier error
			return nil
		}
		return def
	case Type:
		return def
	}
	log.Panicf("name %s has unknown type %T", x.Name, def)
	return nil
}

func (a *typeCompiler) compileArrayType(x *ast.ArrayType, allowRec bool) Type {
	// Compile element type
	elem := a.compileType(x.Elt, allowRec)

	// Compile length expression
	if x.Len == nil {
		if elem == nil {
			return nil
		}
		return NewSliceType(elem)
	}

	if _, ok := x.Len.(*ast.Ellipsis); ok {
		a.diagAt(x.Len.Pos(), "... array initializers not implemented")
		return nil
	}
	l, ok := a.compileArrayLen(a.block, x.Len)
	if !ok {
		return nil
	}
	if l < 0 {
		a.diagAt(x.Len.Pos(), "array length must be non-negative")
		return nil
	}
	if elem == nil {
		return nil
	}

	return NewArrayType(l, elem)
}

func (a *typeCompiler) compileFields(fields *ast.FieldList, allowRec bool) ([]Type, []*ast.Ident, []token.Pos, bool) {
	n := fields.NumFields()
	ts := make([]Type, n)
	ns := make([]*ast.Ident, n)
	ps := make([]token.Pos, n)
	bad := false

	if fields != nil {
		i := 0
		for _, f := range fields.List {
			t := a.compileType(f.Type, allowRec)
			if t == nil {
				bad = true
			}
			if f.Names == nil {
				ns[i] = nil
				ts[i] = t
				ps[i] = f.Type.Pos()
				i++
				continue
			}
			for _, n := range f.Names {
				ns[i] = n
				ts[i] = t
				ps[i] = n.Pos()
				i++
			}
		}
	}

	return ts, ns, ps, bad
}

func (a *typeCompiler) compileStructType(x *ast.StructType, allowRec bool) Type {
	ts, names, poss, bad := a.compileFields(x.Fields, allowRec)

	// XXX(Spec) The spec claims that field identifiers must be
	// unique, but 6g only checks this when they are accessed.  I
	// think the spec is better in this regard: if I write two
	// fields with the same name in the same struct type, clearly
	// that's a mistake.  This definition does *not* descend into
	// anonymous fields, so it doesn't matter if those change.
	// There's separate language in the spec about checking
	// uniqueness of field names inherited from anonymous fields
	// at use time.
	fields := make([]StructField, len(ts))
	nameSet := make(map[string]token.Pos, len(ts))
	for i := range fields {
		// Compute field name and check anonymous fields
		var name string
		if names[i] != nil {
			name = names[i].Name
		} else {
			if ts[i] == nil {
				continue
			}

			var nt *NamedType
			// [For anonymous fields,] the unqualified
			// type name acts as the field identifier.
			switch t := ts[i].(type) {
			case *NamedType:
				name = t.Name
				nt = t
			case *PtrType:
				switch t := t.Elem.(type) {
				case *NamedType:
					name = t.Name
					nt = t
				}
			}
			// [An anonymous field] must be specified as a
			// type name T or as a pointer to a type name
			// *T, and T itself, may not be a pointer or
			// interface type.
			if nt == nil {
				a.diagAt(poss[i], "embedded type must T or *T, where T is a named type")
				bad = true
				continue
			}
			// The check for embedded pointer types must
			// be deferred because of things like
			//  type T *struct { T }
			lateCheck := a.lateCheck
			a.lateCheck = func() bool {
				if _, ok := nt.lit().(*PtrType); ok {
					a.diagAt(poss[i], "embedded type %v is a pointer type", nt)
					return false
				}
				return lateCheck()
			}
		}

		// Check name uniqueness
		if prev, ok := nameSet[name]; ok {
			a.diagAt(poss[i], "field %s redeclared\n\tprevious declaration at %s", name, a.fset.Position(prev))
			bad = true
			continue
		}
		nameSet[name] = poss[i]

		// Create field
		fields[i].Name = name
		fields[i].Type = ts[i]
		fields[i].Anonymous = (names[i] == nil)
	}

	if bad {
		return nil
	}

	return NewStructType(fields)
}

func (a *typeCompiler) compilePtrType(x *ast.StarExpr) Type {
	elem := a.compileType(x.X, true)
	if elem == nil {
		return nil
	}
	return NewPtrType(elem)
}

func (a *typeCompiler) compileFuncType(x *ast.FuncType, allowRec bool) *FuncDecl {
	// TODO(austin) Variadic function types

	// The types of parameters and results must be complete.
	//
	// TODO(austin) It's not clear they actually have to be complete.
	in, inNames, _, inBad := a.compileFields(x.Params, allowRec)
	out, outNames, _, outBad := a.compileFields(x.Results, allowRec)

	if inBad || outBad {
		return nil
	}
	return &FuncDecl{NewFuncType(in, false, out), nil, inNames, outNames}
}

func (a *typeCompiler) compileInterfaceType(x *ast.InterfaceType, allowRec bool) *InterfaceType {
	ts, names, poss, bad := a.compileFields(x.Methods, allowRec)

	methods := make([]IMethod, len(ts))
	nameSet := make(map[string]token.Pos, len(ts))
	embeds := make([]*InterfaceType, len(ts))

	var nm, ne int
	for i := range ts {
		if ts[i] == nil {
			continue
		}

		if names[i] != nil {
			name := names[i].Name
			methods[nm].Name = name
			methods[nm].Type = ts[i].(*FuncType)
			nm++
			if prev, ok := nameSet[name]; ok {
				a.diagAt(poss[i], "method %s redeclared\n\tprevious declaration at %s", name, a.fset.Position(prev))
				bad = true
				continue
			}
			nameSet[name] = poss[i]
		} else {
			// Embedded interface
			it, ok := ts[i].lit().(*InterfaceType)
			if !ok {
				a.diagAt(poss[i], "embedded type must be an interface")
				bad = true
				continue
			}
			embeds[ne] = it
			ne++
			for _, m := range it.methods {
				if prev, ok := nameSet[m.Name]; ok {
					a.diagAt(poss[i], "method %s redeclared\n\tprevious declaration at %s", m.Name, a.fset.Position(prev))
					bad = true
					continue
				}
				nameSet[m.Name] = poss[i]
			}
		}
	}

	if bad {
		return nil
	}

	methods = methods[0:nm]
	embeds = embeds[0:ne]

	return NewInterfaceType(methods, embeds)
}

func (a *typeCompiler) compileMapType(x *ast.MapType) Type {
	key := a.compileType(x.Key, true)
	val := a.compileType(x.Value, true)
	if key == nil || val == nil {
		return nil
	}
	// XXX(Spec) The Map types section explicitly lists all types
	// that can be map keys except for function types.
	switch key.lit().(type) {
	case *StructType:
		a.diagAt(x.Pos(), "map key cannot be a struct type")
		return nil
	case *ArrayType:
		a.diagAt(x.Pos(), "map key cannot be an array type")
		return nil
	case *SliceType:
		a.diagAt(x.Pos(), "map key cannot be a slice type")
		return nil
	}
	return NewMapType(key, val)
}

func (a *typeCompiler) compileType(x ast.Expr, allowRec bool) Type {
	switch x := x.(type) {
	case *ast.BadExpr:
		// Error already reported by parser
		a.silentErrors++
		return nil

	case *ast.Ident:
		return a.compileIdent(x, allowRec)

	case *ast.ArrayType:
		return a.compileArrayType(x, allowRec)

	case *ast.StructType:
		return a.compileStructType(x, allowRec)

	case *ast.StarExpr:
		return a.compilePtrType(x)

	case *ast.FuncType:
		fd := a.compileFuncType(x, allowRec)
		if fd == nil {
			return nil
		}
		return fd.Type

	case *ast.InterfaceType:
		return a.compileInterfaceType(x, allowRec)

	case *ast.MapType:
		return a.compileMapType(x)

	case *ast.ChanType:
		goto notimpl

	case *ast.ParenExpr:
		return a.compileType(x.X, allowRec)

	case *ast.Ellipsis:
		a.diagAt(x.Pos(), "illegal use of ellipsis")
		return nil
	}
	a.diagAt(x.Pos(), "expression used as type")
	return nil

notimpl:
	a.diagAt(x.Pos(), "compileType: %T not implemented", x)
	return nil
}

/*
 * Type compiler interface
 */

func noLateCheck() bool { return true }

func (a *compiler) compileType(b *block, typ ast.Expr) Type {
	tc := &typeCompiler{a, b, noLateCheck}
	t := tc.compileType(typ, false)
	if !tc.lateCheck() {
		t = nil
	}
	return t
}

func (a *compiler) compileTypeDecl(b *block, decl *ast.GenDecl) bool {
	ok := true
	for _, spec := range decl.Specs {
		spec := spec.(*ast.TypeSpec)
		// Create incomplete type for this type
		nt := b.DefineType(spec.Name.Name, spec.Name.Pos(), nil)
		if nt != nil {
			nt.(*NamedType).incomplete = true
		}
		// Compile type
		tc := &typeCompiler{a, b, noLateCheck}
		t := tc.compileType(spec.Type, false)
		if t == nil {
			// Create a placeholder type
			ok = false
		}
		// Fill incomplete type
		if nt != nil {
			nt.(*NamedType).Complete(t)
		}
		// Perform late type checking with complete type
		if !tc.lateCheck() {
			ok = false
			if nt != nil {
				// Make the type a placeholder
				nt.(*NamedType).Def = nil
			}
		}
	}
	return ok
}

func (a *compiler) compileFuncType(b *block, typ *ast.FuncType) *FuncDecl {
	tc := &typeCompiler{a, b, noLateCheck}
	res := tc.compileFuncType(typ, false)
	if res != nil {
		if !tc.lateCheck() {
			res = nil
		}
	}
	return res
}
