goose: use function name as implicit provider set

Single-element provider sets are frequently useful enough to warrant
being a default.  Larger groupings within a package are less frequent.

Reviewed-by: Herbie Ong <herbie@google.com>
Reviewed-by: Tuo Shan <shantuo@google.com>
This commit is contained in:
Ross Light
2018-03-28 17:49:12 -07:00
parent 4abf804032
commit 34987b6bee
3 changed files with 27 additions and 32 deletions

View File

@@ -31,7 +31,7 @@ func ProvideFoo() Foo {
Providers are always part of a **provider set**: if there is no provider set Providers are always part of a **provider set**: if there is no provider set
named on the `//goose:provide` line, then the provider is added to the provider named on the `//goose:provide` line, then the provider is added to the provider
set with the name `Module`. set with the same name as the function (`ProvideFoo`, in this case).
Providers can specify dependencies with parameters: Providers can specify dependencies with parameters:
@@ -71,11 +71,11 @@ func ProvideBaz(ctx context.Context, bar Bar) (Baz, error) {
} }
``` ```
Provider sets can import other provider sets. To add `Module` in Provider sets can import other provider sets. To add the `ProvideFoo` set to
`SuperSet`: `SuperSet`:
```go ```go
// goose:import SuperSet Module // goose:import SuperSet ProvideFoo
``` ```
You can also import provider sets in another package, provided that you have a You can also import provider sets in another package, provided that you have a

View File

@@ -256,8 +256,6 @@ type providerSetImport struct {
pos token.Pos pos token.Pos
} }
const implicitModuleName = "Module"
// findProviderSets processes a package and extracts the provider sets declared in it. // findProviderSets processes a package and extracts the provider sets declared in it.
func findProviderSets(fset *token.FileSet, pkg *types.Package, typeInfo *types.Info, files []*ast.File) (map[string]*providerSet, error) { func findProviderSets(fset *token.FileSet, pkg *types.Package, typeInfo *types.Info, files []*ast.File) (map[string]*providerSet, error) {
sets := make(map[string]*providerSet) sets := make(map[string]*providerSet)
@@ -274,14 +272,12 @@ func findProviderSets(fset *token.FileSet, pkg *types.Package, typeInfo *types.I
if fileScope == nil { if fileScope == nil {
return nil, fmt.Errorf("%s: no scope found for file (likely a bug)", fset.File(f.Pos()).Name()) return nil, fmt.Errorf("%s: no scope found for file (likely a bug)", fset.File(f.Pos()).Name())
} }
var name, spec string i := strings.IndexByte(d.line, ' ')
if strings.HasPrefix(d.line, `"`) { // TODO(light): allow multiple imports in one line
name, spec = implicitModuleName, d.line if i == -1 {
} else if i := strings.IndexByte(d.line, ' '); i != -1 { return nil, fmt.Errorf("%s: invalid import: expected TARGET SETREF", fset.Position(d.pos))
name, spec = d.line[:i], d.line[i+1:]
} else {
name, spec = implicitModuleName, d.line
} }
name, spec := d.line[:i], d.line[i+1:]
ref, err := parseProviderSetRef(spec, fileScope, pkg.Path(), d.pos) ref, err := parseProviderSetRef(spec, fileScope, pkg.Path(), d.pos)
if err != nil { if err != nil {
return nil, fmt.Errorf("%v: %v", fset.Position(d.pos), err) return nil, fmt.Errorf("%v: %v", fset.Position(d.pos), err)
@@ -337,9 +333,8 @@ func findProviderSets(fset *token.FileSet, pkg *types.Package, typeInfo *types.I
if !isFunction { if !isFunction {
return nil, fmt.Errorf("%v: only functions can be marked as providers", fset.Position(d.pos)) return nil, fmt.Errorf("%v: only functions can be marked as providers", fset.Position(d.pos))
} }
if d.line == "" { providerSetName = fn.Name.Name
providerSetName = implicitModuleName if d.line != "" {
} else {
// TODO(light): validate identifier // TODO(light): validate identifier
providerSetName = d.line providerSetName = d.line
} }

View File

@@ -44,7 +44,7 @@ func provideMessage() string { return "Hello, World!"; }
package main package main
//goose:use Module //goose:use provideMessage
func injectedMessage() string func injectedMessage() string
`, `,
@@ -59,7 +59,7 @@ func injectedMessage() string
import "fmt" import "fmt"
func main() { fmt.Println(injectedMessage()); } func main() { fmt.Println(injectedMessage()); }
//goose:provide //goose:provide Set
// provideMessage provides a friendly user greeting. // provideMessage provides a friendly user greeting.
func provideMessage() string { return "Hello, World!"; } func provideMessage() string { return "Hello, World!"; }
@@ -86,17 +86,17 @@ func main() {
type Foo int type Foo int
type FooBar int type FooBar int
//goose:provide //goose:provide Set
func provideFoo() Foo { return 41 } func provideFoo() Foo { return 41 }
//goose:provide //goose:provide Set
func provideFooBar(foo Foo) FooBar { return FooBar(foo) + 1 } func provideFooBar(foo Foo) FooBar { return FooBar(foo) + 1 }
`, `,
"foo/foo_goose.go": `//+build gooseinject "foo/foo_goose.go": `//+build gooseinject
package main package main
//goose:use Module //goose:use Set
func injectFooBar() FooBar func injectFooBar() FooBar
`, `,
@@ -117,20 +117,20 @@ type Foo int
type Bar int type Bar int
type FooBar int type FooBar int
//goose:provide //goose:provide Set
func provideFoo() Foo { return 40 } func provideFoo() Foo { return 40 }
//goose:provide //goose:provide Set
func provideBar() Bar { return 2 } func provideBar() Bar { return 2 }
//goose:provide //goose:provide Set
func provideFooBar(foo Foo, bar Bar) FooBar { return FooBar(foo) + FooBar(bar) } func provideFooBar(foo Foo, bar Bar) FooBar { return FooBar(foo) + FooBar(bar) }
`, `,
"foo/foo_goose.go": `//+build gooseinject "foo/foo_goose.go": `//+build gooseinject
package main package main
//goose:use Module //goose:use Set
func injectFooBar() FooBar func injectFooBar() FooBar
`, `,
@@ -151,17 +151,17 @@ type Foo int
type Bar int type Bar int
type FooBar int type FooBar int
//goose:provide //goose:provide Set
func provideBar() Bar { return 2 } func provideBar() Bar { return 2 }
//goose:provide //goose:provide Set
func provideFooBar(foo Foo, bar Bar) FooBar { return FooBar(foo) + FooBar(bar) } func provideFooBar(foo Foo, bar Bar) FooBar { return FooBar(foo) + FooBar(bar) }
`, `,
"foo/foo_goose.go": `//+build gooseinject "foo/foo_goose.go": `//+build gooseinject
package main package main
//goose:use Module //goose:use Set
func injectFooBar(foo Foo) FooBar func injectFooBar(foo Foo) FooBar
`, `,
@@ -181,17 +181,17 @@ func main() {
type Foo int type Foo int
type Bar int type Bar int
//goose:provide //goose:provide Set
func provideFoo() Foo { return -888 } func provideFoo() Foo { return -888 }
//goose:provide //goose:provide Set
func provideBar(foo Foo) Bar { return 2 } func provideBar(foo Foo) Bar { return 2 }
`, `,
"foo/foo_goose.go": `//+build gooseinject "foo/foo_goose.go": `//+build gooseinject
package main package main
//goose:use Module //goose:use Set
func injectBar(foo Foo) Bar func injectBar(foo Foo) Bar
`, `,
@@ -218,14 +218,14 @@ func main() {
type Foo int type Foo int
//goose:provide //goose:provide Set
func provideFoo() (Foo, error) { return 42, errors.New("there is no Foo") } func provideFoo() (Foo, error) { return 42, errors.New("there is no Foo") }
`, `,
"foo/foo_goose.go": `//+build gooseinject "foo/foo_goose.go": `//+build gooseinject
package main package main
//goose:use Module //goose:use Set
func injectFoo() (Foo, error) func injectFoo() (Foo, error)
`, `,