1 package loader
2 3 import "go/types"
4 5 // ImplementsCodec reports whether t (or *t) satisfies the moxie.Codec
6 // interface as defined in the loaded program. Types from .mxh packages are
7 // assumed to implement Codec (the header file asserts this). Returns false
8 // if the moxie package is not present in the program.
9 func ImplementsCodec(t types.Type, prog *Program) bool {
10 // Types from .mxh packages are known to implement Codec by definition.
11 if named, ok := t.(*types.Named); ok {
12 if pkg := named.Obj().Pkg(); pkg != nil && prog.MXHPackages[pkg.Path()] {
13 return true
14 }
15 }
16 moxiePkg, ok := prog.Packages["moxie"]
17 if !ok {
18 return false
19 }
20 codecObj := moxiePkg.Pkg.Scope().Lookup("Codec")
21 if codecObj == nil {
22 return false
23 }
24 codecIface, ok := codecObj.Type().Underlying().(*types.Interface)
25 if !ok {
26 return false
27 }
28 return implementsCodec(t, codecIface)
29 }
30 31 // ImplementsCodecIface checks whether t or *t satisfies the given Codec
32 // interface value. Used by the compiler when it already has the interface
33 // resolved from the SSA program.
34 func ImplementsCodecIface(t types.Type, codec *types.Interface) bool {
35 return types.Implements(t, codec) || types.Implements(types.NewPointer(t), codec)
36 }
37 38 // implementsCodec is the package-private alias for internal use.
39 func implementsCodec(t types.Type, codec *types.Interface) bool {
40 return ImplementsCodecIface(t, codec)
41 }
42