internal/wire: factor out common code in solve (#98)
- Fixed a bug when a interface is bind to a value wire would fail to record it is used. - Also rename ProvidedType.ConcreteType to Type since it doesn't necessarily returns a concrete type. Fixes #72
This commit is contained in:
@@ -114,8 +114,8 @@ dfs:
|
||||
continue
|
||||
}
|
||||
|
||||
switch pv := set.For(curr.t); {
|
||||
case pv.IsNil():
|
||||
pv := set.For(curr.t)
|
||||
if pv.IsNil() {
|
||||
if curr.from == nil {
|
||||
ec.add(fmt.Errorf("no provider found for %s, output of injector", types.TypeString(curr.t, nil)))
|
||||
index.Set(curr.t, errAbort)
|
||||
@@ -129,33 +129,25 @@ dfs:
|
||||
ec.add(errors.New(sb.String()))
|
||||
index.Set(curr.t, errAbort)
|
||||
continue
|
||||
case pv.IsArg():
|
||||
}
|
||||
src := set.srcMap.At(curr.t).(*providerSetSrc)
|
||||
used = append(used, src)
|
||||
if concrete := pv.ConcreteType(); !types.Identical(concrete, curr.t) {
|
||||
// Interface binding.
|
||||
if concrete := pv.Type(); !types.Identical(concrete, curr.t) {
|
||||
// Interface binding does not create a call.
|
||||
i := index.At(concrete)
|
||||
if i == nil {
|
||||
stk = append(stk, curr, frame{t: concrete, from: curr.t, up: &curr})
|
||||
continue
|
||||
}
|
||||
index.Set(curr.t, i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch pv := set.For(curr.t); {
|
||||
case pv.IsArg():
|
||||
// Continue, already added to stk.
|
||||
case pv.IsProvider():
|
||||
p := pv.Provider()
|
||||
src := set.srcMap.At(curr.t).(*providerSetSrc)
|
||||
used = append(used, src)
|
||||
if concrete := pv.ConcreteType(); !types.Identical(concrete, curr.t) {
|
||||
// Interface binding. Don't create a call ourselves.
|
||||
i := index.At(concrete)
|
||||
if i == nil {
|
||||
stk = append(stk, curr, frame{t: concrete, from: curr.t, up: &curr})
|
||||
continue
|
||||
}
|
||||
index.Set(curr.t, i)
|
||||
continue
|
||||
}
|
||||
// Ensure that all argument types have been visited. If not, push them
|
||||
// on the stack in reverse order so that calls are added in argument
|
||||
// order.
|
||||
@@ -204,18 +196,6 @@ dfs:
|
||||
})
|
||||
case pv.IsValue():
|
||||
v := pv.Value()
|
||||
if !types.Identical(v.Out, curr.t) {
|
||||
// Interface binding. Don't create a call ourselves.
|
||||
i := index.At(v.Out)
|
||||
if i == nil {
|
||||
stk = append(stk, curr, frame{t: v.Out, from: curr.t, up: &curr})
|
||||
continue
|
||||
}
|
||||
index.Set(curr.t, i)
|
||||
continue
|
||||
}
|
||||
src := set.srcMap.At(curr.t).(*providerSetSrc)
|
||||
used = append(used, src)
|
||||
index.Set(curr.t, given.Len()+len(calls))
|
||||
calls = append(calls, call{
|
||||
kind: valueExpr,
|
||||
|
||||
@@ -939,8 +939,14 @@ func (pt ProvidedType) IsNil() bool {
|
||||
return pt.p == nil && pt.v == nil && pt.a == nil
|
||||
}
|
||||
|
||||
// ConcreteType returns the concrete type that was provided.
|
||||
func (pt ProvidedType) ConcreteType() types.Type {
|
||||
// Type returns the output type.
|
||||
//
|
||||
// - For a function provider, this is the first return value type.
|
||||
// - For a struct provider, this is either the struct type or the pointer type
|
||||
// whose element type is the struct type.
|
||||
// - For a value, this is the type of the expression.
|
||||
// - For an argument, this is the type of the argument.
|
||||
func (pt ProvidedType) Type() types.Type {
|
||||
return pt.t
|
||||
}
|
||||
|
||||
|
||||
20
internal/wire/testdata/BindInterfaceWithValue/foo/foo.go
vendored
Normal file
20
internal/wire/testdata/BindInterfaceWithValue/foo/foo.go
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 The Wire Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
w := inject()
|
||||
w.Write([]byte("Hello, World!"))
|
||||
}
|
||||
32
internal/wire/testdata/BindInterfaceWithValue/foo/wire.go
vendored
Normal file
32
internal/wire/testdata/BindInterfaceWithValue/foo/wire.go
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2018 The Wire Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//+build wireinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
func inject() io.Writer {
|
||||
wire.Build(
|
||||
wire.Value(os.Stdout),
|
||||
wire.Bind(new(io.Writer), new(os.File)),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
1
internal/wire/testdata/BindInterfaceWithValue/pkg
vendored
Normal file
1
internal/wire/testdata/BindInterfaceWithValue/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
example.com/foo
|
||||
1
internal/wire/testdata/BindInterfaceWithValue/want/program_out.txt
vendored
Normal file
1
internal/wire/testdata/BindInterfaceWithValue/want/program_out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
22
internal/wire/testdata/BindInterfaceWithValue/want/wire_gen.go
vendored
Normal file
22
internal/wire/testdata/BindInterfaceWithValue/want/wire_gen.go
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// Code generated by Wire. DO NOT EDIT.
|
||||
|
||||
//go:generate wire
|
||||
//+build !wireinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Injectors from wire.go:
|
||||
|
||||
func inject() io.Writer {
|
||||
file := _wireFileValue
|
||||
return file
|
||||
}
|
||||
|
||||
var (
|
||||
_wireFileValue = os.Stdout
|
||||
)
|
||||
Reference in New Issue
Block a user