goose: add goose.Value directive
Subsumes previous usage of goose.Optional. Reviewed-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Tuo Shan <shantuo@google.com>
This commit is contained in:
@@ -16,17 +16,34 @@ package goose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/go/types/typeutil"
|
||||
)
|
||||
|
||||
type callKind int
|
||||
|
||||
const (
|
||||
funcProviderCall callKind = iota
|
||||
structProvider
|
||||
valueExpr
|
||||
)
|
||||
|
||||
// A call represents a step of an injector function. It may be either a
|
||||
// function call or a composite struct literal, depending on the value
|
||||
// of isStruct.
|
||||
// of kind.
|
||||
type call struct {
|
||||
// importPath and name identify the provider to call.
|
||||
// kind indicates the code pattern to use.
|
||||
kind callKind
|
||||
|
||||
// out is the type this step produces.
|
||||
out types.Type
|
||||
|
||||
// importPath and name identify the provider to call for kind ==
|
||||
// funcProviderCall or the type to construct for kind ==
|
||||
// structProvider.
|
||||
importPath string
|
||||
name string
|
||||
|
||||
@@ -34,24 +51,29 @@ type call struct {
|
||||
// a) one of the givens (args[i] < len(given)),
|
||||
// b) the result of a previous provider call (args[i] >= len(given)), or
|
||||
// c) the zero value for the type (args[i] == -1).
|
||||
//
|
||||
// This will be nil for kind == valueExpr.
|
||||
args []int
|
||||
|
||||
// isStruct indicates whether this should generate a struct composite
|
||||
// literal instead of a function call.
|
||||
isStruct bool
|
||||
|
||||
// fieldNames maps the arguments to struct field names.
|
||||
// This will only be set if isStruct is true.
|
||||
// This will only be set if kind == structProvider.
|
||||
fieldNames []string
|
||||
|
||||
// ins is the list of types this call receives as arguments.
|
||||
// This will be nil for kind == valueExpr.
|
||||
ins []types.Type
|
||||
// out is the type produced by this provider call.
|
||||
out types.Type
|
||||
|
||||
// The following are only set for kind == funcProviderCall:
|
||||
|
||||
// hasCleanup is true if the provider call returns a cleanup function.
|
||||
hasCleanup bool
|
||||
// hasErr is true if the provider call returns an error.
|
||||
hasErr bool
|
||||
|
||||
// The following are only set for kind == valueExpr:
|
||||
|
||||
valueExpr ast.Expr
|
||||
valueTypeInfo *types.Info
|
||||
}
|
||||
|
||||
// solve finds the sequence of calls required to produce an output type
|
||||
@@ -97,50 +119,69 @@ func solve(fset *token.FileSet, out types.Type, given []types.Type, set *Provide
|
||||
}
|
||||
}
|
||||
|
||||
p, _ := providers.At(typ).(*Provider)
|
||||
if p == nil {
|
||||
switch p := providers.At(typ).(type) {
|
||||
case nil:
|
||||
if len(trail) == 1 {
|
||||
return fmt.Errorf("no provider found for %s (output of injector)", types.TypeString(typ, nil))
|
||||
}
|
||||
// TODO(light): Give name of provider.
|
||||
return fmt.Errorf("no provider found for %s (required by provider of %s)", types.TypeString(typ, nil), types.TypeString(trail[len(trail)-2].Type, nil))
|
||||
}
|
||||
if !types.Identical(p.Out, typ) {
|
||||
// Interface binding. Don't create a call ourselves.
|
||||
if err := visit(append(trail, ProviderInput{Type: p.Out})); err != nil {
|
||||
return err
|
||||
case *Provider:
|
||||
if !types.Identical(p.Out, typ) {
|
||||
// Interface binding. Don't create a call ourselves.
|
||||
if err := visit(append(trail, ProviderInput{Type: p.Out})); err != nil {
|
||||
return err
|
||||
}
|
||||
index.Set(typ, index.At(p.Out))
|
||||
return nil
|
||||
}
|
||||
index.Set(typ, index.At(p.Out))
|
||||
return nil
|
||||
}
|
||||
for _, a := range p.Args {
|
||||
// TODO(light): This will discard grown trail arrays.
|
||||
if err := visit(append(trail, a)); err != nil {
|
||||
return err
|
||||
for _, a := range p.Args {
|
||||
// TODO(light): This will discard grown trail arrays.
|
||||
if err := visit(append(trail, a)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
args := make([]int, len(p.Args))
|
||||
ins := make([]types.Type, len(p.Args))
|
||||
for i := range p.Args {
|
||||
ins[i] = p.Args[i].Type
|
||||
if x := index.At(p.Args[i].Type); x != nil {
|
||||
args[i] = x.(int)
|
||||
} else {
|
||||
args[i] = -1
|
||||
args := make([]int, len(p.Args))
|
||||
ins := make([]types.Type, len(p.Args))
|
||||
for i := range p.Args {
|
||||
ins[i] = p.Args[i].Type
|
||||
args[i] = index.At(p.Args[i].Type).(int)
|
||||
}
|
||||
index.Set(typ, len(given)+len(calls))
|
||||
kind := funcProviderCall
|
||||
if p.IsStruct {
|
||||
kind = structProvider
|
||||
}
|
||||
calls = append(calls, call{
|
||||
kind: kind,
|
||||
importPath: p.ImportPath,
|
||||
name: p.Name,
|
||||
args: args,
|
||||
fieldNames: p.Fields,
|
||||
ins: ins,
|
||||
out: typ,
|
||||
hasCleanup: p.HasCleanup,
|
||||
hasErr: p.HasErr,
|
||||
})
|
||||
case *Value:
|
||||
if !types.Identical(p.Out, typ) {
|
||||
// Interface binding. Don't create a call ourselves.
|
||||
if err := visit(append(trail, ProviderInput{Type: p.Out})); err != nil {
|
||||
return err
|
||||
}
|
||||
index.Set(typ, index.At(p.Out))
|
||||
return nil
|
||||
}
|
||||
index.Set(typ, len(given)+len(calls))
|
||||
calls = append(calls, call{
|
||||
kind: valueExpr,
|
||||
out: typ,
|
||||
valueExpr: p.expr,
|
||||
valueTypeInfo: p.info,
|
||||
})
|
||||
default:
|
||||
panic("unknown provider map value type")
|
||||
}
|
||||
index.Set(typ, len(given)+len(calls))
|
||||
calls = append(calls, call{
|
||||
importPath: p.ImportPath,
|
||||
name: p.Name,
|
||||
args: args,
|
||||
isStruct: p.IsStruct,
|
||||
fieldNames: p.Fields,
|
||||
ins: ins,
|
||||
out: typ,
|
||||
hasCleanup: p.HasCleanup,
|
||||
hasErr: p.HasErr,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
if err := visit([]ProviderInput{{Type: out}}); err != nil {
|
||||
@@ -155,7 +196,7 @@ func buildProviderMap(fset *token.FileSet, set *ProviderSet) (*typeutil.Map, err
|
||||
set *ProviderSet
|
||||
}
|
||||
|
||||
providerMap := new(typeutil.Map) // to *Provider
|
||||
providerMap := new(typeutil.Map) // to *Provider or *Value
|
||||
setMap := new(typeutil.Map) // to *ProviderSet, for error messages
|
||||
var bindings []binding
|
||||
visited := make(map[*ProviderSet]struct{})
|
||||
@@ -175,6 +216,13 @@ func buildProviderMap(fset *token.FileSet, set *ProviderSet) (*typeutil.Map, err
|
||||
providerMap.Set(p.Out, p)
|
||||
setMap.Set(p.Out, curr)
|
||||
}
|
||||
for _, v := range curr.Values {
|
||||
if providerMap.At(v.Out) != nil {
|
||||
return nil, bindingConflictError(fset, v.Pos, v.Out, setMap.At(v.Out).(*ProviderSet))
|
||||
}
|
||||
providerMap.Set(v.Out, v)
|
||||
setMap.Set(v.Out, curr)
|
||||
}
|
||||
for _, b := range curr.Bindings {
|
||||
bindings = append(bindings, binding{
|
||||
IfaceBinding: b,
|
||||
|
||||
@@ -244,15 +244,24 @@ func (g *gen) inject(fset *token.FileSet, name string, sig *types.Signature, set
|
||||
paramTypes[i] = types.TypeString(params.At(i).Type(), g.qualifyPkg)
|
||||
}
|
||||
for _, c := range calls {
|
||||
g.qualifyImport(c.importPath)
|
||||
if !c.isStruct {
|
||||
// Struct providers just omit zero-valued fields.
|
||||
continue
|
||||
}
|
||||
for i := range c.args {
|
||||
if c.args[i] == -1 {
|
||||
zeroValue(c.ins[i], g.qualifyPkg)
|
||||
switch c.kind {
|
||||
case funcProviderCall:
|
||||
g.qualifyImport(c.importPath)
|
||||
for i := range c.args {
|
||||
if c.args[i] == -1 {
|
||||
zeroValue(c.ins[i], g.qualifyPkg)
|
||||
}
|
||||
}
|
||||
case structProvider:
|
||||
g.qualifyImport(c.importPath)
|
||||
case valueExpr:
|
||||
if err := accessibleFrom(c.valueTypeInfo, c.valueExpr, g.currPackage); err != nil {
|
||||
// TODO(light): Display line number of value expression.
|
||||
ts := types.TypeString(c.out, nil)
|
||||
return fmt.Errorf("inject %s: value %s can't be used: %v", name, ts, err)
|
||||
}
|
||||
default:
|
||||
panic("unknown kind")
|
||||
}
|
||||
}
|
||||
outTypeString := types.TypeString(outType, g.qualifyPkg)
|
||||
@@ -326,7 +335,8 @@ func (g *gen) inject(fset *token.FileSet, name string, sig *types.Signature, set
|
||||
g.p(", %s", errVar)
|
||||
}
|
||||
g.p(" := ")
|
||||
if c.isStruct {
|
||||
switch c.kind {
|
||||
case structProvider:
|
||||
if _, ok := c.out.(*types.Pointer); ok {
|
||||
g.p("&")
|
||||
}
|
||||
@@ -345,7 +355,7 @@ func (g *gen) inject(fset *token.FileSet, name string, sig *types.Signature, set
|
||||
g.p(",\n")
|
||||
}
|
||||
g.p("\t}\n")
|
||||
} else {
|
||||
case funcProviderCall:
|
||||
g.p("%s(", g.qualifiedID(c.importPath, c.name))
|
||||
for j, a := range c.args {
|
||||
if j > 0 {
|
||||
@@ -360,6 +370,11 @@ func (g *gen) inject(fset *token.FileSet, name string, sig *types.Signature, set
|
||||
}
|
||||
}
|
||||
g.p(")\n")
|
||||
case valueExpr:
|
||||
g.writeAST(fset, c.valueTypeInfo, c.valueExpr)
|
||||
g.p("\n")
|
||||
default:
|
||||
panic("unknown kind")
|
||||
}
|
||||
if c.hasErr {
|
||||
g.p("\tif %s != nil {\n", errVar)
|
||||
@@ -656,6 +671,32 @@ func disambiguate(name string, collides func(string) bool) string {
|
||||
}
|
||||
}
|
||||
|
||||
// accessibleFrom reports whether node can be copied to wantPkg without
|
||||
// violating Go visibility rules.
|
||||
func accessibleFrom(info *types.Info, node ast.Node, wantPkg string) error {
|
||||
var unexportError error
|
||||
ast.Inspect(node, func(node ast.Node) bool {
|
||||
if unexportError != nil {
|
||||
return false
|
||||
}
|
||||
ident, ok := node.(*ast.Ident)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
obj := info.ObjectOf(ident)
|
||||
if _, ok := obj.(*types.PkgName); ok {
|
||||
// Local package names are fine, since we can just reimport them.
|
||||
return true
|
||||
}
|
||||
if pkg := obj.Pkg(); pkg != nil && !ast.IsExported(ident.Name) && pkg.Path() != wantPkg {
|
||||
unexportError = fmt.Errorf("uses unexported identifier %s", obj.Name())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
return unexportError
|
||||
}
|
||||
|
||||
var (
|
||||
errorType = types.Universe.Lookup("error").Type()
|
||||
cleanupType = types.NewSignature(nil, nil, nil, false)
|
||||
|
||||
@@ -41,6 +41,7 @@ type ProviderSet struct {
|
||||
|
||||
Providers []*Provider
|
||||
Bindings []*IfaceBinding
|
||||
Values []*Value
|
||||
Imports []*ProviderSet
|
||||
}
|
||||
|
||||
@@ -100,6 +101,21 @@ type ProviderInput struct {
|
||||
// TODO(light): Move field name into this struct.
|
||||
}
|
||||
|
||||
// Value describes a value expression.
|
||||
type Value struct {
|
||||
// Pos is the source position of the expression defining this value.
|
||||
Pos token.Pos
|
||||
|
||||
// Out is the type this value produces.
|
||||
Out types.Type
|
||||
|
||||
// expr is the expression passed to goose.Value.
|
||||
expr ast.Expr
|
||||
|
||||
// info is the type info for the expression.
|
||||
info *types.Info
|
||||
}
|
||||
|
||||
// Load finds all the provider sets in the given packages, as well as
|
||||
// the provider sets' transitive dependencies.
|
||||
func Load(bctx *build.Context, wd string, pkgs []string) (*Info, error) {
|
||||
@@ -163,7 +179,7 @@ func (id ProviderSetID) String() string {
|
||||
// objectCache is a lazily evaluated mapping of objects to goose structures.
|
||||
type objectCache struct {
|
||||
prog *loader.Program
|
||||
objects map[objRef]interface{} // *Provider or *ProviderSet
|
||||
objects map[objRef]interface{} // *Provider, *ProviderSet, *IfaceBinding, or *Value
|
||||
}
|
||||
|
||||
type objRef struct {
|
||||
@@ -179,7 +195,8 @@ func newObjectCache(prog *loader.Program) *objectCache {
|
||||
}
|
||||
|
||||
// get converts a Go object into a goose structure. It may return a
|
||||
// *Provider, a structProviderPair, an *IfaceBinding, or a *ProviderSet.
|
||||
// *Provider, a structProviderPair, an *IfaceBinding, a *ProviderSet,
|
||||
// or a *Value.
|
||||
func (oc *objectCache) get(obj types.Object) (interface{}, error) {
|
||||
ref := objRef{
|
||||
importPath: obj.Pkg().Path(),
|
||||
@@ -239,8 +256,8 @@ func (oc *objectCache) varDecl(obj *types.Var) *ast.ValueSpec {
|
||||
}
|
||||
|
||||
// processExpr converts an expression into a goose structure. It may
|
||||
// return a *Provider, a structProviderPair, an *IfaceBinding, or a
|
||||
// *ProviderSet.
|
||||
// return a *Provider, a structProviderPair, an *IfaceBinding, a
|
||||
// *ProviderSet, or a *Value.
|
||||
func (oc *objectCache) processExpr(pkg *loader.PackageInfo, expr ast.Expr) (interface{}, error) {
|
||||
exprPos := oc.prog.Fset.Position(expr.Pos())
|
||||
expr = astutil.Unparen(expr)
|
||||
@@ -269,6 +286,12 @@ func (oc *objectCache) processExpr(pkg *loader.PackageInfo, expr ast.Expr) (inte
|
||||
return nil, fmt.Errorf("%v: %v", exprPos, err)
|
||||
}
|
||||
return b, nil
|
||||
case "Value":
|
||||
v, err := processValue(oc.prog.Fset, &pkg.Info, call)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v: %v", exprPos, err)
|
||||
}
|
||||
return v, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("%v: unknown pattern", exprPos)
|
||||
}
|
||||
@@ -312,6 +335,8 @@ func (oc *objectCache) processNewSet(pkg *loader.PackageInfo, call *ast.CallExpr
|
||||
pset.Bindings = append(pset.Bindings, item)
|
||||
case structProviderPair:
|
||||
pset.Providers = append(pset.Providers, item.provider, item.ptrProvider)
|
||||
case *Value:
|
||||
pset.Values = append(pset.Values, item)
|
||||
default:
|
||||
panic("unknown item type")
|
||||
}
|
||||
@@ -471,6 +496,48 @@ func processBind(fset *token.FileSet, info *types.Info, call *ast.CallExpr) (*If
|
||||
}, nil
|
||||
}
|
||||
|
||||
// processValue creates a value from a goose.Value call.
|
||||
func processValue(fset *token.FileSet, info *types.Info, call *ast.CallExpr) (*Value, error) {
|
||||
// Assumes that call.Fun is goose.Value.
|
||||
|
||||
if len(call.Args) != 1 {
|
||||
return nil, fmt.Errorf("%v: call to Value takes exactly one argument", fset.Position(call.Pos()))
|
||||
}
|
||||
ok := true
|
||||
ast.Inspect(call.Args[0], func(node ast.Node) bool {
|
||||
switch node.(type) {
|
||||
case nil, *ast.ArrayType, *ast.BasicLit, *ast.BinaryExpr, *ast.ChanType, *ast.CompositeLit, *ast.FuncType, *ast.Ident, *ast.IndexExpr, *ast.InterfaceType, *ast.KeyValueExpr, *ast.MapType, *ast.ParenExpr, *ast.SelectorExpr, *ast.SliceExpr, *ast.StarExpr, *ast.StructType, *ast.TypeAssertExpr:
|
||||
// Good!
|
||||
case *ast.UnaryExpr:
|
||||
expr := node.(*ast.UnaryExpr)
|
||||
if expr.Op == token.ARROW {
|
||||
ok = false
|
||||
return false
|
||||
}
|
||||
case *ast.CallExpr:
|
||||
// Only acceptable if it's a type conversion.
|
||||
call := node.(*ast.CallExpr)
|
||||
if _, isFunc := info.TypeOf(call.Fun).(*types.Signature); isFunc {
|
||||
ok = false
|
||||
return false
|
||||
}
|
||||
default:
|
||||
ok = false
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%v: argument to Value is too complex", fset.Position(call.Pos()))
|
||||
}
|
||||
return &Value{
|
||||
Pos: call.Args[0].Pos(),
|
||||
Out: info.TypeOf(call.Args[0]),
|
||||
expr: call.Args[0],
|
||||
info: info,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// isInjector checks whether a given function declaration is an
|
||||
// injector template, returning the goose.Use call. It returns nil if
|
||||
// the function is not an injector template.
|
||||
|
||||
21
internal/goose/testdata/ExportedValue/bar/bar.go
vendored
Normal file
21
internal/goose/testdata/ExportedValue/bar/bar.go
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 bar
|
||||
|
||||
import "github.com/google/go-cloud/goose"
|
||||
|
||||
var Value = goose.Value(PublicMsg)
|
||||
|
||||
var PublicMsg = "Hello, World!"
|
||||
21
internal/goose/testdata/ExportedValue/foo/foo.go
vendored
Normal file
21
internal/goose/testdata/ExportedValue/foo/foo.go
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println(injectedMessage())
|
||||
}
|
||||
26
internal/goose/testdata/ExportedValue/foo/goose.go
vendored
Normal file
26
internal/goose/testdata/ExportedValue/foo/goose.go
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bar"
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectedMessage() string {
|
||||
panic(goose.Use(bar.Value))
|
||||
}
|
||||
1
internal/goose/testdata/ExportedValue/out.txt
vendored
Normal file
1
internal/goose/testdata/ExportedValue/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
1
internal/goose/testdata/ExportedValue/pkg
vendored
Normal file
1
internal/goose/testdata/ExportedValue/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
23
internal/goose/testdata/ExportedValueDifferentPackage/bar/bar.go
vendored
Normal file
23
internal/goose/testdata/ExportedValueDifferentPackage/bar/bar.go
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 bar
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
var Value = goose.Value(os.Stdout)
|
||||
21
internal/goose/testdata/ExportedValueDifferentPackage/foo/foo.go
vendored
Normal file
21
internal/goose/testdata/ExportedValueDifferentPackage/foo/foo.go
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Fprintln(injectedFile(), "Hello, World!")
|
||||
}
|
||||
28
internal/goose/testdata/ExportedValueDifferentPackage/foo/goose.go
vendored
Normal file
28
internal/goose/testdata/ExportedValueDifferentPackage/foo/goose.go
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"bar"
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectedFile() *os.File {
|
||||
panic(goose.Use(bar.Value))
|
||||
}
|
||||
1
internal/goose/testdata/ExportedValueDifferentPackage/out.txt
vendored
Normal file
1
internal/goose/testdata/ExportedValueDifferentPackage/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
1
internal/goose/testdata/ExportedValueDifferentPackage/pkg
vendored
Normal file
1
internal/goose/testdata/ExportedValueDifferentPackage/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
21
internal/goose/testdata/NiladicValue/foo/foo.go
vendored
Normal file
21
internal/goose/testdata/NiladicValue/foo/foo.go
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println(injectedMessage())
|
||||
}
|
||||
25
internal/goose/testdata/NiladicValue/foo/goose.go
vendored
Normal file
25
internal/goose/testdata/NiladicValue/foo/goose.go
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectedMessage() string {
|
||||
panic(goose.Use(goose.Value("Hello, World!")))
|
||||
}
|
||||
1
internal/goose/testdata/NiladicValue/out.txt
vendored
Normal file
1
internal/goose/testdata/NiladicValue/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
1
internal/goose/testdata/NiladicValue/pkg
vendored
Normal file
1
internal/goose/testdata/NiladicValue/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
21
internal/goose/testdata/UnexportedValue/bar/bar.go
vendored
Normal file
21
internal/goose/testdata/UnexportedValue/bar/bar.go
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 bar
|
||||
|
||||
import "github.com/google/go-cloud/goose"
|
||||
|
||||
var Value = goose.Value(privateMsg)
|
||||
|
||||
var privateMsg = "Hello, World!"
|
||||
21
internal/goose/testdata/UnexportedValue/foo/foo.go
vendored
Normal file
21
internal/goose/testdata/UnexportedValue/foo/foo.go
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println(injectedMessage())
|
||||
}
|
||||
26
internal/goose/testdata/UnexportedValue/foo/goose.go
vendored
Normal file
26
internal/goose/testdata/UnexportedValue/foo/goose.go
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bar"
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectedMessage() string {
|
||||
panic(goose.Use(bar.Value))
|
||||
}
|
||||
1
internal/goose/testdata/UnexportedValue/out.txt
vendored
Normal file
1
internal/goose/testdata/UnexportedValue/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ERROR
|
||||
1
internal/goose/testdata/UnexportedValue/pkg
vendored
Normal file
1
internal/goose/testdata/UnexportedValue/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
36
internal/goose/testdata/ValueChain/foo/foo.go
vendored
Normal file
36
internal/goose/testdata/ValueChain/foo/foo.go
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(injectFooBar())
|
||||
}
|
||||
|
||||
type Foo int
|
||||
type FooBar int
|
||||
|
||||
var Set = goose.NewSet(
|
||||
goose.Value(Foo(41)),
|
||||
provideFooBar)
|
||||
|
||||
func provideFooBar(foo Foo) FooBar {
|
||||
return FooBar(foo) + 1
|
||||
}
|
||||
25
internal/goose/testdata/ValueChain/foo/goose.go
vendored
Normal file
25
internal/goose/testdata/ValueChain/foo/goose.go
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectFooBar() FooBar {
|
||||
panic(goose.Use(Set))
|
||||
}
|
||||
1
internal/goose/testdata/ValueChain/out.txt
vendored
Normal file
1
internal/goose/testdata/ValueChain/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
42
|
||||
1
internal/goose/testdata/ValueChain/pkg
vendored
Normal file
1
internal/goose/testdata/ValueChain/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
23
internal/goose/testdata/ValueConversion/foo/foo.go
vendored
Normal file
23
internal/goose/testdata/ValueConversion/foo/foo.go
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println(injectedMessage())
|
||||
}
|
||||
|
||||
type Foo string
|
||||
25
internal/goose/testdata/ValueConversion/foo/goose.go
vendored
Normal file
25
internal/goose/testdata/ValueConversion/foo/goose.go
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectedMessage() Foo {
|
||||
panic(goose.Use(goose.Value(Foo("Hello, World!"))))
|
||||
}
|
||||
1
internal/goose/testdata/ValueConversion/out.txt
vendored
Normal file
1
internal/goose/testdata/ValueConversion/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
1
internal/goose/testdata/ValueConversion/pkg
vendored
Normal file
1
internal/goose/testdata/ValueConversion/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
26
internal/goose/testdata/VarValue/foo/foo.go
vendored
Normal file
26
internal/goose/testdata/VarValue/foo/foo.go
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// Value should be deferred until function call.
|
||||
msg = "Hello, World!"
|
||||
|
||||
fmt.Println(injectedMessage())
|
||||
}
|
||||
|
||||
var msg string
|
||||
25
internal/goose/testdata/VarValue/foo/goose.go
vendored
Normal file
25
internal/goose/testdata/VarValue/foo/goose.go
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// 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 gooseinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/google/go-cloud/goose"
|
||||
)
|
||||
|
||||
func injectedMessage() string {
|
||||
panic(goose.Use(goose.Value(msg)))
|
||||
}
|
||||
1
internal/goose/testdata/VarValue/out.txt
vendored
Normal file
1
internal/goose/testdata/VarValue/out.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
1
internal/goose/testdata/VarValue/pkg
vendored
Normal file
1
internal/goose/testdata/VarValue/pkg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo
|
||||
Reference in New Issue
Block a user