Chore: Vendor wire into pkg/build (#84637)

* vendor latest wire into pkg/build

* use vendored wire in builds

* fix wire import path

* remove wire from bingo

* also support google/wire import

* make prettier happy

* change package in tess

* add debug walk for drone

* add wire_gen in tests

* remove debug walk

* restore imports
This commit is contained in:
Serge Zaitsev
2024-03-25 11:23:27 +01:00
committed by GitHub
parent 36ee1571b6
commit 4d4c06b480
371 changed files with 12711 additions and 29 deletions
+5
View File
@@ -0,0 +1,5 @@
github.com/google/subcommands
github.com/google/wire
github.com/pmezard/go-difflib
golang.org/x/mod
golang.org/x/tools
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env bash
# Copyright 2019 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.
# This script checks to see if there are any incompatible API changes on the
# current branch relative to the upstream branch.
# It fails if it finds any, unless there is a commit with BREAKING_CHANGE_OK
# in the first line of the commit message.
# This script expects:
# a) to be run at the root of the repository
# b) HEAD is pointing to a commit that merges between the pull request and the
# upstream branch (GITHUB_BASE_REF).
set -euo pipefail
UPSTREAM_BRANCH="${GITHUB_BASE_REF:-master}"
echo "Checking for incompatible API changes relative to ${UPSTREAM_BRANCH}..."
MASTER_CLONE_DIR="$(mktemp -d)"
PKGINFO_BRANCH=$(mktemp)
PKGINFO_MASTER=$(mktemp)
function cleanup() {
rm -rf "$MASTER_CLONE_DIR"
rm -f "$PKGINFO_BRANCH"
rm -f "$PKGINFO_MASTER"
}
trap cleanup EXIT
# Install apidiff.
go install golang.org/x/exp/cmd/apidiff@latest
git clone -b "$UPSTREAM_BRANCH" . "$MASTER_CLONE_DIR" &> /dev/null
incompatible_change_pkgs=()
PKGS=$(cd "$MASTER_CLONE_DIR"; go list ./... | grep -v test | grep -v internal)
for pkg in $PKGS; do
echo " Testing ${pkg}..."
# Compute export data for the current branch.
package_deleted=0
apidiff -w "$PKGINFO_BRANCH" "$pkg" || package_deleted=1
if [[ $package_deleted -eq 1 ]]; then
echo " Package ${pkg} was deleted! Recording as an incompatible change.";
incompatible_change_pkgs+=(${pkg});
continue;
fi
# Compute export data for master@HEAD.
(cd "$MASTER_CLONE_DIR"; apidiff -w "$PKGINFO_MASTER" "$pkg")
# Print all changes for posterity.
apidiff "$PKGINFO_MASTER" "$PKGINFO_BRANCH"
# Note if there's an incompatible change.
ic=$(apidiff -incompatible "$PKGINFO_MASTER" "$PKGINFO_BRANCH")
if [ ! -z "$ic" ]; then
incompatible_change_pkgs+=("$pkg");
fi
done
if [ ${#incompatible_change_pkgs[@]} -eq 0 ]; then
# No incompatible changes, we are good.
echo "OK: No incompatible changes found."
exit 0;
fi
echo "Found breaking API change(s) in: ${incompatible_change_pkgs[*]}."
# Found incompatible changes; see if they were declared as OK via a commit.
if git cherry -v master | grep -q "BREAKING_CHANGE_OK"; then
echo "Allowing them due to a commit message with BREAKING_CHANGE_OK.";
exit 0;
fi
echo "FAIL. If this is expected and OK, you can pass this check by adding a commit with BREAKING_CHANGE_OK in the first line of the message."
exit 1
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Copyright 2019 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.
set -euo pipefail
# To run this script manually to update alldeps:
#
# $ internal/listdeps.sh > internal/alldeps
#
# Important note: there are changes in module tooling behavior between go 1.11
# and go 1.12; please make sure to use the same version of Go as used by Github
# Actions (see .github/workflows/tests.yml) when updating the alldeps file.
go list -deps -f '{{with .Module}}{{.Path}}{{end}}' ./... | sort | uniq
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env bash
# Copyright 2019 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.
# https://coderwall.com/p/fkfaqq/safer-bash-scripts-with-set-euxo-pipefail
set -euo pipefail
if [[ $# -gt 0 ]]; then
echo "usage: runtests.sh" 1>&2
exit 64
fi
# Run Go tests. Only do coverage for the Linux build
# because it is slow, and codecov will only save the last one anyway.
result=0
if [[ "${RUNNER_OS:-}" == "Linux" ]]; then
echo "Running Go tests (with coverage)..."
go test -mod=readonly -race -coverpkg=./... -coverprofile=coverage.out ./... || result=1
if [ -f coverage.out ] && [ $result -eq 0 ]; then
bash <(curl -s https://codecov.io/bash)
fi
else
echo "Running Go tests..."
go test -mod=readonly -race ./... || result=1
fi
# No need to run other checks on OSs other than linux.
# We default RUNNER_OS to "Linux" so that we don't abort here when run locally.
if [[ "${RUNNER_OS:-Linux}" != "Linux" ]]; then
exit $result
fi
echo
echo "Ensuring .go files are formatted with gofmt -s..."
mapfile -t go_files < <(find . -name '*.go' -type f | grep -v testdata)
DIFF="$(gofmt -s -d "${go_files[@]}")"
if [ -n "$DIFF" ]; then
echo "FAIL: please run gofmt -s and commit the result"
echo "$DIFF";
result=1;
else
echo "OK"
fi;
# Ensure that the code has no extra dependencies (including transitive
# dependencies) that we're not already aware of by comparing with
# ./internal/alldeps
#
# Whenever project dependencies change, rerun ./internal/listdeps.sh
echo
echo "Ensuring that there are no dependencies not listed in ./internal/alldeps..."
(./internal/listdeps.sh | diff ./internal/alldeps - && echo "OK") || {
echo "FAIL: dependencies changed; run: internal/listdeps.sh > internal/alldeps"
# Module behavior may differ across versions.
echo "using the latest go version."
result=1
}
# For pull requests, check if there are undeclared incompatible API changes.
# Skip this if we're already going to fail since it is expensive.
# CURRENTLY BROKEN
# if [[ ${result} -eq 0 ]] && [[ ! -z "${GITHUB_HEAD_REF:-x}" ]]; then
# echo
# ./internal/check_api_change.sh || result=1;
# fi
exit $result
+521
View File
@@ -0,0 +1,521 @@
// 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 wire
import (
"errors"
"fmt"
"go/ast"
"go/token"
"go/types"
"sort"
"strings"
"golang.org/x/tools/go/types/typeutil"
)
type callKind int
const (
funcProviderCall callKind = iota
structProvider
valueExpr
selectorExpr
)
// 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 kind.
type call struct {
// kind indicates the code pattern to use.
kind callKind
// out is the type this step produces.
out types.Type
// pkg and name identify one of the following:
// 1) the provider to call for kind == funcProviderCall;
// 2) the type to construct for kind == structProvider;
// 3) the name to select for kind == selectorExpr.
pkg *types.Package
name string
// args is a list of arguments to call the provider with. Each element is:
// a) one of the givens (args[i] < len(given)),
// b) the result of a previous provider call (args[i] >= len(given))
//
// This will be nil for kind == valueExpr.
//
// If kind == selectorExpr, then the length of this slice will be 1 and the
// "argument" will be the value to access fields from.
args []int
// varargs is true if the provider function is variadic.
varargs bool
// fieldNames maps the arguments to struct field names.
// 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
// 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
// The following are only set for kind == selectorExpr:
ptrToField bool
}
// solve finds the sequence of calls required to produce an output type
// with an optional set of provided inputs.
func solve(fset *token.FileSet, out types.Type, given *types.Tuple, set *ProviderSet) ([]call, []error) {
ec := new(errorCollector)
// Start building the mapping of type to local variable of the given type.
// The first len(given) local variables are the given types.
index := new(typeutil.Map)
for i := 0; i < given.Len(); i++ {
index.Set(given.At(i).Type(), i)
}
// Topological sort of the directed graph defined by the providers
// using a depth-first search using a stack. Provider set graphs are
// guaranteed to be acyclic. An index value of errAbort indicates that
// the type was visited, but failed due to an error added to ec.
errAbort := errors.New("failed to visit")
var used []*providerSetSrc
var calls []call
type frame struct {
t types.Type
from types.Type
up *frame
}
stk := []frame{{t: out}}
dfs:
for len(stk) > 0 {
curr := stk[len(stk)-1]
stk = stk[:len(stk)-1]
if index.At(curr.t) != nil {
continue
}
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)
continue
}
sb := new(strings.Builder)
fmt.Fprintf(sb, "no provider found for %s", types.TypeString(curr.t, nil))
for f := curr.up; f != nil; f = f.up {
fmt.Fprintf(sb, "\nneeded by %s in %s", types.TypeString(f.t, nil), set.srcMap.At(f.t).(*providerSetSrc).description(fset, f.t))
}
ec.add(errors.New(sb.String()))
index.Set(curr.t, errAbort)
continue
}
src := set.srcMap.At(curr.t).(*providerSetSrc)
used = append(used, src)
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()
// 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.
visitedArgs := true
for i := len(p.Args) - 1; i >= 0; i-- {
a := p.Args[i]
if index.At(a.Type) == nil {
if visitedArgs {
// Make sure to re-visit this type after visiting all arguments.
stk = append(stk, curr)
visitedArgs = false
}
stk = append(stk, frame{t: a.Type, from: curr.t, up: &curr})
}
}
if !visitedArgs {
continue
}
args := make([]int, len(p.Args))
ins := make([]types.Type, len(p.Args))
for i := range p.Args {
ins[i] = p.Args[i].Type
v := index.At(p.Args[i].Type)
if v == errAbort {
index.Set(curr.t, errAbort)
continue dfs
}
args[i] = v.(int)
}
index.Set(curr.t, given.Len()+len(calls))
kind := funcProviderCall
fieldNames := []string(nil)
if p.IsStruct {
kind = structProvider
for _, arg := range p.Args {
fieldNames = append(fieldNames, arg.FieldName)
}
}
calls = append(calls, call{
kind: kind,
pkg: p.Pkg,
name: p.Name,
args: args,
varargs: p.Varargs,
fieldNames: fieldNames,
ins: ins,
out: curr.t,
hasCleanup: p.HasCleanup,
hasErr: p.HasErr,
})
case pv.IsValue():
v := pv.Value()
index.Set(curr.t, given.Len()+len(calls))
calls = append(calls, call{
kind: valueExpr,
out: curr.t,
valueExpr: v.expr,
valueTypeInfo: v.info,
})
case pv.IsField():
f := pv.Field()
if index.At(f.Parent) == nil {
// Fields have one dependency which is the parent struct. Make
// sure to visit it first if it is not already visited.
stk = append(stk, curr, frame{t: f.Parent, from: curr.t, up: &curr})
continue
}
index.Set(curr.t, given.Len()+len(calls))
v := index.At(f.Parent)
if v == errAbort {
index.Set(curr.t, errAbort)
continue dfs
}
// Use args[0] to store the position of the parent struct.
args := []int{v.(int)}
// If f.Out has 2 elements and curr.t is the 2nd one, then the call must
// provide a pointer to the field.
ptrToField := len(f.Out) == 2 && types.Identical(curr.t, f.Out[1])
calls = append(calls, call{
kind: selectorExpr,
pkg: f.Pkg,
name: f.Name,
out: curr.t,
args: args,
ptrToField: ptrToField,
})
default:
panic("unknown return value from ProviderSet.For")
}
}
if len(ec.errors) > 0 {
return nil, ec.errors
}
if errs := verifyArgsUsed(set, used); len(errs) > 0 {
return nil, errs
}
return calls, nil
}
// verifyArgsUsed ensures that all of the arguments in set were used during solve.
func verifyArgsUsed(set *ProviderSet, used []*providerSetSrc) []error {
var errs []error
for _, imp := range set.Imports {
found := false
for _, u := range used {
if u.Import == imp {
found = true
break
}
}
if !found {
if imp.VarName == "" {
errs = append(errs, errors.New("unused provider set"))
} else {
errs = append(errs, fmt.Errorf("unused provider set %q", imp.VarName))
}
}
}
for _, p := range set.Providers {
found := false
for _, u := range used {
if u.Provider == p {
found = true
break
}
}
if !found {
errs = append(errs, fmt.Errorf("unused provider %q", p.Pkg.Name()+"."+p.Name))
}
}
for _, v := range set.Values {
found := false
for _, u := range used {
if u.Value == v {
found = true
break
}
}
if !found {
errs = append(errs, fmt.Errorf("unused value of type %s", types.TypeString(v.Out, nil)))
}
}
for _, b := range set.Bindings {
found := false
for _, u := range used {
if u.Binding == b {
found = true
break
}
}
if !found {
errs = append(errs, fmt.Errorf("unused interface binding to type %s", types.TypeString(b.Iface, nil)))
}
}
for _, f := range set.Fields {
found := false
for _, u := range used {
if u.Field == f {
found = true
break
}
}
if !found {
errs = append(errs, fmt.Errorf("unused field %q.%s", f.Parent, f.Name))
}
}
return errs
}
// buildProviderMap creates the providerMap and srcMap fields for a given
// provider set. The given provider set's providerMap and srcMap fields are
// ignored.
func buildProviderMap(fset *token.FileSet, hasher typeutil.Hasher, set *ProviderSet) (*typeutil.Map, *typeutil.Map, []error) {
providerMap := new(typeutil.Map)
providerMap.SetHasher(hasher)
srcMap := new(typeutil.Map) // to *providerSetSrc
srcMap.SetHasher(hasher)
ec := new(errorCollector)
// Process injector arguments.
if set.InjectorArgs != nil {
givens := set.InjectorArgs.Tuple
for i := 0; i < givens.Len(); i++ {
typ := givens.At(i).Type()
arg := &InjectorArg{Args: set.InjectorArgs, Index: i}
src := &providerSetSrc{InjectorArg: arg}
if prevSrc := srcMap.At(typ); prevSrc != nil {
ec.add(bindingConflictError(fset, typ, set, src, prevSrc.(*providerSetSrc)))
continue
}
providerMap.Set(typ, &ProvidedType{t: typ, a: arg})
srcMap.Set(typ, src)
}
}
// Process imports, verifying that there are no conflicts between sets.
for _, imp := range set.Imports {
src := &providerSetSrc{Import: imp}
imp.providerMap.Iterate(func(k types.Type, v interface{}) {
if prevSrc := srcMap.At(k); prevSrc != nil {
ec.add(bindingConflictError(fset, k, set, src, prevSrc.(*providerSetSrc)))
return
}
providerMap.Set(k, v)
srcMap.Set(k, src)
})
}
if len(ec.errors) > 0 {
return nil, nil, ec.errors
}
// Process non-binding providers in new set.
for _, p := range set.Providers {
src := &providerSetSrc{Provider: p}
for _, typ := range p.Out {
if prevSrc := srcMap.At(typ); prevSrc != nil {
ec.add(bindingConflictError(fset, typ, set, src, prevSrc.(*providerSetSrc)))
continue
}
providerMap.Set(typ, &ProvidedType{t: typ, p: p})
srcMap.Set(typ, src)
}
}
for _, v := range set.Values {
src := &providerSetSrc{Value: v}
if prevSrc := srcMap.At(v.Out); prevSrc != nil {
ec.add(bindingConflictError(fset, v.Out, set, src, prevSrc.(*providerSetSrc)))
continue
}
providerMap.Set(v.Out, &ProvidedType{t: v.Out, v: v})
srcMap.Set(v.Out, src)
}
for _, f := range set.Fields {
src := &providerSetSrc{Field: f}
for _, typ := range f.Out {
if prevSrc := srcMap.At(typ); prevSrc != nil {
ec.add(bindingConflictError(fset, typ, set, src, prevSrc.(*providerSetSrc)))
continue
}
providerMap.Set(typ, &ProvidedType{t: typ, f: f})
srcMap.Set(typ, src)
}
}
if len(ec.errors) > 0 {
return nil, nil, ec.errors
}
// Process bindings in set. Must happen after the other providers to
// ensure the concrete type is being provided.
for _, b := range set.Bindings {
src := &providerSetSrc{Binding: b}
if prevSrc := srcMap.At(b.Iface); prevSrc != nil {
ec.add(bindingConflictError(fset, b.Iface, set, src, prevSrc.(*providerSetSrc)))
continue
}
concrete := providerMap.At(b.Provided)
if concrete == nil {
setName := set.VarName
if setName == "" {
setName = "provider set"
}
ec.add(notePosition(fset.Position(b.Pos), fmt.Errorf("wire.Bind of concrete type %q to interface %q, but %s does not include a provider for %q", b.Provided, b.Iface, setName, b.Provided)))
continue
}
providerMap.Set(b.Iface, concrete)
srcMap.Set(b.Iface, src)
}
if len(ec.errors) > 0 {
return nil, nil, ec.errors
}
return providerMap, srcMap, nil
}
func verifyAcyclic(providerMap *typeutil.Map, hasher typeutil.Hasher) []error {
// We must visit every provider type inside provider map, but we don't
// have a well-defined starting point and there may be several
// distinct graphs. Thus, we start a depth-first search at every
// provider, but keep a shared record of visited providers to avoid
// duplicating work.
visited := new(typeutil.Map) // to bool
visited.SetHasher(hasher)
ec := new(errorCollector)
// Sort output types so that errors about cycles are consistent.
outputs := providerMap.Keys()
sort.Slice(outputs, func(i, j int) bool { return types.TypeString(outputs[i], nil) < types.TypeString(outputs[j], nil) })
for _, root := range outputs {
// Depth-first search using a stack of trails through the provider map.
stk := [][]types.Type{{root}}
for len(stk) > 0 {
curr := stk[len(stk)-1]
stk = stk[:len(stk)-1]
head := curr[len(curr)-1]
if v, _ := visited.At(head).(bool); v {
continue
}
visited.Set(head, true)
x := providerMap.At(head)
if x == nil {
// Leaf: input.
continue
}
pt := x.(*ProvidedType)
switch {
case pt.IsValue():
// Leaf: values do not have dependencies.
case pt.IsArg():
// Injector arguments do not have dependencies.
case pt.IsProvider() || pt.IsField():
var args []types.Type
if pt.IsProvider() {
for _, arg := range pt.Provider().Args {
args = append(args, arg.Type)
}
} else {
args = append(args, pt.Field().Parent)
}
for _, a := range args {
hasCycle := false
for i, b := range curr {
if types.Identical(a, b) {
sb := new(strings.Builder)
fmt.Fprintf(sb, "cycle for %s:\n", types.TypeString(a, nil))
for j := i; j < len(curr); j++ {
t := providerMap.At(curr[j]).(*ProvidedType)
if t.IsProvider() {
p := t.Provider()
fmt.Fprintf(sb, "%s (%s.%s) ->\n", types.TypeString(curr[j], nil), p.Pkg.Path(), p.Name)
} else {
p := t.Field()
fmt.Fprintf(sb, "%s (%s.%s) ->\n", types.TypeString(curr[j], nil), p.Parent, p.Name)
}
}
fmt.Fprintf(sb, "%s", types.TypeString(a, nil))
ec.add(errors.New(sb.String()))
hasCycle = true
break
}
}
if !hasCycle {
next := append(append([]types.Type(nil), curr...), a)
stk = append(stk, next)
}
}
default:
panic("invalid provider map value")
}
}
}
return ec.errors
}
// bindingConflictError creates a new error describing multiple bindings
// for the same output type.
func bindingConflictError(fset *token.FileSet, typ types.Type, set *ProviderSet, cur, prev *providerSetSrc) error {
sb := new(strings.Builder)
if set.VarName != "" {
fmt.Fprintf(sb, "%s has ", set.VarName)
}
fmt.Fprintf(sb, "multiple bindings for %s\n", types.TypeString(typ, nil))
fmt.Fprintf(sb, "current:\n<- %s\n", strings.Join(cur.trace(fset, typ), "\n<- "))
fmt.Fprintf(sb, "previous:\n<- %s", strings.Join(prev.trace(fset, typ), "\n<- "))
return notePosition(fset.Position(set.Pos), errors.New(sb.String()))
}
+493
View File
@@ -0,0 +1,493 @@
// 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 wire
import (
"fmt"
"go/ast"
"golang.org/x/tools/go/ast/astutil"
)
// copyAST performs a deep copy of an AST. *ast.Ident identity will be
// preserved.
//
// This allows using astutil.Apply to rewrite an AST without modifying
// the original AST.
func copyAST(original ast.Node) ast.Node {
// This function is necessarily long. No utility function exists to do this
// clone, as most any attempt would need to have customization options, which
// would need to be as expressive as Apply. A possibility to shorten the code
// here would be to use reflection, but that trades clarity for shorter code.
m := make(map[ast.Node]ast.Node)
astutil.Apply(original, nil, func(c *astutil.Cursor) bool {
switch node := c.Node().(type) {
case nil:
// No-op.
case *ast.ArrayType:
m[node] = &ast.ArrayType{
Lbrack: node.Lbrack,
Len: exprFromMap(m, node.Len),
Elt: exprFromMap(m, node.Elt),
}
case *ast.AssignStmt:
m[node] = &ast.AssignStmt{
Lhs: copyExprList(m, node.Lhs),
TokPos: node.TokPos,
Tok: node.Tok,
Rhs: copyExprList(m, node.Rhs),
}
case *ast.BadDecl:
m[node] = &ast.BadDecl{
From: node.From,
To: node.To,
}
case *ast.BadExpr:
m[node] = &ast.BadExpr{
From: node.From,
To: node.To,
}
case *ast.BadStmt:
m[node] = &ast.BadStmt{
From: node.From,
To: node.To,
}
case *ast.BasicLit:
m[node] = &ast.BasicLit{
ValuePos: node.ValuePos,
Kind: node.Kind,
Value: node.Value,
}
case *ast.BinaryExpr:
m[node] = &ast.BinaryExpr{
X: exprFromMap(m, node.X),
OpPos: node.OpPos,
Op: node.Op,
Y: exprFromMap(m, node.Y),
}
case *ast.BlockStmt:
m[node] = &ast.BlockStmt{
Lbrace: node.Lbrace,
List: copyStmtList(m, node.List),
Rbrace: node.Rbrace,
}
case *ast.BranchStmt:
m[node] = &ast.BranchStmt{
TokPos: node.TokPos,
Tok: node.Tok,
Label: identFromMap(m, node.Label),
}
case *ast.CallExpr:
m[node] = &ast.CallExpr{
Fun: exprFromMap(m, node.Fun),
Lparen: node.Lparen,
Args: copyExprList(m, node.Args),
Ellipsis: node.Ellipsis,
Rparen: node.Rparen,
}
case *ast.CaseClause:
m[node] = &ast.CaseClause{
Case: node.Case,
List: copyExprList(m, node.List),
Colon: node.Colon,
Body: copyStmtList(m, node.Body),
}
case *ast.ChanType:
m[node] = &ast.ChanType{
Begin: node.Begin,
Arrow: node.Arrow,
Dir: node.Dir,
Value: exprFromMap(m, node.Value),
}
case *ast.CommClause:
m[node] = &ast.CommClause{
Case: node.Case,
Comm: stmtFromMap(m, node.Comm),
Colon: node.Colon,
Body: copyStmtList(m, node.Body),
}
case *ast.Comment:
m[node] = &ast.Comment{
Slash: node.Slash,
Text: node.Text,
}
case *ast.CommentGroup:
cg := new(ast.CommentGroup)
if node.List != nil {
cg.List = make([]*ast.Comment, len(node.List))
for i := range node.List {
cg.List[i] = m[node.List[i]].(*ast.Comment)
}
}
m[node] = cg
case *ast.CompositeLit:
m[node] = &ast.CompositeLit{
Type: exprFromMap(m, node.Type),
Lbrace: node.Lbrace,
Elts: copyExprList(m, node.Elts),
Rbrace: node.Rbrace,
}
case *ast.DeclStmt:
m[node] = &ast.DeclStmt{
Decl: m[node.Decl].(ast.Decl),
}
case *ast.DeferStmt:
m[node] = &ast.DeferStmt{
Defer: node.Defer,
Call: callExprFromMap(m, node.Call),
}
case *ast.Ellipsis:
m[node] = &ast.Ellipsis{
Ellipsis: node.Ellipsis,
Elt: exprFromMap(m, node.Elt),
}
case *ast.EmptyStmt:
m[node] = &ast.EmptyStmt{
Semicolon: node.Semicolon,
Implicit: node.Implicit,
}
case *ast.ExprStmt:
m[node] = &ast.ExprStmt{
X: exprFromMap(m, node.X),
}
case *ast.Field:
m[node] = &ast.Field{
Doc: commentGroupFromMap(m, node.Doc),
Names: copyIdentList(m, node.Names),
Type: exprFromMap(m, node.Type),
Tag: basicLitFromMap(m, node.Tag),
Comment: commentGroupFromMap(m, node.Comment),
}
case *ast.FieldList:
fl := &ast.FieldList{
Opening: node.Opening,
Closing: node.Closing,
}
if node.List != nil {
fl.List = make([]*ast.Field, len(node.List))
for i := range node.List {
fl.List[i] = m[node.List[i]].(*ast.Field)
}
}
m[node] = fl
case *ast.ForStmt:
m[node] = &ast.ForStmt{
For: node.For,
Init: stmtFromMap(m, node.Init),
Cond: exprFromMap(m, node.Cond),
Post: stmtFromMap(m, node.Post),
Body: blockStmtFromMap(m, node.Body),
}
case *ast.FuncDecl:
m[node] = &ast.FuncDecl{
Doc: commentGroupFromMap(m, node.Doc),
Recv: fieldListFromMap(m, node.Recv),
Name: identFromMap(m, node.Name),
Type: funcTypeFromMap(m, node.Type),
Body: blockStmtFromMap(m, node.Body),
}
case *ast.FuncLit:
m[node] = &ast.FuncLit{
Type: funcTypeFromMap(m, node.Type),
Body: blockStmtFromMap(m, node.Body),
}
case *ast.FuncType:
m[node] = &ast.FuncType{
Func: node.Func,
Params: fieldListFromMap(m, node.Params),
Results: fieldListFromMap(m, node.Results),
}
case *ast.GenDecl:
decl := &ast.GenDecl{
Doc: commentGroupFromMap(m, node.Doc),
TokPos: node.TokPos,
Tok: node.Tok,
Lparen: node.Lparen,
Rparen: node.Rparen,
}
if node.Specs != nil {
decl.Specs = make([]ast.Spec, len(node.Specs))
for i := range node.Specs {
decl.Specs[i] = m[node.Specs[i]].(ast.Spec)
}
}
m[node] = decl
case *ast.GoStmt:
m[node] = &ast.GoStmt{
Go: node.Go,
Call: callExprFromMap(m, node.Call),
}
case *ast.Ident:
// Keep identifiers the same identity so they can be conveniently
// used with the original *types.Info.
m[node] = node
case *ast.IfStmt:
m[node] = &ast.IfStmt{
If: node.If,
Init: stmtFromMap(m, node.Init),
Cond: exprFromMap(m, node.Cond),
Body: blockStmtFromMap(m, node.Body),
Else: stmtFromMap(m, node.Else),
}
case *ast.ImportSpec:
m[node] = &ast.ImportSpec{
Doc: commentGroupFromMap(m, node.Doc),
Name: identFromMap(m, node.Name),
Path: basicLitFromMap(m, node.Path),
Comment: commentGroupFromMap(m, node.Comment),
EndPos: node.EndPos,
}
case *ast.IncDecStmt:
m[node] = &ast.IncDecStmt{
X: exprFromMap(m, node.X),
TokPos: node.TokPos,
Tok: node.Tok,
}
case *ast.IndexExpr:
m[node] = &ast.IndexExpr{
X: exprFromMap(m, node.X),
Lbrack: node.Lbrack,
Index: exprFromMap(m, node.Index),
Rbrack: node.Rbrack,
}
case *ast.InterfaceType:
m[node] = &ast.InterfaceType{
Interface: node.Interface,
Methods: fieldListFromMap(m, node.Methods),
Incomplete: node.Incomplete,
}
case *ast.KeyValueExpr:
m[node] = &ast.KeyValueExpr{
Key: exprFromMap(m, node.Key),
Colon: node.Colon,
Value: exprFromMap(m, node.Value),
}
case *ast.LabeledStmt:
m[node] = &ast.LabeledStmt{
Label: identFromMap(m, node.Label),
Colon: node.Colon,
Stmt: stmtFromMap(m, node.Stmt),
}
case *ast.MapType:
m[node] = &ast.MapType{
Map: node.Map,
Key: exprFromMap(m, node.Key),
Value: exprFromMap(m, node.Value),
}
case *ast.ParenExpr:
m[node] = &ast.ParenExpr{
Lparen: node.Lparen,
X: exprFromMap(m, node.X),
Rparen: node.Rparen,
}
case *ast.RangeStmt:
m[node] = &ast.RangeStmt{
For: node.For,
Key: exprFromMap(m, node.Key),
Value: exprFromMap(m, node.Value),
TokPos: node.TokPos,
Tok: node.Tok,
X: exprFromMap(m, node.X),
Body: blockStmtFromMap(m, node.Body),
}
case *ast.ReturnStmt:
m[node] = &ast.ReturnStmt{
Return: node.Return,
Results: copyExprList(m, node.Results),
}
case *ast.SelectStmt:
m[node] = &ast.SelectStmt{
Select: node.Select,
Body: blockStmtFromMap(m, node.Body),
}
case *ast.SelectorExpr:
m[node] = &ast.SelectorExpr{
X: exprFromMap(m, node.X),
Sel: identFromMap(m, node.Sel),
}
case *ast.SendStmt:
m[node] = &ast.SendStmt{
Chan: exprFromMap(m, node.Chan),
Arrow: node.Arrow,
Value: exprFromMap(m, node.Value),
}
case *ast.SliceExpr:
m[node] = &ast.SliceExpr{
X: exprFromMap(m, node.X),
Lbrack: node.Lbrack,
Low: exprFromMap(m, node.Low),
High: exprFromMap(m, node.High),
Max: exprFromMap(m, node.Max),
Slice3: node.Slice3,
Rbrack: node.Rbrack,
}
case *ast.StarExpr:
m[node] = &ast.StarExpr{
Star: node.Star,
X: exprFromMap(m, node.X),
}
case *ast.StructType:
m[node] = &ast.StructType{
Struct: node.Struct,
Fields: fieldListFromMap(m, node.Fields),
Incomplete: node.Incomplete,
}
case *ast.SwitchStmt:
m[node] = &ast.SwitchStmt{
Switch: node.Switch,
Init: stmtFromMap(m, node.Init),
Tag: exprFromMap(m, node.Tag),
Body: blockStmtFromMap(m, node.Body),
}
case *ast.TypeAssertExpr:
m[node] = &ast.TypeAssertExpr{
X: exprFromMap(m, node.X),
Lparen: node.Lparen,
Type: exprFromMap(m, node.Type),
Rparen: node.Rparen,
}
case *ast.TypeSpec:
m[node] = &ast.TypeSpec{
Doc: commentGroupFromMap(m, node.Doc),
Name: identFromMap(m, node.Name),
Assign: node.Assign,
Type: exprFromMap(m, node.Type),
Comment: commentGroupFromMap(m, node.Comment),
}
case *ast.TypeSwitchStmt:
m[node] = &ast.TypeSwitchStmt{
Switch: node.Switch,
Init: stmtFromMap(m, node.Init),
Assign: stmtFromMap(m, node.Assign),
Body: blockStmtFromMap(m, node.Body),
}
case *ast.UnaryExpr:
m[node] = &ast.UnaryExpr{
OpPos: node.OpPos,
Op: node.Op,
X: exprFromMap(m, node.X),
}
case *ast.ValueSpec:
m[node] = &ast.ValueSpec{
Doc: commentGroupFromMap(m, node.Doc),
Names: copyIdentList(m, node.Names),
Type: exprFromMap(m, node.Type),
Values: copyExprList(m, node.Values),
Comment: commentGroupFromMap(m, node.Comment),
}
default:
panic(fmt.Sprintf("unhandled AST node: %T", node))
}
return true
})
return m[original]
}
func commentGroupFromMap(m map[ast.Node]ast.Node, key *ast.CommentGroup) *ast.CommentGroup {
if key == nil {
return nil
}
return m[key].(*ast.CommentGroup)
}
func exprFromMap(m map[ast.Node]ast.Node, key ast.Expr) ast.Expr {
if key == nil {
return nil
}
return m[key].(ast.Expr)
}
func stmtFromMap(m map[ast.Node]ast.Node, key ast.Stmt) ast.Stmt {
if key == nil {
return nil
}
return m[key].(ast.Stmt)
}
func identFromMap(m map[ast.Node]ast.Node, key *ast.Ident) *ast.Ident {
if key == nil {
return nil
}
return m[key].(*ast.Ident)
}
func blockStmtFromMap(m map[ast.Node]ast.Node, key *ast.BlockStmt) *ast.BlockStmt {
if key == nil {
return nil
}
return m[key].(*ast.BlockStmt)
}
func fieldListFromMap(m map[ast.Node]ast.Node, key *ast.FieldList) *ast.FieldList {
if key == nil {
return nil
}
return m[key].(*ast.FieldList)
}
func callExprFromMap(m map[ast.Node]ast.Node, key *ast.CallExpr) *ast.CallExpr {
if key == nil {
return nil
}
return m[key].(*ast.CallExpr)
}
func basicLitFromMap(m map[ast.Node]ast.Node, key *ast.BasicLit) *ast.BasicLit {
if key == nil {
return nil
}
return m[key].(*ast.BasicLit)
}
func funcTypeFromMap(m map[ast.Node]ast.Node, key *ast.FuncType) *ast.FuncType {
if key == nil {
return nil
}
return m[key].(*ast.FuncType)
}
func copyExprList(m map[ast.Node]ast.Node, exprs []ast.Expr) []ast.Expr {
if exprs == nil {
return nil
}
newExprs := make([]ast.Expr, len(exprs))
for i := range exprs {
newExprs[i] = m[exprs[i]].(ast.Expr)
}
return newExprs
}
func copyStmtList(m map[ast.Node]ast.Node, stmts []ast.Stmt) []ast.Stmt {
if stmts == nil {
return nil
}
newStmts := make([]ast.Stmt, len(stmts))
for i := range stmts {
newStmts[i] = m[stmts[i]].(ast.Stmt)
}
return newStmts
}
func copyIdentList(m map[ast.Node]ast.Node, idents []*ast.Ident) []*ast.Ident {
if idents == nil {
return nil
}
newIdents := make([]*ast.Ident, len(idents))
for i := range idents {
newIdents[i] = m[idents[i]].(*ast.Ident)
}
return newIdents
}
+84
View File
@@ -0,0 +1,84 @@
// 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 wire
import (
"go/token"
)
// errorCollector manages a list of errors. The zero value is an empty list.
type errorCollector struct {
errors []error
}
// add appends any non-nil errors to the collector.
func (ec *errorCollector) add(errs ...error) {
for _, e := range errs {
if e != nil {
ec.errors = append(ec.errors, e)
}
}
}
// mapErrors returns a new slice that wraps any errors using the given function.
func mapErrors(errs []error, f func(error) error) []error {
if len(errs) == 0 {
return nil
}
newErrs := make([]error, len(errs))
for i := range errs {
newErrs[i] = f(errs[i])
}
return newErrs
}
// A wireErr is an error with an optional position.
type wireErr struct {
error error
position token.Position
}
// notePosition wraps an error with position information if it doesn't already
// have it.
//
// notePosition is usually called multiple times as an error goes up the call
// stack, so calling notePosition on an existing *wireErr will not modify the
// position, as the assumption is that deeper calls have more precise position
// information about the source of the error.
func notePosition(p token.Position, e error) error {
switch e.(type) {
case nil:
return nil
case *wireErr:
return e
default:
return &wireErr{error: e, position: p}
}
}
// notePositionAll wraps a list of errors with the given position.
func notePositionAll(p token.Position, errs []error) []error {
return mapErrors(errs, func(e error) error {
return notePosition(p, e)
})
}
// Error returns the error message prefixed by the position if valid.
func (w *wireErr) Error() string {
if !w.position.IsValid() {
return w.error.Error()
}
return w.position.String() + ": " + w.error.Error()
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,43 @@
// 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
import (
"fmt"
)
func main() {
fmt.Println(inject(Foo{"hello"}).Name)
}
type Fooer interface {
Foo() string
}
type Foo struct {
f string
}
func (f Foo) Foo() string {
return f.f
}
type Bar struct {
Name string
}
func NewBar(fooer Fooer) *Bar {
return &Bar{Name: fooer.Foo()}
}
@@ -0,0 +1,29 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func inject(foo Foo) *Bar {
wire.Build(
NewBar,
wire.Bind(new(Fooer), new(Foo)),
)
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
hello
@@ -0,0 +1,14 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func inject(foo Foo) *Bar {
bar := NewBar(foo)
return bar
}
@@ -0,0 +1,43 @@
// Copyright 2019 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
import (
"fmt"
)
func main() {
fmt.Println(inject(&Foo{"hello"}).Name)
}
type Fooer interface {
Foo() string
}
type Foo struct {
f string
}
func (f *Foo) Foo() string {
return f.f
}
type Bar struct {
Name string
}
func NewBar(fooer Fooer) *Bar {
return &Bar{Name: fooer.Foo()}
}
@@ -0,0 +1,29 @@
// Copyright 2019 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func inject(foo *Foo) *Bar {
wire.Build(
NewBar,
wire.Bind(new(Fooer), new(*Foo)),
)
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
hello
@@ -0,0 +1,14 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func inject(foo *Foo) *Bar {
bar := NewBar(foo)
return bar
}
@@ -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!"))
}
@@ -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/grafana/grafana/pkg/build/wire"
)
func inject() io.Writer {
wire.Build(
wire.Value(os.Stdout),
wire.Bind(new(io.Writer), new(*os.File)),
)
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World!
@@ -0,0 +1,23 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"io"
"os"
)
// Injectors from wire.go:
func inject() io.Writer {
file := _wireFileValue
return file
}
var (
_wireFileValue = os.Stdout
)
@@ -0,0 +1,23 @@
// 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 bar includes both wireinject and non-wireinject variants.
package bar
import "github.com/grafana/grafana/pkg/build/wire"
// Set provides an unfriendly user greeting.
var Set = wire.NewSet(wire.Value("Bah humbug! This is the wrong variant!"))
@@ -0,0 +1,22 @@
// 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 bar
import "github.com/grafana/grafana/pkg/build/wire"
// Set provides a friendly user greeting.
var Set = wire.NewSet(wire.Value("Hello, World!"))
@@ -0,0 +1,21 @@
// 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
import "fmt"
func main() {
fmt.Println(injectedMessage())
}
@@ -0,0 +1,27 @@
// 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 (
"example.com/bar"
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedMessage() string {
wire.Build(bar.Set)
return ""
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World!
@@ -0,0 +1,18 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func injectedMessage() string {
string2 := _wireStringValue
return string2
}
var (
_wireStringValue = "Hello, World!"
)
+40
View File
@@ -0,0 +1,40 @@
// 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
import (
"fmt"
"github.com/grafana/grafana/pkg/build/wire"
)
func main() {
fmt.Println(injectFooBar())
}
type Foo int
type FooBar int
var Set = wire.NewSet(
provideFoo,
provideFooBar)
func provideFoo() Foo {
return 41
}
func provideFooBar(foo Foo) FooBar {
return FooBar(foo) + 1
}
+26
View File
@@ -0,0 +1,26 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectFooBar() FooBar {
wire.Build(Set)
return 0
}
+1
View File
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
42
@@ -0,0 +1,15 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func injectFooBar() FooBar {
foo := provideFoo()
fooBar := provideFooBar(foo)
return fooBar
}
@@ -0,0 +1,46 @@
// 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
import (
"fmt"
)
func main() {
bar, cleanup := injectBar()
fmt.Println(*bar)
cleanup()
fmt.Println(*bar)
}
type Foo int
type Bar int
func provideFoo() (*Foo, func()) {
foo := new(Foo)
*foo = 42
return foo, func() { *foo = 0 }
}
func provideBar(foo *Foo) (*Bar, func()) {
bar := new(Bar)
*bar = 77
return bar, func() {
if *foo == 0 {
panic("foo cleaned up before bar")
}
*bar = 0
}
}
@@ -0,0 +1,26 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectBar() (*Bar, func()) {
wire.Build(provideFoo, provideBar)
return nil, nil
}
+1
View File
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1,2 @@
77
0
@@ -0,0 +1,18 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func injectBar() (*Bar, func()) {
foo, cleanup := provideFoo()
bar, cleanup2 := provideBar(foo)
return bar, func() {
cleanup2()
cleanup()
}
}
@@ -0,0 +1,40 @@
// 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
// All of the declarations are in one file.
// Wire should copy non-injectors over, preserving imports.
package main
import (
"fmt"
"github.com/grafana/grafana/pkg/build/wire"
)
func main() {
fmt.Println(injectedMessage())
}
// provideMessage provides a friendly user greeting.
func provideMessage() string {
return "Hello, World!"
}
func injectedMessage() string {
wire.Build(provideMessage)
return ""
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World!
@@ -0,0 +1,29 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"fmt"
)
// Injectors from foo.go:
func injectedMessage() string {
string2 := provideMessage()
return string2
}
// foo.go:
func main() {
fmt.Println(injectedMessage())
}
// provideMessage provides a friendly user greeting.
func provideMessage() string {
return "Hello, World!"
}
+37
View File
@@ -0,0 +1,37 @@
// 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
import "fmt"
func main() {
fmt.Println(injectedBaz())
}
type Foo int
type Bar int
type Baz int
func provideFoo(_ Baz) Foo {
return 0
}
func provideBar(_ Foo) Bar {
return 0
}
func provideBaz(_ Bar) Baz {
return 0
}
+26
View File
@@ -0,0 +1,26 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedBaz() Baz {
wire.Build(provideFoo, provideBar, provideBaz)
return 0
}
+1
View File
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1,5 @@
example.com/foo/wire.go:x:y: cycle for example.com/foo.Bar:
example.com/foo.Bar (example.com/foo.provideBar) ->
example.com/foo.Foo (example.com/foo.provideFoo) ->
example.com/foo.Baz (example.com/foo.provideBaz) ->
example.com/foo.Bar
@@ -0,0 +1,28 @@
// Copyright 2020 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
import (
"fmt"
)
type (
Bar struct{}
Foo struct{}
)
func main() {
fmt.Println("Hello, World")
}
@@ -0,0 +1,31 @@
// Copyright 2020 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
/* blockComment returns Foo and has a /*- style doc comment */
func blockComment() *Foo {
panic(wire.Build(wire.Struct(new(Foo))))
}
// lineComment returns Bar and has a //- style doc comment
func lineComment() *Bar {
panic(wire.Build(wire.Struct(new(Bar))))
}
+1
View File
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World
@@ -0,0 +1,21 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
/* blockComment returns Foo and has a /*- style doc comment */
func blockComment() *Foo {
foo := &Foo{}
return foo
}
// lineComment returns Bar and has a //- style doc comment
func lineComment() *Bar {
bar := &Bar{}
return bar
}
@@ -0,0 +1,25 @@
// 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
import (
"fmt"
)
func main() {
fmt.Println(injectedMessage())
}
var myFakeSet struct{}
@@ -0,0 +1,26 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedMessage() string {
wire.Build(myFakeSet)
return ""
}
+1
View File
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
example.com/foo/wire.go:x:y: var example.com/foo.myFakeSet struct{} is not a provider or a provider set
@@ -0,0 +1,120 @@
// 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.
// This test demonstrates how to use mocks with wire.
package main
import (
"fmt"
"time"
"github.com/grafana/grafana/pkg/build/wire"
)
func main() {
// Create a "real" greeter.
// Greet() will include the real current time, so elide it for repeatable
// tests.
fmt.Printf("Real time greeting: %s [current time elided]\n", initApp().Greet()[0:15])
// There are two approaches for creating an app with mocks.
// Approach A: create the mocks manually, and pass them to an injector.
// This approach is useful if you need to prime the mocks beforehand.
fmt.Println("Approach A")
mt := newMockTimer()
mockedApp := initMockedAppFromArgs(mt)
fmt.Println(mockedApp.Greet()) // prints greeting with time = zero time
mt.T = mt.T.AddDate(1999, 0, 0)
fmt.Println(mockedApp.Greet()) // prints greeting with time = year 2000
// Approach B: allow the injector to create the mocks, and return a struct
// that includes the resulting app plus the mocks.
fmt.Println("Approach B")
appWithMocks := initMockedApp()
fmt.Println(appWithMocks.app.Greet()) // prints greeting with time = zero time
appWithMocks.mt.T = appWithMocks.mt.T.AddDate(999, 0, 0)
fmt.Println(appWithMocks.app.Greet()) // prints greeting with time = year 1000
}
// appSet is a provider set for creating a real app.
var appSet = wire.NewSet(
wire.Struct(new(app), "*"),
wire.Struct(new(greeter), "*"),
wire.InterfaceValue(new(timer), realTime{}),
)
// appSetWithoutMocks is a provider set for creating an app with mocked
// dependencies. The mocked dependencies are omitted and must be provided as
// arguments to the injector.
// It is used for Approach A.
var appSetWithoutMocks = wire.NewSet(
wire.Struct(new(app), "*"),
wire.Struct(new(greeter), "*"),
)
// mockAppSet is a provider set for creating a mocked app, including the mocked
// dependencies.
// It is used for Approach B.
var mockAppSet = wire.NewSet(
wire.Struct(new(app), "*"),
wire.Struct(new(greeter), "*"),
wire.Struct(new(appWithMocks), "*"),
// For each mocked dependency, add a provider and use wire.Bind to bind
// the concrete type to the relevant interface.
newMockTimer,
wire.Bind(new(timer), new(*mockTimer)),
)
type timer interface {
Now() time.Time
}
// realTime implements timer with the real time.
type realTime struct{}
func (realTime) Now() time.Time { return time.Now() }
// mockTimer implements timer using a mocked time.
type mockTimer struct {
T time.Time
}
func newMockTimer() *mockTimer { return &mockTimer{} }
func (m *mockTimer) Now() time.Time { return m.T }
// greeter issues greetings with the time provided by T.
type greeter struct {
T timer
}
func (g greeter) Greet() string {
return fmt.Sprintf("Good day! It is %v", g.T.Now())
}
type app struct {
g greeter
}
func (a app) Greet() string {
return a.g.Greet()
}
// appWithMocks is used for Approach B, to return the app plus its mocked
// dependencies.
type appWithMocks struct {
app app
mt *mockTimer
}
@@ -0,0 +1,42 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
// initApp returns a real app.
func initApp() *app {
wire.Build(appSet)
return nil
}
// initMockedAppFromArgs returns an app with mocked dependencies provided via
// arguments (Approach A). Note that the argument's type is the interface
// type (timer), but the concrete mock type should be passed.
func initMockedAppFromArgs(mt timer) *app {
wire.Build(appSetWithoutMocks)
return nil
}
// initMockedApp returns an app with its mocked dependencies, created
// via providers (Approach B).
func initMockedApp() *appWithMocks {
wire.Build(mockAppSet)
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1,7 @@
Real time greeting: Good day! It is [current time elided]
Approach A
Good day! It is 0001-01-01 00:00:00 +0000 UTC
Good day! It is 2000-01-01 00:00:00 +0000 UTC
Approach B
Good day! It is 0001-01-01 00:00:00 +0000 UTC
Good day! It is 1000-01-01 00:00:00 +0000 UTC
@@ -0,0 +1,55 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
// initApp returns a real app.
func initApp() *app {
mainTimer := _wireRealTimeValue
mainGreeter := greeter{
T: mainTimer,
}
mainApp := &app{
g: mainGreeter,
}
return mainApp
}
var (
_wireRealTimeValue = realTime{}
)
// initMockedAppFromArgs returns an app with mocked dependencies provided via
// arguments (Approach A). Note that the argument's type is the interface
// type (timer), but the concrete mock type should be passed.
func initMockedAppFromArgs(mt timer) *app {
mainGreeter := greeter{
T: mt,
}
mainApp := &app{
g: mainGreeter,
}
return mainApp
}
// initMockedApp returns an app with its mocked dependencies, created
// via providers (Approach B).
func initMockedApp() *appWithMocks {
mainMockTimer := newMockTimer()
mainGreeter := greeter{
T: mainMockTimer,
}
mainApp := app{
g: mainGreeter,
}
mainAppWithMocks := &appWithMocks{
app: mainApp,
mt: mainMockTimer,
}
return mainAppWithMocks
}
@@ -0,0 +1,21 @@
// 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 bar
import "github.com/grafana/grafana/pkg/build/wire"
var Value = wire.Value(PublicMsg)
var PublicMsg = "Hello, World!"
@@ -0,0 +1,21 @@
// 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
import "fmt"
func main() {
fmt.Println(injectedMessage())
}
@@ -0,0 +1,27 @@
// 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 (
"example.com/bar"
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedMessage() string {
wire.Build(bar.Value)
return ""
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World!
@@ -0,0 +1,22 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"example.com/bar"
)
// Injectors from wire.go:
func injectedMessage() string {
string2 := _wireStringValue
return string2
}
var (
_wireStringValue = bar.PublicMsg
)
@@ -0,0 +1,23 @@
// 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 bar
import (
"os"
"github.com/grafana/grafana/pkg/build/wire"
)
var Value = wire.Value(os.Stdout)
@@ -0,0 +1,21 @@
// 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
import "fmt"
func main() {
fmt.Fprintln(injectedFile(), "Hello, World!")
}
@@ -0,0 +1,29 @@
// 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 (
"os"
"example.com/bar"
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedFile() *os.File {
wire.Build(bar.Value)
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World!
@@ -0,0 +1,22 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"os"
)
// Injectors from wire.go:
func injectedFile() *os.File {
file := _wireFileValue
return file
}
var (
_wireFileValue = os.Stdout
)
@@ -0,0 +1,38 @@
// Copyright 2019 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
import (
"fmt"
)
func main() {
fmt.Println(injectedBaz())
}
type Foo int
type Baz int
type Bar struct {
Bz Baz
}
func provideFoo(_ Baz) Foo {
return 0
}
func provideBar(_ Foo) Bar {
return Bar{}
}
@@ -0,0 +1,26 @@
// Copyright 2019 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedBaz() Baz {
wire.Build(provideFoo, provideBar, wire.FieldsOf(new(Bar), "Bz"))
return 0
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1,5 @@
example.com/foo/wire.go:x:y: cycle for example.com/foo.Bar:
example.com/foo.Bar (example.com/foo.provideBar) ->
example.com/foo.Foo (example.com/foo.provideFoo) ->
example.com/foo.Baz (example.com/foo.Bar.Bz) ->
example.com/foo.Bar
@@ -0,0 +1,32 @@
// Copyright 2019 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 bar
import (
"example.com/foo"
)
type Config struct {
V int
}
type Service struct {
Cfg *Config
F *foo.Service
}
func New(cfg *Config, f *foo.Service) *Service {
return &Service{Cfg: cfg, F: f}
}
@@ -0,0 +1,36 @@
// Copyright 2019 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 baz
import (
"fmt"
"example.com/bar"
"example.com/foo"
)
type Config struct {
Foo *foo.Config
Bar *bar.Config
}
type Service struct {
Foo *foo.Service
Bar *bar.Service
}
func (m *Service) String() string {
return fmt.Sprintf("%d %d", m.Foo.Cfg.V, m.Bar.Cfg.V)
}
@@ -0,0 +1,27 @@
// Copyright 2019 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 foo
type Config struct {
V int
}
type Service struct {
Cfg *Config
}
func New(cfg *Config) *Service {
return &Service{Cfg: cfg}
}
@@ -0,0 +1,49 @@
// Copyright 2019 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 (
"fmt"
"example.com/bar"
"example.com/baz"
"example.com/foo"
"github.com/grafana/grafana/pkg/build/wire"
)
func newBazService(*baz.Config) *baz.Service {
wire.Build(
wire.Struct(new(baz.Service), "*"),
wire.FieldsOf(
new(*baz.Config),
"Foo",
"Bar",
),
foo.New,
bar.New,
)
return nil
}
func main() {
cfg := &baz.Config{
Foo: &foo.Config{1},
Bar: &bar.Config{2},
}
svc := newBazService(cfg)
fmt.Println(svc.String())
}
@@ -0,0 +1 @@
example.com/main
@@ -0,0 +1,39 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"example.com/bar"
"example.com/baz"
"example.com/foo"
"fmt"
)
// Injectors from wire.go:
func newBazService(config *baz.Config) *baz.Service {
fooConfig := config.Foo
service := foo.New(fooConfig)
barConfig := config.Bar
barService := bar.New(barConfig, service)
bazService := &baz.Service{
Foo: service,
Bar: barService,
}
return bazService
}
// wire.go:
func main() {
cfg := &baz.Config{
Foo: &foo.Config{1},
Bar: &bar.Config{2},
}
svc := newBazService(cfg)
fmt.Println(svc.String())
}
@@ -0,0 +1,29 @@
// 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
import "fmt"
type S struct {
Foo string
}
func provideS() S {
return S{Foo: "Hello, World!"}
}
func main() {
fmt.Println(injectedMessage())
}
@@ -0,0 +1,28 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedMessage() string {
wire.Build(
provideS,
wire.FieldsOf(new(S), "Foo"))
return ""
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
Hello, World!
@@ -0,0 +1,15 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func injectedMessage() string {
s := provideS()
string2 := s.Foo
return string2
}
@@ -0,0 +1,29 @@
// Copyright 2019 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
import "fmt"
type S struct {
Foo string
}
func provideS() S {
return S{Foo: "Hello, World!"}
}
func main() {
fmt.Println("pointer to " + *injectedMessagePtr())
}
@@ -0,0 +1,32 @@
// Copyright 2019 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedMessagePtr() *string {
// This shouldn't work; FieldsOf provides a pointer to the
// field only when the struct type is a pointer to a struct.
// See FieldsOfStructPointer for a working example using
// a pointer to a struct.
wire.Build(
provideS,
wire.FieldsOf(new(S), "Foo"))
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1 @@
example.com/foo/wire.go:x:y: inject injectedMessagePtr: no provider found for *string, output of injector
@@ -0,0 +1,30 @@
// 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
import "fmt"
type S struct {
Foo string
}
func provideS() *S {
return &S{Foo: "Hello, World!"}
}
func main() {
fmt.Println(injectedMessage())
fmt.Println("pointer to " + *injectedMessagePtr())
}
@@ -0,0 +1,35 @@
// 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 (
"github.com/grafana/grafana/pkg/build/wire"
)
func injectedMessage() string {
wire.Build(
provideS,
wire.FieldsOf(new(*S), "Foo"))
return ""
}
func injectedMessagePtr() *string {
wire.Build(
provideS,
wire.FieldsOf(new(*S), "Foo"))
return nil
}
@@ -0,0 +1 @@
example.com/foo
@@ -0,0 +1,2 @@
Hello, World!
pointer to Hello, World!
@@ -0,0 +1,21 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
// Injectors from wire.go:
func injectedMessage() string {
s := provideS()
string2 := s.Foo
return string2
}
func injectedMessagePtr() *string {
s := provideS()
string2 := &s.Foo
return string2
}
@@ -0,0 +1,32 @@
// Copyright 2019 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 bar
import (
"example.com/foo"
)
type Config struct {
V int
}
type Service struct {
Cfg *Config
F *foo.Service
}
func New(cfg *Config, f *foo.Service) *Service {
return &Service{Cfg: cfg, F: f}
}

Some files were not shown because too many files have changed in this diff Show More