MCPcopy
hub / github.com/uber-go/nilaway / structsImplementingInterface

Function structsImplementingInterface

annotation/helper_test.go:150–230  ·  view source on GitHub ↗

structsImplementingInterface is a helper function that returns all the struct names implementing the given interface in the given package recursively

(interfaceName string, packageName ...string)

Source from the content-addressed store, hash-verified

148// structsImplementingInterface is a helper function that returns all the struct names implementing the given interface
149// in the given package recursively
150func structsImplementingInterface(interfaceName string, packageName ...string) map[string]bool {
151 structs := make(map[string]bool)
152
153 // if no package name is provided, default to using the current directory
154 if len(packageName) == 0 {
155 packageName = []string{"."}
156 }
157
158 cfg := &packages.Config{
159 Mode: packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles |
160 packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo,
161 }
162
163 for _, p := range packageName {
164 pkgs, err := packages.Load(cfg, p)
165 if err != nil {
166 panic(err)
167 }
168 if len(pkgs) == 0 {
169 panic("no packages found")
170 }
171
172 for _, pkg := range pkgs {
173 // scan the packages to find the interface and get its *types.Interface object
174 obj := pkgs[0].Types.Scope().Lookup(interfaceName)
175 if obj == nil {
176 continue
177 }
178 interfaceObj, ok := obj.Type().Underlying().(*types.Interface)
179 if !ok {
180 continue
181 }
182
183 // iterate over all Go files in the package to find the structs implementing the interface
184 for _, filepath := range pkg.GoFiles {
185 fset := token.NewFileSet()
186 node, err := parser.ParseFile(fset, filepath, nil, parser.AllErrors)
187 if err != nil {
188 panic(err)
189 }
190
191 ast.Inspect(node, func(n ast.Node) bool {
192 if typeSpec, ok := n.(*ast.TypeSpec); ok {
193 if _, ok := typeSpec.Type.(*ast.StructType); ok {
194 sObj := pkg.Types.Scope().Lookup(typeSpec.Name.Name)
195 if sObj == nil {
196 return true
197 }
198 sType, ok := types.Unalias(sObj.Type()).(*types.Named)
199 if !ok {
200 return true
201 }
202
203 structMethods := getImplementedMethods(sType)
204 if interfaceObj.NumMethods() > len(structMethods) {
205 return true
206 }
207

Callers 1

structsCheckedTestHelperFunction · 0.85

Calls 3

getImplementedMethodsFunction · 0.85
LookupMethod · 0.65
LoadMethod · 0.45

Tested by

no test coverage detected