// Copyright 2012 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 file implements commonly used type predicates.

package types

import (
	"go/token"
)

// isNamed reports whether typ has a name.
// isNamed may be called with types that are not fully set up.
func isNamed(typ Type) bool {
	switch typ.(type) {
	case *Basic, *Named, *TypeParam, *instance:
		return true
	}
	return false
}

// isGeneric reports whether a type is a generic, uninstantiated type (generic
// signatures are not included).
func isGeneric(typ Type) bool {
	// A parameterized type is only instantiated if it doesn't have an instantiation already.
	named, _ := typ.(*Named)
	return named != nil && named.obj != nil && named.tparams != nil && named.targs == nil
}

func is(typ Type, what BasicInfo) bool {
	switch t := optype(typ).(type) {
	case *Basic:
		return t.info&what != 0
	case *Sum:
		return t.is(func(typ Type) bool { return is(typ, what) })
	}
	return false
}

func isBoolean(typ Type) bool  { return is(typ, IsBoolean) }
func isInteger(typ Type) bool  { return is(typ, IsInteger) }
func isUnsigned(typ Type) bool { return is(typ, IsUnsigned) }
func isFloat(typ Type) bool    { return is(typ, IsFloat) }
func isComplex(typ Type) bool  { return is(typ, IsComplex) }
func isNumeric(typ Type) bool  { return is(typ, IsNumeric) }
func isString(typ Type) bool   { return is(typ, IsString) }

// Note that if typ is a type parameter, isInteger(typ) || isFloat(typ) does not
// produce the expected result because a type list that contains both an integer
// and a floating-point type is neither (all) integers, nor (all) floats.
// Use isIntegerOrFloat instead.
func isIntegerOrFloat(typ Type) bool { return is(typ, IsInteger|IsFloat) }

// isNumericOrString is the equivalent of isIntegerOrFloat for isNumeric(typ) || isString(typ).
func isNumericOrString(typ Type) bool { return is(typ, IsNumeric|IsString) }

// isTyped reports whether typ is typed; i.e., not an untyped
// constant or boolean. isTyped may be called with types that
// are not fully set up.
func isTyped(typ Type) bool {
	// isTyped is called with types that are not fully
	// set up. Must not call asBasic()!
	// A *Named or *instance type is always typed, so
	// we only need to check if we have a true *Basic
	// type.
	t, _ := typ.(*Basic)
	return t == nil || t.info&IsUntyped == 0
}

// isUntyped(typ) is the same as !isTyped(typ).
func isUntyped(typ Type) bool {
	return !isTyped(typ)
}

func isOrdered(typ Type) bool { return is(typ, IsOrdered) }

func isConstType(typ Type) bool {
	// Type parameters are never const types.
	t, _ := under(typ).(*Basic)
	return t != nil && t.info&IsConstType != 0
}

// IsInterface reports whether typ is an interface type.
func IsInterface(typ Type) bool {
	return asInterface(typ) != nil
}

// Comparable reports whether values of type T are comparable.
func Comparable(T Type) bool {
	return comparable(T, nil)
}

func comparable(T Type, seen map[Type]bool) bool {
	if seen[T] {
		return true
	}
	if seen == nil {
		seen = make(map[Type]bool)
	}
	seen[T] = true

	// If T is a type parameter not constrained by any type
	// list (i.e., it's underlying type is the top type),
	// T is comparable if it has the == method. Otherwise,
	// the underlying type "wins". For instance
	//
	//     interface{ comparable; type []byte }
	//
	// is not comparable because []byte is not comparable.
	if t := asTypeParam(T); t != nil && optype(t) == theTop {
		return t.Bound().IsComparable()
	}

	switch t := optype(T).(type) {
	case *Basic:
		// assume invalid types to be comparable
		// to avoid follow-up errors
		return t.kind != UntypedNil
	case *Pointer, *Interface, *Chan:
		return true
	case *Struct:
		for _, f := range t.fields {
			if !comparable(f.typ, seen) {
				return false
			}
		}
		return true
	case *Array:
		return comparable(t.elem, seen)
	case *Sum:
		pred := func(t Type) bool {
			return comparable(t, seen)
		}
		return t.is(pred)
	case *TypeParam:
		return t.Bound().IsComparable()
	}
	return false
}

// hasNil reports whether a type includes the nil value.
func hasNil(typ Type) bool {
	switch t := optype(typ).(type) {
	case *Basic:
		return t.kind == UnsafePointer
	case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
		return true
	case *Sum:
		return t.is(hasNil)
	}
	return false
}

// identical reports whether x and y are identical types.
// Receivers of Signature types are ignored.
func (check *Checker) identical(x, y Type) bool {
	return check.identical0(x, y, true, nil)
}

// identicalIgnoreTags reports whether x and y are identical types if tags are ignored.
// Receivers of Signature types are ignored.
func (check *Checker) identicalIgnoreTags(x, y Type) bool {
	return check.identical0(x, y, false, nil)
}

// An ifacePair is a node in a stack of interface type pairs compared for identity.
type ifacePair struct {
	x, y *Interface
	prev *ifacePair
}

func (p *ifacePair) identical(q *ifacePair) bool {
	return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
}

// For changes to this code the corresponding changes should be made to unifier.nify.
func (check *Checker) identical0(x, y Type, cmpTags bool, p *ifacePair) bool {
	// types must be expanded for comparison
	x = expandf(x)
	y = expandf(y)

	if x == y {
		return true
	}

	switch x := x.(type) {
	case *Basic:
		// Basic types are singletons except for the rune and byte
		// aliases, thus we cannot solely rely on the x == y check
		// above. See also comment in TypeName.IsAlias.
		if y, ok := y.(*Basic); ok {
			return x.kind == y.kind
		}

	case *Array:
		// Two array types are identical if they have identical element types
		// and the same array length.
		if y, ok := y.(*Array); ok {
			// If one or both array lengths are unknown (< 0) due to some error,
			// assume they are the same to avoid spurious follow-on errors.
			return (x.len < 0 || y.len < 0 || x.len == y.len) && check.identical0(x.elem, y.elem, cmpTags, p)
		}

	case *Slice:
		// Two slice types are identical if they have identical element types.
		if y, ok := y.(*Slice); ok {
			return check.identical0(x.elem, y.elem, cmpTags, p)
		}

	case *Struct:
		// Two struct types are identical if they have the same sequence of fields,
		// and if corresponding fields have the same names, and identical types,
		// and identical tags. Two embedded fields are considered to have the same
		// name. Lower-case field names from different packages are always different.
		if y, ok := y.(*Struct); ok {
			if x.NumFields() == y.NumFields() {
				for i, f := range x.fields {
					g := y.fields[i]
					if f.embedded != g.embedded ||
						cmpTags && x.Tag(i) != y.Tag(i) ||
						!f.sameId(g.pkg, g.name) ||
						!check.identical0(f.typ, g.typ, cmpTags, p) {
						return false
					}
				}
				return true
			}
		}

	case *Pointer:
		// Two pointer types are identical if they have identical base types.
		if y, ok := y.(*Pointer); ok {
			return check.identical0(x.base, y.base, cmpTags, p)
		}

	case *Tuple:
		// Two tuples types are identical if they have the same number of elements
		// and corresponding elements have identical types.
		if y, ok := y.(*Tuple); ok {
			if x.Len() == y.Len() {
				if x != nil {
					for i, v := range x.vars {
						w := y.vars[i]
						if !check.identical0(v.typ, w.typ, cmpTags, p) {
							return false
						}
					}
				}
				return true
			}
		}

	case *Signature:
		// Two function types are identical if they have the same number of parameters
		// and result values, corresponding parameter and result types are identical,
		// and either both functions are variadic or neither is. Parameter and result
		// names are not required to match.
		// Generic functions must also have matching type parameter lists, but for the
		// parameter names.
		if y, ok := y.(*Signature); ok {
			return x.variadic == y.variadic &&
				check.identicalTParams(x.tparams, y.tparams, cmpTags, p) &&
				check.identical0(x.params, y.params, cmpTags, p) &&
				check.identical0(x.results, y.results, cmpTags, p)
		}

	case *Sum:
		// Two sum types are identical if they contain the same types.
		// (Sum types always consist of at least two types. Also, the
		// the set (list) of types in a sum type consists of unique
		// types - each type appears exactly once. Thus, two sum types
		// must contain the same number of types to have chance of
		// being equal.
		if y, ok := y.(*Sum); ok && len(x.types) == len(y.types) {
			// Every type in x.types must be in y.types.
			// Quadratic algorithm, but probably good enough for now.
			// TODO(gri) we need a fast quick type ID/hash for all types.
		L:
			for _, x := range x.types {
				for _, y := range y.types {
					if Identical(x, y) {
						continue L // x is in y.types
					}
				}
				return false // x is not in y.types
			}
			return true
		}

	case *Interface:
		// Two interface types are identical if they have the same set of methods with
		// the same names and identical function types. Lower-case method names from
		// different packages are always different. The order of the methods is irrelevant.
		if y, ok := y.(*Interface); ok {
			// If identical0 is called (indirectly) via an external API entry point
			// (such as Identical, IdenticalIgnoreTags, etc.), check is nil. But in
			// that case, interfaces are expected to be complete and lazy completion
			// here is not needed.
			if check != nil {
				check.completeInterface(token.NoPos, x)
				check.completeInterface(token.NoPos, y)
			}
			a := x.allMethods
			b := y.allMethods
			if len(a) == len(b) {
				// Interface types are the only types where cycles can occur
				// that are not "terminated" via named types; and such cycles
				// can only be created via method parameter types that are
				// anonymous interfaces (directly or indirectly) embedding
				// the current interface. Example:
				//
				//    type T interface {
				//        m() interface{T}
				//    }
				//
				// If two such (differently named) interfaces are compared,
				// endless recursion occurs if the cycle is not detected.
				//
				// If x and y were compared before, they must be equal
				// (if they were not, the recursion would have stopped);
				// search the ifacePair stack for the same pair.
				//
				// This is a quadratic algorithm, but in practice these stacks
				// are extremely short (bounded by the nesting depth of interface
				// type declarations that recur via parameter types, an extremely
				// rare occurrence). An alternative implementation might use a
				// "visited" map, but that is probably less efficient overall.
				q := &ifacePair{x, y, p}
				for p != nil {
					if p.identical(q) {
						return true // same pair was compared before
					}
					p = p.prev
				}
				if debug {
					assertSortedMethods(a)
					assertSortedMethods(b)
				}
				for i, f := range a {
					g := b[i]
					if f.Id() != g.Id() || !check.identical0(f.typ, g.typ, cmpTags, q) {
						return false
					}
				}
				return true
			}
		}

	case *Map:
		// Two map types are identical if they have identical key and value types.
		if y, ok := y.(*Map); ok {
			return check.identical0(x.key, y.key, cmpTags, p) && check.identical0(x.elem, y.elem, cmpTags, p)
		}

	case *Chan:
		// Two channel types are identical if they have identical value types
		// and the same direction.
		if y, ok := y.(*Chan); ok {
			return x.dir == y.dir && check.identical0(x.elem, y.elem, cmpTags, p)
		}

	case *Named:
		// Two named types are identical if their type names originate
		// in the same type declaration.
		if y, ok := y.(*Named); ok {
			// TODO(gri) Why is x == y not sufficient? And if it is,
			//           we can just return false here because x == y
			//           is caught in the very beginning of this function.
			return x.obj == y.obj
		}

	case *TypeParam:
		// nothing to do (x and y being equal is caught in the very beginning of this function)

	// case *instance:
	//	unreachable since types are expanded

	case *bottom, *top:
		// Either both types are theBottom, or both are theTop in which
		// case the initial x == y check will have caught them. Otherwise
		// they are not identical.

	case nil:
		// avoid a crash in case of nil type

	default:
		unreachable()
	}

	return false
}

func (check *Checker) identicalTParams(x, y []*TypeName, cmpTags bool, p *ifacePair) bool {
	if len(x) != len(y) {
		return false
	}
	for i, x := range x {
		y := y[i]
		if !check.identical0(x.typ.(*TypeParam).bound, y.typ.(*TypeParam).bound, cmpTags, p) {
			return false
		}
	}
	return true
}

// Default returns the default "typed" type for an "untyped" type;
// it returns the incoming type for all other types. The default type
// for untyped nil is untyped nil.
//
func Default(typ Type) Type {
	if t, ok := typ.(*Basic); ok {
		switch t.kind {
		case UntypedBool:
			return Typ[Bool]
		case UntypedInt:
			return Typ[Int]
		case UntypedRune:
			return universeRune // use 'rune' name
		case UntypedFloat:
			return Typ[Float64]
		case UntypedComplex:
			return Typ[Complex128]
		case UntypedString:
			return Typ[String]
		}
	}
	return typ
}
