// newSumTypeDef attempts to extract a sum type definition from a single
// package. If no such type corresponds to the given decl, then this function
// returns a nil def and a nil error.
//
// If the decl corresponds to a type that isn't an interface containing at
// least one unexported method, then this returns an error.
newSumTypeDef attempts to extract a sum type definition from a single
package. If no such type corresponds to the given decl, then this function
returns a nil def and a nil error.

If the decl corresponds to a type that isn't an interface containing at
least one unexported method, then this returns an error.
// newSumTypeDef attempts to extract a sum type definition from a single // package . If no such type corresponds to the given decl then this function // returns a nil def and a nil error . // // If the decl corresponds to a type that isn ' t an interface containing at // least one unexported method then this returns an error .
func newSumTypeDef(pkg *types.Package, decl sumTypeDecl) (*sumTypeDef, error) {
	obj := pkg.Scope().Lookup(decl.TypeName)
	if obj == nil {
		return nil, nil
	}
	iface, ok := obj.Type().Underlying().(*types.Interface)
	if !ok {
		return nil, notInterfaceError{decl}
	}
	hasUnexported := false
	for i := 0; i < iface.NumMethods(); i++ {
		if !iface.Method(i).Exported() {
			hasUnexported = true
			break
		}
	}
	if !hasUnexported {
		return nil, unsealedError{decl}
	}
	def := &sumTypeDef{
		Decl: decl,
		Ty:   iface,
	}
	for _, name := range pkg.Scope().Names() {
		obj, ok := pkg.Scope().Lookup(name).(*types.TypeName)
		if !ok {
			continue
		}
		ty := obj.Type()
		if types.Identical(ty.Underlying(), iface) {
			continue
		}
		_, ok = ty.Underlying().(*types.Interface)
		if ok {
			continue
		}
		if types.Implements(ty, iface) || types.Implements(types.NewPointer(ty), iface) {
			def.Variants = append(def.Variants, obj)
		}
	}
	return def, nil
}
func newSumTypeDef ( pkg * types . Package , decl sumTypeDecl ) ( * sumTypeDef , error ) { obj := pkg . Scope ( ) . Lookup ( decl . TypeName ) if obj == nil { return nil , nil } iface , ok := obj . Type ( ) . Underlying ( ) . ( * types . Interface ) if ! ok { return nil , notInterfaceError { decl } } hasUnexported := false for i := 0 ; i < iface . NumMethods ( ) ; i ++ { if ! iface . Method ( i ) . Exported ( ) { hasUnexported = true break } } if ! hasUnexported { return nil , unsealedError { decl } } def := & sumTypeDef { Decl : decl , Ty : iface , } for _ , name := range pkg . Scope ( ) . Names ( ) { obj , ok := pkg . Scope ( ) . Lookup ( name ) . ( * types . TypeName ) if ! ok { continue } ty := obj . Type ( ) if types . Identical ( ty . Underlying ( ) , iface ) { continue } _ , ok = ty . Underlying ( ) . ( * types . Interface ) if ok { continue } if types . Implements ( ty , iface ) || types . Implements ( types . NewPointer ( ty ) , iface ) { def . Variants = append ( def . Variants , obj ) } } return def , nil }
newSumTypeDef attempts to extract a sum type definition from a single
package.
newSumTypeDef attempts to extract a sum type definition from a single package .