func()

in mockgen/parse.go [250:353]


func (p *fileParser) parseInterface(name, pkg string, it *ast.InterfaceType) (*model.Interface, error) {
	iface := &model.Interface{Name: name}
	for _, field := range it.Methods.List {
		switch v := field.Type.(type) {
		case *ast.FuncType:
			if nn := len(field.Names); nn != 1 {
				return nil, fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn)
			}
			m := &model.Method{
				Name: field.Names[0].String(),
			}
			var err error
			m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v)
			if err != nil {
				return nil, err
			}
			iface.AddMethod(m)
		case *ast.Ident:
			// Embedded interface in this package.
			embeddedIfaceType := p.auxInterfaces[pkg][v.String()]
			if embeddedIfaceType == nil {
				embeddedIfaceType = p.importedInterfaces[pkg][v.String()]
			}

			var embeddedIface *model.Interface
			if embeddedIfaceType != nil {
				var err error
				embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType)
				if err != nil {
					return nil, err
				}
			} else {
				// This is built-in error interface.
				if v.String() == model.ErrorInterface.Name {
					embeddedIface = &model.ErrorInterface
				} else {
					ip, err := p.parsePackage(pkg)
					if err != nil {
						return nil, p.errorf(v.Pos(), "could not parse package %s: %v", pkg, err)
					}

					if embeddedIfaceType = ip.importedInterfaces[pkg][v.String()]; embeddedIfaceType == nil {
						return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", pkg, v.String())
					}

					embeddedIface, err = ip.parseInterface(v.String(), pkg, embeddedIfaceType)
					if err != nil {
						return nil, err
					}
				}
			}
			// Copy the methods.
			for _, m := range embeddedIface.Methods {
				iface.AddMethod(m)
			}
		case *ast.SelectorExpr:
			// Embedded interface in another package.
			filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String()
			embeddedPkg, ok := p.imports[filePkg]
			if !ok {
				return nil, p.errorf(v.X.Pos(), "unknown package %s", filePkg)
			}

			var embeddedIface *model.Interface
			var err error
			embeddedIfaceType := p.auxInterfaces[filePkg][sel]
			if embeddedIfaceType != nil {
				embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType)
				if err != nil {
					return nil, err
				}
			} else {
				path := embeddedPkg.Path()
				parser := embeddedPkg.Parser()
				if parser == nil {
					ip, err := p.parsePackage(path)
					if err != nil {
						return nil, p.errorf(v.Pos(), "could not parse package %s: %v", path, err)
					}
					parser = ip
					p.imports[filePkg] = importedPkg{
						path:   embeddedPkg.Path(),
						parser: parser,
					}
				}
				if embeddedIfaceType = parser.importedInterfaces[path][sel]; embeddedIfaceType == nil {
					return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel)
				}
				embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType)
				if err != nil {
					return nil, err
				}
			}
			// Copy the methods.
			// TODO: apply shadowing rules.
			for _, m := range embeddedIface.Methods {
				iface.AddMethod(m)
			}
		default:
			return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type)
		}
	}
	return iface, nil
}