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:
@@ -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
|
||||
Executable
+89
@@ -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
|
||||
|
||||
Executable
+25
@@ -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
|
||||
Executable
+80
@@ -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
|
||||
@@ -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()))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
hello
|
||||
+14
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
+23
@@ -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
|
||||
+1
@@ -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!"
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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!"
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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))))
|
||||
}
|
||||
@@ -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 ""
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
+23
@@ -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)
|
||||
+21
@@ -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!")
|
||||
}
|
||||
+29
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
Hello, World!
|
||||
+22
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
1 2
|
||||
+39
@@ -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
|
||||
}
|
||||
+29
@@ -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())
|
||||
}
|
||||
+32
@@ -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
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
example.com/foo
|
||||
Vendored
+1
@@ -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
|
||||
+2
@@ -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
Reference in New Issue
Block a user