]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: move Interface type decl into interface.go (cleanup)
authorRob Findley <rfindley@google.com>
Fri, 16 Jul 2021 14:45:51 +0000 (10:45 -0400)
committerRobert Findley <rfindley@google.com>
Fri, 16 Jul 2021 23:34:53 +0000 (23:34 +0000)
This is a port of CL 332092 to go/types.

Change-Id: I9971c49570424368575108832eac0cd978eb3fe6
Reviewed-on: https://go-review.googlesource.com/c/go/+/335039
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/interface.go
src/go/types/type.go

index 367fc7947750508b6604776920e97686f7888584..91270cfcd37c3fef8bb2bb6405a6c4bef78a047c 100644 (file)
@@ -10,6 +10,166 @@ import (
        "go/token"
 )
 
+// ----------------------------------------------------------------------------
+// API
+
+// An Interface represents an interface type.
+type Interface struct {
+       obj       *TypeName    // type name object defining this interface; or nil (for better error messages)
+       methods   []*Func      // ordered list of explicitly declared methods
+       embeddeds []Type       // ordered list of explicitly embedded elements
+       embedPos  *[]token.Pos // positions of embedded elements; or nil (for error messages) - use pointer to save space
+       complete  bool         // indicates that obj, methods, and embeddeds are set and type set can be computed
+
+       tset *TypeSet // type set described by this interface, computed lazily
+}
+
+// typeSet returns the type set for interface t.
+func (t *Interface) typeSet() *TypeSet { return computeTypeSet(nil, token.NoPos, t) }
+
+// is reports whether interface t represents types that all satisfy f.
+func (t *Interface) is(f func(Type, bool) bool) bool {
+       switch t := t.typeSet().types.(type) {
+       case nil, *top:
+               // TODO(gri) should settle on top or nil to represent this case
+               return false // we must have at least one type! (was bug)
+       case *Union:
+               return t.is(func(typ Type, tilde bool) bool { return f(typ, tilde) })
+       default:
+               return f(t, false)
+       }
+}
+
+// emptyInterface represents the empty (completed) interface
+var emptyInterface = Interface{complete: true, tset: &topTypeSet}
+
+// NewInterface returns a new interface for the given methods and embedded types.
+// NewInterface takes ownership of the provided methods and may modify their types
+// by setting missing receivers.
+//
+// Deprecated: Use NewInterfaceType instead which allows arbitrary embedded types.
+func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
+       tnames := make([]Type, len(embeddeds))
+       for i, t := range embeddeds {
+               tnames[i] = t
+       }
+       return NewInterfaceType(methods, tnames)
+}
+
+// NewInterfaceType returns a new interface for the given methods and embedded types.
+// NewInterfaceType takes ownership of the provided methods and may modify their types
+// by setting missing receivers.
+func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
+       if len(methods) == 0 && len(embeddeds) == 0 {
+               return &emptyInterface
+       }
+
+       // set method receivers if necessary
+       typ := new(Interface)
+       for _, m := range methods {
+               if sig := m.typ.(*Signature); sig.recv == nil {
+                       sig.recv = NewVar(m.pos, m.pkg, "", typ)
+               }
+       }
+
+       // TODO(rfindley): this guard is not present in types2. Remove it?
+       // All embedded types should be interfaces; however, defined types
+       // may not yet be fully resolved. Only verify that non-defined types
+       // are interfaces. This matches the behavior of the code before the
+       // fix for #25301 (issue #25596).
+       for _, t := range embeddeds {
+               if _, ok := t.(*Named); !ok && !IsInterface(t) {
+                       panic("embedded type is not an interface")
+               }
+       }
+
+       // sort for API stability
+       sortMethods(methods)
+
+       typ.methods = methods
+       typ.embeddeds = embeddeds
+       typ.complete = true
+
+       return typ
+}
+
+// NumExplicitMethods returns the number of explicitly declared methods of interface t.
+func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
+
+// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
+
+// NumEmbeddeds returns the number of embedded types in interface t.
+func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
+
+// Embedded returns the i'th embedded defined (*Named) type of interface t for 0 <= i < t.NumEmbeddeds().
+// The result is nil if the i'th embedded type is not a defined type.
+//
+// Deprecated: Use EmbeddedType which is not restricted to defined (*Named) types.
+func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname }
+
+// EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
+func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
+
+// NumMethods returns the total number of methods of interface t.
+func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
+
+// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
+
+// Empty reports whether t is the empty interface.
+func (t *Interface) Empty() bool { return t.typeSet().IsTop() }
+
+// IsComparable reports whether interface t is or embeds the predeclared interface "comparable".
+func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable() }
+
+// IsConstraint reports whether interface t is not just a method set.
+func (t *Interface) IsConstraint() bool { return !t.typeSet().IsMethodSet() }
+
+// isSatisfiedBy reports whether interface t's type list is satisfied by the type typ.
+// If the type list is empty (absent), typ trivially satisfies the interface.
+// TODO(gri) This is not a great name. Eventually, we should have a more comprehensive
+//           "implements" predicate.
+func (t *Interface) isSatisfiedBy(typ Type) bool {
+       t.Complete()
+       switch t := t.typeSet().types.(type) {
+       case nil:
+               return true // no type restrictions
+       case *Union:
+               r, _ := t.intersect(typ, false)
+               return r != nil
+       default:
+               return Identical(t, typ)
+       }
+}
+
+// Complete computes the interface's type set. It must be called by users of
+// NewInterfaceType and NewInterface after the interface's embedded types are
+// fully defined and before using the interface type in any way other than to
+// form other types. The interface must not contain duplicate methods or a
+// panic occurs. Complete returns the receiver.
+//
+// Deprecated: Type sets are now computed lazily, on demand; this function
+//             is only here for backward-compatibility. It does not have to
+//             be called explicitly anymore.
+func (t *Interface) Complete() *Interface {
+       // Some tests are still depending on the state change
+       // (string representation of an Interface not containing an
+       // /* incomplete */ marker) caused by the explicit Complete
+       // call, so we compute the type set eagerly here.
+       t.complete = true
+       t.typeSet()
+       return t
+}
+
+func (t *Interface) Underlying() Type { return t }
+func (t *Interface) String() string   { return TypeString(t, nil) }
+
+// ----------------------------------------------------------------------------
+// Implementation
+
 func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
        var tlist []ast.Expr
        var tname *ast.Ident // "type" name of first entry in a type list declaration
index a4c47d17ea18b79b2377ec7ab1082183b7045eaa..2adc2fa3ca97afd66220b56df02d543b609e306f 100644 (file)
@@ -163,156 +163,6 @@ func (t *Tuple) Len() int {
 // At returns the i'th variable of tuple t.
 func (t *Tuple) At(i int) *Var { return t.vars[i] }
 
-// An Interface represents an interface type.
-type Interface struct {
-       obj       *TypeName    // type name object defining this interface; or nil (for better error messages)
-       methods   []*Func      // ordered list of explicitly declared methods
-       embeddeds []Type       // ordered list of explicitly embedded elements
-       embedPos  *[]token.Pos // positions of embedded elements; or nil (for error messages) - use pointer to save space
-       complete  bool         // indicates that obj, methods, and embeddeds are set and type set can be computed
-
-       tset *TypeSet // type set described by this interface, computed lazily
-}
-
-// typeSet returns the type set for interface t.
-func (t *Interface) typeSet() *TypeSet { return computeTypeSet(nil, token.NoPos, t) }
-
-// is reports whether interface t represents types that all satisfy f.
-func (t *Interface) is(f func(Type, bool) bool) bool {
-       switch t := t.typeSet().types.(type) {
-       case nil, *top:
-               // TODO(gri) should settle on top or nil to represent this case
-               return false // we must have at least one type! (was bug)
-       case *Union:
-               return t.is(func(typ Type, tilde bool) bool { return f(typ, tilde) })
-       default:
-               return f(t, false)
-       }
-}
-
-// emptyInterface represents the empty (completed) interface
-var emptyInterface = Interface{complete: true, tset: &topTypeSet}
-
-// NewInterface returns a new interface for the given methods and embedded types.
-// NewInterface takes ownership of the provided methods and may modify their types
-// by setting missing receivers.
-//
-// Deprecated: Use NewInterfaceType instead which allows arbitrary embedded types.
-func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
-       tnames := make([]Type, len(embeddeds))
-       for i, t := range embeddeds {
-               tnames[i] = t
-       }
-       return NewInterfaceType(methods, tnames)
-}
-
-// NewInterfaceType returns a new interface for the given methods and embedded types.
-// NewInterfaceType takes ownership of the provided methods and may modify their types
-// by setting missing receivers.
-func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
-       if len(methods) == 0 && len(embeddeds) == 0 {
-               return &emptyInterface
-       }
-
-       // set method receivers if necessary
-       typ := new(Interface)
-       for _, m := range methods {
-               if sig := m.typ.(*Signature); sig.recv == nil {
-                       sig.recv = NewVar(m.pos, m.pkg, "", typ)
-               }
-       }
-
-       // All embedded types should be interfaces; however, defined types
-       // may not yet be fully resolved. Only verify that non-defined types
-       // are interfaces. This matches the behavior of the code before the
-       // fix for #25301 (issue #25596).
-       for _, t := range embeddeds {
-               if _, ok := t.(*Named); !ok && !IsInterface(t) {
-                       panic("embedded type is not an interface")
-               }
-       }
-
-       // sort for API stability
-       sortMethods(methods)
-
-       typ.methods = methods
-       typ.embeddeds = embeddeds
-       typ.complete = true
-
-       return typ
-}
-
-// NumExplicitMethods returns the number of explicitly declared methods of interface t.
-func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
-
-// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
-// The methods are ordered by their unique Id.
-func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
-
-// NumEmbeddeds returns the number of embedded types in interface t.
-func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
-
-// Embedded returns the i'th embedded defined (*Named) type of interface t for 0 <= i < t.NumEmbeddeds().
-// The result is nil if the i'th embedded type is not a defined type.
-//
-// Deprecated: Use EmbeddedType which is not restricted to defined (*Named) types.
-func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname }
-
-// EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
-func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
-
-// NumMethods returns the total number of methods of interface t.
-func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
-
-// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
-// The methods are ordered by their unique Id.
-func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
-
-// Empty reports whether t is the empty interface.
-func (t *Interface) Empty() bool { return t.typeSet().IsTop() }
-
-// IsComparable reports whether interface t is or embeds the predeclared interface "comparable".
-func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable() }
-
-// IsConstraint reports whether interface t is not just a method set.
-func (t *Interface) IsConstraint() bool { return !t.typeSet().IsMethodSet() }
-
-// isSatisfiedBy reports whether interface t's type list is satisfied by the type typ.
-// If the type list is empty (absent), typ trivially satisfies the interface.
-// TODO(gri) This is not a great name. Eventually, we should have a more comprehensive
-//           "implements" predicate.
-func (t *Interface) isSatisfiedBy(typ Type) bool {
-       t.Complete()
-       switch t := t.typeSet().types.(type) {
-       case nil:
-               return true // no type restrictions
-       case *Union:
-               r, _ := t.intersect(typ, false)
-               return r != nil
-       default:
-               return Identical(t, typ)
-       }
-}
-
-// Complete computes the interface's type set. It must be called by users of
-// NewInterfaceType and NewInterface after the interface's embedded types are
-// fully defined and before using the interface type in any way other than to
-// form other types. The interface must not contain duplicate methods or a
-// panic occurs. Complete returns the receiver.
-//
-// Deprecated: Type sets are now computed lazily, on demand; this function
-//             is only here for backward-compatibility. It does not have to
-//             be called explicitly anymore.
-func (t *Interface) Complete() *Interface {
-       // Some tests are still depending on the state change
-       // (string representation of an Interface not containing an
-       // /* incomplete */ marker) caused by the explicit Complete
-       // call, so we compute the type set eagerly here.
-       t.complete = true
-       t.typeSet()
-       return t
-}
-
 // A Map represents a map type.
 type Map struct {
        key, elem Type
@@ -638,7 +488,6 @@ func (t *Array) Underlying() Type     { return t }
 func (t *Slice) Underlying() Type     { return t }
 func (t *Pointer) Underlying() Type   { return t }
 func (t *Tuple) Underlying() Type     { return t }
-func (t *Interface) Underlying() Type { return t }
 func (t *Map) Underlying() Type       { return t }
 func (t *Chan) Underlying() Type      { return t }
 func (t *Named) Underlying() Type     { return t.expand().underlying }
@@ -652,7 +501,6 @@ func (t *Array) String() string     { return TypeString(t, nil) }
 func (t *Slice) String() string     { return TypeString(t, nil) }
 func (t *Pointer) String() string   { return TypeString(t, nil) }
 func (t *Tuple) String() string     { return TypeString(t, nil) }
-func (t *Interface) String() string { return TypeString(t, nil) }
 func (t *Map) String() string       { return TypeString(t, nil) }
 func (t *Chan) String() string      { return TypeString(t, nil) }
 func (t *Named) String() string     { return TypeString(t, nil) }