|
|
|
|
@@ -74,6 +74,7 @@ func (p *providerSetSrc) description(fset *token.FileSet, typ types.Type) string
|
|
|
|
|
|
|
|
|
|
// trace returns a slice of strings describing the (possibly recursive) source
|
|
|
|
|
// of p, including line numbers.
|
|
|
|
|
// 这里是 srcMap 唯一使用的地方,看起来似乎只是用作错误输出,应该不会干扰我的修改。
|
|
|
|
|
func (p *providerSetSrc) trace(fset *token.FileSet, typ types.Type) []string {
|
|
|
|
|
var retval []string
|
|
|
|
|
// Only Imports need recursion.
|
|
|
|
|
@@ -122,12 +123,39 @@ func (set *ProviderSet) Outputs() []types.Type {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For returns a ProvidedType for the given type, or the zero ProvidedType.
|
|
|
|
|
// 这个方法是我们改造的重点,两个功能都要从这个函数进行动作
|
|
|
|
|
// - 自动查找所有接口的实现
|
|
|
|
|
//
|
|
|
|
|
// 已知的困难是
|
|
|
|
|
//
|
|
|
|
|
// 比如遇见一个新的接口,遍历所有 ProvidedType 进行检查并向 ProviderMap 中添加项以避免下次检查。
|
|
|
|
|
// 但是如果有两个接口先后需要查找,此时第二次查找同样会遍历第一次查找生成的 ProviderType 数据。
|
|
|
|
|
// 我想起来了,好像 ProviderSet 中有个 providers 属性储存了原始的那啥。可以使用这个遍历避免 ProviderType 膨胀问题
|
|
|
|
|
func (set *ProviderSet) For(t types.Type) ProvidedType {
|
|
|
|
|
pt := set.providerMap.At(t)
|
|
|
|
|
if pt == nil {
|
|
|
|
|
if pt != nil {
|
|
|
|
|
return *pt.(*ProvidedType)
|
|
|
|
|
}
|
|
|
|
|
face, isFace := t.Underlying().(*types.Interface)
|
|
|
|
|
if !isFace {
|
|
|
|
|
return ProvidedType{}
|
|
|
|
|
}
|
|
|
|
|
return *pt.(*ProvidedType)
|
|
|
|
|
var addMap []ProvidedType
|
|
|
|
|
for _, provider := range set.Providers {
|
|
|
|
|
pro := types.Implements(provider.Out[0], face)
|
|
|
|
|
if pro {
|
|
|
|
|
addMap = append(addMap, ProvidedType{t: t, p: provider})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(addMap) == 0 {
|
|
|
|
|
return ProvidedType{}
|
|
|
|
|
} else if len(addMap) == 1 {
|
|
|
|
|
provider := addMap[0]
|
|
|
|
|
set.providerMap.Set(t, &provider)
|
|
|
|
|
set.srcMap.Set(t, &providerSetSrc{Provider: provider.p})
|
|
|
|
|
return provider
|
|
|
|
|
}
|
|
|
|
|
panic("接口 " + t.String() + " 拥有多个实现")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// An IfaceBinding declares that a type should be used to satisfy inputs
|
|
|
|
|
@@ -1155,6 +1183,9 @@ func isProviderSetType(t types.Type) bool {
|
|
|
|
|
// can be a *Provider (a provider function), a *Value (wire.Value), or an
|
|
|
|
|
// *InjectorArgs (arguments to the injector function). The zero value has
|
|
|
|
|
// none of the above, and returns true for IsNil.
|
|
|
|
|
//
|
|
|
|
|
// 在我的角度来看,这东西其实有点职责混淆。因为他还顺带兼任了判断类是否存在的功能。
|
|
|
|
|
// 总之,这个结构体标记了提供者,还有一个检查是否有提供者的方法。当然,可能不止这一个功能。
|
|
|
|
|
type ProvidedType struct {
|
|
|
|
|
// t is the provided concrete type.
|
|
|
|
|
t types.Type
|
|
|
|
|
|