Example #1
0
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
}
Example #2
0
// 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
}