func analyzeCode(scope *types.Scope, docs *doc.Package, variable string) (imports.Importer, []fn, error) { pkg := docs.Name v, ok := scope.Lookup(variable).(*types.Var) if v == nil { return nil, nil, fmt.Errorf("impossible to find variable %s", variable) } if !ok { return nil, nil, fmt.Errorf("%s must be a variable", variable) } var vType interface { NumMethods() int Method(int) *types.Func } switch t := v.Type().(type) { case *types.Interface: vType = t case *types.Pointer: vType = t.Elem().(*types.Named) case *types.Named: vType = t if t, ok := t.Underlying().(*types.Interface); ok { vType = t } default: return nil, nil, fmt.Errorf("variable is of an invalid type: %T", v.Type().Underlying()) } importer := imports.New(pkg) var funcs []fn for i := 0; i < vType.NumMethods(); i++ { f := vType.Method(i) if !f.Exported() { continue } sig := f.Type().(*types.Signature) funcs = append(funcs, fn{ WrappedVar: variable, Name: f.Name(), CurrentPkg: pkg, TypeInfo: f, }) importer.AddImportsFrom(sig.Params()) importer.AddImportsFrom(sig.Results()) } return importer, funcs, nil }
// analyzeCode takes the types scope and the docs and returns the import // information and information about all the assertion functions. func analyzeCode(scope *types.Scope, docs *doc.Package) (imports.Importer, []testFunc, error) { testingT := scope.Lookup("TestingT").Type().Underlying().(*types.Interface) importer := imports.New(*outputPkg) var funcs []testFunc // Go through all the top level functions for _, fdocs := range docs.Funcs { // Find the function obj := scope.Lookup(fdocs.Name) fn, ok := obj.(*types.Func) if !ok { continue } // Check function signatuer has at least two arguments sig := fn.Type().(*types.Signature) if sig.Params().Len() < 2 { continue } // Check first argument is of type testingT first, ok := sig.Params().At(0).Type().(*types.Named) if !ok { continue } firstType, ok := first.Underlying().(*types.Interface) if !ok { continue } if !types.Implements(firstType, testingT) { continue } funcs = append(funcs, testFunc{*outputPkg, fdocs, fn}) importer.AddImportsFrom(sig.Params()) } return importer, funcs, nil }