...

Source file src/go/types/predicates.go

     1	// Copyright 2012 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// This file implements commonly used type predicates.
     6	
     7	package types
     8	
     9	import "sort"
    10	
    11	func isNamed(typ Type) bool {
    12		if _, ok := typ.(*Basic); ok {
    13			return ok
    14		}
    15		_, ok := typ.(*Named)
    16		return ok
    17	}
    18	
    19	func isBoolean(typ Type) bool {
    20		t, ok := typ.Underlying().(*Basic)
    21		return ok && t.info&IsBoolean != 0
    22	}
    23	
    24	func isInteger(typ Type) bool {
    25		t, ok := typ.Underlying().(*Basic)
    26		return ok && t.info&IsInteger != 0
    27	}
    28	
    29	func isUnsigned(typ Type) bool {
    30		t, ok := typ.Underlying().(*Basic)
    31		return ok && t.info&IsUnsigned != 0
    32	}
    33	
    34	func isFloat(typ Type) bool {
    35		t, ok := typ.Underlying().(*Basic)
    36		return ok && t.info&IsFloat != 0
    37	}
    38	
    39	func isComplex(typ Type) bool {
    40		t, ok := typ.Underlying().(*Basic)
    41		return ok && t.info&IsComplex != 0
    42	}
    43	
    44	func isNumeric(typ Type) bool {
    45		t, ok := typ.Underlying().(*Basic)
    46		return ok && t.info&IsNumeric != 0
    47	}
    48	
    49	func isString(typ Type) bool {
    50		t, ok := typ.Underlying().(*Basic)
    51		return ok && t.info&IsString != 0
    52	}
    53	
    54	func isTyped(typ Type) bool {
    55		t, ok := typ.Underlying().(*Basic)
    56		return !ok || t.info&IsUntyped == 0
    57	}
    58	
    59	func isUntyped(typ Type) bool {
    60		t, ok := typ.Underlying().(*Basic)
    61		return ok && t.info&IsUntyped != 0
    62	}
    63	
    64	func isOrdered(typ Type) bool {
    65		t, ok := typ.Underlying().(*Basic)
    66		return ok && t.info&IsOrdered != 0
    67	}
    68	
    69	func isConstType(typ Type) bool {
    70		t, ok := typ.Underlying().(*Basic)
    71		return ok && t.info&IsConstType != 0
    72	}
    73	
    74	// IsInterface reports whether typ is an interface type.
    75	func IsInterface(typ Type) bool {
    76		_, ok := typ.Underlying().(*Interface)
    77		return ok
    78	}
    79	
    80	// Comparable reports whether values of type T are comparable.
    81	func Comparable(T Type) bool {
    82		switch t := T.Underlying().(type) {
    83		case *Basic:
    84			// assume invalid types to be comparable
    85			// to avoid follow-up errors
    86			return t.kind != UntypedNil
    87		case *Pointer, *Interface, *Chan:
    88			return true
    89		case *Struct:
    90			for _, f := range t.fields {
    91				if !Comparable(f.typ) {
    92					return false
    93				}
    94			}
    95			return true
    96		case *Array:
    97			return Comparable(t.elem)
    98		}
    99		return false
   100	}
   101	
   102	// hasNil reports whether a type includes the nil value.
   103	func hasNil(typ Type) bool {
   104		switch t := typ.Underlying().(type) {
   105		case *Basic:
   106			return t.kind == UnsafePointer
   107		case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
   108			return true
   109		}
   110		return false
   111	}
   112	
   113	// Identical reports whether x and y are identical types.
   114	// Receivers of Signature types are ignored.
   115	func Identical(x, y Type) bool {
   116		return identical(x, y, true, nil)
   117	}
   118	
   119	// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
   120	// Receivers of Signature types are ignored.
   121	func IdenticalIgnoreTags(x, y Type) bool {
   122		return identical(x, y, false, nil)
   123	}
   124	
   125	// An ifacePair is a node in a stack of interface type pairs compared for identity.
   126	type ifacePair struct {
   127		x, y *Interface
   128		prev *ifacePair
   129	}
   130	
   131	func (p *ifacePair) identical(q *ifacePair) bool {
   132		return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
   133	}
   134	
   135	func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
   136		if x == y {
   137			return true
   138		}
   139	
   140		switch x := x.(type) {
   141		case *Basic:
   142			// Basic types are singletons except for the rune and byte
   143			// aliases, thus we cannot solely rely on the x == y check
   144			// above. See also comment in TypeName.IsAlias.
   145			if y, ok := y.(*Basic); ok {
   146				return x.kind == y.kind
   147			}
   148	
   149		case *Array:
   150			// Two array types are identical if they have identical element types
   151			// and the same array length.
   152			if y, ok := y.(*Array); ok {
   153				// If one or both array lengths are unknown (< 0) due to some error,
   154				// assume they are the same to avoid spurious follow-on errors.
   155				return (x.len < 0 || y.len < 0 || x.len == y.len) && identical(x.elem, y.elem, cmpTags, p)
   156			}
   157	
   158		case *Slice:
   159			// Two slice types are identical if they have identical element types.
   160			if y, ok := y.(*Slice); ok {
   161				return identical(x.elem, y.elem, cmpTags, p)
   162			}
   163	
   164		case *Struct:
   165			// Two struct types are identical if they have the same sequence of fields,
   166			// and if corresponding fields have the same names, and identical types,
   167			// and identical tags. Two embedded fields are considered to have the same
   168			// name. Lower-case field names from different packages are always different.
   169			if y, ok := y.(*Struct); ok {
   170				if x.NumFields() == y.NumFields() {
   171					for i, f := range x.fields {
   172						g := y.fields[i]
   173						if f.embedded != g.embedded ||
   174							cmpTags && x.Tag(i) != y.Tag(i) ||
   175							!f.sameId(g.pkg, g.name) ||
   176							!identical(f.typ, g.typ, cmpTags, p) {
   177							return false
   178						}
   179					}
   180					return true
   181				}
   182			}
   183	
   184		case *Pointer:
   185			// Two pointer types are identical if they have identical base types.
   186			if y, ok := y.(*Pointer); ok {
   187				return identical(x.base, y.base, cmpTags, p)
   188			}
   189	
   190		case *Tuple:
   191			// Two tuples types are identical if they have the same number of elements
   192			// and corresponding elements have identical types.
   193			if y, ok := y.(*Tuple); ok {
   194				if x.Len() == y.Len() {
   195					if x != nil {
   196						for i, v := range x.vars {
   197							w := y.vars[i]
   198							if !identical(v.typ, w.typ, cmpTags, p) {
   199								return false
   200							}
   201						}
   202					}
   203					return true
   204				}
   205			}
   206	
   207		case *Signature:
   208			// Two function types are identical if they have the same number of parameters
   209			// and result values, corresponding parameter and result types are identical,
   210			// and either both functions are variadic or neither is. Parameter and result
   211			// names are not required to match.
   212			if y, ok := y.(*Signature); ok {
   213				return x.variadic == y.variadic &&
   214					identical(x.params, y.params, cmpTags, p) &&
   215					identical(x.results, y.results, cmpTags, p)
   216			}
   217	
   218		case *Interface:
   219			// Two interface types are identical if they have the same set of methods with
   220			// the same names and identical function types. Lower-case method names from
   221			// different packages are always different. The order of the methods is irrelevant.
   222			if y, ok := y.(*Interface); ok {
   223				a := x.allMethods
   224				b := y.allMethods
   225				if len(a) == len(b) {
   226					// Interface types are the only types where cycles can occur
   227					// that are not "terminated" via named types; and such cycles
   228					// can only be created via method parameter types that are
   229					// anonymous interfaces (directly or indirectly) embedding
   230					// the current interface. Example:
   231					//
   232					//    type T interface {
   233					//        m() interface{T}
   234					//    }
   235					//
   236					// If two such (differently named) interfaces are compared,
   237					// endless recursion occurs if the cycle is not detected.
   238					//
   239					// If x and y were compared before, they must be equal
   240					// (if they were not, the recursion would have stopped);
   241					// search the ifacePair stack for the same pair.
   242					//
   243					// This is a quadratic algorithm, but in practice these stacks
   244					// are extremely short (bounded by the nesting depth of interface
   245					// type declarations that recur via parameter types, an extremely
   246					// rare occurrence). An alternative implementation might use a
   247					// "visited" map, but that is probably less efficient overall.
   248					q := &ifacePair{x, y, p}
   249					for p != nil {
   250						if p.identical(q) {
   251							return true // same pair was compared before
   252						}
   253						p = p.prev
   254					}
   255					if debug {
   256						assert(sort.IsSorted(byUniqueMethodName(a)))
   257						assert(sort.IsSorted(byUniqueMethodName(b)))
   258					}
   259					for i, f := range a {
   260						g := b[i]
   261						if f.Id() != g.Id() || !identical(f.typ, g.typ, cmpTags, q) {
   262							return false
   263						}
   264					}
   265					return true
   266				}
   267			}
   268	
   269		case *Map:
   270			// Two map types are identical if they have identical key and value types.
   271			if y, ok := y.(*Map); ok {
   272				return identical(x.key, y.key, cmpTags, p) && identical(x.elem, y.elem, cmpTags, p)
   273			}
   274	
   275		case *Chan:
   276			// Two channel types are identical if they have identical value types
   277			// and the same direction.
   278			if y, ok := y.(*Chan); ok {
   279				return x.dir == y.dir && identical(x.elem, y.elem, cmpTags, p)
   280			}
   281	
   282		case *Named:
   283			// Two named types are identical if their type names originate
   284			// in the same type declaration.
   285			if y, ok := y.(*Named); ok {
   286				return x.obj == y.obj
   287			}
   288	
   289		case nil:
   290	
   291		default:
   292			unreachable()
   293		}
   294	
   295		return false
   296	}
   297	
   298	// Default returns the default "typed" type for an "untyped" type;
   299	// it returns the incoming type for all other types. The default type
   300	// for untyped nil is untyped nil.
   301	//
   302	func Default(typ Type) Type {
   303		if t, ok := typ.(*Basic); ok {
   304			switch t.kind {
   305			case UntypedBool:
   306				return Typ[Bool]
   307			case UntypedInt:
   308				return Typ[Int]
   309			case UntypedRune:
   310				return universeRune // use 'rune' name
   311			case UntypedFloat:
   312				return Typ[Float64]
   313			case UntypedComplex:
   314				return Typ[Complex128]
   315			case UntypedString:
   316				return Typ[String]
   317			}
   318		}
   319		return typ
   320	}
   321	

View as plain text