pax_global_header00006660000000000000000000000064135742304650014523gustar00rootroot0000000000000052 comment=578b29ef42c1970b9853962dd1c4308fd7eb5387 wire-0.4.0/000077500000000000000000000000001357423046500124725ustar00rootroot00000000000000wire-0.4.0/.codecov.yml000066400000000000000000000003211357423046500147110ustar00rootroot00000000000000comment: off coverage: status: project: default: target: 0 threshold: null base: auto patch: default: target: 0 threshold: null base: auto wire-0.4.0/.contributebot000066400000000000000000000003501357423046500153540ustar00rootroot00000000000000{ "issue_title_pattern": "^.*$", "pull_request_title_response": "Please edit the title of this pull request with the name of the affected component, or \"all\", followed by a colon, followed by a short summary of the change." } wire-0.4.0/.github/000077500000000000000000000000001357423046500140325ustar00rootroot00000000000000wire-0.4.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001357423046500162155ustar00rootroot00000000000000wire-0.4.0/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000010241357423046500207040ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve Wire --- You can use `go bug` to have a cool, automatically filled out bug template, or fill out the template below. ### Describe the bug A clear and concise description of what the bug is. ### To Reproduce Steps to reproduce the behavior. ## Expected behavior A clear and concise description of what you expected to happen. ### Version Which version of Wire are you seeing the bug with? ### Additional context Add any other context about the problem here. wire-0.4.0/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000010641357423046500217430ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project --- ### Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] ### Describe the solution you'd like A clear and concise description of what you want to happen. ### Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered. ### Additional context Add any other context or screenshots about the feature request here. wire-0.4.0/.github/pull_request_template.md000066400000000000000000000003201357423046500207660ustar00rootroot00000000000000Please reference any Issue related to this Pull Request. Example: `Fixes #1`. See [here](https://blog.github.com/2015-01-21-how-to-write-the-perfect-pull-request/) for tips on good Pull Request description. wire-0.4.0/.travis.yml000066400000000000000000000031261357423046500146050ustar00rootroot00000000000000# 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. language: go go_import_path: github.com/google/wire before_install: # The Bash that comes with OS X is ancient. # grep is similar: it's not GNU grep, which means commands aren't portable. # Homebrew installs grep as ggrep if you don't build from source, so it needs # moving so it takes precedence in the PATH. - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then HOMEBREW_NO_AUTO_UPDATE=1 brew install bash grep; mv $(brew --prefix)/bin/ggrep $(brew --prefix)/bin/grep; fi install: # Re-checkout files preserving line feeds. This prevents Windows builds from # converting \n to \r\n. - "git config --global core.autocrlf input" - "git checkout -- ." script: - 'internal/runtests.sh' env: global: - GO111MODULE=on - GOPROXY=https://proxy.golang.org # When updating Go versions: # In addition to changing the "go:" versions below, edit the version # test in internal/runtests.sh. jobs: include: - go: "1.13.x" os: linux - go: "1.13.x" os: osx - go: "1.13.x" os: windows wire-0.4.0/AUTHORS000066400000000000000000000012051357423046500135400ustar00rootroot00000000000000# This is the official list of Wire authors for copyright purposes. # This file is distinct from the CONTRIBUTORS files. # See the latter for an explanation. # Names should be added to this file as one of # Organization's name # Individual's name # Individual's name # See CONTRIBUTORS for the meaning of multiple email addresses. # Please keep the list sorted. Google LLC ktr Kumbirai Tanekha Oleg Kovalov Yoichiro Shimizu Zachary Romero wire-0.4.0/CODE_OF_CONDUCT.md000066400000000000000000000005171357423046500152740ustar00rootroot00000000000000# Code of Conduct This project is covered under the [Go Code of Conduct][]. In summary: - Treat everyone with respect and kindness. - Be thoughtful in how you communicate. - Don’t be destructive or inflammatory. - If you encounter an issue, please mail conduct@golang.org. [Go Code of Conduct]: https://golang.org/conduct wire-0.4.0/CONTRIBUTING.md000066400000000000000000000163261357423046500147330ustar00rootroot00000000000000# How to Contribute We would love to accept your patches and contributions to this project. Here is how you can help. ## Filing issues Filing issues is an important way you can contribute to the Wire Project. We want your feedback on things like bugs, desired API changes, or just anything that isn't working for you. ### Bugs If your issue is a bug, open one [here](https://github.com/google/wire/issues/new). The easiest way to file an issue with all the right information is to run `go bug`. `go bug` will print out a handy template of questions and system information that will help us get to the root of the issue quicker. ### Changes Unlike the core Go project, we do not have a formal proposal process for changes. If you have a change you would like to see in Wire, please file an issue with the necessary details. ### Triaging The Go Cloud team triages issues at least every two weeks, but usually within two business days. Bugs or feature requests are either placed into a **Sprint** milestone which means the issue is intended to be worked on. Issues that we would like to address but do not have time for are placed into the [Unplanned][] milestone. [Unplanned]: https://github.com/google/wire/milestone/1 ## Contributing Code We love accepting contributions! If your change is minor, please feel free submit a [pull request](https://help.github.com/articles/about-pull-requests/). If your change is larger, or adds a feature, please file an issue beforehand so that we can discuss the change. You're welcome to file an implementation pull request immediately as well, although we generally lean towards discussing the change and then reviewing the implementation separately. ### Finding something to work on If you want to write some code, but don't know where to start or what you might want to do, take a look at our [Unplanned][] milestone. This is where you can find issues we would like to address but can't currently find time for. See if any of the latest ones look interesting! If you need help before you can start work, you can comment on the issue and we will try to help as best we can. ### Contributor License Agreement Contributions to this project can only be made by those who have signed Google's Contributor License Agreement. You (or your employer) retain the copyright to your contribution, this simply gives us permission to use and redistribute your contributions as part of the project. Head over to to see your current agreements on file or to sign a new one. As a personal contributor, you only need to sign the Google CLA once across all Google projects. If you've already signed the CLA, there is no need to do it again. If you are submitting code on behalf of your employer, there's [a separate corporate CLA that your employer manages for you](https://opensource.google.com/docs/cla/#external-contributors). ## Making a pull request * Follow the normal [pull request flow](https://help.github.com/articles/creating-a-pull-request/) * Build your changes using Go 1.11 with Go modules enabled. Wire's continuous integration uses Go modules in order to ensure [reproducible builds](https://research.swtch.com/vgo-repro). * Test your changes using `go test ./...`. Please add tests that show the change does what it says it does, even if there wasn't a test in the first place. * Feel free to make as many commits as you want; we will squash them all into a single commit before merging your change. * Check the diffs, write a useful description (including something like `Fixes #123` if it's fixing a bug) and send the PR out. * [Travis CI](http://travis-ci.com) will run tests against the PR. This should happen within 10 minutes or so. If a test fails, go back to the coding stage and try to fix the test and push the same branch again. You won't need to make a new pull request, the changes will be rolled directly into the PR you already opened. Wait for Travis again. There is no need to assign a reviewer to the PR, the project team will assign someone for review during the standard [triage](#triaging) process. ## Code review All submissions, including submissions by project members, require review. It is almost never the case that a pull request is accepted without some changes requested, so please do not be offended! When you have finished making requested changes to your pull request, please make a comment containing "PTAL" (Please Take Another Look) on your pull request. GitHub notifications can be noisy, and it is unfortunately easy for things to be lost in the shuffle. Once your PR is approved (hooray!) the reviewer will squash your commits into a single commit, and then merge the commit onto the Wire master branch. Thank you! ## Github code review workflow conventions (For project members and frequent contributors.) As a contributor: - Try hard to make each Pull Request as small and focused as possible. In particular, this means that if a reviewer asks you to do something that is beyond the scope of the Pull Request, the best practice is to file another issue and reference it from the Pull Request rather than just adding more commits to the existing PR. - Adding someone as a Reviewer means "please feel free to look and comment"; the review is optional. Choose as many Reviewers as you'd like. - Adding someone as an Assignee means that the Pull Request should not be submitted until they approve. If you choose multiple Assignees, wait until all of them approve. It is fine to ask someone if they are OK with being removed as an Assignee. - Note that if you don't select any assignees, ContributeBot will turn all of your Reviewers into Assignees. - Make as many commits as you want locally, but try not to push them to Github until you've addressed comments; this allows the email notification about the push to be a signal to reviewers that the PR is ready to be looked at again. - When there may be confusion about what should happen next for a PR, be explicit; add a "PTAL" comment if it is ready for review again, or a "Please hold off on reviewing for now" if you are still working on addressing comments. - "Resolve" comments that you are sure you've addressed; let your reviewers resolve ones that you're not sure about. - Do not use `git push --force`; this can cause comments from your reviewers that are associated with a specific commit to be lost. This implies that once you've sent a Pull Request, you should use `git merge` instead of `git rebase` to incorporate commits from the master branch. As a reviewer: - Be timely in your review process, especially if you are an Assignee. - Try to use `Start a Review` instead of single comments, to reduce email spam. - "Resolve" your own comments if they have been addressed. - If you want your review to be blocking, and are not currently an Assignee, add yourself as an Assignee. When squashing-and-merging: - Ensure that **all** of the Assignees have approved. - Do a final review of the one-line PR summary, ensuring that it accurately describes the change. - Delete the automatically added commit lines; these are generally not interesting and make commit history harder to read. wire-0.4.0/CONTRIBUTORS000066400000000000000000000035051357423046500143550ustar00rootroot00000000000000# This is the official list of people who can contribute # (and typically have contributed) code to the Wire repository. # The AUTHORS file lists the copyright holders; this file # lists people. For example, Google employees are listed here # but not in AUTHORS, because Google holds the copyright. # # Names should be added to this file only after verifying that # the individual or the individual's organization has agreed to # the appropriate Contributor License Agreement, found here: # # http://code.google.com/legal/individual-cla-v1.0.html # http://code.google.com/legal/corporate-cla-v1.0.html # # The agreement for individuals can be filled out on the web. # # When adding J Random Contributor's name to this file, # either J's name or J's organization's name should be # added to the AUTHORS file, depending on whether the # individual or corporate CLA was used. # Names should be added to this file like so: # Individual's name # Individual's name # # An entry with multiple email addresses specifies that the # first address should be used in the submit logs and # that the other addresses should be recognized as the # same person when interacting with Git. # Please keep the list sorted. Chris Lewis Christina Austin <4240737+clausti@users.noreply.github.com> Eno Compton Issac Trotts ktr Kumbirai Tanekha Oleg Kovalov Robert van Gent Ross Light Tuo Shan Yoichiro Shimizu Zachary Romero wire-0.4.0/LICENSE000066400000000000000000000261361357423046500135070ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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 http://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. wire-0.4.0/README.md000066400000000000000000000035141357423046500137540ustar00rootroot00000000000000# Wire: Automated Initialization in Go [![Build Status](https://travis-ci.com/google/wire.svg?branch=master)][travis] [![godoc](https://godoc.org/github.com/google/wire?status.svg)][godoc] [![Coverage](https://codecov.io/gh/google/wire/branch/master/graph/badge.svg)](https://codecov.io/gh/google/wire) Wire is a code generation tool that automates connecting components using [dependency injection][]. Dependencies between components are represented in Wire as function parameters, encouraging explicit initialization instead of global variables. Because Wire operates without runtime state or reflection, code written to be used with Wire is useful even for hand-written initialization. For an overview, see the [introductory blog post][]. [dependency injection]: https://en.wikipedia.org/wiki/Dependency_injection [introductory blog post]: https://blog.golang.org/wire [godoc]: https://godoc.org/github.com/google/wire [travis]: https://travis-ci.com/google/wire ## Installing Install Wire by running: ```shell go get github.com/google/wire/cmd/wire ``` and ensuring that `$GOPATH/bin` is added to your `$PATH`. ## Documentation - [Tutorial][] - [User Guide][] - [Best Practices][] - [FAQ][] [Tutorial]: ./_tutorial/README.md [Best Practices]: ./docs/best-practices.md [FAQ]: ./docs/faq.md [User Guide]: ./docs/guide.md ## Project status As of version v0.3.0, Wire is *beta* and is considered feature complete. It works well for the tasks it was designed to perform, and we prefer to keep it as simple as possible. We'll not be accepting new features at this time, but will gladly accept bug reports and fixes. ## Community You can contact us on the [go-cloud mailing list][]. This project is covered by the Go [Code of Conduct][]. [Code of Conduct]: ./CODE_OF_CONDUCT.md [go-cloud mailing list]: https://groups.google.com/forum/#!forum/go-cloud wire-0.4.0/_tutorial/000077500000000000000000000000001357423046500144745ustar00rootroot00000000000000wire-0.4.0/_tutorial/README.md000066400000000000000000000314341357423046500157600ustar00rootroot00000000000000# Wire Tutorial Let's learn to use Wire by example. The [Wire guide][guide] provides thorough documentation of the tool's usage. For readers eager to see Wire applied to a larger server, the [guestbook sample in Go Cloud][guestbook] uses Wire to initialize its components. Here we are going to build a small greeter program to understand how to use Wire. The finished product may be found in the same directory as this README. [guestbook]: https://github.com/google/go-cloud/tree/master/samples/guestbook [guide]: https://github.com/google/wire/blob/master/docs/guide.md ## A First Pass of Building the Greeter Program Let's create a small program that simulates an event with a greeter greeting guests with a particular message. To start, we will create three types: 1) a message for a greeter, 2) a greeter who conveys that message, and 3) an event that starts with the greeter greeting guests. In this design, we have three `struct` types: ``` go type Message string type Greeter struct { // ... TBD } type Event struct { // ... TBD } ``` The `Message` type just wraps a string. For now, we will create a simple initializer that always returns a hard-coded message: ``` go func NewMessage() Message { return Message("Hi there!") } ``` Our `Greeter` will need reference to the `Message`. So let's create an initializer for our `Greeter` as well. ``` go func NewGreeter(m Message) Greeter { return Greeter{Message: m} } type Greeter struct { Message Message // <- adding a Message field } ``` In the initializer we assign a `Message` field to `Greeter`. Now, we can use the `Message` when we create a `Greet` method on `Greeter`: ``` go func (g Greeter) Greet() Message { return g.Message } ``` Next, we need our `Event` to have a `Greeter`, so we will create an initializer for it as well. ``` go func NewEvent(g Greeter) Event { return Event{Greeter: g} } type Event struct { Greeter Greeter // <- adding a Greeter field } ``` Then we add a method to start the `Event`: ``` go func (e Event) Start() { msg := e.Greeter.Greet() fmt.Println(msg) } ``` The `Start` method holds the core of our small application: it tells the greeter to issue a greeting and then prints that message to the screen. Now that we have all the components of our application ready, let's see what it takes to initialize all the components without using Wire. Our main function would look like this: ``` go func main() { message := NewMessage() greeter := NewGreeter(message) event := NewEvent(greeter) event.Start() } ``` First we create a message, then we create a greeter with that message, and finally we create an event with that greeter. With all the initialization done, we're ready to start our event. We are using the [dependency injection][di] design principle. In practice, that means we pass in whatever each component needs. This style of design lends itself to writing easily tested code and makes it easy to swap out one dependency with another. [di]: https://stackoverflow.com/questions/130794/what-is-dependency-injection ## Using Wire to Generate Code One downside to dependency injection is the need for so many initialization steps. Let's see how we can use Wire to make the process of initializing our components smoother. Let's start by changing our `main` function to look like this: ``` go func main() { e := InitializeEvent() e.Start() } ``` Next, in a separate file called `wire.go` we will define `InitializeEvent`. This is where things get interesting: ``` go // wire.go func InitializeEvent() Event { wire.Build(NewEvent, NewGreeter, NewMessage) return Event{} } ``` Rather than go through the trouble of initializing each component in turn and passing it into the next one, we instead have a single call to `wire.Build` passing in the initializers we want to use. In Wire, initializers are known as "providers," functions which provide a particular type. We add a zero value for `Event` as a return value to satisfy the compiler. Note that even if we add values to `Event`, Wire will ignore them. In fact, the injector's purpose is to provide information about which providers to use to construct an `Event` and so we will exclude it from our final binary with a build constraint at the top of the file: ``` go //+build wireinject ``` Note, a [build constraint][constraint] requires a blank, trailing line. In Wire parlance, `InitializeEvent` is an "injector." Now that we have our injector complete, we are ready to use the `wire` command line tool. Install the tool with: ``` shell go get github.com/google/wire/cmd/wire ``` Then in the same directory with the above code, simply run `wire`. Wire will find the `InitializeEvent` injector and generate a function whose body is filled out with all the necessary initialization steps. The result will be written to a file named `wire_gen.go`. Let's take a look at what Wire did for us: ``` go // wire_gen.go func InitializeEvent() Event { message := NewMessage() greeter := NewGreeter(message) event := NewEvent(greeter) return event } ``` It looks just like what we wrote above! Now this is a simple example with just three components, so writing the initializer by hand isn't too painful. Imagine how useful Wire is for components that are much more complex. When working with Wire, we will commit both `wire.go` and `wire_gen.go` to source control. [constraint]: https://godoc.org/go/build#hdr-Build_Constraints ## Making Changes with Wire To show a small part of how Wire handles more complex setups, let's refactor our initializer for `Event` to return an error and see what happens. ``` go func NewEvent(g Greeter) (Event, error) { if g.Grumpy { return Event{}, errors.New("could not create event: event greeter is grumpy") } return Event{Greeter: g}, nil } ``` We'll say that sometimes a `Greeter` might be grumpy and so we cannot create an `Event`. The `NewGreeter` initializer now looks like this: ``` go func NewGreeter(m Message) Greeter { var grumpy bool if time.Now().Unix()%2 == 0 { grumpy = true } return Greeter{Message: m, Grumpy: grumpy} } ``` We have added a `Grumpy` field to `Greeter` struct and if the invocation time of the initializer is an even number of seconds since the Unix epoch, we will create a grumpy greeter instead of a friendly one. The `Greet` method then becomes: ``` go func (g Greeter) Greet() Message { if g.Grumpy { return Message("Go away!") } return g.Message } ``` Now you see how a grumpy `Greeter` is no good for an `Event`. So `NewEvent` may fail. Our `main` must now take into account that `InitializeEvent` may in fact fail: ``` go func main() { e, err := InitializeEvent() if err != nil { fmt.Printf("failed to create event: %s\n", err) os.Exit(2) } e.Start() } ``` We also need to update `InitializeEvent` to add an `error` type to the return value: ``` go // wire.go func InitializeEvent() (Event, error) { wire.Build(NewEvent, NewGreeter, NewMessage) return Event{}, nil } ``` With the setup complete, we are ready to invoke the `wire` command again. Note, that after running `wire` once to produce a `wire_gen.go` file, we may also use `go generate`. Having run the command, our `wire_gen.go` file looks like this: ``` go // wire_gen.go func InitializeEvent() (Event, error) { message := NewMessage() greeter := NewGreeter(message) event, err := NewEvent(greeter) if err != nil { return Event{}, err } return event, nil } ``` Wire has detected that the `NewEvent` provider may fail and has done the right thing inside the generated code: it checks the error and returns early if one is present. ## Changing the Injector Signature As another improvement, let's look at how Wire generates code based on the signature of the injector. Presently, we have hard-coded the message inside `NewMessage`. In practice, it's much nicer to allow callers to change that message however they see fit. So let's change `InitializeEvent` to look like this: ``` go func InitializeEvent(phrase string) (Event, error) { wire.Build(NewEvent, NewGreeter, NewMessage) return Event{}, nil } ``` Now `InitializeEvent` allows callers to pass in the `phrase` for a `Greeter` to use. We also add a `phrase` argument to `NewMessage`: ``` go func NewMessage(phrase string) Message { return Message(phrase) } ``` After we run `wire` again, we will see that the tool has generated an initializer which passes the `phrase` value as a `Message` into `Greeter`. Neat! ``` go // wire_gen.go func InitializeEvent(phrase string) (Event, error) { message := NewMessage(phrase) greeter := NewGreeter(message) event, err := NewEvent(greeter) if err != nil { return Event{}, err } return event, nil } ``` Wire inspects the arguments to the injector, sees that we added a string to the list of arguments (e.g., `phrase`), and likewise sees that among all the providers, `NewMessage` takes a string, and so it passes `phrase` into `NewMessage`. ## Catching Mistakes with Helpful Errors Let's also look at what happens when Wire detects mistakes in our code and see how Wire's error messages help us correct any problems. For example, when writing our injector `InitializeEvent`, let's say we forget to add a provider for `Greeter`. Let's see what happens: ``` go func InitializeEvent(phrase string) (Event, error) { wire.Build(NewEvent, NewMessage) // woops! We forgot to add a provider for Greeter return Event{}, nil } ``` Running `wire`, we see the following: ``` shell # wrapping the error across lines for readability $GOPATH/src/github.com/google/wire/_tutorial/wire.go:24:1: inject InitializeEvent: no provider found for github.com/google/wire/_tutorial.Greeter (required by provider of github.com/google/wire/_tutorial.Event) wire: generate failed ``` Wire is telling us some useful information: it cannot find a provider for `Greeter`. Note that the error message prints out the full path to the `Greeter` type. It's also telling us the line number and injector name where the problem occurred: line 24 inside `InitializeEvent`. In addition, the error message tells us which provider needs a `Greeter`. It's the `Event` type. Once we pass in a provider of `Greeter`, the problem will be solved. Alternatively, what happens if we provide one too many providers to `wire.Build`? ``` go func NewEventNumber() int { return 1 } func InitializeEvent(phrase string) (Event, error) { // woops! NewEventNumber is unused. wire.Build(NewEvent, NewGreeter, NewMessage, NewEventNumber) return Event{}, nil } ``` Wire helpfully tells us that we have an unused provider: ``` shell $GOPATH/src/github.com/google/wire/_tutorial/wire.go:24:1: inject InitializeEvent: unused provider "NewEventNumber" wire: generate failed ``` Deleting the unused provider from the call to `wire.Build` resolves the error. ## Conclusion Let's summarize what we have done here. First, we wrote a number of components with corresponding initializers, or providers. Next, we created an injector function, specifying which arguments it receives and which types it returns. Then, we filled in the injector function with a call to `wire.Build` supplying all necessary providers. Finally, we ran the `wire` command to generate code that wires up all the different initializers. When we added an argument to the injector and an error return value, running `wire` again made all the necessary updates to our generated code. The example here is small, but it demonstrates some of the power of Wire, and how it takes much of the pain out of initializing code using dependency injection. Furthermore, using Wire produced code that looks much like what we would otherwise write. There are no bespoke types that commit a user to Wire. Instead it's just generated code. We may do with it what we will. Finally, another point worth considering is how easy it is to add new dependencies to our component initialization. As long as we tell Wire how to provide (i.e., initialize) a component, we may add that component anywhere in the dependency graph and Wire will handle the rest. In closing, it is worth mentioning that Wire supports a number of additional features not discussed here. Providers may be grouped in [provider sets][sets]. There is support for [binding interfaces][interfaces], [binding values][values], as well as support for [cleanup functions][cleanup]. See the [Advanced Features][advanced] section for more. [advanced]: https://github.com/google/wire/blob/master/docs/guide.md#advanced-features [cleanup]: https://github.com/google/wire/blob/master/docs/guide.md#cleanup-functions [interfaces]: https://github.com/google/wire/blob/master/docs/guide.md#binding-interfaces [sets]: https://github.com/google/wire/blob/master/docs/guide.md#defining-providers [values]: https://github.com/google/wire/blob/master/docs/guide.md#binding-values wire-0.4.0/_tutorial/main.go000066400000000000000000000037561357423046500157620ustar00rootroot00000000000000// 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. // The greeter binary simulates an event with greeters greeting guests. package main import ( "errors" "fmt" "os" "time" ) // Message is what greeters will use to greet guests. type Message string // NewMessage creates a default Message. func NewMessage(phrase string) Message { return Message(phrase) } // NewGreeter initializes a Greeter. If the current epoch time is an even // number, NewGreeter will create a grumpy Greeter. func NewGreeter(m Message) Greeter { var grumpy bool if time.Now().Unix()%2 == 0 { grumpy = true } return Greeter{Message: m, Grumpy: grumpy} } // Greeter is the type charged with greeting guests. type Greeter struct { Grumpy bool Message Message } // Greet produces a greeting for guests. func (g Greeter) Greet() Message { if g.Grumpy { return Message("Go away!") } return g.Message } // NewEvent creates an event with the specified greeter. func NewEvent(g Greeter) (Event, error) { if g.Grumpy { return Event{}, errors.New("could not create event: event greeter is grumpy") } return Event{Greeter: g}, nil } // Event is a gathering with greeters. type Event struct { Greeter Greeter } // Start ensures the event starts with greeting all guests. func (e Event) Start() { msg := e.Greeter.Greet() fmt.Println(msg) } func main() { e, err := InitializeEvent("hi there!") if err != nil { fmt.Printf("failed to create event: %s\n", err) os.Exit(2) } e.Start() } wire-0.4.0/_tutorial/wire.go000066400000000000000000000016741357423046500160010ustar00rootroot00000000000000// 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 // The build tag makes sure the stub is not built in the final build. package main import "github.com/google/wire" // InitializeEvent creates an Event. It will error if the Event is staffed with // a grumpy greeter. func InitializeEvent(phrase string) (Event, error) { wire.Build(NewEvent, NewGreeter, NewMessage) return Event{}, nil } wire-0.4.0/_tutorial/wire_gen.go000066400000000000000000000005201357423046500166170ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func InitializeEvent(phrase string) (Event, error) { message := NewMessage(phrase) greeter := NewGreeter(message) event, err := NewEvent(greeter) if err != nil { return Event{}, err } return event, nil } wire-0.4.0/cmd/000077500000000000000000000000001357423046500132355ustar00rootroot00000000000000wire-0.4.0/cmd/wire/000077500000000000000000000000001357423046500142035ustar00rootroot00000000000000wire-0.4.0/cmd/wire/main.go000066400000000000000000000402021357423046500154540ustar00rootroot00000000000000// 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. // Wire is a compile-time dependency injection tool. // // For an overview, see https://github.com/google/wire/blob/master/README.md package main import ( "context" "flag" "fmt" "go/token" "go/types" "io/ioutil" "log" "os" "reflect" "sort" "strconv" "strings" "github.com/google/subcommands" "github.com/google/wire/internal/wire" "github.com/pmezard/go-difflib/difflib" "golang.org/x/tools/go/types/typeutil" ) func main() { subcommands.Register(subcommands.CommandsCommand(), "") subcommands.Register(subcommands.FlagsCommand(), "") subcommands.Register(subcommands.HelpCommand(), "") subcommands.Register(&checkCmd{}, "") subcommands.Register(&diffCmd{}, "") subcommands.Register(&genCmd{}, "") subcommands.Register(&showCmd{}, "") flag.Parse() // Initialize the default logger to log to stderr. log.SetFlags(0) log.SetPrefix("wire: ") log.SetOutput(os.Stderr) // TODO(rvangent): Use subcommands's VisitCommands instead of hardcoded map, // once there is a release that contains it: // allCmds := map[string]bool{} // subcommands.DefaultCommander.VisitCommands(func(_ *subcommands.CommandGroup, cmd subcommands.Command) { allCmds[cmd.Name()] = true }) allCmds := map[string]bool{ "commands": true, // builtin "help": true, // builtin "flags": true, // builtin "check": true, "diff": true, "gen": true, "show": true, } // Default to running the "gen" command. if args := flag.Args(); len(args) == 0 || !allCmds[args[0]] { genCmd := &genCmd{} os.Exit(int(genCmd.Execute(context.Background(), flag.CommandLine))) } os.Exit(int(subcommands.Execute(context.Background()))) } // packages returns the slice of packages to run wire over based on f. // It defaults to ".". func packages(f *flag.FlagSet) []string { pkgs := f.Args() if len(pkgs) == 0 { pkgs = []string{"."} } return pkgs } // newGenerateOptions returns an initialized wire.GenerateOptions, possibly // with the Header option set. func newGenerateOptions(headerFile string) (*wire.GenerateOptions, error) { opts := new(wire.GenerateOptions) if headerFile != "" { var err error opts.Header, err = ioutil.ReadFile(headerFile) if err != nil { return nil, fmt.Errorf("failed to read header file %q: %v", headerFile, err) } } return opts, nil } type genCmd struct { headerFile string prefixFileName string } func (*genCmd) Name() string { return "gen" } func (*genCmd) Synopsis() string { return "generate the wire_gen.go file for each package" } func (*genCmd) Usage() string { return `gen [packages] Given one or more packages, gen creates the wire_gen.go file for each. If no packages are listed, it defaults to ".". ` } func (cmd *genCmd) SetFlags(f *flag.FlagSet) { f.StringVar(&cmd.headerFile, "header_file", "", "path to file to insert as a header in wire_gen.go") f.StringVar(&cmd.prefixFileName, "output_file_prefix", "", "string to prepend to output file names.") } func (cmd *genCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { wd, err := os.Getwd() if err != nil { log.Println("failed to get working directory: ", err) return subcommands.ExitFailure } opts, err := newGenerateOptions(cmd.headerFile) if err != nil { log.Println(err) return subcommands.ExitFailure } opts.PrefixOutputFile = cmd.prefixFileName outs, errs := wire.Generate(ctx, wd, os.Environ(), packages(f), opts) if len(errs) > 0 { logErrors(errs) log.Println("generate failed") return subcommands.ExitFailure } if len(outs) == 0 { return subcommands.ExitSuccess } success := true for _, out := range outs { if len(out.Errs) > 0 { logErrors(out.Errs) log.Printf("%s: generate failed\n", out.PkgPath) success = false } if len(out.Content) == 0 { // No Wire output. Maybe errors, maybe no Wire directives. continue } if err := out.Commit(); err == nil { log.Printf("%s: wrote %s\n", out.PkgPath, out.OutputPath) } else { log.Printf("%s: failed to write %s: %v\n", out.PkgPath, out.OutputPath, err) success = false } } if !success { log.Println("at least one generate failure") return subcommands.ExitFailure } return subcommands.ExitSuccess } type diffCmd struct { headerFile string } func (*diffCmd) Name() string { return "diff" } func (*diffCmd) Synopsis() string { return "output a diff between existing wire_gen.go files and what gen would generate" } func (*diffCmd) Usage() string { return `diff [packages] Given one or more packages, diff generates the content for their wire_gen.go files and outputs the diff against the existing files. If no packages are listed, it defaults to ".". Similar to the diff command, it returns 0 if no diff, 1 if different, 2 plus an error if trouble. ` } func (cmd *diffCmd) SetFlags(f *flag.FlagSet) { f.StringVar(&cmd.headerFile, "header_file", "", "path to file to insert as a header in wire_gen.go") } func (cmd *diffCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { const ( errReturn = subcommands.ExitStatus(2) diffReturn = subcommands.ExitStatus(1) ) wd, err := os.Getwd() if err != nil { log.Println("failed to get working directory: ", err) return errReturn } opts, err := newGenerateOptions(cmd.headerFile) if err != nil { log.Println(err) return subcommands.ExitFailure } outs, errs := wire.Generate(ctx, wd, os.Environ(), packages(f), opts) if len(errs) > 0 { logErrors(errs) log.Println("generate failed") return errReturn } if len(outs) == 0 { return subcommands.ExitSuccess } success := true hadDiff := false for _, out := range outs { if len(out.Errs) > 0 { logErrors(out.Errs) log.Printf("%s: generate failed\n", out.PkgPath) success = false } if len(out.Content) == 0 { // No Wire output. Maybe errors, maybe no Wire directives. continue } // Assumes the current file is empty if we can't read it. cur, _ := ioutil.ReadFile(out.OutputPath) if diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ A: difflib.SplitLines(string(cur)), B: difflib.SplitLines(string(out.Content)), }); err == nil { if diff != "" { // Print the actual diff to stdout, not stderr. fmt.Printf("%s: diff from %s:\n%s\n", out.PkgPath, out.OutputPath, diff) hadDiff = true } } else { log.Printf("%s: failed to diff %s: %v\n", out.PkgPath, out.OutputPath, err) success = false } } if !success { log.Println("at least one generate failure") return errReturn } if hadDiff { return diffReturn } return subcommands.ExitSuccess } type showCmd struct{} func (*showCmd) Name() string { return "show" } func (*showCmd) Synopsis() string { return "describe all top-level provider sets" } func (*showCmd) Usage() string { return `show [packages] Given one or more packages, show finds all the provider sets declared as top-level variables and prints what other provider sets they import and what outputs they can produce, given possible inputs. It also lists any injector functions defined in the package. If no packages are listed, it defaults to ".". ` } func (*showCmd) SetFlags(_ *flag.FlagSet) {} func (*showCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { wd, err := os.Getwd() if err != nil { log.Println("failed to get working directory: ", err) return subcommands.ExitFailure } info, errs := wire.Load(ctx, wd, os.Environ(), packages(f)) if info != nil { keys := make([]wire.ProviderSetID, 0, len(info.Sets)) for k := range info.Sets { keys = append(keys, k) } sort.Slice(keys, func(i, j int) bool { if keys[i].ImportPath == keys[j].ImportPath { return keys[i].VarName < keys[j].VarName } return keys[i].ImportPath < keys[j].ImportPath }) for i, k := range keys { if i > 0 { fmt.Println() } outGroups, imports := gather(info, k) fmt.Println(k) for _, imp := range sortSet(imports) { fmt.Printf("\t%s\n", imp) } for i := range outGroups { fmt.Printf("\tOutputs given %s:\n", outGroups[i].name) out := make(map[string]token.Pos, outGroups[i].outputs.Len()) outGroups[i].outputs.Iterate(func(t types.Type, v interface{}) { switch v := v.(type) { case *wire.Provider: out[types.TypeString(t, nil)] = v.Pos case *wire.Value: out[types.TypeString(t, nil)] = v.Pos case *wire.Field: out[types.TypeString(t, nil)] = v.Pos default: panic("unreachable") } }) for _, t := range sortSet(out) { fmt.Printf("\t\t%s\n", t) fmt.Printf("\t\t\tat %v\n", info.Fset.Position(out[t])) } } } if len(info.Injectors) > 0 { injectors := append([]*wire.Injector(nil), info.Injectors...) sort.Slice(injectors, func(i, j int) bool { if injectors[i].ImportPath == injectors[j].ImportPath { return injectors[i].FuncName < injectors[j].FuncName } return injectors[i].ImportPath < injectors[j].ImportPath }) fmt.Println("\nInjectors:") for _, in := range injectors { fmt.Printf("\t%v\n", in) } } } if len(errs) > 0 { logErrors(errs) log.Println("error loading packages") return subcommands.ExitFailure } return subcommands.ExitSuccess } type checkCmd struct{} func (*checkCmd) Name() string { return "check" } func (*checkCmd) Synopsis() string { return "print any Wire errors found" } func (*checkCmd) Usage() string { return `check [packages] Given one or more packages, check prints any type-checking or Wire errors found with top-level variable provider sets or injector functions. If no packages are listed, it defaults to ".". ` } func (*checkCmd) SetFlags(_ *flag.FlagSet) {} func (*checkCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { wd, err := os.Getwd() if err != nil { log.Println("failed to get working directory: ", err) return subcommands.ExitFailure } _, errs := wire.Load(ctx, wd, os.Environ(), packages(f)) if len(errs) > 0 { logErrors(errs) log.Println("error loading packages") return subcommands.ExitFailure } return subcommands.ExitSuccess } type outGroup struct { name string inputs *typeutil.Map // values are not important outputs *typeutil.Map // values are *wire.Provider, *wire.Value, or *wire.Field } // gather flattens a provider set into outputs grouped by the inputs // required to create them. As it flattens the provider set, it records // the visited named provider sets as imports. func gather(info *wire.Info, key wire.ProviderSetID) (_ []outGroup, imports map[string]struct{}) { set := info.Sets[key] hash := typeutil.MakeHasher() // Find imports. next := []*wire.ProviderSet{info.Sets[key]} visited := make(map[*wire.ProviderSet]struct{}) imports = make(map[string]struct{}) for len(next) > 0 { curr := next[len(next)-1] next = next[:len(next)-1] if _, found := visited[curr]; found { continue } visited[curr] = struct{}{} if curr.VarName != "" && !(curr.PkgPath == key.ImportPath && curr.VarName == key.VarName) { imports[formatProviderSetName(curr.PkgPath, curr.VarName)] = struct{}{} } for _, imp := range curr.Imports { next = append(next, imp) } } // Depth-first search to build groups. var groups []outGroup inputVisited := new(typeutil.Map) // values are int, indices into groups or -1 for input. inputVisited.SetHasher(hash) var stk []types.Type for _, k := range set.Outputs() { // Start a DFS by picking a random unvisited node. if inputVisited.At(k) == nil { stk = append(stk, k) } // Run DFS dfs: for len(stk) > 0 { curr := stk[len(stk)-1] stk = stk[:len(stk)-1] if inputVisited.At(curr) != nil { continue } switch pv := set.For(curr); { case pv.IsNil(): // This is an input. inputVisited.Set(curr, -1) case pv.IsArg(): // This is an injector argument. inputVisited.Set(curr, -1) case pv.IsProvider(): // Try to see if any args haven't been visited. p := pv.Provider() allPresent := true for _, arg := range p.Args { if inputVisited.At(arg.Type) == nil { allPresent = false } } if !allPresent { stk = append(stk, curr) for _, arg := range p.Args { if inputVisited.At(arg.Type) == nil { stk = append(stk, arg.Type) } } continue dfs } // Build up set of input types, match to a group. in := new(typeutil.Map) in.SetHasher(hash) for _, arg := range p.Args { i := inputVisited.At(arg.Type).(int) if i == -1 { in.Set(arg.Type, true) } else { mergeTypeSets(in, groups[i].inputs) } } for i := range groups { if sameTypeKeys(groups[i].inputs, in) { groups[i].outputs.Set(curr, p) inputVisited.Set(curr, i) continue dfs } } out := new(typeutil.Map) out.SetHasher(hash) out.Set(curr, p) inputVisited.Set(curr, len(groups)) groups = append(groups, outGroup{ inputs: in, outputs: out, }) case pv.IsValue(): v := pv.Value() for i := range groups { if groups[i].inputs.Len() == 0 { groups[i].outputs.Set(curr, v) inputVisited.Set(curr, i) continue dfs } } in := new(typeutil.Map) in.SetHasher(hash) out := new(typeutil.Map) out.SetHasher(hash) out.Set(curr, v) inputVisited.Set(curr, len(groups)) groups = append(groups, outGroup{ inputs: in, outputs: out, }) case pv.IsField(): // Try to see if the parent struct hasn't been visited. f := pv.Field() if inputVisited.At(f.Parent) == nil { stk = append(stk, curr, f.Parent) continue } // Build the input map for the parent struct. in := new(typeutil.Map) in.SetHasher(hash) i := inputVisited.At(f.Parent).(int) if i == -1 { in.Set(f.Parent, true) } else { mergeTypeSets(in, groups[i].inputs) } // Group all fields together under the same parent struct. for i := range groups { if sameTypeKeys(groups[i].inputs, in) { groups[i].outputs.Set(curr, f) inputVisited.Set(curr, i) continue dfs } } out := new(typeutil.Map) out.SetHasher(hash) out.Set(curr, f) inputVisited.Set(curr, len(groups)) groups = append(groups, outGroup{ inputs: in, outputs: out, }) default: panic("unreachable") } } } // Name and sort groups. for i := range groups { if groups[i].inputs.Len() == 0 { groups[i].name = "no inputs" continue } instr := make([]string, 0, groups[i].inputs.Len()) groups[i].inputs.Iterate(func(k types.Type, _ interface{}) { instr = append(instr, types.TypeString(k, nil)) }) sort.Strings(instr) groups[i].name = strings.Join(instr, ", ") } sort.Slice(groups, func(i, j int) bool { if groups[i].inputs.Len() == groups[j].inputs.Len() { return groups[i].name < groups[j].name } return groups[i].inputs.Len() < groups[j].inputs.Len() }) return groups, imports } func mergeTypeSets(dst, src *typeutil.Map) { src.Iterate(func(k types.Type, _ interface{}) { dst.Set(k, true) }) } func sameTypeKeys(a, b *typeutil.Map) bool { if a.Len() != b.Len() { return false } same := true a.Iterate(func(k types.Type, _ interface{}) { if b.At(k) == nil { same = false } }) return same } func sortSet(set interface{}) []string { rv := reflect.ValueOf(set) a := make([]string, 0, rv.Len()) keys := rv.MapKeys() for _, k := range keys { a = append(a, k.String()) } sort.Strings(a) return a } func formatProviderSetName(importPath, varName string) string { // Since varName is an identifier, it doesn't make sense to quote. return strconv.Quote(importPath) + "." + varName } func logErrors(errs []error) { for _, err := range errs { log.Println(strings.Replace(err.Error(), "\n", "\n\t", -1)) } } wire-0.4.0/docs/000077500000000000000000000000001357423046500134225ustar00rootroot00000000000000wire-0.4.0/docs/best-practices.md000066400000000000000000000107251357423046500166610ustar00rootroot00000000000000# Best Practices The following are practices we recommend for using Wire. This list will grow over time. ## Distinguishing Types If you need to inject a common type like `string`, create a new string type to avoid conflicts with other providers. For example: ```go type MySQLConnectionString string ``` ## Options Structs A provider function that includes many dependencies can pair the function with an options struct. ```go type Options struct { // Messages is the set of recommended greetings. Messages []Message // Writer is the location to send greetings. nil goes to stdout. Writer io.Writer } func NewGreeter(ctx context.Context, opts *Options) (*Greeter, error) { // ... } var GreeterSet = wire.NewSet(wire.Struct(new(Options), "*"), NewGreeter) ``` ## Provider Sets in Libraries When creating a provider set for use in a library, the only changes you can make without breaking compatibility are: - Change which provider a provider set uses to provide a specific output, as long as it does not introduce a new input to the provider set. It may remove inputs. However, note that existing injectors will use the old provider until they are regenerated. - Introduce a new output type into the provider set, but only if the type itself is newly added. If the type is not new, it is possible that some injector already has the output type included, which would cause a conflict. All other changes are not safe. This includes: - Requiring a new input in the provider set. - Removing an output type from a provider set. - Adding an existing output type into the provider set. Instead of making one of these breaking changes, consider adding a new provider set. As an example, if you have a provider set like this: ```go var GreeterSet = wire.NewSet(NewStdoutGreeter) func DefaultGreeter(ctx context.Context) *Greeter { // ... } func NewStdoutGreeter(ctx context.Context, msgs []Message) *Greeter { // ... } func NewGreeter(ctx context.Context, w io.Writer, msgs []Message) (*Greeter, error) { // ... } ``` You may: - Use `DefaultGreeter` instead of `NewStdoutGreeter` in `GreeterSet`. - Create a new type `T` and add a provider for `T` to `GreeterSet`, as long as `T` is introduced in the same commit/release as the provider is added. You may not: - Use `NewGreeter` instead of `NewStdoutGreeter` in `GreeterSet`. This both adds an input type (`io.Writer`) and requires injectors to return an `error` where the provider of `*Greeter` did not require this before. - Remove `NewStdoutGreeter` from `GreeterSet`. Injectors depending on `*Greeter` will be broken. - Add a provider for `io.Writer` to `GreeterSet`. Injectors might already have a provider for `io.Writer` which might conflict with this one. As such, you should pick the output types in a library provider set carefully. In general, prefer small provider sets in a library. For example, it is common for a library provider set to contain a single provider function along with a `wire.Bind` to the interface the return type implements. Avoiding larger provider sets reduces the likelihood that applications will encounter conflicts. To illustrate, imagine your library provides a client for a web service. While it may be tempting to bundle a provider for `*http.Client` in a provider set for your library's client, doing so would cause conflicts if every library did the same. Instead, the library's provider set should only include the provider for the API client, and let `*http.Client` be an input of the provider set. ## Mocking There are two approaches for creating an injected app with mocked dependencies. Examples of both approaches are shown [here](https://github.com/google/wire/tree/master/internal/wire/testdata/ExampleWithMocks/foo). ### Approach A: Pass mocks to the injector Create a test-only injector that takes all of the mocks as arguments; the argument types must be the interface types the mocks are mocking. `wire.Build` can't include providers for the mocked dependencies without creating conflicts, so if you're using provider set(s) you will need to define one that doesn't include the mocked types. ### Approach B: Return the mocks from the injector Create a new struct that includes the app plus all of the dependencies you want to mock. Create a test-only injector that returns this struct, give it providers for the concrete mock types, and use `wire.Bind` to tell Wire that the concrete mock types should be used to fulfill the appropriate interface. wire-0.4.0/docs/faq.md000066400000000000000000000112541357423046500145160ustar00rootroot00000000000000# Frequently Asked Questions ## How does Wire relate to other Go dependency injection tools? Other dependency injection tools for Go like [dig][] or [facebookgo/inject][] are based on reflection. Wire runs as a code generator, which means that the injector works without making calls to a runtime library. This enables easier introspection of initialization and correct cross-references for tooling like [guru][]. [dig]: https://github.com/uber-go/dig [facebookgo/inject]: https://github.com/facebookgo/inject [guru]: https://golang.org/s/using-guru ## How does Wire relate to other non-Go dependency injection tools (like Dagger 2)? Wire's approach was inspired by [Dagger 2][]. However, it is not the aim of Wire to emulate dependency injection tools from other languages: the design space and requirements are quite different. For example, the Go compiler does not support anything like Java's annotation processing mechanisms. The difference in languages and their idioms necessarily requires different approaches in primitives and API. [Dagger 2]: https://google.github.io/dagger/ ## Why use pseudo-functions to create provider sets or injectors? In the early prototypes, Wire directives were specially formatted comments. This seemed appealing at first glance as this meant no compile-time or runtime impact. However, this unstructured approach becomes opaque to other tooling not written for Wire. Tools like [`gorename`][] or [guru][] would not be able to recognize references to the identifiers existing in comments without being specially modified to understand Wire's comment format. By moving the references into no-op function calls, Wire interoperates seamlessly with other Go tooling. [`gorename`]: https://godoc.org/golang.org/x/tools/cmd/gorename ## What if my dependency graph has two dependencies of the same type? This most frequently appears with common types like `string`. An example of this problem would be: ```go type Foo struct { /* ... */ } type Bar struct { /* ... */ } func newFoo1() *Foo { /* ... */ } func newFoo2() *Foo { /* ... */ } func newBar(foo1 *Foo, foo2 *Foo) *Bar { /* ... */ } func inject() *Bar { // ERROR! Multiple providers for *Foo. wire.Build(newFoo1, newFoo2, newBar) return nil } ``` Wire does not allow multiple providers for one type to exist in the transitive closure of the providers presented to `wire.Build`, as this is usually a mistake. For legitimate cases where you need multiple dependencies of the same type, you need to invent a new type to call this other dependency. For example, you can name OAuth credentials after the service they connect to. Once you have a suitable different type, you can wrap and unwrap the type when plumbing it through Wire. Continuing our above example: ```go type OtherFoo Foo func newOtherFoo() *OtherFoo { // Call the original provider... foo := newFoo2() // ...then convert it to the new type. return (*OtherFoo)(foo) } func provideBar(foo1 *Foo, otherFoo *OtherFoo) *Bar { // Convert the new type into the unwrapped type... foo2 := (*Foo)(otherFoo) // ...then use it to call the original provider. return newBar(foo1, foo2) } func inject() *Bar { wire.Build(newFoo1, newOtherFoo, provideBar) return nil } ``` ## Why does Wire forbid including the same provider multiple times? Wire forbids this to remain consistent with the principle that specifying multiple providers for the same type is an error. On the surface, Wire could permit duplication, but this would introduce a few unintended consequences: - Wire would have to specify what kinds of duplicates are permissible: are two `wire.Value` calls ever considered to be the "same"? - If a provider set changes the function it uses to provide a type, then this could break an application, since it may introduce a new conflict between another provider set that was specifying the "same" provider. As such, we decided that the simpler behavior would be for this case to be an error, knowing we can always relax this restriction later. The user can always create a new provider set that does not have the conflicting type. A [proposed subtract command][] would automate the toil in this process. [proposed subtract command]: https://github.com/google/wire/issues/8 ## Should I use Wire for small applications? Probably not. Wire is designed to automate more intricate setup code found in larger applications. For small applications, hand-wiring dependencies is simpler. ## Who is using Wire? Wire is still fairly new and doesn't have a large user base yet. However, we have heard a lot of interest from Go users wanting to simplify their applications. If your project or company uses Wire, please let us know by either emailing us or sending a pull request amending this section. wire-0.4.0/docs/guide.md000066400000000000000000000251111357423046500150410ustar00rootroot00000000000000# Wire User Guide ## Basics Wire has two core concepts: providers and injectors. ### Defining Providers The primary mechanism in Wire is the **provider**: a function that can produce a value. These functions are ordinary Go code. ```go package foobarbaz type Foo struct { X int } // ProvideFoo returns a Foo. func ProvideFoo() Foo { return Foo{X: 42} } ``` Provider functions must be exported in order to be used from other packages, just like ordinary functions. Providers can specify dependencies with parameters: ```go package foobarbaz // ... type Bar struct { X int } // ProvideBar returns a Bar: a negative Foo. func ProvideBar(foo Foo) Bar { return Bar{X: -foo.X} } ``` Providers can also return errors: ```go package foobarbaz import ( "context" "errors" ) // ... type Baz struct { X int } // ProvideBaz returns a value if Bar is not zero. func ProvideBaz(ctx context.Context, bar Bar) (Baz, error) { if bar.X == 0 { return Baz{}, errors.New("cannot provide baz when bar is zero") } return Baz{X: bar.X}, nil } ``` Providers can be grouped into **provider sets**. This is useful if several providers will frequently be used together. To add these providers to a new set called `SuperSet`, use the `wire.NewSet` function: ```go package foobarbaz import ( // ... "github.com/google/wire" ) // ... var SuperSet = wire.NewSet(ProvideFoo, ProvideBar, ProvideBaz) ``` You can also add other provider sets into a provider set. ```go package foobarbaz import ( // ... "example.com/some/other/pkg" ) // ... var MegaSet = wire.NewSet(SuperSet, pkg.OtherSet) ``` ### Injectors An application wires up these providers with an **injector**: a function that calls providers in dependency order. With Wire, you write the injector's signature, then Wire generates the function's body. An injector is declared by writing a function declaration whose body is a call to `wire.Build`. The return values don't matter as long as they are of the correct type. The values themselves will be ignored in the generated code. Let's say that the above providers were defined in a package called `example.com/foobarbaz`. The following would declare an injector to obtain a `Baz`: ```go // +build wireinject // The build tag makes sure the stub is not built in the final build. package main import ( "context" "github.com/google/wire" "example.com/foobarbaz" ) func initializeBaz(ctx context.Context) (foobarbaz.Baz, error) { wire.Build(foobarbaz.MegaSet) return foobarbaz.Baz{}, nil } ``` Like providers, injectors can be parameterized on inputs (which then get sent to providers) and can return errors. Arguments to `wire.Build` are the same as `wire.NewSet`: they form a provider set. This is the provider set that gets used during code generation for that injector. Any non-injector declarations found in a file with injectors will be copied into the generated file. You can generate the injector by invoking Wire in the package directory: ```shell wire ``` Wire will produce an implementation of the injector in a file called `wire_gen.go` that looks something like this: ```go // Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "example.com/foobarbaz" ) func initializeBaz(ctx context.Context) (foobarbaz.Baz, error) { foo := foobarbaz.ProvideFoo() bar := foobarbaz.ProvideBar(foo) baz, err := foobarbaz.ProvideBaz(ctx, bar) if err != nil { return 0, err } return baz, nil } ``` As you can see, the output is very close to what a developer would write themselves. Further, there is little dependency on Wire at runtime: all of the written code is just normal Go code, and can be used without Wire. Once `wire_gen.go` is created, you can regenerate it by running [`go generate`]. [`go generate`]: https://blog.golang.org/generate ## Advanced Features The following features all build on top of the concepts of providers and injectors. ### Binding Interfaces Frequently, dependency injection is used to bind a concrete implementation for an interface. Wire matches inputs to outputs via [type identity][], so the inclination might be to create a provider that returns an interface type. However, this would not be idiomatic, since the Go best practice is to [return concrete types][]. Instead, you can declare an interface binding in a provider set: ```go type Fooer interface { Foo() string } type MyFooer string func (b *MyFooer) Foo() string { return string(*b) } func provideMyFooer() *MyFooer { b := new(MyFooer) *b = "Hello, World!" return b } type Bar string func provideBar(f Fooer) string { // f will be a *MyFooer. return f.Foo() } var Set = wire.NewSet( provideMyFooer, wire.Bind(new(Fooer), new(*MyFooer)), provideBar) ``` The first argument to `wire.Bind` is a pointer to a value of the desired interface type and the second argument is a pointer to a value of the type that implements the interface. Any set that includes an interface binding must also have a provider in the same set that provides the concrete type. [type identity]: https://golang.org/ref/spec#Type_identity [return concrete types]: https://github.com/golang/go/wiki/CodeReviewComments#interfaces ### Struct Providers Structs can be constructed using provided types. Use the `wire.Struct` function to construct a struct type and tell the injector which field(s) should be injected. The injector will fill in each field using the provider for the field's type. For the resulting struct type `S`, `wire.Struct` provides both `S` and `*S`. For example, given the following providers: ```go type Foo int type Bar int func ProvideFoo() Foo {/* ... */} func ProvideBar() Bar {/* ... */} type FooBar struct { MyFoo Foo MyBar Bar } var Set = wire.NewSet( ProvideFoo, ProvideBar, wire.Struct(new(FooBar), "MyFoo", "MyBar")) ``` A generated injector for `FooBar` would look like this: ```go func injectFooBar() FooBar { foo := ProvideFoo() bar := ProvideBar() fooBar := FooBar{ MyFoo: foo, MyBar: bar, } return fooBar } ``` The first argument to `wire.Struct` is a pointer to the desired struct type and the subsequent arguments are the names of fields to be injected. A special string `"*"` can be used as a shortcut to tell the injector to inject all fields. So `wire.Struct(new(FooBar), "*")` produces the same result as above. For the above example, you can specify only injecting `"MyFoo"` by changing the `Set` to: ```go var Set = wire.NewSet( ProvideFoo, wire.Struct(new(FooBar), "MyFoo")) ``` Then the generated injector for `FooBar` would look like this: ```go func injectFooBar() FooBar { foo := ProvideFoo() fooBar := FooBar{ MyFoo: foo, } return fooBar } ``` If the injector returned a `*FooBar` instead of a `FooBar`, the generated injector would look like this: ```go func injectFooBar() *FooBar { foo := ProvideFoo() fooBar := &FooBar{ MyFoo: foo, } return fooBar } ``` It is sometimes useful to prevent certain fields from being filled in by the injector, especially when passing `*` to `wire.Struct`. You can tag a field with `` `wire:"-"` `` to have Wire ignore such fields. For example: ```go type Foo struct { mu sync.Mutex `wire:"-"` Bar Bar } ``` When you provide the `Foo` type using `wire.Struct(new(Foo), "*")`, Wire will automatically omit the `mu` field. Additionally, it is an error to explicitly specify a prevented field as in `wire.Struct(new(Foo), "mu")`. ### Binding Values Occasionally, it is useful to bind a basic value (usually `nil`) to a type. Instead of having injectors depend on a throwaway provider function, you can add a value expression to a provider set. ```go type Foo struct { X int } func injectFoo() Foo { wire.Build(wire.Value(Foo{X: 42})) return Foo{} } ``` The generated injector would look like this: ```go func injectFoo() Foo { foo := _wireFooValue return foo } var ( _wireFooValue = Foo{X: 42} ) ``` It's important to note that the expression will be copied to the injector's package; references to variables will be evaluated during the injector package's initialization. Wire will emit an error if the expression calls any functions or receives from any channels. For interface values, use `InterfaceValue`: ```go func injectReader() io.Reader { wire.Build(wire.InterfaceValue(new(io.Reader), os.Stdin)) return nil } ``` ### Use Fields of a Struct as Providers Sometimes the providers the user wants are some fields of a struct. If you find yourself writing a provider like `getS` in the example below to promote struct fields into provided types: ```go type Foo struct { S string N int F float64 } func getS(foo Foo) string { // Bad! Use wire.FieldsOf instead. return foo.S } func provideFoo() Foo { return Foo{ S: "Hello, World!", N: 1, F: 3.14 } } func injectedMessage() string { wire.Build( provideFoo, getS, return "" } ``` You can instead use `wire.FieldsOf` to use those fields directly without writing `getS`: ```go func injectedMessage() string { wire.Build( provideFoo, wire.FieldsOf(new(Foo), "S")) return "" } ``` The generated injector would look like this: ```go func injectedMessage() string { foo := provideFoo() string2 := foo.S return string2 } ``` You can add as many field names to a `wire.FieldsOf` function as you like. For a given field type `T`, `FieldsOf` provides at least `T`; if the struct argument is a pointer to a struct, then `FieldsOf` also provides `*T`. ### Cleanup functions If a provider creates a value that needs to be cleaned up (e.g. closing a file), then it can return a closure to clean up the resource. The injector will use this to either return an aggregated cleanup function to the caller or to clean up the resource if a provider called later in the injector's implementation returns an error. ```go func provideFile(log Logger, path Path) (*os.File, func(), error) { f, err := os.Open(string(path)) if err != nil { return nil, nil, err } cleanup := func() { if err := f.Close(); err != nil { log.Log(err) } } return f, cleanup, nil } ``` A cleanup function is guaranteed to be called before the cleanup function of any of the provider's inputs and must have the signature `func()`. ### Alternate Injector Syntax If you grow weary of writing `return foobarbaz.Foo{}, nil` at the end of your injector function declaration, you can instead write it more concisely with a `panic`: ```go func injectFoo() Foo { panic(wire.Build(/* ... */)) } ``` wire-0.4.0/go.mod000066400000000000000000000003301357423046500135740ustar00rootroot00000000000000module github.com/google/wire go 1.12 require ( github.com/google/go-cmp v0.2.0 github.com/google/subcommands v1.0.1 github.com/pmezard/go-difflib v1.0.0 golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b ) wire-0.4.0/go.sum000066400000000000000000000021601357423046500136240ustar00rootroot00000000000000github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b h1:NVD8gBK33xpdqCaZVVtd6OFJp+3dxkXuz7+U7KaVN6s= golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= wire-0.4.0/internal/000077500000000000000000000000001357423046500143065ustar00rootroot00000000000000wire-0.4.0/internal/alldeps000066400000000000000000000001461357423046500156560ustar00rootroot00000000000000github.com/google/subcommands github.com/google/wire github.com/pmezard/go-difflib golang.org/x/tools wire-0.4.0/internal/check_api_change.sh000077500000000000000000000064371357423046500200720ustar00rootroot00000000000000#!/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 (TRAVIS_BRANCH). This is what Travis does (see # https://docs.travis-ci.com/user/pull-requests/ for details), but if you # are testing this script manually, you may need to manually create a merge # commit. set -euo pipefail UPSTREAM_BRANCH="${TRAVIS_BRANCH:-master}" echo "Checking for incompatible API changes relative to ${UPSTREAM_BRANCH}..." INSTALL_DIR="$(mktemp -d)" MASTER_CLONE_DIR="$(mktemp -d)" PKGINFO_BRANCH=$(mktemp) PKGINFO_MASTER=$(mktemp) function cleanup() { rm -rf "$INSTALL_DIR" rm -rf "$MASTER_CLONE_DIR" rm -f "$PKGINFO_BRANCH" rm -f "$PKGINFO_MASTER" } trap cleanup EXIT # Move to a temporary directory while installing apidiff to avoid changing # the local .mod file. ( cd "$INSTALL_DIR" && exec go mod init unused ) ( cd "$INSTALL_DIR" && exec go install golang.org/x/exp/cmd/apidiff ) 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 wire-0.4.0/internal/listdeps.sh000077500000000000000000000017511357423046500165000ustar00rootroot00000000000000#!/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 Travis # (see .travis.yml) when updating the alldeps file. go list -deps -f '{{with .Module}}{{.Path}}{{end}}' ./... | sort | uniq wire-0.4.0/internal/runtests.sh000077500000000000000000000052631357423046500165420ustar00rootroot00000000000000#!/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 [[ "${TRAVIS_OS_NAME:-}" == "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 TRAVIS_OS_NAME to "linux" so that we don't abort here when run locally. if [[ "${TRAVIS_OS_NAME:-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 if [[ $(go version) == *go1\.12* ]]; then 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 go version 1.12." result=1 } fi # For pull requests, check if there are undeclared incompatible API changes. # Skip this if we're already going to fail since it is expensive. if [[ ${result} -eq 0 ]] && [[ ! -z "${TRAVIS_BRANCH:-x}" ]] && [[ ! -z "${TRAVIS_PULL_REQUEST_SHA:-x}" ]]; then echo ./internal/check_api_change.sh || result=1; fi exit $result wire-0.4.0/internal/wire/000077500000000000000000000000001357423046500152545ustar00rootroot00000000000000wire-0.4.0/internal/wire/analyze.go000066400000000000000000000360101357423046500172460ustar00rootroot00000000000000// 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())) } wire-0.4.0/internal/wire/copyast.go000066400000000000000000000310501357423046500172640ustar00rootroot00000000000000// 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 } wire-0.4.0/internal/wire/errors.go000066400000000000000000000044331357423046500171230ustar00rootroot00000000000000// 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() } wire-0.4.0/internal/wire/parse.go000066400000000000000000001143521357423046500167230ustar00rootroot00000000000000// 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 ( "context" "errors" "fmt" "go/ast" "go/token" "go/types" "os" "reflect" "strconv" "strings" "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/packages" "golang.org/x/tools/go/types/typeutil" ) // A providerSetSrc captures the source for a type provided by a ProviderSet. // Exactly one of the fields will be set. type providerSetSrc struct { Provider *Provider Binding *IfaceBinding Value *Value Import *ProviderSet InjectorArg *InjectorArg Field *Field } // description returns a string describing the source of p, including line numbers. func (p *providerSetSrc) description(fset *token.FileSet, typ types.Type) string { quoted := func(s string) string { if s == "" { return "" } return fmt.Sprintf("%q ", s) } switch { case p.Provider != nil: kind := "provider" if p.Provider.IsStruct { kind = "struct provider" } return fmt.Sprintf("%s %s(%s)", kind, quoted(p.Provider.Name), fset.Position(p.Provider.Pos)) case p.Binding != nil: return fmt.Sprintf("wire.Bind (%s)", fset.Position(p.Binding.Pos)) case p.Value != nil: return fmt.Sprintf("wire.Value (%s)", fset.Position(p.Value.Pos)) case p.Import != nil: return fmt.Sprintf("provider set %s(%s)", quoted(p.Import.VarName), fset.Position(p.Import.Pos)) case p.InjectorArg != nil: args := p.InjectorArg.Args return fmt.Sprintf("argument %s to injector function %s (%s)", args.Tuple.At(p.InjectorArg.Index).Name(), args.Name, fset.Position(args.Pos)) case p.Field != nil: return fmt.Sprintf("wire.FieldsOf (%s)", fset.Position(p.Field.Pos)) } panic("providerSetSrc with no fields set") } // trace returns a slice of strings describing the (possibly recursive) source // of p, including line numbers. func (p *providerSetSrc) trace(fset *token.FileSet, typ types.Type) []string { var retval []string // Only Imports need recursion. if p.Import != nil { if parent := p.Import.srcMap.At(typ); parent != nil { retval = append(retval, parent.(*providerSetSrc).trace(fset, typ)...) } } retval = append(retval, p.description(fset, typ)) return retval } // A ProviderSet describes a set of providers. The zero value is an empty // ProviderSet. type ProviderSet struct { // Pos is the position of the call to wire.NewSet or wire.Build that // created the set. Pos token.Pos // PkgPath is the import path of the package that declared this set. PkgPath string // VarName is the variable name of the set, if it came from a package // variable. VarName string Providers []*Provider Bindings []*IfaceBinding Values []*Value Fields []*Field Imports []*ProviderSet // InjectorArgs is only filled in for wire.Build. InjectorArgs *InjectorArgs // providerMap maps from provided type to a *ProvidedType. // It includes all of the imported types. providerMap *typeutil.Map // srcMap maps from provided type to a *providerSetSrc capturing the // Provider, Binding, Value, or Import that provided the type. srcMap *typeutil.Map } // Outputs returns a new slice containing the set of possible types the // provider set can produce. The order is unspecified. func (set *ProviderSet) Outputs() []types.Type { return set.providerMap.Keys() } // For returns a ProvidedType for the given type, or the zero ProvidedType. func (set *ProviderSet) For(t types.Type) ProvidedType { pt := set.providerMap.At(t) if pt == nil { return ProvidedType{} } return *pt.(*ProvidedType) } // An IfaceBinding declares that a type should be used to satisfy inputs // of the given interface type. type IfaceBinding struct { // Iface is the interface type, which is what can be injected. Iface types.Type // Provided is always a type that is assignable to Iface. Provided types.Type // Pos is the position where the binding was declared. Pos token.Pos } // Provider records the signature of a provider. A provider is a // single Go object, either a function or a named struct type. type Provider struct { // Pkg is the package that the Go object resides in. Pkg *types.Package // Name is the name of the Go object. Name string // Pos is the source position of the func keyword or type spec // defining this provider. Pos token.Pos // Args is the list of data dependencies this provider has. Args []ProviderInput // Varargs is true if the provider function is variadic. Varargs bool // IsStruct is true if this provider is a named struct type. // Otherwise it's a function. IsStruct bool // Out is the set of types this provider produces. It will always // contain at least one type. Out []types.Type // HasCleanup reports whether the provider function returns a cleanup // function. (Always false for structs.) HasCleanup bool // HasErr reports whether the provider function can return an error. // (Always false for structs.) HasErr bool } // ProviderInput describes an incoming edge in the provider graph. type ProviderInput struct { Type types.Type // If the provider is a struct, FieldName will be the field name to set. FieldName string } // Value describes a value expression. type Value struct { // Pos is the source position of the expression defining this value. Pos token.Pos // Out is the type this value produces. Out types.Type // expr is the expression passed to wire.Value. expr ast.Expr // info is the type info for the expression. info *types.Info } // InjectorArg describes a specific argument passed to an injector function. type InjectorArg struct { // Args is the full set of arguments. Args *InjectorArgs // Index is the index into Args.Tuple for this argument. Index int } // InjectorArgs describes the arguments passed to an injector function. type InjectorArgs struct { // Name is the name of the injector function. Name string // Tuple represents the arguments. Tuple *types.Tuple // Pos is the source position of the injector function. Pos token.Pos } // Field describes a specific field selected from a struct. type Field struct { // Parent is the struct or pointer to the struct that the field belongs to. Parent types.Type // Name is the field name. Name string // Pkg is the package that the struct resides in. Pkg *types.Package // Pos is the source position of the field declaration. // defining these fields. Pos token.Pos // Out is the field's provided types. The first element provides the // field type. If the field is coming from a pointer to a struct, // there will be a second element providing a pointer to the field. Out []types.Type } // Load finds all the provider sets in the packages that match the given // patterns, as well as the provider sets' transitive dependencies. It // may return both errors and Info. The patterns are defined by the // underlying build system. For the go tool, this is described at // https://golang.org/cmd/go/#hdr-Package_lists_and_patterns // // wd is the working directory and env is the set of environment // variables to use when loading the packages specified by patterns. If // env is nil or empty, it is interpreted as an empty set of variables. // In case of duplicate environment variables, the last one in the list // takes precedence. func Load(ctx context.Context, wd string, env []string, patterns []string) (*Info, []error) { pkgs, errs := load(ctx, wd, env, patterns) if len(errs) > 0 { return nil, errs } if len(pkgs) == 0 { return new(Info), nil } fset := pkgs[0].Fset info := &Info{ Fset: fset, Sets: make(map[ProviderSetID]*ProviderSet), } oc := newObjectCache(pkgs) ec := new(errorCollector) for _, pkg := range pkgs { if isWireImport(pkg.PkgPath) { // The marker function package confuses analysis. continue } scope := pkg.Types.Scope() for _, name := range scope.Names() { obj := scope.Lookup(name) if !isProviderSetType(obj.Type()) { continue } item, errs := oc.get(obj) if len(errs) > 0 { ec.add(notePositionAll(fset.Position(obj.Pos()), errs)...) continue } pset := item.(*ProviderSet) // pset.Name may not equal name, since it could be an alias to // another provider set. id := ProviderSetID{ImportPath: pset.PkgPath, VarName: name} info.Sets[id] = pset } for _, f := range pkg.Syntax { for _, decl := range f.Decls { fn, ok := decl.(*ast.FuncDecl) if !ok { continue } buildCall, err := findInjectorBuild(pkg.TypesInfo, fn) if err != nil { ec.add(notePosition(fset.Position(fn.Pos()), fmt.Errorf("inject %s: %v", fn.Name.Name, err))) continue } if buildCall == nil { continue } sig := pkg.TypesInfo.ObjectOf(fn.Name).Type().(*types.Signature) ins, out, err := injectorFuncSignature(sig) if err != nil { if w, ok := err.(*wireErr); ok { ec.add(notePosition(w.position, fmt.Errorf("inject %s: %v", fn.Name.Name, w.error))) } else { ec.add(notePosition(fset.Position(fn.Pos()), fmt.Errorf("inject %s: %v", fn.Name.Name, err))) } continue } injectorArgs := &InjectorArgs{ Name: fn.Name.Name, Tuple: ins, Pos: fn.Pos(), } set, errs := oc.processNewSet(pkg.TypesInfo, pkg.PkgPath, buildCall, injectorArgs, "") if len(errs) > 0 { ec.add(notePositionAll(fset.Position(fn.Pos()), errs)...) continue } _, errs = solve(fset, out.out, ins, set) if len(errs) > 0 { ec.add(mapErrors(errs, func(e error) error { if w, ok := e.(*wireErr); ok { return notePosition(w.position, fmt.Errorf("inject %s: %v", fn.Name.Name, w.error)) } return notePosition(fset.Position(fn.Pos()), fmt.Errorf("inject %s: %v", fn.Name.Name, e)) })...) continue } info.Injectors = append(info.Injectors, &Injector{ ImportPath: pkg.PkgPath, FuncName: fn.Name.Name, }) } } } return info, ec.errors } // load typechecks the packages that match the given patterns and // includes source for all transitive dependencies. The patterns are // defined by the underlying build system. For the go tool, this is // described at https://golang.org/cmd/go/#hdr-Package_lists_and_patterns // // wd is the working directory and env is the set of environment // variables to use when loading the packages specified by patterns. If // env is nil or empty, it is interpreted as an empty set of variables. // In case of duplicate environment variables, the last one in the list // takes precedence. func load(ctx context.Context, wd string, env []string, patterns []string) ([]*packages.Package, []error) { cfg := &packages.Config{ Context: ctx, Mode: packages.LoadAllSyntax, Dir: wd, Env: env, BuildFlags: []string{"-tags=wireinject"}, // TODO(light): Use ParseFile to skip function bodies and comments in indirect packages. } escaped := make([]string, len(patterns)) for i := range patterns { escaped[i] = "pattern=" + patterns[i] } pkgs, err := packages.Load(cfg, escaped...) if err != nil { return nil, []error{err} } var errs []error for _, p := range pkgs { for _, e := range p.Errors { errs = append(errs, e) } } if len(errs) > 0 { return nil, errs } return pkgs, nil } // Info holds the result of Load. type Info struct { Fset *token.FileSet // Sets contains all the provider sets in the initial packages. Sets map[ProviderSetID]*ProviderSet // Injectors contains all the injector functions in the initial packages. // The order is undefined. Injectors []*Injector } // A ProviderSetID identifies a named provider set. type ProviderSetID struct { ImportPath string VarName string } // String returns the ID as ""path/to/pkg".Foo". func (id ProviderSetID) String() string { return strconv.Quote(id.ImportPath) + "." + id.VarName } // An Injector describes an injector function. type Injector struct { ImportPath string FuncName string } // String returns the injector name as ""path/to/pkg".Foo". func (in *Injector) String() string { return strconv.Quote(in.ImportPath) + "." + in.FuncName } // objectCache is a lazily evaluated mapping of objects to Wire structures. type objectCache struct { fset *token.FileSet packages map[string]*packages.Package objects map[objRef]objCacheEntry hasher typeutil.Hasher } type objRef struct { importPath string name string } type objCacheEntry struct { val interface{} // *Provider, *ProviderSet, *IfaceBinding, or *Value errs []error } func newObjectCache(pkgs []*packages.Package) *objectCache { if len(pkgs) == 0 { panic("object cache must have packages to draw from") } oc := &objectCache{ fset: pkgs[0].Fset, packages: make(map[string]*packages.Package), objects: make(map[objRef]objCacheEntry), hasher: typeutil.MakeHasher(), } // Depth-first search of all dependencies to gather import path to // packages.Package mapping. go/packages guarantees that for a single // call to packages.Load and an import path X, there will exist only // one *packages.Package value with PkgPath X. stk := append([]*packages.Package(nil), pkgs...) for len(stk) > 0 { p := stk[len(stk)-1] stk = stk[:len(stk)-1] if oc.packages[p.PkgPath] != nil { continue } oc.packages[p.PkgPath] = p for _, imp := range p.Imports { stk = append(stk, imp) } } return oc } // get converts a Go object into a Wire structure. It may return a *Provider, an // *IfaceBinding, a *ProviderSet, a *Value, or a []*Field. func (oc *objectCache) get(obj types.Object) (val interface{}, errs []error) { ref := objRef{ importPath: obj.Pkg().Path(), name: obj.Name(), } if ent, cached := oc.objects[ref]; cached { return ent.val, append([]error(nil), ent.errs...) } defer func() { oc.objects[ref] = objCacheEntry{ val: val, errs: append([]error(nil), errs...), } }() switch obj := obj.(type) { case *types.Var: spec := oc.varDecl(obj) if spec == nil || len(spec.Values) == 0 { return nil, []error{fmt.Errorf("%v is not a provider or a provider set", obj)} } var i int for i = range spec.Names { if spec.Names[i].Name == obj.Name() { break } } pkgPath := obj.Pkg().Path() return oc.processExpr(oc.packages[pkgPath].TypesInfo, pkgPath, spec.Values[i], obj.Name()) case *types.Func: return processFuncProvider(oc.fset, obj) default: return nil, []error{fmt.Errorf("%v is not a provider or a provider set", obj)} } } // varDecl finds the declaration that defines the given variable. func (oc *objectCache) varDecl(obj *types.Var) *ast.ValueSpec { // TODO(light): Walk files to build object -> declaration mapping, if more performant. // Recommended by https://golang.org/s/types-tutorial pkg := oc.packages[obj.Pkg().Path()] pos := obj.Pos() for _, f := range pkg.Syntax { tokenFile := oc.fset.File(f.Pos()) if base := tokenFile.Base(); base <= int(pos) && int(pos) < base+tokenFile.Size() { path, _ := astutil.PathEnclosingInterval(f, pos, pos) for _, node := range path { if spec, ok := node.(*ast.ValueSpec); ok { return spec } } } } return nil } // processExpr converts an expression into a Wire structure. It may return a // *Provider, an *IfaceBinding, a *ProviderSet, a *Value or a []*Field. func (oc *objectCache) processExpr(info *types.Info, pkgPath string, expr ast.Expr, varName string) (interface{}, []error) { exprPos := oc.fset.Position(expr.Pos()) expr = astutil.Unparen(expr) if obj := qualifiedIdentObject(info, expr); obj != nil { item, errs := oc.get(obj) return item, mapErrors(errs, func(err error) error { return notePosition(exprPos, err) }) } if call, ok := expr.(*ast.CallExpr); ok { fnObj := qualifiedIdentObject(info, call.Fun) if fnObj == nil || !isWireImport(fnObj.Pkg().Path()) { return nil, []error{notePosition(exprPos, errors.New("unknown pattern"))} } switch fnObj.Name() { case "NewSet": pset, errs := oc.processNewSet(info, pkgPath, call, nil, varName) return pset, notePositionAll(exprPos, errs) case "Bind": b, err := processBind(oc.fset, info, call) if err != nil { return nil, []error{notePosition(exprPos, err)} } return b, nil case "Value": v, err := processValue(oc.fset, info, call) if err != nil { return nil, []error{notePosition(exprPos, err)} } return v, nil case "InterfaceValue": v, err := processInterfaceValue(oc.fset, info, call) if err != nil { return nil, []error{notePosition(exprPos, err)} } return v, nil case "Struct": s, err := processStructProvider(oc.fset, info, call) if err != nil { return nil, []error{notePosition(exprPos, err)} } return s, nil case "FieldsOf": v, err := processFieldsOf(oc.fset, info, call) if err != nil { return nil, []error{notePosition(exprPos, err)} } return v, nil default: return nil, []error{notePosition(exprPos, errors.New("unknown pattern"))} } } if tn := structArgType(info, expr); tn != nil { p, errs := processStructLiteralProvider(oc.fset, tn) if len(errs) > 0 { return nil, notePositionAll(exprPos, errs) } return p, nil } return nil, []error{notePosition(exprPos, errors.New("unknown pattern"))} } func (oc *objectCache) processNewSet(info *types.Info, pkgPath string, call *ast.CallExpr, args *InjectorArgs, varName string) (*ProviderSet, []error) { // Assumes that call.Fun is wire.NewSet or wire.Build. pset := &ProviderSet{ Pos: call.Pos(), InjectorArgs: args, PkgPath: pkgPath, VarName: varName, } ec := new(errorCollector) for _, arg := range call.Args { item, errs := oc.processExpr(info, pkgPath, arg, "") if len(errs) > 0 { ec.add(errs...) continue } switch item := item.(type) { case *Provider: pset.Providers = append(pset.Providers, item) case *ProviderSet: pset.Imports = append(pset.Imports, item) case *IfaceBinding: pset.Bindings = append(pset.Bindings, item) case *Value: pset.Values = append(pset.Values, item) case []*Field: pset.Fields = append(pset.Fields, item...) default: panic("unknown item type") } } if len(ec.errors) > 0 { return nil, ec.errors } var errs []error pset.providerMap, pset.srcMap, errs = buildProviderMap(oc.fset, oc.hasher, pset) if len(errs) > 0 { return nil, errs } if errs := verifyAcyclic(pset.providerMap, oc.hasher); len(errs) > 0 { return nil, errs } return pset, nil } // structArgType attempts to interpret an expression as a simple struct type. // It assumes any parentheses have been stripped. func structArgType(info *types.Info, expr ast.Expr) *types.TypeName { lit, ok := expr.(*ast.CompositeLit) if !ok { return nil } tn, ok := qualifiedIdentObject(info, lit.Type).(*types.TypeName) if !ok { return nil } if _, isStruct := tn.Type().Underlying().(*types.Struct); !isStruct { return nil } return tn } // qualifiedIdentObject finds the object for an identifier or a // qualified identifier, or nil if the object could not be found. func qualifiedIdentObject(info *types.Info, expr ast.Expr) types.Object { switch expr := expr.(type) { case *ast.Ident: return info.ObjectOf(expr) case *ast.SelectorExpr: pkgName, ok := expr.X.(*ast.Ident) if !ok { return nil } if _, ok := info.ObjectOf(pkgName).(*types.PkgName); !ok { return nil } return info.ObjectOf(expr.Sel) default: return nil } } // processFuncProvider creates a provider for a function declaration. func processFuncProvider(fset *token.FileSet, fn *types.Func) (*Provider, []error) { sig := fn.Type().(*types.Signature) fpos := fn.Pos() providerSig, err := funcOutput(sig) if err != nil { return nil, []error{notePosition(fset.Position(fpos), fmt.Errorf("wrong signature for provider %s: %v", fn.Name(), err))} } params := sig.Params() provider := &Provider{ Pkg: fn.Pkg(), Name: fn.Name(), Pos: fn.Pos(), Args: make([]ProviderInput, params.Len()), Varargs: sig.Variadic(), Out: []types.Type{providerSig.out}, HasCleanup: providerSig.cleanup, HasErr: providerSig.err, } for i := 0; i < params.Len(); i++ { provider.Args[i] = ProviderInput{ Type: params.At(i).Type(), } for j := 0; j < i; j++ { if types.Identical(provider.Args[i].Type, provider.Args[j].Type) { return nil, []error{notePosition(fset.Position(fpos), fmt.Errorf("provider has multiple parameters of type %s", types.TypeString(provider.Args[j].Type, nil)))} } } } return provider, nil } func injectorFuncSignature(sig *types.Signature) (*types.Tuple, outputSignature, error) { out, err := funcOutput(sig) if err != nil { return nil, outputSignature{}, err } return sig.Params(), out, nil } type outputSignature struct { out types.Type cleanup bool err bool } // funcOutput validates an injector or provider function's return signature. func funcOutput(sig *types.Signature) (outputSignature, error) { results := sig.Results() switch results.Len() { case 0: return outputSignature{}, errors.New("no return values") case 1: return outputSignature{out: results.At(0).Type()}, nil case 2: out := results.At(0).Type() switch t := results.At(1).Type(); { case types.Identical(t, errorType): return outputSignature{out: out, err: true}, nil case types.Identical(t, cleanupType): return outputSignature{out: out, cleanup: true}, nil default: return outputSignature{}, fmt.Errorf("second return type is %s; must be error or func()", types.TypeString(t, nil)) } case 3: if t := results.At(1).Type(); !types.Identical(t, cleanupType) { return outputSignature{}, fmt.Errorf("second return type is %s; must be func()", types.TypeString(t, nil)) } if t := results.At(2).Type(); !types.Identical(t, errorType) { return outputSignature{}, fmt.Errorf("third return type is %s; must be error", types.TypeString(t, nil)) } return outputSignature{ out: results.At(0).Type(), cleanup: true, err: true, }, nil default: return outputSignature{}, errors.New("too many return values") } } // processStructLiteralProvider creates a provider for a named struct type. // It produces pointer and non-pointer variants via two values in Out. // // This is a copy of the old processStructProvider, which is deprecated now. // It will not support any new feature introduced after v0.2. Please use the new // wire.Struct syntax for those. func processStructLiteralProvider(fset *token.FileSet, typeName *types.TypeName) (*Provider, []error) { out := typeName.Type() st, ok := out.Underlying().(*types.Struct) if !ok { return nil, []error{fmt.Errorf("%v does not name a struct", typeName)} } pos := typeName.Pos() fmt.Fprintf(os.Stderr, "Warning: %v, see https://godoc.org/github.com/google/wire#Struct for more information.\n", notePosition(fset.Position(pos), fmt.Errorf("using struct literal to inject %s is deprecated and will be removed in the next release; use wire.Struct instead", typeName.Type()))) provider := &Provider{ Pkg: typeName.Pkg(), Name: typeName.Name(), Pos: pos, Args: make([]ProviderInput, st.NumFields()), IsStruct: true, Out: []types.Type{out, types.NewPointer(out)}, } for i := 0; i < st.NumFields(); i++ { f := st.Field(i) provider.Args[i] = ProviderInput{ Type: f.Type(), FieldName: f.Name(), } for j := 0; j < i; j++ { if types.Identical(provider.Args[i].Type, provider.Args[j].Type) { return nil, []error{notePosition(fset.Position(pos), fmt.Errorf("provider struct has multiple fields of type %s", types.TypeString(provider.Args[j].Type, nil)))} } } } return provider, nil } // processStructProvider creates a provider for a named struct type. // It produces pointer and non-pointer variants via two values in Out. func processStructProvider(fset *token.FileSet, info *types.Info, call *ast.CallExpr) (*Provider, error) { // Assumes that call.Fun is wire.Struct. if len(call.Args) < 1 { return nil, notePosition(fset.Position(call.Pos()), errors.New("call to Struct must specify the struct to be injected")) } const firstArgReqFormat = "first argument to Struct must be a pointer to a named struct; found %s" structType := info.TypeOf(call.Args[0]) structPtr, ok := structType.(*types.Pointer) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf(firstArgReqFormat, types.TypeString(structType, nil))) } st, ok := structPtr.Elem().Underlying().(*types.Struct) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf(firstArgReqFormat, types.TypeString(structPtr, nil))) } stExpr := call.Args[0].(*ast.CallExpr) typeName := qualifiedIdentObject(info, stExpr.Args[0]) // should be either an identifier or selector provider := &Provider{ Pkg: typeName.Pkg(), Name: typeName.Name(), Pos: typeName.Pos(), IsStruct: true, Out: []types.Type{structPtr.Elem(), structPtr}, } if allFields(call) { for i := 0; i < st.NumFields(); i++ { if isPrevented(st.Tag(i)) { continue } f := st.Field(i) provider.Args = append(provider.Args, ProviderInput{ Type: f.Type(), FieldName: f.Name(), }) } } else { provider.Args = make([]ProviderInput, len(call.Args)-1) for i := 1; i < len(call.Args); i++ { v, err := checkField(call.Args[i], st) if err != nil { return nil, notePosition(fset.Position(call.Pos()), err) } provider.Args[i-1] = ProviderInput{ Type: v.Type(), FieldName: v.Name(), } } } for i := 0; i < len(provider.Args); i++ { for j := 0; j < i; j++ { if types.Identical(provider.Args[i].Type, provider.Args[j].Type) { f := st.Field(j) return nil, notePosition(fset.Position(f.Pos()), fmt.Errorf("provider struct has multiple fields of type %s", types.TypeString(provider.Args[j].Type, nil))) } } } return provider, nil } func allFields(call *ast.CallExpr) bool { if len(call.Args) != 2 { return false } b, ok := call.Args[1].(*ast.BasicLit) if !ok { return false } return strings.EqualFold(strconv.Quote("*"), b.Value) } // isPrevented checks whether field i is prevented by tag "-". // Since this is the only tag used by wire, we can do string comparison // without using reflect. func isPrevented(tag string) bool { return reflect.StructTag(tag).Get("wire") == "-" } // processBind creates an interface binding from a wire.Bind call. func processBind(fset *token.FileSet, info *types.Info, call *ast.CallExpr) (*IfaceBinding, error) { // Assumes that call.Fun is wire.Bind. if len(call.Args) != 2 { return nil, notePosition(fset.Position(call.Pos()), errors.New("call to Bind takes exactly two arguments")) } // TODO(light): Verify that arguments are simple expressions. ifaceArgType := info.TypeOf(call.Args[0]) ifacePtr, ok := ifaceArgType.(*types.Pointer) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("first argument to Bind must be a pointer to an interface type; found %s", types.TypeString(ifaceArgType, nil))) } iface := ifacePtr.Elem() methodSet, ok := iface.Underlying().(*types.Interface) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("first argument to Bind must be a pointer to an interface type; found %s", types.TypeString(ifaceArgType, nil))) } provided := info.TypeOf(call.Args[1]) if bindShouldUsePointer(info, call) { providedPtr, ok := provided.(*types.Pointer) if !ok { return nil, notePosition(fset.Position(call.Args[0].Pos()), fmt.Errorf("second argument to Bind must be a pointer or a pointer to a pointer; found %s", types.TypeString(provided, nil))) } provided = providedPtr.Elem() } if types.Identical(iface, provided) { return nil, notePosition(fset.Position(call.Pos()), errors.New("cannot bind interface to itself")) } if !types.Implements(provided, methodSet) { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("%s does not implement %s", types.TypeString(provided, nil), types.TypeString(iface, nil))) } return &IfaceBinding{ Pos: call.Pos(), Iface: iface, Provided: provided, }, nil } // processValue creates a value from a wire.Value call. func processValue(fset *token.FileSet, info *types.Info, call *ast.CallExpr) (*Value, error) { // Assumes that call.Fun is wire.Value. if len(call.Args) != 1 { return nil, notePosition(fset.Position(call.Pos()), errors.New("call to Value takes exactly one argument")) } ok := true ast.Inspect(call.Args[0], func(node ast.Node) bool { switch expr := node.(type) { case nil, *ast.ArrayType, *ast.BasicLit, *ast.BinaryExpr, *ast.ChanType, *ast.CompositeLit, *ast.FuncType, *ast.Ident, *ast.IndexExpr, *ast.InterfaceType, *ast.KeyValueExpr, *ast.MapType, *ast.ParenExpr, *ast.SelectorExpr, *ast.SliceExpr, *ast.StarExpr, *ast.StructType, *ast.TypeAssertExpr: // Good! case *ast.UnaryExpr: if expr.Op == token.ARROW { ok = false return false } case *ast.CallExpr: // Only acceptable if it's a type conversion. if _, isFunc := info.TypeOf(expr.Fun).(*types.Signature); isFunc { ok = false return false } default: ok = false return false } return true }) if !ok { return nil, notePosition(fset.Position(call.Pos()), errors.New("argument to Value is too complex")) } // Result type can't be an interface type; use wire.InterfaceValue for that. argType := info.TypeOf(call.Args[0]) if _, isInterfaceType := argType.Underlying().(*types.Interface); isInterfaceType { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("argument to Value may not be an interface value (found %s); use InterfaceValue instead", types.TypeString(argType, nil))) } return &Value{ Pos: call.Args[0].Pos(), Out: info.TypeOf(call.Args[0]), expr: call.Args[0], info: info, }, nil } // processInterfaceValue creates a value from a wire.InterfaceValue call. func processInterfaceValue(fset *token.FileSet, info *types.Info, call *ast.CallExpr) (*Value, error) { // Assumes that call.Fun is wire.InterfaceValue. if len(call.Args) != 2 { return nil, notePosition(fset.Position(call.Pos()), errors.New("call to InterfaceValue takes exactly two arguments")) } ifaceArgType := info.TypeOf(call.Args[0]) ifacePtr, ok := ifaceArgType.(*types.Pointer) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("first argument to InterfaceValue must be a pointer to an interface type; found %s", types.TypeString(ifaceArgType, nil))) } iface := ifacePtr.Elem() methodSet, ok := iface.Underlying().(*types.Interface) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("first argument to InterfaceValue must be a pointer to an interface type; found %s", types.TypeString(ifaceArgType, nil))) } provided := info.TypeOf(call.Args[1]) if !types.Implements(provided, methodSet) { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("%s does not implement %s", types.TypeString(provided, nil), types.TypeString(iface, nil))) } return &Value{ Pos: call.Args[1].Pos(), Out: iface, expr: call.Args[1], info: info, }, nil } // processFieldsOf creates a slice of fields from a wire.FieldsOf call. func processFieldsOf(fset *token.FileSet, info *types.Info, call *ast.CallExpr) ([]*Field, error) { // Assumes that call.Fun is wire.FieldsOf. if len(call.Args) < 2 { return nil, notePosition(fset.Position(call.Pos()), errors.New("call to FieldsOf must specify fields to be extracted")) } const firstArgReqFormat = "first argument to FieldsOf must be a pointer to a struct or a pointer to a pointer to a struct; found %s" structType := info.TypeOf(call.Args[0]) structPtr, ok := structType.(*types.Pointer) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf(firstArgReqFormat, types.TypeString(structType, nil))) } var struc *types.Struct isPtrToStruct := false switch t := structPtr.Elem().Underlying().(type) { case *types.Pointer: struc, ok = t.Elem().Underlying().(*types.Struct) if !ok { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf(firstArgReqFormat, types.TypeString(struc, nil))) } isPtrToStruct = true case *types.Struct: struc = t default: return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf(firstArgReqFormat, types.TypeString(t, nil))) } if struc.NumFields() < len(call.Args)-1 { return nil, notePosition(fset.Position(call.Pos()), fmt.Errorf("fields number exceeds the number available in the struct which has %d fields", struc.NumFields())) } fields := make([]*Field, 0, len(call.Args)-1) for i := 1; i < len(call.Args); i++ { v, err := checkField(call.Args[i], struc) if err != nil { return nil, notePosition(fset.Position(call.Pos()), err) } out := []types.Type{v.Type()} if isPtrToStruct { // If the field is from a pointer to a struct, then // wire.Fields also provides a pointer to the field. out = append(out, types.NewPointer(v.Type())) } fields = append(fields, &Field{ Parent: structPtr.Elem(), Name: v.Name(), Pkg: v.Pkg(), Pos: v.Pos(), Out: out, }) } return fields, nil } // checkField reports whether f is a field of st. f should be a string with the // field name. func checkField(f ast.Expr, st *types.Struct) (*types.Var, error) { b, ok := f.(*ast.BasicLit) if !ok { return nil, fmt.Errorf("%v must be a string with the field name", f) } for i := 0; i < st.NumFields(); i++ { if strings.EqualFold(strconv.Quote(st.Field(i).Name()), b.Value) { if isPrevented(st.Tag(i)) { return nil, fmt.Errorf("%s is prevented from injecting by wire", b.Value) } return st.Field(i), nil } } return nil, fmt.Errorf("%s is not a field of %s", b.Value, st.String()) } // findInjectorBuild returns the wire.Build call if fn is an injector template. // It returns nil if the function is not an injector template. func findInjectorBuild(info *types.Info, fn *ast.FuncDecl) (*ast.CallExpr, error) { if fn.Body == nil { return nil, nil } numStatements := 0 invalid := false var wireBuildCall *ast.CallExpr for _, stmt := range fn.Body.List { switch stmt := stmt.(type) { case *ast.ExprStmt: numStatements++ if numStatements > 1 { invalid = true } call, ok := stmt.X.(*ast.CallExpr) if !ok { continue } if qualifiedIdentObject(info, call.Fun) == types.Universe.Lookup("panic") { if len(call.Args) != 1 { continue } call, ok = call.Args[0].(*ast.CallExpr) if !ok { continue } } buildObj := qualifiedIdentObject(info, call.Fun) if buildObj == nil || buildObj.Pkg() == nil || !isWireImport(buildObj.Pkg().Path()) || buildObj.Name() != "Build" { continue } wireBuildCall = call case *ast.EmptyStmt: // Do nothing. case *ast.ReturnStmt: // Allow the function to end in a return. if numStatements == 0 { return nil, nil } default: invalid = true } } if wireBuildCall == nil { return nil, nil } if invalid { return nil, errors.New("a call to wire.Build indicates that this function is an injector, but injectors must consist of only the wire.Build call and an optional return") } return wireBuildCall, nil } func isWireImport(path string) bool { // TODO(light): This is depending on details of the current loader. const vendorPart = "vendor/" if i := strings.LastIndex(path, vendorPart); i != -1 && (i == 0 || path[i-1] == '/') { path = path[i+len(vendorPart):] } return path == "github.com/google/wire" } func isProviderSetType(t types.Type) bool { n, ok := t.(*types.Named) if !ok { return false } obj := n.Obj() return obj.Pkg() != nil && isWireImport(obj.Pkg().Path()) && obj.Name() == "ProviderSet" } // ProvidedType represents a type provided from a source. The source // can be a *Provider (a provider function), a *Value (wire.Value), or an // *InjectorArgs (arguments to the injector function). The zero value has // none of the above, and returns true for IsNil. type ProvidedType struct { // t is the provided concrete type. t types.Type p *Provider v *Value a *InjectorArg f *Field } // IsNil reports whether pt is the zero value. func (pt ProvidedType) IsNil() bool { return pt.p == nil && pt.v == nil && pt.a == nil && pt.f == nil } // Type returns the output type. // // - For a function provider, this is the first return value type. // - For a struct provider, this is either the struct type or the pointer type // whose element type is the struct type. // - For a value, this is the type of the expression. // - For an argument, this is the type of the argument. func (pt ProvidedType) Type() types.Type { return pt.t } // IsProvider reports whether pt points to a Provider. func (pt ProvidedType) IsProvider() bool { return pt.p != nil } // IsValue reports whether pt points to a Value. func (pt ProvidedType) IsValue() bool { return pt.v != nil } // IsArg reports whether pt points to an injector argument. func (pt ProvidedType) IsArg() bool { return pt.a != nil } // IsField reports whether pt points to a Fields. func (pt ProvidedType) IsField() bool { return pt.f != nil } // Provider returns pt as a Provider pointer. It panics if pt does not point // to a Provider. func (pt ProvidedType) Provider() *Provider { if pt.p == nil { panic("ProvidedType does not hold a Provider") } return pt.p } // Value returns pt as a Value pointer. It panics if pt does not point // to a Value. func (pt ProvidedType) Value() *Value { if pt.v == nil { panic("ProvidedType does not hold a Value") } return pt.v } // Arg returns pt as an *InjectorArg representing an injector argument. It // panics if pt does not point to an arg. func (pt ProvidedType) Arg() *InjectorArg { if pt.a == nil { panic("ProvidedType does not hold an Arg") } return pt.a } // Field returns pt as a Field pointer. It panics if pt does not point to a // struct Field. func (pt ProvidedType) Field() *Field { if pt.f == nil { panic("ProvidedType does not hold a Field") } return pt.f } // bindShouldUsePointer loads the wire package the user is importing from their // injector. The call is a wire marker function call. func bindShouldUsePointer(info *types.Info, call *ast.CallExpr) bool { // These type assertions should not fail, otherwise panic. fun := call.Fun.(*ast.SelectorExpr) // wire.Bind pkgName := fun.X.(*ast.Ident) // wire wireName := info.ObjectOf(pkgName).(*types.PkgName) // wire package return wireName.Imported().Scope().Lookup("bindToUsePointer") != nil } wire-0.4.0/internal/wire/testdata/000077500000000000000000000000001357423046500170655ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArg/000077500000000000000000000000001357423046500220715ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArg/foo/000077500000000000000000000000001357423046500226545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArg/foo/foo.go000066400000000000000000000016031357423046500237660ustar00rootroot00000000000000// 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()} } wire-0.4.0/internal/wire/testdata/BindInjectorArg/foo/wire.go000066400000000000000000000014051357423046500241510ustar00rootroot00000000000000// 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/google/wire" ) func inject(foo Foo) *Bar { wire.Build( NewBar, wire.Bind(new(Fooer), new(Foo)), ) return nil } wire-0.4.0/internal/wire/testdata/BindInjectorArg/pkg000066400000000000000000000000201357423046500225650ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/BindInjectorArg/want/000077500000000000000000000000001357423046500230425ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArg/want/program_out.txt000066400000000000000000000000061357423046500261350ustar00rootroot00000000000000hello wire-0.4.0/internal/wire/testdata/BindInjectorArg/want/wire_gen.go000066400000000000000000000002721357423046500251710ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func inject(foo Foo) *Bar { bar := NewBar(foo) return bar } wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/000077500000000000000000000000001357423046500234325ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/foo/000077500000000000000000000000001357423046500242155ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/foo/foo.go000066400000000000000000000016051357423046500253310ustar00rootroot00000000000000// 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()} } wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/foo/wire.go000066400000000000000000000014071357423046500255140ustar00rootroot00000000000000// 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/google/wire" ) func inject(foo *Foo) *Bar { wire.Build( NewBar, wire.Bind(new(Fooer), new(*Foo)), ) return nil } wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/pkg000066400000000000000000000000201357423046500241260ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/want/000077500000000000000000000000001357423046500244035ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/want/program_out.txt000066400000000000000000000000061357423046500274760ustar00rootroot00000000000000hello wire-0.4.0/internal/wire/testdata/BindInjectorArgPointer/want/wire_gen.go000066400000000000000000000002731357423046500265330ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func inject(foo *Foo) *Bar { bar := NewBar(foo) return bar } wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/000077500000000000000000000000001357423046500234135ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/foo/000077500000000000000000000000001357423046500241765ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/foo/foo.go000066400000000000000000000012421357423046500253070ustar00rootroot00000000000000// 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!")) } wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/foo/wire.go000066400000000000000000000014501357423046500254730ustar00rootroot00000000000000// Copyright 2018 The Wire Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //+build wireinject package main import ( "io" "os" "github.com/google/wire" ) func inject() io.Writer { wire.Build( wire.Value(os.Stdout), wire.Bind(new(io.Writer), new(*os.File)), ) return nil } wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/pkg000066400000000000000000000000201357423046500241070ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/want/000077500000000000000000000000001357423046500243645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/want/program_out.txt000066400000000000000000000000151357423046500274570ustar00rootroot00000000000000Hello, World!wire-0.4.0/internal/wire/testdata/BindInterfaceWithValue/want/wire_gen.go000066400000000000000000000003721357423046500265140ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "io" "os" ) // Injectors from wire.go: func inject() io.Writer { file := _wireFileValue return file } var ( _wireFileValue = os.Stdout ) wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/000077500000000000000000000000001357423046500230335ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/bar/000077500000000000000000000000001357423046500235775ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/bar/bar.go000066400000000000000000000015251357423046500246750ustar00rootroot00000000000000// 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/google/wire" // Set provides an unfriendly user greeting. var Set = wire.NewSet(wire.Value("Bah humbug! This is the wrong variant!")) wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/bar/bar_inject.go000066400000000000000000000013631357423046500262310ustar00rootroot00000000000000// 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/google/wire" // Set provides a friendly user greeting. var Set = wire.NewSet(wire.Value("Hello, World!")) wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/foo/000077500000000000000000000000001357423046500236165ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/foo/foo.go000066400000000000000000000012371357423046500247330ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/foo/wire.go000066400000000000000000000013611357423046500251140ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(bar.Set) return "" } wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/pkg000066400000000000000000000000201357423046500235270ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/want/000077500000000000000000000000001357423046500240045ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/want/program_out.txt000066400000000000000000000000161357423046500271000ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/BuildTagsAllPackages/want/wire_gen.go000066400000000000000000000003701357423046500261320ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { string2 := _wireStringValue return string2 } var ( _wireStringValue = "Hello, World!" ) wire-0.4.0/internal/wire/testdata/Chain/000077500000000000000000000000001357423046500201075ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Chain/foo/000077500000000000000000000000001357423046500206725ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Chain/foo/foo.go000066400000000000000000000015651357423046500220130ustar00rootroot00000000000000// 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/google/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 } wire-0.4.0/internal/wire/testdata/Chain/foo/wire.go000066400000000000000000000013261357423046500221710ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() FooBar { wire.Build(Set) return 0 } wire-0.4.0/internal/wire/testdata/Chain/pkg000066400000000000000000000000201357423046500206030ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/Chain/want/000077500000000000000000000000001357423046500210605ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Chain/want/program_out.txt000066400000000000000000000000031357423046500241500ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/Chain/want/wire_gen.go000066400000000000000000000003351357423046500232070ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar() FooBar { foo := provideFoo() fooBar := provideFooBar(foo) return fooBar } wire-0.4.0/internal/wire/testdata/Cleanup/000077500000000000000000000000001357423046500204545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Cleanup/foo/000077500000000000000000000000001357423046500212375ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Cleanup/foo/foo.go000066400000000000000000000017711357423046500223570ustar00rootroot00000000000000// 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 } } wire-0.4.0/internal/wire/testdata/Cleanup/foo/wire.go000066400000000000000000000013651357423046500225410ustar00rootroot00000000000000// 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/google/wire" ) func injectBar() (*Bar, func()) { wire.Build(provideFoo, provideBar) return nil, nil } wire-0.4.0/internal/wire/testdata/Cleanup/pkg000066400000000000000000000000201357423046500211500ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/Cleanup/want/000077500000000000000000000000001357423046500214255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Cleanup/want/program_out.txt000066400000000000000000000000051357423046500245170ustar00rootroot0000000000000077 0 wire-0.4.0/internal/wire/testdata/Cleanup/want/wire_gen.go000066400000000000000000000004221357423046500235510ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectBar() (*Bar, func()) { foo, cleanup := provideFoo() bar, cleanup2 := provideBar(foo) return bar, func() { cleanup2() cleanup() } } wire-0.4.0/internal/wire/testdata/CopyOtherDecls/000077500000000000000000000000001357423046500217545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/CopyOtherDecls/foo/000077500000000000000000000000001357423046500225375ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/CopyOtherDecls/foo/foo.go000066400000000000000000000017661357423046500236630ustar00rootroot00000000000000// 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/google/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 "" } wire-0.4.0/internal/wire/testdata/CopyOtherDecls/pkg000066400000000000000000000000201357423046500224500ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/CopyOtherDecls/want/000077500000000000000000000000001357423046500227255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/CopyOtherDecls/want/program_out.txt000066400000000000000000000000161357423046500260210ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/CopyOtherDecls/want/wire_gen.go000066400000000000000000000006111357423046500250510ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+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!" } wire-0.4.0/internal/wire/testdata/Cycle/000077500000000000000000000000001357423046500201245ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Cycle/foo/000077500000000000000000000000001357423046500207075ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Cycle/foo/foo.go000066400000000000000000000015011357423046500220160ustar00rootroot00000000000000// 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 } wire-0.4.0/internal/wire/testdata/Cycle/foo/wire.go000066400000000000000000000013611357423046500222050ustar00rootroot00000000000000// 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/google/wire" ) func injectedBaz() Baz { wire.Build(provideFoo, provideBar, provideBaz) return 0 } wire-0.4.0/internal/wire/testdata/Cycle/pkg000066400000000000000000000000201357423046500206200ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/Cycle/want/000077500000000000000000000000001357423046500210755ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Cycle/want/wire_errs.txt000066400000000000000000000003531357423046500236400ustar00rootroot00000000000000example.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.Barwire-0.4.0/internal/wire/testdata/EmptyVar/000077500000000000000000000000001357423046500206345ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/EmptyVar/foo/000077500000000000000000000000001357423046500214175ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/EmptyVar/foo/foo.go000066400000000000000000000012741357423046500225350ustar00rootroot00000000000000// 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{} wire-0.4.0/internal/wire/testdata/EmptyVar/foo/wire.go000066400000000000000000000013401357423046500227120ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(myFakeSet) return "" } wire-0.4.0/internal/wire/testdata/EmptyVar/pkg000066400000000000000000000000201357423046500213300ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/EmptyVar/want/000077500000000000000000000000001357423046500216055ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/EmptyVar/want/wire_errs.txt000066400000000000000000000001471357423046500243510ustar00rootroot00000000000000example.com/foo/wire.go:x:y: var example.com/foo.myFakeSet struct{} is not a provider or a provider setwire-0.4.0/internal/wire/testdata/ExampleWithMocks/000077500000000000000000000000001357423046500223115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExampleWithMocks/foo/000077500000000000000000000000001357423046500230745ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExampleWithMocks/foo/foo.go000066400000000000000000000067301357423046500242140ustar00rootroot00000000000000// 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/google/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 } wire-0.4.0/internal/wire/testdata/ExampleWithMocks/foo/wire.go000066400000000000000000000023251357423046500243730ustar00rootroot00000000000000// 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/google/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 } wire-0.4.0/internal/wire/testdata/ExampleWithMocks/pkg000066400000000000000000000000201357423046500230050ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ExampleWithMocks/want/000077500000000000000000000000001357423046500232625ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExampleWithMocks/want/program_out.txt000066400000000000000000000004101357423046500263540ustar00rootroot00000000000000Real 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 wire-0.4.0/internal/wire/testdata/ExampleWithMocks/want/wire_gen.go000066400000000000000000000013221357423046500254060ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func initApp() *app { mainTimer := _wireRealTimeValue mainGreeter := greeter{ T: mainTimer, } mainApp := &app{ g: mainGreeter, } return mainApp } var ( _wireRealTimeValue = realTime{} ) func initMockedAppFromArgs(mt timer) *app { mainGreeter := greeter{ T: mt, } mainApp := &app{ g: mainGreeter, } return mainApp } func initMockedApp() *appWithMocks { mainMockTimer := newMockTimer() mainGreeter := greeter{ T: mainMockTimer, } mainApp := app{ g: mainGreeter, } mainAppWithMocks := &appWithMocks{ app: mainApp, mt: mainMockTimer, } return mainAppWithMocks } wire-0.4.0/internal/wire/testdata/ExportedValue/000077500000000000000000000000001357423046500216545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValue/bar/000077500000000000000000000000001357423046500224205ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValue/bar/bar.go000066400000000000000000000013041357423046500235110ustar00rootroot00000000000000// 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/google/wire" var Value = wire.Value(PublicMsg) var PublicMsg = "Hello, World!" wire-0.4.0/internal/wire/testdata/ExportedValue/foo/000077500000000000000000000000001357423046500224375ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValue/foo/foo.go000066400000000000000000000012371357423046500235540ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/ExportedValue/foo/wire.go000066400000000000000000000013631357423046500237370ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(bar.Value) return "" } wire-0.4.0/internal/wire/testdata/ExportedValue/pkg000066400000000000000000000000201357423046500223500ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ExportedValue/want/000077500000000000000000000000001357423046500226255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValue/want/program_out.txt000066400000000000000000000000161357423046500257210ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/ExportedValue/want/wire_gen.go000066400000000000000000000004251357423046500247540ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "example.com/bar" ) // Injectors from wire.go: func injectedMessage() string { string2 := _wireStringValue return string2 } var ( _wireStringValue = bar.PublicMsg ) wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/000077500000000000000000000000001357423046500247575ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/bar/000077500000000000000000000000001357423046500255235ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/bar/bar.go000066400000000000000000000012571357423046500266230ustar00rootroot00000000000000// 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/google/wire" ) var Value = wire.Value(os.Stdout) wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/foo/000077500000000000000000000000001357423046500255425ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/foo/foo.go000066400000000000000000000012561357423046500266600ustar00rootroot00000000000000// 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!") } wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/foo/wire.go000066400000000000000000000013721357423046500270420ustar00rootroot00000000000000// 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/google/wire" ) func injectedFile() *os.File { wire.Build(bar.Value) return nil } wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/pkg000066400000000000000000000000201357423046500254530ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/want/000077500000000000000000000000001357423046500257305ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/want/program_out.txt000066400000000000000000000000161357423046500310240ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/ExportedValueDifferentPackage/want/wire_gen.go000066400000000000000000000003711357423046500300570ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "os" ) // Injectors from wire.go: func injectedFile() *os.File { file := _wireFileValue return file } var ( _wireFileValue = os.Stdout ) wire-0.4.0/internal/wire/testdata/FieldsOfCycle/000077500000000000000000000000001357423046500215405ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfCycle/foo/000077500000000000000000000000001357423046500223235ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfCycle/foo/foo.go000066400000000000000000000014601357423046500234360ustar00rootroot00000000000000// 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{} } wire-0.4.0/internal/wire/testdata/FieldsOfCycle/foo/wire.go000066400000000000000000000014041357423046500236170ustar00rootroot00000000000000// 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/google/wire" ) func injectedBaz() Baz { wire.Build(provideFoo, provideBar, wire.FieldsOf(new(Bar), "Bz")) return 0 } wire-0.4.0/internal/wire/testdata/FieldsOfCycle/pkg000066400000000000000000000000201357423046500222340ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/FieldsOfCycle/want/000077500000000000000000000000001357423046500225115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfCycle/want/wire_errs.txt000066400000000000000000000003471357423046500252570ustar00rootroot00000000000000example.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.Barwire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/000077500000000000000000000000001357423046500234715ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/bar/000077500000000000000000000000001357423046500242355ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/bar/bar.go000066400000000000000000000014521357423046500253320ustar00rootroot00000000000000// 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} } wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/baz/000077500000000000000000000000001357423046500242455ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/baz/baz.go000066400000000000000000000015561357423046500253570ustar00rootroot00000000000000// 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) } wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/foo/000077500000000000000000000000001357423046500242545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/foo/foo.go000066400000000000000000000013431357423046500253670ustar00rootroot00000000000000// 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} } wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/main/000077500000000000000000000000001357423046500244155ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/main/wire.go000066400000000000000000000020621357423046500257120ustar00rootroot00000000000000// 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/google/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()) } wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/pkg000066400000000000000000000000211357423046500241660ustar00rootroot00000000000000example.com/main wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/want/000077500000000000000000000000001357423046500244425ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/want/program_out.txt000066400000000000000000000000041357423046500275330ustar00rootroot000000000000001 2 wire-0.4.0/internal/wire/testdata/FieldsOfImportedStruct/want/wire_gen.go000066400000000000000000000011541357423046500265710ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+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()) } wire-0.4.0/internal/wire/testdata/FieldsOfStruct/000077500000000000000000000000001357423046500217655ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStruct/foo/000077500000000000000000000000001357423046500225505ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStruct/foo/foo.go000066400000000000000000000013651357423046500236670ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/FieldsOfStruct/foo/wire.go000066400000000000000000000014021357423046500240420ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build( provideS, wire.FieldsOf(new(S), "Foo")) return "" } wire-0.4.0/internal/wire/testdata/FieldsOfStruct/pkg000066400000000000000000000000201357423046500224610ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/FieldsOfStruct/want/000077500000000000000000000000001357423046500227365ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStruct/want/program_out.txt000066400000000000000000000000161357423046500260320ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/FieldsOfStruct/want/wire_gen.go000066400000000000000000000003211357423046500250600ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { s := provideS() string2 := s.Foo return string2 } wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/000077500000000000000000000000001357423046500262175ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/foo/000077500000000000000000000000001357423046500270025ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/foo/foo.go000066400000000000000000000014111357423046500301110ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/foo/wire.go000066400000000000000000000017261357423046500303050ustar00rootroot00000000000000// 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/google/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 } wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/pkg000066400000000000000000000000201357423046500267130ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/want/000077500000000000000000000000001357423046500271705ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStructDoNotProvidePtrToField/want/wire_errs.txt000066400000000000000000000001511357423046500317270ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectedMessagePtr: no provider found for *string, output of injectorwire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/000077500000000000000000000000001357423046500233265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/foo/000077500000000000000000000000001357423046500241115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/foo/foo.go000066400000000000000000000014531357423046500252260ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/foo/wire.go000066400000000000000000000015601357423046500254100ustar00rootroot00000000000000// 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/google/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 } wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/pkg000066400000000000000000000000201357423046500240220ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/want/000077500000000000000000000000001357423046500242775ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/want/program_out.txt000066400000000000000000000000471357423046500273770ustar00rootroot00000000000000Hello, World! pointer to Hello, World! wire-0.4.0/internal/wire/testdata/FieldsOfStructPointer/want/wire_gen.go000066400000000000000000000004541357423046500264300ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+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 } wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/000077500000000000000000000000001357423046500227625ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/bar/000077500000000000000000000000001357423046500235265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/bar/bar.go000066400000000000000000000014521357423046500246230ustar00rootroot00000000000000// 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} } wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/baz/000077500000000000000000000000001357423046500235365ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/baz/baz.go000066400000000000000000000015561357423046500246500ustar00rootroot00000000000000// 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) } wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/foo/000077500000000000000000000000001357423046500235455ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/foo/foo.go000066400000000000000000000013431357423046500246600ustar00rootroot00000000000000// 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} } wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/main/000077500000000000000000000000001357423046500237065ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/main/wire.go000066400000000000000000000020561357423046500252060ustar00rootroot00000000000000// 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/google/wire" ) func newBazService() *baz.Service { wire.Build( wire.Struct(new(baz.Service), "*"), wire.Value(&baz.Config{ Foo: &foo.Config{1}, Bar: &bar.Config{2}, }), wire.FieldsOf( new(*baz.Config), "Foo", "Bar", ), foo.New, bar.New, ) return nil } func main() { svc := newBazService() fmt.Println(svc.String()) } wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/pkg000066400000000000000000000000211357423046500234570ustar00rootroot00000000000000example.com/main wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/want/000077500000000000000000000000001357423046500237335ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/want/program_out.txt000066400000000000000000000000041357423046500270240ustar00rootroot000000000000001 2 wire-0.4.0/internal/wire/testdata/FieldsOfValueStruct/want/wire_gen.go000066400000000000000000000012101357423046500260530ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "example.com/bar" "example.com/baz" "example.com/foo" "fmt" ) // Injectors from wire.go: func newBazService() *baz.Service { config := _wireConfigValue fooConfig := config.Foo service := foo.New(fooConfig) barConfig := config.Bar barService := bar.New(barConfig, service) bazService := &baz.Service{ Foo: service, Bar: barService, } return bazService } var ( _wireConfigValue = &baz.Config{ Foo: &foo.Config{1}, Bar: &bar.Config{2}, } ) // wire.go: func main() { svc := newBazService() fmt.Println(svc.String()) } wire-0.4.0/internal/wire/testdata/FuncArgProvider/000077500000000000000000000000001357423046500221255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FuncArgProvider/foo/000077500000000000000000000000001357423046500227105ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FuncArgProvider/foo/foo.go000066400000000000000000000015431357423046500240250ustar00rootroot00000000000000// 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 := injectBar(func() *Foo { return &Foo{42} }) fmt.Println(bar.Name) } type Foo struct { Val int } type Bar struct { Name string } func NewBar(f *Foo) *Bar { return &Bar{Name: fmt.Sprintf("foo value %d", f.Val)} } wire-0.4.0/internal/wire/testdata/FuncArgProvider/foo/wire.go000066400000000000000000000014451357423046500242110ustar00rootroot00000000000000// 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/google/wire" ) func injectBar(fn func() *Foo) *Bar { // fails because it doesn't identify fn as a Provider; see #723. panic(wire.Build(fn, NewBar)) } wire-0.4.0/internal/wire/testdata/FuncArgProvider/pkg000066400000000000000000000000201357423046500226210ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/FuncArgProvider/want/000077500000000000000000000000001357423046500230765ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/FuncArgProvider/want/wire_errs.txt000066400000000000000000000001431357423046500256360ustar00rootroot00000000000000example.com/foo/wire.go:x:y: var fn func() *example.com/foo.Foo is not a provider or a provider setwire-0.4.0/internal/wire/testdata/Header/000077500000000000000000000000001357423046500202555ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Header/foo/000077500000000000000000000000001357423046500210405ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Header/foo/foo.go000066400000000000000000000013221357423046500221500ustar00rootroot00000000000000// 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(injectFoo()) } type Foo int func provideFoo() Foo { return 41 } wire-0.4.0/internal/wire/testdata/Header/foo/wire.go000066400000000000000000000013341357423046500223360ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() Foo { wire.Build(provideFoo) return Foo(0) } wire-0.4.0/internal/wire/testdata/Header/header000066400000000000000000000000441357423046500214260ustar00rootroot00000000000000// This is a sample header file. // wire-0.4.0/internal/wire/testdata/Header/pkg000066400000000000000000000000201357423046500207510ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/Header/want/000077500000000000000000000000001357423046500212265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Header/want/program_out.txt000066400000000000000000000000031357423046500243160ustar00rootroot0000000000000041 wire-0.4.0/internal/wire/testdata/Header/want/wire_gen.go000066400000000000000000000003321357423046500233520ustar00rootroot00000000000000// This is a sample header file. // // Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFoo() Foo { foo := provideFoo() return foo } wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/000077500000000000000000000000001357423046500237645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/bar/000077500000000000000000000000001357423046500245305ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/bar/bar.go000066400000000000000000000016571357423046500256340ustar00rootroot00000000000000// 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" "example.com/foo" "github.com/google/wire" ) func main() { fmt.Println(injectFooer().Foo()) } type Bar string func (b *Bar) Foo() string { return string(*b) } func provideBar() *Bar { b := new(Bar) *b = "Hello, World!" return b } var Set = wire.NewSet( provideBar, wire.Bind(new(foo.Fooer), new(*Bar))) wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/bar/wire.go000066400000000000000000000013551357423046500260310ustar00rootroot00000000000000// 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/foo" "github.com/google/wire" ) func injectFooer() foo.Fooer { wire.Build(Set) return nil } wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/foo/000077500000000000000000000000001357423046500245475ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/foo/foo.go000066400000000000000000000012071357423046500256610ustar00rootroot00000000000000// 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 foo type Fooer interface { Foo() string } wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/pkg000066400000000000000000000000201357423046500244600ustar00rootroot00000000000000example.com/bar wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/want/000077500000000000000000000000001357423046500247355ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/want/program_out.txt000066400000000000000000000000161357423046500300310ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/ImportedInterfaceBinding/want/wire_gen.go000066400000000000000000000003351357423046500270640ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "example.com/foo" ) // Injectors from wire.go: func injectFooer() foo.Fooer { bar := provideBar() return bar } wire-0.4.0/internal/wire/testdata/InjectInput/000077500000000000000000000000001357423046500213215ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectInput/foo/000077500000000000000000000000001357423046500221045ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectInput/foo/foo.go000066400000000000000000000016261357423046500232230ustar00rootroot00000000000000// 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/google/wire" ) func main() { fmt.Println(injectFooBar(40)) } type Foo int type Bar int type FooBar int var Set = wire.NewSet( provideBar, provideFooBar) func provideBar() Bar { return 2 } func provideFooBar(foo Foo, bar Bar) FooBar { return FooBar(foo) + FooBar(bar) } wire-0.4.0/internal/wire/testdata/InjectInput/foo/wire.go000066400000000000000000000013351357423046500234030ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar(foo Foo) FooBar { wire.Build(Set) return 0 } wire-0.4.0/internal/wire/testdata/InjectInput/pkg000066400000000000000000000000201357423046500220150ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InjectInput/want/000077500000000000000000000000001357423046500222725ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectInput/want/program_out.txt000066400000000000000000000000031357423046500253620ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/InjectInput/want/wire_gen.go000066400000000000000000000003511357423046500244170ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar(foo Foo) FooBar { bar := provideBar() fooBar := provideFooBar(foo, bar) return fooBar } wire-0.4.0/internal/wire/testdata/InjectInputConflict/000077500000000000000000000000001357423046500230035ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectInputConflict/foo/000077500000000000000000000000001357423046500235665ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectInputConflict/foo/foo.go000066400000000000000000000017611357423046500247050ustar00rootroot00000000000000// 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/google/wire" ) func main() { // I'm on the fence as to whether this should be an error (versus an // override). For now, I will make it an error that can be relaxed // later. fmt.Println(injectBar(40)) } type Foo int type Bar int var Set = wire.NewSet( provideFoo, provideBar) func provideFoo() Foo { return -888 } func provideBar(foo Foo) Bar { return 2 } wire-0.4.0/internal/wire/testdata/InjectInputConflict/foo/wire.go000066400000000000000000000013271357423046500250660ustar00rootroot00000000000000// 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/google/wire" ) func injectBar(foo Foo) Bar { wire.Build(Set) return 0 } wire-0.4.0/internal/wire/testdata/InjectInputConflict/pkg000066400000000000000000000000201357423046500234770ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InjectInputConflict/want/000077500000000000000000000000001357423046500237545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectInputConflict/want/wire_errs.txt000066400000000000000000000004171357423046500265200ustar00rootroot00000000000000example.com/foo/wire.go:x:y: multiple bindings for example.com/foo.Foo current: <- provider "provideFoo" (example.com/foo/foo.go:x:y) <- provider set "Set" (example.com/foo/foo.go:x:y) previous: <- argument foo to injector function injectBar (example.com/foo/wire.go:x:y)wire-0.4.0/internal/wire/testdata/InjectWithPanic/000077500000000000000000000000001357423046500221105ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectWithPanic/foo/000077500000000000000000000000001357423046500226735ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectWithPanic/foo/foo.go000066400000000000000000000014161357423046500240070ustar00rootroot00000000000000// 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()) } // provideMessage provides a friendly user greeting. func provideMessage() string { return "Hello, World!" } wire-0.4.0/internal/wire/testdata/InjectWithPanic/foo/wire.go000066400000000000000000000013411357423046500241670ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { panic(wire.Build(provideMessage)) } wire-0.4.0/internal/wire/testdata/InjectWithPanic/pkg000066400000000000000000000000201357423046500226040ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InjectWithPanic/want/000077500000000000000000000000001357423046500230615ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectWithPanic/want/program_out.txt000066400000000000000000000000161357423046500261550ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/InjectWithPanic/want/wire_gen.go000066400000000000000000000003131357423046500252040ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { string2 := provideMessage() return string2 } wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/000077500000000000000000000000001357423046500235045ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/foo/000077500000000000000000000000001357423046500242675ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/foo/foo.go000066400000000000000000000013701357423046500254020ustar00rootroot00000000000000// 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() { foo := injectFoo() fmt.Println(foo) } type Foo int func provideFoo() (Foo, func()) { return Foo(42), func() {} } wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/foo/wire.go000066400000000000000000000014261357423046500255670ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() Foo { // provideFoo returns a cleanup, but injectFoo does not. wire.Build(provideFoo) return Foo(0) } wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/pkg000066400000000000000000000000201357423046500242000ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/want/000077500000000000000000000000001357423046500244555ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectorMissingCleanup/want/wire_errs.txt000066400000000000000000000002161357423046500272160ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectFoo: provider for example.com/foo.Foo returns cleanup but injection does not return cleanup functionwire-0.4.0/internal/wire/testdata/InjectorMissingError/000077500000000000000000000000001357423046500232065ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectorMissingError/foo/000077500000000000000000000000001357423046500237715ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectorMissingError/foo/foo.go000066400000000000000000000013611357423046500251040ustar00rootroot00000000000000// 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() { foo := injectFoo() fmt.Println(foo) } type Foo int func provideFoo() (Foo, error) { return Foo(42), nil } wire-0.4.0/internal/wire/testdata/InjectorMissingError/foo/wire.go000066400000000000000000000014251357423046500252700ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() Foo { // provideFoo returns an error, but injectFoo does not. wire.Build(provideFoo) return Foo(0) } wire-0.4.0/internal/wire/testdata/InjectorMissingError/pkg000066400000000000000000000000201357423046500237020ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InjectorMissingError/want/000077500000000000000000000000001357423046500241575ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InjectorMissingError/want/wire_errs.txt000066400000000000000000000001771357423046500267260ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectFoo: provider for example.com/foo.Foo returns error but injection not allowed to failwire-0.4.0/internal/wire/testdata/InterfaceBinding/000077500000000000000000000000001357423046500222605ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBinding/foo/000077500000000000000000000000001357423046500230435ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBinding/foo/foo.go000066400000000000000000000017001357423046500241530ustar00rootroot00000000000000// 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/google/wire" ) func main() { fmt.Println(injectFooer().Foo()) } type Fooer interface { Foo() string } type Bar string func (b *Bar) Foo() string { return string(*b) } func provideBar() *Bar { b := new(Bar) *b = "Hello, World!" return b } var Set = wire.NewSet( provideBar, wire.Bind(new(Fooer), new(*Bar))) wire-0.4.0/internal/wire/testdata/InterfaceBinding/foo/wire.go000066400000000000000000000013261357423046500243420ustar00rootroot00000000000000// 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/google/wire" ) func injectFooer() Fooer { wire.Build(Set) return nil } wire-0.4.0/internal/wire/testdata/InterfaceBinding/pkg000066400000000000000000000000201357423046500227540ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceBinding/want/000077500000000000000000000000001357423046500232315ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBinding/want/program_out.txt000066400000000000000000000000161357423046500263250ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/InterfaceBinding/want/wire_gen.go000066400000000000000000000002721357423046500253600ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooer() Fooer { bar := provideBar() return bar } wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/000077500000000000000000000000001357423046500253105ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/foo/000077500000000000000000000000001357423046500260735ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/foo/foo.go000066400000000000000000000013161357423046500272060ustar00rootroot00000000000000// 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(injectFooer().Foo()) } type Fooer interface { Foo() string } wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/foo/wire.go000066400000000000000000000014401357423046500273670ustar00rootroot00000000000000// 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/google/wire" ) func injectFooer() Fooer { // wrong: string doesn't implement Fooer. wire.Build(wire.Bind(new(Fooer), new(string))) return nil } wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/pkg000066400000000000000000000000201357423046500260040ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/want/000077500000000000000000000000001357423046500262615ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingDoesntImplement/want/wire_errs.txt000066400000000000000000000001141357423046500310170ustar00rootroot00000000000000example.com/foo/wire.go:x:y: string does not implement example.com/foo.Fooerwire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/000077500000000000000000000000001357423046500243015ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/foo/000077500000000000000000000000001357423046500250645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/foo/foo.go000066400000000000000000000013161357423046500261770ustar00rootroot00000000000000// 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(injectFooer().Foo()) } type Fooer interface { Foo() string } wire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/foo/wire.go000066400000000000000000000014351357423046500263640ustar00rootroot00000000000000// 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/google/wire" ) func injectFooer() Fooer { // wrong: arg0 must be a pointer to an interface. wire.Build(wire.Bind("foo", "bar")) return nil } wire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/pkg000066400000000000000000000000201357423046500247750ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/want/000077500000000000000000000000001357423046500252525ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingInvalidArg0/want/wire_errs.txt000066400000000000000000000001501357423046500300100ustar00rootroot00000000000000example.com/foo/wire.go:x:y: first argument to Bind must be a pointer to an interface type; found stringwire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/000077500000000000000000000000001357423046500247245ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/foo/000077500000000000000000000000001357423046500255075ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/foo/foo.go000066400000000000000000000013161357423046500266220ustar00rootroot00000000000000// 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(injectFooer().Foo()) } type Fooer interface { Foo() string } wire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/foo/wire.go000066400000000000000000000014161357423046500270060ustar00rootroot00000000000000// 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/google/wire" ) func injectFooer() Fooer { // wrong: wire.Bind requires 2 args. wire.Build(wire.Bind(new(Fooer))) return nil } wire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/pkg000066400000000000000000000000201357423046500254200ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/want/000077500000000000000000000000001357423046500256755ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingNotEnoughArgs/want/wire_errs.txt000066400000000000000000000001031357423046500304310ustar00rootroot00000000000000example.com/foo/wire.go:x:y: too few arguments in call to wire.Bindwire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/000077500000000000000000000000001357423046500232645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/foo/000077500000000000000000000000001357423046500240475ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/foo/foo.go000066400000000000000000000023211357423046500251570ustar00rootroot00000000000000// 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 verifies that the concrete type is provided only once, even if an // interface additionally depends on it. package main import ( "fmt" "sync" ) func main() { injectFooBar() fmt.Println(provideBarCalls) } type Fooer interface { Foo() string } type Bar string type FooBar struct { Fooer Fooer Bar *Bar } func (b *Bar) Foo() string { return string(*b) } func provideBar() *Bar { mu.Lock() provideBarCalls++ mu.Unlock() b := new(Bar) *b = "Hello, World!" return b } var ( mu sync.Mutex provideBarCalls int ) func provideFooBar(fooer Fooer, bar *Bar) FooBar { return FooBar{fooer, bar} } wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/foo/wire.go000066400000000000000000000014371357423046500253510ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() FooBar { wire.Build( provideBar, provideFooBar, wire.Bind(new(Fooer), new(*Bar)), ) return FooBar{} } wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/pkg000066400000000000000000000000201357423046500237600ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/want/000077500000000000000000000000001357423046500242355ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/want/program_out.txt000066400000000000000000000000021357423046500273240ustar00rootroot000000000000001 wire-0.4.0/internal/wire/testdata/InterfaceBindingReuse/want/wire_gen.go000066400000000000000000000003421357423046500263620ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar() FooBar { bar := provideBar() fooBar := provideFooBar(bar, bar) return fooBar } wire-0.4.0/internal/wire/testdata/InterfaceValue/000077500000000000000000000000001357423046500217625ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValue/foo/000077500000000000000000000000001357423046500225455ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValue/foo/foo.go000066400000000000000000000013371357423046500236630ustar00rootroot00000000000000// 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" "io/ioutil" ) func main() { r := injectedReader() buf, _ := ioutil.ReadAll(r) fmt.Println(string(buf)) } wire-0.4.0/internal/wire/testdata/InterfaceValue/foo/wire.go000066400000000000000000000014611357423046500240440ustar00rootroot00000000000000// 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" "strings" "github.com/google/wire" ) func injectedReader() io.Reader { wire.Build(wire.InterfaceValue(new(io.Reader), strings.NewReader("hello world"))) return nil } wire-0.4.0/internal/wire/testdata/InterfaceValue/pkg000066400000000000000000000000201357423046500224560ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceValue/want/000077500000000000000000000000001357423046500227335ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValue/want/program_out.txt000066400000000000000000000000141357423046500260250ustar00rootroot00000000000000hello world wire-0.4.0/internal/wire/testdata/InterfaceValue/want/wire_gen.go000066400000000000000000000004461357423046500250650ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "io" "strings" ) // Injectors from wire.go: func injectedReader() io.Reader { reader := _wireReaderValue return reader } var ( _wireReaderValue = strings.NewReader("hello world") ) wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/000077500000000000000000000000001357423046500250125ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/foo/000077500000000000000000000000001357423046500255755ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/foo/foo.go000066400000000000000000000012371357423046500267120ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/foo/wire.go000066400000000000000000000014661357423046500271010ustar00rootroot00000000000000// 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/google/wire" "io" ) func injectedMessage() string { // wrong: string doesn't implement io.Reader. wire.Build(wire.InterfaceValue(new(io.Reader), "bar")) return "" } wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/pkg000066400000000000000000000000201357423046500255060ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/want/000077500000000000000000000000001357423046500257635ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueDoesntImplement/want/wire_errs.txt000066400000000000000000000001001357423046500305140ustar00rootroot00000000000000example.com/foo/wire.go:x:y: string does not implement io.Readerwire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/000077500000000000000000000000001357423046500240035ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/foo/000077500000000000000000000000001357423046500245665ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/foo/foo.go000066400000000000000000000012371357423046500257030ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/foo/wire.go000066400000000000000000000014531357423046500260660ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { // wrong: arg0 must be a pointer to an interface. wire.Build(wire.InterfaceValue("foo", "bar")) return "" } wire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/pkg000066400000000000000000000000201357423046500244770ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/want/000077500000000000000000000000001357423046500247545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueInvalidArg0/want/wire_errs.txt000066400000000000000000000001621357423046500275150ustar00rootroot00000000000000example.com/foo/wire.go:x:y: first argument to InterfaceValue must be a pointer to an interface type; found stringwire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/000077500000000000000000000000001357423046500244265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/foo/000077500000000000000000000000001357423046500252115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/foo/foo.go000066400000000000000000000012371357423046500263260ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/foo/wire.go000066400000000000000000000014341357423046500265100ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { // wrong: InterfaceValue requires 2 args. wire.Build(wire.InterfaceValue("foo")) return "" } wire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/pkg000066400000000000000000000000201357423046500251220ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/want/000077500000000000000000000000001357423046500253775ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InterfaceValueNotEnoughArgs/want/wire_errs.txt000066400000000000000000000001151357423046500301360ustar00rootroot00000000000000example.com/foo/wire.go:x:y: too few arguments in call to wire.InterfaceValuewire-0.4.0/internal/wire/testdata/InvalidInjector/000077500000000000000000000000001357423046500221515ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InvalidInjector/foo/000077500000000000000000000000001357423046500227345ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InvalidInjector/foo/foo.go000066400000000000000000000015001357423046500240420ustar00rootroot00000000000000// 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() { foo := injectFoo() bar := injectBar() fmt.Println(foo) fmt.Println(bar) } type Foo int type Bar int func provideFoo() Foo { return Foo(42) } func provideBar() Bar { return Bar(99) } wire-0.4.0/internal/wire/testdata/InvalidInjector/foo/wire.go000066400000000000000000000016321357423046500242330ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() Foo { // This non-call statement makes this an invalid injector. _ = 42 panic(wire.Build(provideFoo)) } func injectBar() Bar { // Two call statements are also invalid. panic(wire.Build(provideBar)) panic(wire.Build(provideBar)) } wire-0.4.0/internal/wire/testdata/InvalidInjector/pkg000066400000000000000000000000201357423046500226450ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/InvalidInjector/want/000077500000000000000000000000001357423046500231225ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/InvalidInjector/want/wire_errs.txt000066400000000000000000000004401357423046500256620ustar00rootroot00000000000000a call to wire.Build indicates that this function is an injector, but injectors must consist of only the wire.Build call and an optional return a call to wire.Build indicates that this function is an injector, but injectors must consist of only the wire.Build call and an optional returnwire-0.4.0/internal/wire/testdata/MultipleArgsSameType/000077500000000000000000000000001357423046500231455ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleArgsSameType/foo/000077500000000000000000000000001357423046500237305ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleArgsSameType/foo/foo.go000066400000000000000000000013771357423046500250520ustar00rootroot00000000000000// 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", "bar").A) } type Foo struct { A string } func provideFoo(a string) *Foo { return &Foo{A: a} } wire-0.4.0/internal/wire/testdata/MultipleArgsSameType/foo/wire.go000066400000000000000000000014151357423046500252260ustar00rootroot00000000000000// 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/google/wire" ) func inject(a, b string) *Foo { // fail: can't have two args of the same type. panic(wire.Build(provideFoo)) } wire-0.4.0/internal/wire/testdata/MultipleArgsSameType/pkg000066400000000000000000000000201357423046500236410ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/MultipleArgsSameType/want/000077500000000000000000000000001357423046500241165ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleArgsSameType/want/wire_errs.txt000066400000000000000000000003341357423046500266600ustar00rootroot00000000000000example.com/foo/wire.go:x:y: multiple bindings for string current: <- argument b to injector function inject (example.com/foo/wire.go:x:y) previous: <- argument a to injector function inject (example.com/foo/wire.go:x:y)wire-0.4.0/internal/wire/testdata/MultipleBindings/000077500000000000000000000000001357423046500223365ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleBindings/foo/000077500000000000000000000000001357423046500231215ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleBindings/foo/foo.go000066400000000000000000000020161357423046500242320ustar00rootroot00000000000000// 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 ( "io" "strings" "github.com/google/wire" ) type context struct{} func main() {} type Foo string type Bar io.Reader var Set = wire.NewSet(provideFoo) var SuperSet = wire.NewSet(Set) var SetWithDuplicateBindings = wire.NewSet(Set, SuperSet) func provideFoo() Foo { return Foo("foo") } func provideFooAgain() Foo { return Foo("foo foo") } func provideBar() Bar { return io.Reader(strings.NewReader("hello")) } wire-0.4.0/internal/wire/testdata/MultipleBindings/foo/wire.go000066400000000000000000000027671357423046500244320ustar00rootroot00000000000000// 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 ( "strings" "github.com/google/wire" ) func inject() Foo { // fail: provideFoo and provideFooAgain both provide Foo. panic(wire.Build(provideFoo, provideFooAgain)) } func injectFromSet() Foo { // fail: provideFoo is also provided by Set. panic(wire.Build(provideFoo, Set)) } func injectFromNestedSet() Foo { // fail: provideFoo is also provided by SuperSet, via Set. panic(wire.Build(provideFoo, SuperSet)) } func injectFromSetWithDuplicateBindings() Foo { // fail: DuplicateBindingsSet has two providers for Foo. panic(wire.Build(SetWithDuplicateBindings)) } func injectDuplicateValues() Foo { // fail: provideFoo and wire.Value both provide Foo. panic(wire.Build(provideFoo, wire.Value(Foo("foo")))) } func injectDuplicateInterface() Bar { // fail: provideBar and wire.Bind both provide Bar. panic(wire.Build(provideBar, wire.Bind(new(Bar), new(*strings.Reader)))) } wire-0.4.0/internal/wire/testdata/MultipleBindings/pkg000066400000000000000000000000201357423046500230320ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/MultipleBindings/want/000077500000000000000000000000001357423046500233075ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleBindings/want/wire_errs.txt000066400000000000000000000027601357423046500260560ustar00rootroot00000000000000example.com/foo/wire.go:x:y: multiple bindings for example.com/foo.Foo current: <- provider "provideFooAgain" (example.com/foo/foo.go:x:y) previous: <- provider "provideFoo" (example.com/foo/foo.go:x:y) example.com/foo/wire.go:x:y: multiple bindings for example.com/foo.Foo current: <- provider "provideFoo" (example.com/foo/foo.go:x:y) previous: <- provider "provideFoo" (example.com/foo/foo.go:x:y) <- provider set "Set" (example.com/foo/foo.go:x:y) example.com/foo/wire.go:x:y: multiple bindings for example.com/foo.Foo current: <- provider "provideFoo" (example.com/foo/foo.go:x:y) previous: <- provider "provideFoo" (example.com/foo/foo.go:x:y) <- provider set "Set" (example.com/foo/foo.go:x:y) <- provider set "SuperSet" (example.com/foo/foo.go:x:y) example.com/foo/foo.go:x:y: SetWithDuplicateBindings has multiple bindings for example.com/foo.Foo current: <- provider "provideFoo" (example.com/foo/foo.go:x:y) <- provider set "Set" (example.com/foo/foo.go:x:y) <- provider set "SuperSet" (example.com/foo/foo.go:x:y) previous: <- provider "provideFoo" (example.com/foo/foo.go:x:y) <- provider set "Set" (example.com/foo/foo.go:x:y) example.com/foo/wire.go:x:y: multiple bindings for example.com/foo.Foo current: <- wire.Value (example.com/foo/wire.go:x:y) previous: <- provider "provideFoo" (example.com/foo/foo.go:x:y) example.com/foo/wire.go:x:y: multiple bindings for example.com/foo.Bar current: <- wire.Bind (example.com/foo/wire.go:x:y) previous: <- provider "provideBar" (example.com/foo/foo.go:x:y)wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/000077500000000000000000000000001357423046500234155ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/foo/000077500000000000000000000000001357423046500242005ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/foo/foo.go000066400000000000000000000020061357423046500253100ustar00rootroot00000000000000// 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(injectMissingOutputType()) fmt.Println(injectMultipleMissingTypes()) fmt.Println(injectMissingRecursiveType()) } type Foo int type Bar int type Baz int func provideBaz(foo Foo, bar Bar) Baz { return 0 } type Zip int type Zap int type Zop int func provideZip(foo Foo) Zip { return 0 } func provideZap(zip Zip) Zap { return 0 } func provideZop(zap Zap) Zop { return 0 } wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/foo/wire.go000066400000000000000000000021701357423046500254750ustar00rootroot00000000000000// 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/google/wire" ) func injectMissingOutputType() Foo { // Error: no provider for Foo. wire.Build() return Foo(0) } func injectMultipleMissingTypes() Baz { // Error: provideBaz needs Foo and Bar, both missing. wire.Build(provideBaz) return Baz(0) } func injectMissingRecursiveType() Zop { // Error: // Zop -> Zap -> Zip -> Foo // provideZop needs Zap, provideZap needs Zip, provideZip needs Foo, // which is missing. wire.Build(provideZop, provideZap, provideZip) return Zop(0) } wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/pkg000066400000000000000000000000201357423046500241110ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/want/000077500000000000000000000000001357423046500243665ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleMissingInputs/want/wire_errs.txt000066400000000000000000000015371357423046500271360ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectMissingOutputType: no provider found for example.com/foo.Foo, output of injector example.com/foo/wire.go:x:y: inject injectMultipleMissingTypes: no provider found for example.com/foo.Foo needed by example.com/foo.Baz in provider "provideBaz" (example.com/foo/foo.go:x:y) example.com/foo/wire.go:x:y: inject injectMultipleMissingTypes: no provider found for example.com/foo.Bar needed by example.com/foo.Baz in provider "provideBaz" (example.com/foo/foo.go:x:y) example.com/foo/wire.go:x:y: inject injectMissingRecursiveType: no provider found for example.com/foo.Foo needed by example.com/foo.Zip in provider "provideZip" (example.com/foo/foo.go:x:y) needed by example.com/foo.Zap in provider "provideZap" (example.com/foo/foo.go:x:y) needed by example.com/foo.Zop in provider "provideZop" (example.com/foo/foo.go:x:y)wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/000077500000000000000000000000001357423046500236405ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/bar/000077500000000000000000000000001357423046500244045ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/bar/bar.go000066400000000000000000000014521357423046500255010ustar00rootroot00000000000000// 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 ( "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} } wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/baz/000077500000000000000000000000001357423046500244145ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/baz/baz.go000066400000000000000000000014521357423046500255210ustar00rootroot00000000000000// 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 baz import ( "example.com/bar" ) type Config struct { V int } type Service struct { Cfg *Config B *bar.Service } func New(cfg *Config, b *bar.Service) *Service { return &Service{Cfg: cfg, B: b} } wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/foo/000077500000000000000000000000001357423046500244235ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/foo/foo.go000066400000000000000000000013431357423046500255360ustar00rootroot00000000000000// 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 foo type Config struct { V int } type Service struct { Cfg *Config } func New(cfg *Config) *Service { return &Service{Cfg: cfg} } wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/main/000077500000000000000000000000001357423046500245645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/main/wire.go000066400000000000000000000026011357423046500260600ustar00rootroot00000000000000// 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 ( "fmt" "example.com/bar" "example.com/baz" "example.com/foo" "github.com/google/wire" ) type MainConfig struct { Foo *foo.Config Bar *bar.Config baz *baz.Config } type MainService struct { Foo *foo.Service Bar *bar.Service baz *baz.Service } func (m *MainService) String() string { return fmt.Sprintf("%d %d %d", m.Foo.Cfg.V, m.Bar.Cfg.V, m.baz.Cfg.V) } func newMainService(MainConfig) *MainService { wire.Build( wire.Struct(new(MainService), "Foo", "Bar", "baz"), wire.FieldsOf( new(MainConfig), "Foo", "Bar", "baz", ), foo.New, bar.New, baz.New, ) return nil } func main() { cfg := MainConfig{ Foo: &foo.Config{1}, Bar: &bar.Config{2}, baz: &baz.Config{3}, } svc := newMainService(cfg) fmt.Println(svc.String()) } wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/pkg000066400000000000000000000000211357423046500243350ustar00rootroot00000000000000example.com/main wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/want/000077500000000000000000000000001357423046500246115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/want/program_out.txt000066400000000000000000000000061357423046500277040ustar00rootroot000000000000001 2 3 wire-0.4.0/internal/wire/testdata/MultipleSimilarPackages/want/wire_gen.go000066400000000000000000000017751357423046500267510ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "example.com/bar" "example.com/baz" "example.com/foo" "fmt" ) // Injectors from wire.go: func newMainService(mainConfig MainConfig) *MainService { config := mainConfig.Foo service := foo.New(config) barConfig := mainConfig.Bar barService := bar.New(barConfig, service) bazConfig := mainConfig.baz bazService := baz.New(bazConfig, barService) mainService := &MainService{ Foo: service, Bar: barService, baz: bazService, } return mainService } // wire.go: type MainConfig struct { Foo *foo.Config Bar *bar.Config baz *baz.Config } type MainService struct { Foo *foo.Service Bar *bar.Service baz *baz.Service } func (m *MainService) String() string { return fmt.Sprintf("%d %d %d", m.Foo.Cfg.V, m.Bar.Cfg.V, m.baz.Cfg.V) } func main() { cfg := MainConfig{ Foo: &foo.Config{1}, Bar: &bar.Config{2}, baz: &baz.Config{3}, } svc := newMainService(cfg) fmt.Println(svc.String()) } wire-0.4.0/internal/wire/testdata/NamingWorstCase/000077500000000000000000000000001357423046500221315ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NamingWorstCase/foo/000077500000000000000000000000001357423046500227145ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NamingWorstCase/foo/foo.go000066400000000000000000000016161357423046500240320ustar00rootroot00000000000000// 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 ( stdcontext "context" "fmt" "os" ) type context struct{} func main() { c, err := inject(stdcontext.Background(), struct{}{}) if err != nil { fmt.Println("ERROR:", err) os.Exit(1) } fmt.Println(c) } func provide(ctx stdcontext.Context) (context, error) { return context{}, nil } wire-0.4.0/internal/wire/testdata/NamingWorstCase/foo/wire.go000066400000000000000000000014321357423046500242110ustar00rootroot00000000000000// 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 ( stdcontext "context" "github.com/google/wire" ) func inject(context stdcontext.Context, err struct{}) (context, error) { panic(wire.Build(provide)) } wire-0.4.0/internal/wire/testdata/NamingWorstCase/pkg000066400000000000000000000000201357423046500226250ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NamingWorstCase/want/000077500000000000000000000000001357423046500231025ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NamingWorstCase/want/program_out.txt000066400000000000000000000000031357423046500261720ustar00rootroot00000000000000{} wire-0.4.0/internal/wire/testdata/NamingWorstCase/want/wire_gen.go000066400000000000000000000005231357423046500252300ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( context2 "context" ) // Injectors from wire.go: func inject(context3 context2.Context, err2 struct{}) (context, error) { mainContext, err := provide(context3) if err != nil { return context{}, err } return mainContext, nil } wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/000077500000000000000000000000001357423046500235135ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/foo/000077500000000000000000000000001357423046500242765ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/foo/foo.go000066400000000000000000000026321357423046500254130ustar00rootroot00000000000000// 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 // This file is specifically designed to cause issues with copying the // AST, particularly with the identifier "context". package main import ( stdcontext "context" "fmt" "os" "reflect" "github.com/google/wire" ) type context struct{} func main() { if _, ok := reflect.TypeOf(context{}).MethodByName("Provide"); !ok { fmt.Println("ERROR: context.Provide renamed") os.Exit(1) } c, err := inject(stdcontext.Background(), struct{}{}) if err != nil { fmt.Println("ERROR:", err) os.Exit(1) } fmt.Println(c) } func Provide(context2 stdcontext.Context) (context, error) { var context3 = stdcontext.Background() _ = context2 _ = context3 return context{}, nil } func inject(context stdcontext.Context, err struct{}) (context, error) { panic(wire.Build(Provide)) } func (context) Provide() { } wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/pkg000066400000000000000000000000201357423046500242070ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/want/000077500000000000000000000000001357423046500244645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/want/program_out.txt000066400000000000000000000000031357423046500275540ustar00rootroot00000000000000{} wire-0.4.0/internal/wire/testdata/NamingWorstCaseAllInOne/want/wire_gen.go000066400000000000000000000015401357423046500266120ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( context2 "context" "fmt" "os" "reflect" ) // Injectors from foo.go: func inject(context3 context2.Context, err2 struct{}) (context, error) { mainContext, err := Provide(context3) if err != nil { return context{}, err } return mainContext, nil } // foo.go: type context struct{} func main() { if _, ok := reflect.TypeOf(context{}).MethodByName("Provide"); !ok { fmt.Println("ERROR: context.Provide renamed") os.Exit(1) } c, err := inject(context2.Background(), struct{}{}) if err != nil { fmt.Println("ERROR:", err) os.Exit(1) } fmt.Println(c) } func Provide(context2_2 context2.Context) (context, error) { var context3 = context2.Background() _ = context2_2 _ = context3 return context{}, nil } func (context) Provide() { } wire-0.4.0/internal/wire/testdata/NiladicIdentity/000077500000000000000000000000001357423046500221425ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NiladicIdentity/foo/000077500000000000000000000000001357423046500227255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NiladicIdentity/foo/foo.go000066400000000000000000000014161357423046500240410ustar00rootroot00000000000000// 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()) } // provideMessage provides a friendly user greeting. func provideMessage() string { return "Hello, World!" } wire-0.4.0/internal/wire/testdata/NiladicIdentity/foo/wire.go000066400000000000000000000013451357423046500242250ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(provideMessage) return "" } wire-0.4.0/internal/wire/testdata/NiladicIdentity/pkg000066400000000000000000000000201357423046500226360ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NiladicIdentity/want/000077500000000000000000000000001357423046500231135ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NiladicIdentity/want/program_out.txt000066400000000000000000000000161357423046500262070ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/NiladicIdentity/want/wire_gen.go000066400000000000000000000003131357423046500252360ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { string2 := provideMessage() return string2 } wire-0.4.0/internal/wire/testdata/NiladicValue/000077500000000000000000000000001357423046500214255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NiladicValue/foo/000077500000000000000000000000001357423046500222105ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NiladicValue/foo/foo.go000066400000000000000000000012371357423046500233250ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/NiladicValue/foo/wire.go000066400000000000000000000013621357423046500235070ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(wire.Value("Hello, World!")) return "" } wire-0.4.0/internal/wire/testdata/NiladicValue/pkg000066400000000000000000000000201357423046500221210ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NiladicValue/want/000077500000000000000000000000001357423046500223765ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NiladicValue/want/program_out.txt000066400000000000000000000000161357423046500254720ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/NiladicValue/want/wire_gen.go000066400000000000000000000003701357423046500245240ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { string2 := _wireStringValue return string2 } var ( _wireStringValue = "Hello, World!" ) wire-0.4.0/internal/wire/testdata/NoImplicitInterface/000077500000000000000000000000001357423046500227555ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoImplicitInterface/foo/000077500000000000000000000000001357423046500235405ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoImplicitInterface/foo/foo.go000066400000000000000000000014761357423046500246620ustar00rootroot00000000000000// 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(injectFooer().Foo()) } type Fooer interface { Foo() string } type Bar string func (b Bar) Foo() string { return string(b) } func provideBar() Bar { return "Hello, World!" } wire-0.4.0/internal/wire/testdata/NoImplicitInterface/foo/wire.go000066400000000000000000000013351357423046500250370ustar00rootroot00000000000000// 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/google/wire" ) func injectFooer() Fooer { wire.Build(provideBar) return nil } wire-0.4.0/internal/wire/testdata/NoImplicitInterface/pkg000066400000000000000000000000201357423046500234510ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NoImplicitInterface/want/000077500000000000000000000000001357423046500237265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoImplicitInterface/want/wire_errs.txt000066400000000000000000000001601357423046500264650ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectFooer: no provider found for example.com/foo.Fooer, output of injectorwire-0.4.0/internal/wire/testdata/NoInjectParamNames/000077500000000000000000000000001357423046500225435ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoInjectParamNames/foo/000077500000000000000000000000001357423046500233265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoInjectParamNames/foo/foo.go000066400000000000000000000016161357423046500244440ustar00rootroot00000000000000// 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 ( stdcontext "context" "fmt" "os" ) type context struct{} func main() { c, err := inject(stdcontext.Background(), struct{}{}) if err != nil { fmt.Println("ERROR:", err) os.Exit(1) } fmt.Println(c) } func provide(ctx stdcontext.Context) (context, error) { return context{}, nil } wire-0.4.0/internal/wire/testdata/NoInjectParamNames/foo/wire.go000066400000000000000000000016061357423046500246260ustar00rootroot00000000000000// 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 ( stdcontext "context" "github.com/google/wire" ) // The notable characteristic of this test is that there are no // parameter names on the inject stub. func inject(stdcontext.Context, struct{}) (context, error) { wire.Build(provide) return context{}, nil } wire-0.4.0/internal/wire/testdata/NoInjectParamNames/pkg000066400000000000000000000000201357423046500232370ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NoInjectParamNames/want/000077500000000000000000000000001357423046500235145ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoInjectParamNames/want/program_out.txt000066400000000000000000000000031357423046500266040ustar00rootroot00000000000000{} wire-0.4.0/internal/wire/testdata/NoInjectParamNames/want/wire_gen.go000066400000000000000000000005361357423046500256460ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( context2 "context" ) // Injectors from wire.go: func inject(contextContext context2.Context, arg struct{}) (context, error) { mainContext, err := provide(contextContext) if err != nil { return context{}, err } return mainContext, nil } wire-0.4.0/internal/wire/testdata/NoopBuild/000077500000000000000000000000001357423046500207605ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoopBuild/foo/000077500000000000000000000000001357423046500215435ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoopBuild/foo/foo.go000066400000000000000000000012351357423046500226560ustar00rootroot00000000000000// 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("Hello, World!") } wire-0.4.0/internal/wire/testdata/NoopBuild/pkg000066400000000000000000000000201357423046500214540ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/NoopBuild/want/000077500000000000000000000000001357423046500217315ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/NoopBuild/want/program_out.txt000066400000000000000000000000161357423046500250250ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/NoopBuild/want/wire_gen.go000066400000000000000000000000001357423046500240450ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PartialCleanup/000077500000000000000000000000001357423046500217715ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PartialCleanup/foo/000077500000000000000000000000001357423046500225545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PartialCleanup/foo/foo.go000066400000000000000000000024741357423046500236750ustar00rootroot00000000000000// 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 ( "errors" "fmt" "strings" ) var ( cleanedFoo = false cleanedBar = false ) func main() { _, cleanup, err := injectBaz() if err == nil { fmt.Println("") } else { fmt.Println(strings.Contains(err.Error(), "bork!")) } fmt.Println(cleanedFoo, cleanedBar, cleanup == nil) } type Foo int type Bar int type Baz int func provideFoo() (*Foo, func()) { foo := new(Foo) *foo = 42 return foo, func() { *foo = 0; cleanedFoo = true } } func provideBar(foo *Foo) (*Bar, func(), error) { bar := new(Bar) *bar = 77 return bar, func() { if *foo == 0 { panic("foo cleaned up before bar") } *bar = 0 cleanedBar = true }, nil } func provideBaz(bar *Bar) (Baz, error) { return 0, errors.New("bork!") } wire-0.4.0/internal/wire/testdata/PartialCleanup/foo/wire.go000066400000000000000000000014121357423046500240470ustar00rootroot00000000000000// 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/google/wire" ) func injectBaz() (Baz, func(), error) { wire.Build(provideFoo, provideBar, provideBaz) return 0, nil, nil } wire-0.4.0/internal/wire/testdata/PartialCleanup/pkg000066400000000000000000000000201357423046500224650ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/PartialCleanup/want/000077500000000000000000000000001357423046500227425ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PartialCleanup/want/program_out.txt000066400000000000000000000000241357423046500260350ustar00rootroot00000000000000true true true true wire-0.4.0/internal/wire/testdata/PartialCleanup/want/wire_gen.go000066400000000000000000000006661357423046500251000ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectBaz() (Baz, func(), error) { foo, cleanup := provideFoo() bar, cleanup2, err := provideBar(foo) if err != nil { cleanup() return 0, nil, err } baz, err := provideBaz(bar) if err != nil { cleanup2() cleanup() return 0, nil, err } return baz, func() { cleanup2() cleanup() }, nil } wire-0.4.0/internal/wire/testdata/PkgImport/000077500000000000000000000000001357423046500210015ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PkgImport/anon1/000077500000000000000000000000001357423046500220155ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PkgImport/anon1/anon1.go000066400000000000000000000011411357423046500233550ustar00rootroot00000000000000// 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 anon1 wire-0.4.0/internal/wire/testdata/PkgImport/anon2/000077500000000000000000000000001357423046500220165ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PkgImport/anon2/anon2.go000066400000000000000000000011411357423046500233570ustar00rootroot00000000000000// 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 anon2 wire-0.4.0/internal/wire/testdata/PkgImport/bar/000077500000000000000000000000001357423046500215455ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PkgImport/bar/bar.go000066400000000000000000000012221357423046500226350ustar00rootroot00000000000000// 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 type Bar int func ProvideBar() Bar { return 1 } wire-0.4.0/internal/wire/testdata/PkgImport/foo/000077500000000000000000000000001357423046500215645ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PkgImport/foo/foo.go000066400000000000000000000016661357423046500227070ustar00rootroot00000000000000// 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" "example.com/bar" "github.com/google/wire" ) func main() { fmt.Println(injectFooBar()) } type Foo int type FooBar int var Set = wire.NewSet( provideFoo, bar.ProvideBar, provideFooBar) func provideFoo() Foo { return 41 } func provideFooBar(foo Foo, barVal bar.Bar) FooBar { return FooBar(foo) + FooBar(barVal) } wire-0.4.0/internal/wire/testdata/PkgImport/foo/wire.go000066400000000000000000000015231357423046500230620ustar00rootroot00000000000000// 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/anon1" // intentionally duplicated _ "example.com/anon1" // intentionally duplicated _ "example.com/anon2" "github.com/google/wire" ) func injectFooBar() FooBar { wire.Build(Set) return 0 } wire-0.4.0/internal/wire/testdata/PkgImport/pkg000066400000000000000000000000201357423046500214750ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/PkgImport/want/000077500000000000000000000000001357423046500217525ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/PkgImport/want/program_out.txt000066400000000000000000000000031357423046500250420ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/PkgImport/want/wire_gen.go000066400000000000000000000005321357423046500241000ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "example.com/bar" ) import ( _ "example.com/anon1" _ "example.com/anon2" ) // Injectors from wire.go: func injectFooBar() FooBar { foo := provideFoo() barBar := bar.ProvideBar() fooBar := provideFooBar(foo, barBar) return fooBar } wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/000077500000000000000000000000001357423046500265055ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/foo/000077500000000000000000000000001357423046500272705ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/foo/foo.go000066400000000000000000000022521357423046500304030ustar00rootroot00000000000000// 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" "github.com/google/wire" ) func main() { fmt.Println(injectFoo()) } type fooer interface { Do() string } type foo struct{} func (f *foo) Do() string { return "did foo" } func newFoo() *foo { return &foo{} } var ( setA = wire.NewSet(newFoo) // This set is invalid because it has a wire.Bind but no matching provider. // From the user guide: // Any set that includes an interface binding must also have a provider in // the same set that provides the concrete type. setB = wire.NewSet(wire.Bind(new(fooer), new(*foo))) setC = wire.NewSet(setA, setB) ) wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/foo/wire.go000066400000000000000000000013241357423046500305650ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() *foo { wire.Build(setC) return nil } wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/pkg000066400000000000000000000000201357423046500272010ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/want/000077500000000000000000000000001357423046500274565ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ProviderSetBindingMissingConcreteType/want/wire_errs.txt000066400000000000000000000002631357423046500322210ustar00rootroot00000000000000example.com/foo/foo.go:x:y: wire.Bind of concrete type "*example.com/foo.foo" to interface "example.com/foo.fooer", but setB does not include a provider for "*example.com/foo.foo"wire-0.4.0/internal/wire/testdata/RelativePkg/000077500000000000000000000000001357423046500213025ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/RelativePkg/foo/000077500000000000000000000000001357423046500220655ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/RelativePkg/foo/foo.go000066400000000000000000000014161357423046500232010ustar00rootroot00000000000000// 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()) } // provideMessage provides a friendly user greeting. func provideMessage() string { return "Hello, World!" } wire-0.4.0/internal/wire/testdata/RelativePkg/foo/wire.go000066400000000000000000000013451357423046500233650ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(provideMessage) return "" } wire-0.4.0/internal/wire/testdata/RelativePkg/pkg000066400000000000000000000000061357423046500220020ustar00rootroot00000000000000./foo wire-0.4.0/internal/wire/testdata/RelativePkg/want/000077500000000000000000000000001357423046500222535ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/RelativePkg/want/program_out.txt000066400000000000000000000000161357423046500253470ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/RelativePkg/want/wire_gen.go000066400000000000000000000003131357423046500243760ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { string2 := provideMessage() return string2 } wire-0.4.0/internal/wire/testdata/ReservedKeywords/000077500000000000000000000000001357423046500223745ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReservedKeywords/foo/000077500000000000000000000000001357423046500231575ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReservedKeywords/foo/foo.go000066400000000000000000000015211357423046500242700ustar00rootroot00000000000000// 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() { i := injectInterface() fmt.Println(i) } type Interface int type Select int func provideInterface(s Select) Interface { return Interface(int(s) + 1) } func provideSelect() Select { return Select(41) } wire-0.4.0/internal/wire/testdata/ReservedKeywords/foo/wire.go000066400000000000000000000020301357423046500244470ustar00rootroot00000000000000// 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/google/wire" ) // Wire tries to disambiguate the variable "select" by prepending // the package name; this package-scoped variable conflicts with that // and forces a different name. var mainSelect = 0 func injectInterface() Interface { // interface and select are Go reserved words, so // Wire should avoid using them as variable names. panic(wire.Build(provideInterface, provideSelect)) } wire-0.4.0/internal/wire/testdata/ReservedKeywords/pkg000066400000000000000000000000201357423046500230700ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ReservedKeywords/want/000077500000000000000000000000001357423046500233455ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReservedKeywords/want/program_out.txt000066400000000000000000000000031357423046500264350ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/ReservedKeywords/want/wire_gen.go000066400000000000000000000007101357423046500254710ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectInterface() Interface { select2 := provideSelect() mainInterface := provideInterface(select2) return mainInterface } // wire.go: // Wire tries to disambiguate the variable "select" by prepending // the package name; this package-scoped variable conflicts with that // and forces a different name. var mainSelect = 0 wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/000077500000000000000000000000001357423046500241545ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/foo/000077500000000000000000000000001357423046500247375ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/foo/foo.go000066400000000000000000000013731357423046500260550ustar00rootroot00000000000000// 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(injectStringer("Hello, World!")) } type MyString string func (s MyString) String() string { return string(s) } wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/foo/wire.go000066400000000000000000000014321357423046500262340ustar00rootroot00000000000000// 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" "github.com/google/wire" ) func injectStringer(s MyString) fmt.Stringer { wire.Build(wire.Bind(new(fmt.Stringer), new(MyString))) return nil } wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/pkg000066400000000000000000000000201357423046500246500ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/want/000077500000000000000000000000001357423046500251255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/want/program_out.txt000066400000000000000000000000161357423046500302210ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/ReturnArgumentAsInterface/want/wire_gen.go000066400000000000000000000003121357423046500272470ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( "fmt" ) // Injectors from wire.go: func injectStringer(s MyString) fmt.Stringer { return s } wire-0.4.0/internal/wire/testdata/ReturnError/000077500000000000000000000000001357423046500213565ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReturnError/foo/000077500000000000000000000000001357423046500221415ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReturnError/foo/foo.go000066400000000000000000000020341357423046500232520ustar00rootroot00000000000000// 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 ( "errors" "fmt" "strings" "github.com/google/wire" ) func main() { foo, err := injectFoo() fmt.Println(foo) // should be zero, the injector should ignore provideFoo's return value. if err == nil { fmt.Println("") } else { fmt.Println(strings.Contains(err.Error(), "there is no Foo")) } } type Foo int func provideFoo() (Foo, error) { return 42, errors.New("there is no Foo") } var Set = wire.NewSet(provideFoo) wire-0.4.0/internal/wire/testdata/ReturnError/foo/wire.go000066400000000000000000000013361357423046500234410ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() (Foo, error) { wire.Build(Set) return 0, nil } wire-0.4.0/internal/wire/testdata/ReturnError/pkg000066400000000000000000000000201357423046500220520ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ReturnError/want/000077500000000000000000000000001357423046500223275ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ReturnError/want/program_out.txt000066400000000000000000000000071357423046500254230ustar00rootroot000000000000000 true wire-0.4.0/internal/wire/testdata/ReturnError/want/wire_gen.go000066400000000000000000000003551357423046500244600ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFoo() (Foo, error) { foo, err := provideFoo() if err != nil { return 0, err } return foo, nil } wire-0.4.0/internal/wire/testdata/Struct/000077500000000000000000000000001357423046500203515ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Struct/foo/000077500000000000000000000000001357423046500211345ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Struct/foo/foo.go000066400000000000000000000021361357423046500222500ustar00rootroot00000000000000// 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" "sync" "github.com/google/wire" ) func main() { fb := injectFooBar() pfb := injectPartFooBar() fmt.Println(fb.Foo, fb.Bar) fmt.Println(pfb.Foo, pfb.Bar) } type Foo int type Bar int type FooBar struct { mu sync.Mutex `wire:"-"` Foo Foo Bar Bar } func provideFoo() Foo { return 41 } func provideBar() Bar { return 1 } var Set = wire.NewSet( wire.Struct(new(FooBar), "*"), provideFoo, provideBar) var PartSet = wire.NewSet( wire.Struct(new(FooBar), "Foo"), provideFoo, ) wire-0.4.0/internal/wire/testdata/Struct/foo/wire.go000066400000000000000000000014471357423046500224370ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() FooBar { wire.Build(Set) return FooBar{} } func injectPartFooBar() FooBar { wire.Build(PartSet) return FooBar{} } wire-0.4.0/internal/wire/testdata/Struct/pkg000066400000000000000000000000201357423046500210450ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/Struct/want/000077500000000000000000000000001357423046500213225ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Struct/want/program_out.txt000066400000000000000000000000121357423046500244120ustar00rootroot0000000000000041 1 41 0 wire-0.4.0/internal/wire/testdata/Struct/want/wire_gen.go000066400000000000000000000005541357423046500234540ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar() FooBar { foo := provideFoo() bar := provideBar() fooBar := FooBar{ Foo: foo, Bar: bar, } return fooBar } func injectPartFooBar() FooBar { foo := provideFoo() fooBar := FooBar{ Foo: foo, } return fooBar } wire-0.4.0/internal/wire/testdata/StructNotAStruct/000077500000000000000000000000001357423046500223405ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructNotAStruct/foo/000077500000000000000000000000001357423046500231235ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructNotAStruct/foo/foo.go000066400000000000000000000013021357423046500242310ustar00rootroot00000000000000// 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(A{"Hello"})) } type A struct { B string } wire-0.4.0/internal/wire/testdata/StructNotAStruct/foo/wire.go000066400000000000000000000013521357423046500244210ustar00rootroot00000000000000// 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/google/wire" ) func inject(a A) string { wire.Build(wire.Struct(new(*A), "*")) return "" } wire-0.4.0/internal/wire/testdata/StructNotAStruct/pkg000066400000000000000000000000201357423046500230340ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/StructNotAStruct/want/000077500000000000000000000000001357423046500233115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructNotAStruct/want/wire_errs.txt000066400000000000000000000001641357423046500260540ustar00rootroot00000000000000example.com/foo/wire.go:x:y: first argument to Struct must be a pointer to a named struct; found **example.com/foo.Awire-0.4.0/internal/wire/testdata/StructPointer/000077500000000000000000000000001357423046500217125ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructPointer/foo/000077500000000000000000000000001357423046500224755ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructPointer/foo/foo.go000066400000000000000000000017631357423046500236160ustar00rootroot00000000000000// 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/google/wire" ) func main() { fb := injectFooBar() e := injectEmptyStruct() fmt.Printf("%d %d %v\n", fb.Foo, fb.Bar, e) } type Foo int type Bar int type FooBar struct { Foo Foo Bar Bar } type Empty struct{} func provideFoo() Foo { return 41 } func provideBar() Bar { return 1 } var Set = wire.NewSet( wire.Struct(new(FooBar), "*"), provideFoo, provideBar) wire-0.4.0/internal/wire/testdata/StructPointer/foo/wire.go000066400000000000000000000014571357423046500240010ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() *FooBar { wire.Build(Set) return nil } func injectEmptyStruct() *Empty { wire.Build(wire.Struct(new(Empty))) return nil } wire-0.4.0/internal/wire/testdata/StructPointer/pkg000066400000000000000000000000201357423046500224060ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/StructPointer/want/000077500000000000000000000000001357423046500226635ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructPointer/want/program_out.txt000066400000000000000000000000111357423046500257520ustar00rootroot0000000000000041 1 &{} wire-0.4.0/internal/wire/testdata/StructPointer/want/wire_gen.go000066400000000000000000000005121357423046500250070ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar() *FooBar { foo := provideFoo() bar := provideBar() fooBar := &FooBar{ Foo: foo, Bar: bar, } return fooBar } func injectEmptyStruct() *Empty { empty := &Empty{} return empty } wire-0.4.0/internal/wire/testdata/StructWithPreventTag/000077500000000000000000000000001357423046500232055ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructWithPreventTag/foo/000077500000000000000000000000001357423046500237705ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructWithPreventTag/foo/foo.go000066400000000000000000000017471357423046500251130ustar00rootroot00000000000000// 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" "sync" "github.com/google/wire" ) func main() { pfb := injectPartFooBar() fmt.Println(pfb.Foo) } type Foo int type FooBar struct { mu sync.Mutex `wire:"-"` Foo Foo } func provideFoo() Foo { return 42 } func provideMutex() sync.Mutex { return sync.Mutex{} } var ProhibitSet = wire.NewSet( wire.Struct(new(FooBar), "mu", "Foo"), provideMutex, provideFoo, ) wire-0.4.0/internal/wire/testdata/StructWithPreventTag/foo/wire.go000066400000000000000000000013511357423046500252650ustar00rootroot00000000000000// 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/google/wire" ) func injectPartFooBar() FooBar { wire.Build(ProhibitSet) return FooBar{} } wire-0.4.0/internal/wire/testdata/StructWithPreventTag/pkg000066400000000000000000000000201357423046500237010ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/StructWithPreventTag/want/000077500000000000000000000000001357423046500241565ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/StructWithPreventTag/want/wire_errs.txt000066400000000000000000000001041357423046500267130ustar00rootroot00000000000000example.com/foo/foo.go:x:y: "mu" is prevented from injecting by wirewire-0.4.0/internal/wire/testdata/TwoDeps/000077500000000000000000000000001357423046500204525ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/TwoDeps/foo/000077500000000000000000000000001357423046500212355ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/TwoDeps/foo/foo.go000066400000000000000000000017071357423046500223540ustar00rootroot00000000000000// 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/google/wire" ) func main() { fmt.Println(injectFooBar()) } type Foo int type Bar int type FooBar int func provideFoo() Foo { return 40 } func provideBar() Bar { return 2 } func provideFooBar(foo Foo, bar Bar) FooBar { return FooBar(foo) + FooBar(bar) } var Set = wire.NewSet( provideFoo, provideBar, provideFooBar) wire-0.4.0/internal/wire/testdata/TwoDeps/foo/wire.go000066400000000000000000000013261357423046500225340ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() FooBar { wire.Build(Set) return 0 } wire-0.4.0/internal/wire/testdata/TwoDeps/pkg000066400000000000000000000000201357423046500211460ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/TwoDeps/want/000077500000000000000000000000001357423046500214235ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/TwoDeps/want/program_out.txt000066400000000000000000000000031357423046500245130ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/TwoDeps/want/wire_gen.go000066400000000000000000000003671357423046500235570ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar() FooBar { foo := provideFoo() bar := provideBar() fooBar := provideFooBar(foo, bar) return fooBar } wire-0.4.0/internal/wire/testdata/UnexportedStruct/000077500000000000000000000000001357423046500224275ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedStruct/bar/000077500000000000000000000000001357423046500231735ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedStruct/bar/bar.go000066400000000000000000000011721357423046500242670ustar00rootroot00000000000000// 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 var foo struct { X int } wire-0.4.0/internal/wire/testdata/UnexportedStruct/foo/000077500000000000000000000000001357423046500232125ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedStruct/foo/foo.go000066400000000000000000000012421357423046500243230ustar00rootroot00000000000000// 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.Printf("%v\n", injectedBar()) } wire-0.4.0/internal/wire/testdata/UnexportedStruct/foo/wire.go000066400000000000000000000014301357423046500245050ustar00rootroot00000000000000// 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/google/wire" ) func injectedBar() string { // Fails because bar.foo is unexported. wire.Build(bar.foo.X) return "" } wire-0.4.0/internal/wire/testdata/UnexportedStruct/pkg000066400000000000000000000000201357423046500231230ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/UnexportedStruct/want/000077500000000000000000000000001357423046500234005ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedStruct/want/wire_errs.txt000066400000000000000000000000741357423046500261430ustar00rootroot00000000000000example.com/foo/wire.go:x:y: foo not exported by package barwire-0.4.0/internal/wire/testdata/UnexportedValue/000077500000000000000000000000001357423046500222175ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedValue/bar/000077500000000000000000000000001357423046500227635ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedValue/bar/bar.go000066400000000000000000000013061357423046500240560ustar00rootroot00000000000000// 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/google/wire" var Value = wire.Value(privateMsg) var privateMsg = "Hello, World!" wire-0.4.0/internal/wire/testdata/UnexportedValue/foo/000077500000000000000000000000001357423046500230025ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedValue/foo/foo.go000066400000000000000000000012371357423046500241170ustar00rootroot00000000000000// 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()) } wire-0.4.0/internal/wire/testdata/UnexportedValue/foo/wire.go000066400000000000000000000014651357423046500243050ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { // Fails because bar.Value references unexported bar.privateMsg. wire.Build(bar.Value) return "" } wire-0.4.0/internal/wire/testdata/UnexportedValue/pkg000066400000000000000000000000201357423046500227130ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/UnexportedValue/want/000077500000000000000000000000001357423046500231705ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnexportedValue/want/wire_errs.txt000066400000000000000000000001661357423046500257350ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectedMessage: value string can't be used: uses unexported identifier privateMsgwire-0.4.0/internal/wire/testdata/UnusedProviders/000077500000000000000000000000001357423046500222265ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnusedProviders/foo/000077500000000000000000000000001357423046500230115ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnusedProviders/foo/foo.go000066400000000000000000000027241357423046500241300ustar00rootroot00000000000000// 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/google/wire" ) func main() { fmt.Println(injectFooBar()) } type Foo int type Bar int type Unused int type UnusedInSet int type OneOfTwo int type TwoOfTwo int type FooBar struct { MyFoo *Foo MyBar Bar MyUnused Unused } var ( unusedSet = wire.NewSet(provideUnusedInSet) partiallyUsedSet = wire.NewSet(provideOneOfTwo, provideTwoOfTwo) ) type Fooer interface { Foo() string } func (f *Foo) Foo() string { return fmt.Sprintf("Hello World %d", f) } func provideFoo() *Foo { f := new(Foo) *f = 1 return f } func provideBar(foo *Foo, one OneOfTwo) Bar { return Bar(int(*foo) + int(one)) } func provideUnused() Unused { return 1 } func provideUnusedInSet() UnusedInSet { return 1 } func provideOneOfTwo() OneOfTwo { return 1 } func provideTwoOfTwo() TwoOfTwo { return 1 } type S struct { Cfg Config } type Config int wire-0.4.0/internal/wire/testdata/UnusedProviders/foo/wire.go000066400000000000000000000024701357423046500243110ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() FooBar { wire.Build( provideFoo, // needed as input for provideBar provideBar, // needed for FooBar partiallyUsedSet, // 1/2 providers in the set are needed provideUnused, // not needed -> error wire.Value("unused"), // not needed -> error unusedSet, // nothing in set is needed -> error wire.Bind(new(Fooer), new(*Foo)), // binding to Fooer is not needed -> error wire.FieldsOf(new(S), "Cfg"), // S.Cfg not needed -> error wire.Struct(new(FooBar), "MyFoo", "MyBar"), // needed for FooBar ) return FooBar{} } wire-0.4.0/internal/wire/testdata/UnusedProviders/pkg000066400000000000000000000000201357423046500227220ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/UnusedProviders/want/000077500000000000000000000000001357423046500231775ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/UnusedProviders/want/wire_errs.txt000066400000000000000000000006721357423046500257460ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectFooBar: unused provider set "unusedSet" example.com/foo/wire.go:x:y: inject injectFooBar: unused provider "main.provideUnused" example.com/foo/wire.go:x:y: inject injectFooBar: unused value of type string example.com/foo/wire.go:x:y: inject injectFooBar: unused interface binding to type example.com/foo.Fooer example.com/foo/wire.go:x:y: inject injectFooBar: unused field "example.com/foo.S".Cfgwire-0.4.0/internal/wire/testdata/ValueChain/000077500000000000000000000000001357423046500211045ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueChain/foo/000077500000000000000000000000001357423046500216675ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueChain/foo/foo.go000066400000000000000000000015301357423046500230000ustar00rootroot00000000000000// 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/google/wire" ) func main() { fmt.Println(injectFooBar()) } type Foo int type FooBar int var Set = wire.NewSet( wire.Value(Foo(41)), provideFooBar) func provideFooBar(foo Foo) FooBar { return FooBar(foo) + 1 } wire-0.4.0/internal/wire/testdata/ValueChain/foo/wire.go000066400000000000000000000013261357423046500231660ustar00rootroot00000000000000// 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/google/wire" ) func injectFooBar() FooBar { wire.Build(Set) return 0 } wire-0.4.0/internal/wire/testdata/ValueChain/pkg000066400000000000000000000000201357423046500216000ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ValueChain/want/000077500000000000000000000000001357423046500220555ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueChain/want/program_out.txt000066400000000000000000000000031357423046500251450ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/ValueChain/want/wire_gen.go000066400000000000000000000004001357423046500241750ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFooBar() FooBar { foo := _wireFooValue fooBar := provideFooBar(foo) return fooBar } var ( _wireFooValue = Foo(41) ) wire-0.4.0/internal/wire/testdata/ValueConversion/000077500000000000000000000000001357423046500222075ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueConversion/foo/000077500000000000000000000000001357423046500227725ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueConversion/foo/foo.go000066400000000000000000000012601357423046500241030ustar00rootroot00000000000000// 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()) } type Foo string wire-0.4.0/internal/wire/testdata/ValueConversion/foo/wire.go000066400000000000000000000013641357423046500242730ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() Foo { wire.Build(wire.Value(Foo("Hello, World!"))) return "" } wire-0.4.0/internal/wire/testdata/ValueConversion/pkg000066400000000000000000000000201357423046500227030ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ValueConversion/want/000077500000000000000000000000001357423046500231605ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueConversion/want/program_out.txt000066400000000000000000000000161357423046500262540ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/ValueConversion/want/wire_gen.go000066400000000000000000000003541357423046500253100ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() Foo { foo := _wireFooValue return foo } var ( _wireFooValue = Foo("Hello, World!") ) wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/000077500000000000000000000000001357423046500234655ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/foo/000077500000000000000000000000001357423046500242505ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/foo/foo.go000066400000000000000000000014521357423046500253640ustar00rootroot00000000000000// 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 foo struct { V int } type bar struct { V int } func newBar(v int) *bar { return &bar{V: v} } func main() { f := &foo{V: 42} b := injectBar(f) fmt.Printf("%d\n", b.V) } wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/foo/wire.go000066400000000000000000000014441357423046500255500ustar00rootroot00000000000000// 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/google/wire" ) func injectBar(f *foo) *bar { wire.Build( newBar, wire.Value(f.V), // fails because f.V is not from package scope ) return nil } wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/pkg000066400000000000000000000000201357423046500241610ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/want/000077500000000000000000000000001357423046500244365ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueFromFunctionScope/want/wire_errs.txt000066400000000000000000000001521357423046500271760ustar00rootroot00000000000000example.com/foo/wire.go:x:y: inject injectBar: value int can't be used: f is not declared in package scopewire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/000077500000000000000000000000001357423046500232535ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/foo/000077500000000000000000000000001357423046500240365ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/foo/foo.go000066400000000000000000000014121357423046500251460ustar00rootroot00000000000000// 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" "io/ioutil" "strings" ) func main() { r := injectedReader(strings.NewReader("hello world")) buf, _ := ioutil.ReadAll(r) fmt.Println(string(buf)) } wire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/foo/wire.go000066400000000000000000000014251357423046500253350ustar00rootroot00000000000000// 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" "strings" "github.com/google/wire" ) func injectedReader(r *strings.Reader) io.Reader { wire.Build(wire.Value(io.Reader(r))) return nil } wire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/pkg000066400000000000000000000000201357423046500237470ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/want/000077500000000000000000000000001357423046500242245ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueIsInterfaceValue/want/wire_errs.txt000066400000000000000000000001721357423046500267660ustar00rootroot00000000000000example.com/foo/wire.go:x:y: argument to Value may not be an interface value (found io.Reader); use InterfaceValue insteadwire-0.4.0/internal/wire/testdata/ValueIsStruct/000077500000000000000000000000001357423046500216425ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueIsStruct/foo/000077500000000000000000000000001357423046500224255ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueIsStruct/foo/foo.go000066400000000000000000000013131357423046500235350ustar00rootroot00000000000000// 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() { f := injectFoo() fmt.Printf("%d\n", f.X) } type Foo struct { X int } wire-0.4.0/internal/wire/testdata/ValueIsStruct/foo/wire.go000066400000000000000000000013471357423046500237270ustar00rootroot00000000000000// 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/google/wire" ) func injectFoo() Foo { wire.Build(wire.Value(Foo{X: 42})) return Foo{} } wire-0.4.0/internal/wire/testdata/ValueIsStruct/pkg000066400000000000000000000000201357423046500223360ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/ValueIsStruct/want/000077500000000000000000000000001357423046500226135ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/ValueIsStruct/want/program_out.txt000066400000000000000000000000031357423046500257030ustar00rootroot0000000000000042 wire-0.4.0/internal/wire/testdata/ValueIsStruct/want/wire_gen.go000066400000000000000000000003341357423046500247410ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectFoo() Foo { foo := _wireFooValue return foo } var ( _wireFooValue = Foo{X: 42} ) wire-0.4.0/internal/wire/testdata/VarValue/000077500000000000000000000000001357423046500206125ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/VarValue/foo/000077500000000000000000000000001357423046500213755ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/VarValue/foo/foo.go000066400000000000000000000014451357423046500225130ustar00rootroot00000000000000// 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() { // Mutating value; value should have been stored at package initialization. msg = "Hello, World!" fmt.Println(injectedMessage()) } var msg string = "Package init" wire-0.4.0/internal/wire/testdata/VarValue/foo/wire.go000066400000000000000000000013461357423046500226760ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage() string { wire.Build(wire.Value(msg)) return "" } wire-0.4.0/internal/wire/testdata/VarValue/pkg000066400000000000000000000000201357423046500213060ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/VarValue/want/000077500000000000000000000000001357423046500215635ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/VarValue/want/program_out.txt000066400000000000000000000000151357423046500246560ustar00rootroot00000000000000Package init wire-0.4.0/internal/wire/testdata/VarValue/want/wire_gen.go000066400000000000000000000003541357423046500237130ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage() string { string2 := _wireStringValue return string2 } var ( _wireStringValue = msg ) wire-0.4.0/internal/wire/testdata/Varargs/000077500000000000000000000000001357423046500204725ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Varargs/foo/000077500000000000000000000000001357423046500212555ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Varargs/foo/foo.go000066400000000000000000000015371357423046500223750ustar00rootroot00000000000000// 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" "strings" ) func main() { fmt.Println(injectedMessage("", "Hello,", "World!")) } type title string // provideMessage provides a friendly user greeting. func provideMessage(words ...string) string { return strings.Join(words, " ") } wire-0.4.0/internal/wire/testdata/Varargs/foo/wire.go000066400000000000000000000013751357423046500225600ustar00rootroot00000000000000// 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/google/wire" ) func injectedMessage(t title, lines ...string) string { wire.Build(provideMessage) return "" } wire-0.4.0/internal/wire/testdata/Varargs/pkg000066400000000000000000000000201357423046500211660ustar00rootroot00000000000000example.com/foo wire-0.4.0/internal/wire/testdata/Varargs/want/000077500000000000000000000000001357423046500214435ustar00rootroot00000000000000wire-0.4.0/internal/wire/testdata/Varargs/want/program_out.txt000066400000000000000000000000161357423046500245370ustar00rootroot00000000000000Hello, World! wire-0.4.0/internal/wire/testdata/Varargs/want/wire_gen.go000066400000000000000000000003531357423046500235720ustar00rootroot00000000000000// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func injectedMessage(t title, lines ...string) string { string2 := provideMessage(lines...) return string2 } wire-0.4.0/internal/wire/wire.go000066400000000000000000000645251357423046500165650ustar00rootroot00000000000000// 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 provides compile-time dependency injection logic as a // Go library. package wire import ( "bytes" "context" "errors" "fmt" "go/ast" "go/format" "go/printer" "go/token" "go/types" "io/ioutil" "path/filepath" "sort" "strconv" "strings" "unicode" "unicode/utf8" "golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/packages" ) // GenerateResult stores the result for a package from a call to Generate. type GenerateResult struct { // PkgPath is the package's PkgPath. PkgPath string // OutputPath is the path where the generated output should be written. // May be empty if there were errors. OutputPath string // Content is the gofmt'd source code that was generated. May be nil if // there were errors during generation. Content []byte // Errs is a slice of errors identified during generation. Errs []error } // Commit writes the generated file to disk. func (gen GenerateResult) Commit() error { if len(gen.Content) == 0 { return nil } return ioutil.WriteFile(gen.OutputPath, gen.Content, 0666) } // GenerateOptions holds options for Generate. type GenerateOptions struct { // Header will be inserted at the start of each generated file. Header []byte PrefixOutputFile string } // Generate performs dependency injection for the packages that match the given // patterns, return a GenerateResult for each package. The package pattern is // defined by the underlying build system. For the go tool, this is described at // https://golang.org/cmd/go/#hdr-Package_lists_and_patterns // // wd is the working directory and env is the set of environment // variables to use when loading the package specified by pkgPattern. If // env is nil or empty, it is interpreted as an empty set of variables. // In case of duplicate environment variables, the last one in the list // takes precedence. // // Generate may return one or more errors if it failed to load the packages. func Generate(ctx context.Context, wd string, env []string, patterns []string, opts *GenerateOptions) ([]GenerateResult, []error) { if opts == nil { opts = &GenerateOptions{} } pkgs, errs := load(ctx, wd, env, patterns) if len(errs) > 0 { return nil, errs } generated := make([]GenerateResult, len(pkgs)) for i, pkg := range pkgs { generated[i].PkgPath = pkg.PkgPath outDir, err := detectOutputDir(pkg.GoFiles) if err != nil { generated[i].Errs = append(generated[i].Errs, err) continue } generated[i].OutputPath = filepath.Join(outDir, opts.PrefixOutputFile+"wire_gen.go") g := newGen(pkg) injectorFiles, errs := generateInjectors(g, pkg) if len(errs) > 0 { generated[i].Errs = errs continue } copyNonInjectorDecls(g, injectorFiles, pkg.TypesInfo) goSrc := g.frame() if len(opts.Header) > 0 { goSrc = append(opts.Header, goSrc...) } fmtSrc, err := format.Source(goSrc) if err != nil { // This is likely a bug from a poorly generated source file. // Add an error but also the unformatted source. generated[i].Errs = append(generated[i].Errs, err) } else { goSrc = fmtSrc } generated[i].Content = goSrc } return generated, nil } func detectOutputDir(paths []string) (string, error) { if len(paths) == 0 { return "", errors.New("no files to derive output directory from") } dir := filepath.Dir(paths[0]) for _, p := range paths[1:] { if dir2 := filepath.Dir(p); dir2 != dir { return "", fmt.Errorf("found conflicting directories %q and %q", dir, dir2) } } return dir, nil } // generateInjectors generates the injectors for a given package. func generateInjectors(g *gen, pkg *packages.Package) (injectorFiles []*ast.File, _ []error) { oc := newObjectCache([]*packages.Package{pkg}) injectorFiles = make([]*ast.File, 0, len(pkg.Syntax)) ec := new(errorCollector) for _, f := range pkg.Syntax { for _, decl := range f.Decls { fn, ok := decl.(*ast.FuncDecl) if !ok { continue } buildCall, err := findInjectorBuild(pkg.TypesInfo, fn) if err != nil { ec.add(err) continue } if buildCall == nil { continue } if len(injectorFiles) == 0 || injectorFiles[len(injectorFiles)-1] != f { // This is the first injector generated for this file. // Write a file header. name := filepath.Base(g.pkg.Fset.File(f.Pos()).Name()) g.p("// Injectors from %s:\n\n", name) injectorFiles = append(injectorFiles, f) } sig := pkg.TypesInfo.ObjectOf(fn.Name).Type().(*types.Signature) ins, _, err := injectorFuncSignature(sig) if err != nil { if w, ok := err.(*wireErr); ok { ec.add(notePosition(w.position, fmt.Errorf("inject %s: %v", fn.Name.Name, w.error))) } else { ec.add(notePosition(g.pkg.Fset.Position(fn.Pos()), fmt.Errorf("inject %s: %v", fn.Name.Name, err))) } continue } injectorArgs := &InjectorArgs{ Name: fn.Name.Name, Tuple: ins, Pos: fn.Pos(), } set, errs := oc.processNewSet(pkg.TypesInfo, pkg.PkgPath, buildCall, injectorArgs, "") if len(errs) > 0 { ec.add(notePositionAll(g.pkg.Fset.Position(fn.Pos()), errs)...) continue } if errs := g.inject(fn.Pos(), fn.Name.Name, sig, set); len(errs) > 0 { ec.add(errs...) continue } } for _, impt := range f.Imports { if impt.Name != nil && impt.Name.Name == "_" { g.anonImports[impt.Path.Value] = true } } } if len(ec.errors) > 0 { return nil, ec.errors } return injectorFiles, nil } // copyNonInjectorDecls copies any non-injector declarations from the // given files into the generated output. func copyNonInjectorDecls(g *gen, files []*ast.File, info *types.Info) { for _, f := range files { name := filepath.Base(g.pkg.Fset.File(f.Pos()).Name()) first := true for _, decl := range f.Decls { switch decl := decl.(type) { case *ast.FuncDecl: // OK to ignore error, as any error cases should already have // been filtered out. if buildCall, _ := findInjectorBuild(info, decl); buildCall != nil { continue } case *ast.GenDecl: if decl.Tok == token.IMPORT { continue } default: continue } if first { g.p("// %s:\n\n", name) first = false } // TODO(light): Add line number at top of each declaration. g.writeAST(info, decl) g.p("\n\n") } } } // importInfo holds info about an import. type importInfo struct { // name is the identifier that is used in the generated source. name string // differs is true if the import is given an identifier that does not // match the package's identifier. differs bool } // gen is the file-wide generator state. type gen struct { pkg *packages.Package buf bytes.Buffer imports map[string]importInfo anonImports map[string]bool values map[ast.Expr]string } func newGen(pkg *packages.Package) *gen { return &gen{ pkg: pkg, anonImports: make(map[string]bool), imports: make(map[string]importInfo), values: make(map[ast.Expr]string), } } // frame bakes the built up source body into an unformatted Go source file. func (g *gen) frame() []byte { if g.buf.Len() == 0 { return nil } var buf bytes.Buffer buf.WriteString("// Code generated by Wire. DO NOT EDIT.\n\n") buf.WriteString("//go:generate wire\n") buf.WriteString("//+build !wireinject\n\n") buf.WriteString("package ") buf.WriteString(g.pkg.Name) buf.WriteString("\n\n") if len(g.imports) > 0 { buf.WriteString("import (\n") imps := make([]string, 0, len(g.imports)) for path := range g.imports { imps = append(imps, path) } sort.Strings(imps) for _, path := range imps { // Omit the local package identifier if it matches the package name. info := g.imports[path] if info.differs { fmt.Fprintf(&buf, "\t%s %q\n", info.name, path) } else { fmt.Fprintf(&buf, "\t%q\n", path) } } buf.WriteString(")\n\n") } if len(g.anonImports) > 0 { buf.WriteString("import (\n") anonImps := make([]string, 0, len(g.anonImports)) for path := range g.anonImports { anonImps = append(anonImps, path) } sort.Strings(anonImps) for _, path := range anonImps { fmt.Fprintf(&buf, "\t_ %s\n", path) } buf.WriteString(")\n\n") } buf.Write(g.buf.Bytes()) return buf.Bytes() } // inject emits the code for an injector. func (g *gen) inject(pos token.Pos, name string, sig *types.Signature, set *ProviderSet) []error { injectSig, err := funcOutput(sig) if err != nil { return []error{notePosition(g.pkg.Fset.Position(pos), fmt.Errorf("inject %s: %v", name, err))} } params := sig.Params() calls, errs := solve(g.pkg.Fset, injectSig.out, params, set) if len(errs) > 0 { return mapErrors(errs, func(e error) error { if w, ok := e.(*wireErr); ok { return notePosition(w.position, fmt.Errorf("inject %s: %v", name, w.error)) } return notePosition(g.pkg.Fset.Position(pos), fmt.Errorf("inject %s: %v", name, e)) }) } type pendingVar struct { name string expr ast.Expr typeInfo *types.Info } var pendingVars []pendingVar ec := new(errorCollector) for i := range calls { c := &calls[i] if c.hasCleanup && !injectSig.cleanup { ts := types.TypeString(c.out, nil) ec.add(notePosition( g.pkg.Fset.Position(pos), fmt.Errorf("inject %s: provider for %s returns cleanup but injection does not return cleanup function", name, ts))) } if c.hasErr && !injectSig.err { ts := types.TypeString(c.out, nil) ec.add(notePosition( g.pkg.Fset.Position(pos), fmt.Errorf("inject %s: provider for %s returns error but injection not allowed to fail", name, ts))) } if c.kind == valueExpr { if err := accessibleFrom(c.valueTypeInfo, c.valueExpr, g.pkg.PkgPath); err != nil { // TODO(light): Display line number of value expression. ts := types.TypeString(c.out, nil) ec.add(notePosition( g.pkg.Fset.Position(pos), fmt.Errorf("inject %s: value %s can't be used: %v", name, ts, err))) } if g.values[c.valueExpr] == "" { t := c.valueTypeInfo.TypeOf(c.valueExpr) name := typeVariableName(t, "", func(name string) string { return "_wire" + export(name) + "Value" }, g.nameInFileScope) g.values[c.valueExpr] = name pendingVars = append(pendingVars, pendingVar{ name: name, expr: c.valueExpr, typeInfo: c.valueTypeInfo, }) } } } if len(ec.errors) > 0 { return ec.errors } // Perform one pass to collect all imports, followed by the real pass. injectPass(name, sig, calls, set, &injectorGen{ g: g, errVar: disambiguate("err", g.nameInFileScope), discard: true, }) injectPass(name, sig, calls, set, &injectorGen{ g: g, errVar: disambiguate("err", g.nameInFileScope), discard: false, }) if len(pendingVars) > 0 { g.p("var (\n") for _, pv := range pendingVars { g.p("\t%s = ", pv.name) g.writeAST(pv.typeInfo, pv.expr) g.p("\n") } g.p(")\n\n") } return nil } // rewritePkgRefs rewrites any package references in an AST into references for the // generated package. func (g *gen) rewritePkgRefs(info *types.Info, node ast.Node) ast.Node { start, end := node.Pos(), node.End() node = copyAST(node) // First, rewrite all package names. This lets us know all the // potentially colliding identifiers. node = astutil.Apply(node, func(c *astutil.Cursor) bool { switch node := c.Node().(type) { case *ast.Ident: // This is an unqualified identifier (qualified identifiers are peeled off below). obj := info.ObjectOf(node) if obj == nil { return false } if pkg := obj.Pkg(); pkg != nil && obj.Parent() == pkg.Scope() && pkg.Path() != g.pkg.PkgPath { // An identifier from either a dot import or read from a different package. newPkgID := g.qualifyImport(pkg.Name(), pkg.Path()) c.Replace(&ast.SelectorExpr{ X: ast.NewIdent(newPkgID), Sel: ast.NewIdent(node.Name), }) return false } return true case *ast.SelectorExpr: pkgIdent, ok := node.X.(*ast.Ident) if !ok { return true } pkgName, ok := info.ObjectOf(pkgIdent).(*types.PkgName) if !ok { return true } // This is a qualified identifier. Rewrite and avoid visiting subexpressions. imported := pkgName.Imported() newPkgID := g.qualifyImport(imported.Name(), imported.Path()) c.Replace(&ast.SelectorExpr{ X: ast.NewIdent(newPkgID), Sel: ast.NewIdent(node.Sel.Name), }) return false default: return true } }, nil) // Now that we have all the identifiers, rename any variables declared // in this scope to not collide. newNames := make(map[types.Object]string) inNewNames := func(n string) bool { for _, other := range newNames { if other == n { return true } } return false } var scopeStack []*types.Scope pkgScope := g.pkg.Types.Scope() node = astutil.Apply(node, func(c *astutil.Cursor) bool { if scope := info.Scopes[c.Node()]; scope != nil { scopeStack = append(scopeStack, scope) } id, ok := c.Node().(*ast.Ident) if !ok { return true } obj := info.ObjectOf(id) if obj == nil { // We rewrote this identifier earlier, so it does not need // further rewriting. return true } if n, ok := newNames[obj]; ok { // We picked a new name for this symbol. Rewrite it. c.Replace(ast.NewIdent(n)) return false } if par := obj.Parent(); par == nil || par == pkgScope { // Don't rename methods, field names, or top-level identifiers. return true } // Rename any symbols defined within rewritePkgRefs's node that conflict // with any symbols in the generated file. objName := obj.Name() if pos := obj.Pos(); pos < start || end <= pos || !(g.nameInFileScope(objName) || inNewNames(objName)) { return true } newName := disambiguate(objName, func(n string) bool { if g.nameInFileScope(n) || inNewNames(n) { return true } if len(scopeStack) > 0 { // Avoid picking a name that conflicts with other names in the // current scope. _, obj := scopeStack[len(scopeStack)-1].LookupParent(n, token.NoPos) if obj != nil { return true } } return false }) newNames[obj] = newName c.Replace(ast.NewIdent(newName)) return false }, func(c *astutil.Cursor) bool { if info.Scopes[c.Node()] != nil { // Should be top of stack; pop it. scopeStack = scopeStack[:len(scopeStack)-1] } return true }) return node } // writeAST prints an AST node into the generated output, rewriting any // package references it encounters. func (g *gen) writeAST(info *types.Info, node ast.Node) { node = g.rewritePkgRefs(info, node) if err := printer.Fprint(&g.buf, g.pkg.Fset, node); err != nil { panic(err) } } func (g *gen) qualifiedID(pkgName, pkgPath, sym string) string { name := g.qualifyImport(pkgName, pkgPath) if name == "" { return sym } return name + "." + sym } func (g *gen) qualifyImport(name, path string) string { if path == g.pkg.PkgPath { return "" } // TODO(light): This is depending on details of the current loader. const vendorPart = "vendor/" unvendored := path if i := strings.LastIndex(path, vendorPart); i != -1 && (i == 0 || path[i-1] == '/') { unvendored = path[i+len(vendorPart):] } if info, ok := g.imports[unvendored]; ok { return info.name } // TODO(light): Use parts of import path to disambiguate. newName := disambiguate(name, func(n string) bool { // Don't let an import take the "err" name. That's annoying. return n == "err" || g.nameInFileScope(n) }) g.imports[unvendored] = importInfo{ name: newName, differs: newName != name, } return newName } func (g *gen) nameInFileScope(name string) bool { for _, other := range g.imports { if other.name == name { return true } } for _, other := range g.values { if other == name { return true } } _, obj := g.pkg.Types.Scope().LookupParent(name, token.NoPos) return obj != nil } func (g *gen) qualifyPkg(pkg *types.Package) string { return g.qualifyImport(pkg.Name(), pkg.Path()) } func (g *gen) p(format string, args ...interface{}) { fmt.Fprintf(&g.buf, format, args...) } // injectorGen is the per-injector pass generator state. type injectorGen struct { g *gen paramNames []string localNames []string cleanupNames []string errVar string // discard causes ig.p and ig.writeAST to no-op. Useful to run // generation for side-effects like filling in g.imports. discard bool } // injectPass generates an injector given the output from analysis. // The sig passed in should be verified. func injectPass(name string, sig *types.Signature, calls []call, set *ProviderSet, ig *injectorGen) { params := sig.Params() injectSig, err := funcOutput(sig) if err != nil { // This should be checked by the caller already. panic(err) } ig.p("func %s(", name) for i := 0; i < params.Len(); i++ { if i > 0 { ig.p(", ") } pi := params.At(i) a := pi.Name() if a == "" || a == "_" { a = typeVariableName(pi.Type(), "arg", unexport, ig.nameInInjector) } else { a = disambiguate(a, ig.nameInInjector) } ig.paramNames = append(ig.paramNames, a) if sig.Variadic() && i == params.Len()-1 { // Keep the varargs signature instead of a slice for the last argument if the // injector is variadic. ig.p("%s ...%s", ig.paramNames[i], types.TypeString(pi.Type().(*types.Slice).Elem(), ig.g.qualifyPkg)) } else { ig.p("%s %s", ig.paramNames[i], types.TypeString(pi.Type(), ig.g.qualifyPkg)) } } outTypeString := types.TypeString(injectSig.out, ig.g.qualifyPkg) switch { case injectSig.cleanup && injectSig.err: ig.p(") (%s, func(), error) {\n", outTypeString) case injectSig.cleanup: ig.p(") (%s, func()) {\n", outTypeString) case injectSig.err: ig.p(") (%s, error) {\n", outTypeString) default: ig.p(") %s {\n", outTypeString) } for i := range calls { c := &calls[i] lname := typeVariableName(c.out, "v", unexport, ig.nameInInjector) ig.localNames = append(ig.localNames, lname) switch c.kind { case structProvider: ig.structProviderCall(lname, c) case funcProviderCall: ig.funcProviderCall(lname, c, injectSig) case valueExpr: ig.valueExpr(lname, c) case selectorExpr: ig.fieldExpr(lname, c) default: panic("unknown kind") } } if len(calls) == 0 { ig.p("\treturn %s", ig.paramNames[set.For(injectSig.out).Arg().Index]) } else { ig.p("\treturn %s", ig.localNames[len(calls)-1]) } if injectSig.cleanup { ig.p(", func() {\n") for i := len(ig.cleanupNames) - 1; i >= 0; i-- { ig.p("\t\t%s()\n", ig.cleanupNames[i]) } ig.p("\t}") } if injectSig.err { ig.p(", nil") } ig.p("\n}\n\n") } func (ig *injectorGen) funcProviderCall(lname string, c *call, injectSig outputSignature) { ig.p("\t%s", lname) prevCleanup := len(ig.cleanupNames) if c.hasCleanup { cname := disambiguate("cleanup", ig.nameInInjector) ig.cleanupNames = append(ig.cleanupNames, cname) ig.p(", %s", cname) } if c.hasErr { ig.p(", %s", ig.errVar) } ig.p(" := ") ig.p("%s(", ig.g.qualifiedID(c.pkg.Name(), c.pkg.Path(), c.name)) for i, a := range c.args { if i > 0 { ig.p(", ") } if a < len(ig.paramNames) { ig.p("%s", ig.paramNames[a]) } else { ig.p("%s", ig.localNames[a-len(ig.paramNames)]) } } if c.varargs { ig.p("...") } ig.p(")\n") if c.hasErr { ig.p("\tif %s != nil {\n", ig.errVar) for i := prevCleanup - 1; i >= 0; i-- { ig.p("\t\t%s()\n", ig.cleanupNames[i]) } ig.p("\t\treturn %s", zeroValue(injectSig.out, ig.g.qualifyPkg)) if injectSig.cleanup { ig.p(", nil") } // TODO(light): Give information about failing provider. ig.p(", err\n") ig.p("\t}\n") } } func (ig *injectorGen) structProviderCall(lname string, c *call) { ig.p("\t%s", lname) ig.p(" := ") if _, ok := c.out.(*types.Pointer); ok { ig.p("&") } ig.p("%s{\n", ig.g.qualifiedID(c.pkg.Name(), c.pkg.Path(), c.name)) for i, a := range c.args { ig.p("\t\t%s: ", c.fieldNames[i]) if a < len(ig.paramNames) { ig.p("%s", ig.paramNames[a]) } else { ig.p("%s", ig.localNames[a-len(ig.paramNames)]) } ig.p(",\n") } ig.p("\t}\n") } func (ig *injectorGen) valueExpr(lname string, c *call) { ig.p("\t%s := %s\n", lname, ig.g.values[c.valueExpr]) } func (ig *injectorGen) fieldExpr(lname string, c *call) { a := c.args[0] ig.p("\t%s := ", lname) if c.ptrToField { ig.p("&") } if a < len(ig.paramNames) { ig.p("%s.%s\n", ig.paramNames[a], c.name) } else { ig.p("%s.%s\n", ig.localNames[a-len(ig.paramNames)], c.name) } } // nameInInjector reports whether name collides with any other identifier // in the current injector. func (ig *injectorGen) nameInInjector(name string) bool { if name == ig.errVar { return true } for _, a := range ig.paramNames { if a == name { return true } } for _, l := range ig.localNames { if l == name { return true } } for _, l := range ig.cleanupNames { if l == name { return true } } return ig.g.nameInFileScope(name) } func (ig *injectorGen) p(format string, args ...interface{}) { if ig.discard { return } ig.g.p(format, args...) } func (ig *injectorGen) writeAST(info *types.Info, node ast.Node) { node = ig.g.rewritePkgRefs(info, node) if ig.discard { return } if err := printer.Fprint(&ig.g.buf, ig.g.pkg.Fset, node); err != nil { panic(err) } } // zeroValue returns the shortest expression that evaluates to the zero // value for the given type. func zeroValue(t types.Type, qf types.Qualifier) string { switch u := t.Underlying().(type) { case *types.Array, *types.Struct: return types.TypeString(t, qf) + "{}" case *types.Basic: info := u.Info() switch { case info&types.IsBoolean != 0: return "false" case info&(types.IsInteger|types.IsFloat|types.IsComplex) != 0: return "0" case info&types.IsString != 0: return `""` default: panic("unreachable") } case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice: return "nil" default: panic("unreachable") } } // typeVariableName invents a disambiguated variable name derived from the type name. // If no name can be derived from the type, defaultName is used. // transform is used to transform the derived name(s) (including defaultName); // commonly used functions include export and unexport. // collides is used to see if a name is ambiguous. If any one of the derived // names is unambiguous, it used; otherwise, the first derived name is // disambiguated using disambiguate(). func typeVariableName(t types.Type, defaultName string, transform func(string) string, collides func(string) bool) string { if p, ok := t.(*types.Pointer); ok { t = p.Elem() } var names []string switch t := t.(type) { case *types.Basic: if t.Name() != "" { names = append(names, t.Name()) } case *types.Named: obj := t.Obj() if name := obj.Name(); name != "" { names = append(names, name) } // Provide an alternate name prefixed with the package name if possible. // E.g., in case of collisions, we'll use "fooCfg" instead of "cfg2". if pkg := obj.Pkg(); pkg != nil && pkg.Name() != "" { names = append(names, fmt.Sprintf("%s%s", pkg.Name(), strings.Title(obj.Name()))) } } // If we were unable to derive a name, use defaultName. if len(names) == 0 { names = append(names, defaultName) } // Transform the name(s). for i, name := range names { names[i] = transform(name) } // See if there's an unambiguous name; if so, use it. for _, name := range names { if !token.Lookup(name).IsKeyword() && !collides(name) { return name } } // Otherwise, disambiguate the first name. return disambiguate(names[0], collides) } // unexport converts a name that is potentially exported to an unexported name. func unexport(name string) string { if name == "" { return "" } r, sz := utf8.DecodeRuneInString(name) if !unicode.IsUpper(r) { // foo -> foo return name } r2, sz2 := utf8.DecodeRuneInString(name[sz:]) if !unicode.IsUpper(r2) { // Foo -> foo return string(unicode.ToLower(r)) + name[sz:] } // UPPERWord -> upperWord sbuf := new(strings.Builder) sbuf.WriteRune(unicode.ToLower(r)) i := sz r, sz = r2, sz2 for unicode.IsUpper(r) && sz > 0 { r2, sz2 := utf8.DecodeRuneInString(name[i+sz:]) if sz2 > 0 && unicode.IsLower(r2) { break } i += sz sbuf.WriteRune(unicode.ToLower(r)) r, sz = r2, sz2 } sbuf.WriteString(name[i:]) return sbuf.String() } // export converts a name that is potentially unexported to an exported name. func export(name string) string { if name == "" { return "" } r, sz := utf8.DecodeRuneInString(name) if unicode.IsUpper(r) { // Foo -> Foo return name } // fooBar -> FooBar sbuf := new(strings.Builder) sbuf.WriteRune(unicode.ToUpper(r)) sbuf.WriteString(name[sz:]) return sbuf.String() } // disambiguate picks a unique name, preferring name if it is already unique. // It also disambiguates against Go's reserved keywords. func disambiguate(name string, collides func(string) bool) string { if !token.Lookup(name).IsKeyword() && !collides(name) { return name } buf := []byte(name) if len(buf) > 0 && buf[len(buf)-1] >= '0' && buf[len(buf)-1] <= '9' { buf = append(buf, '_') } base := len(buf) for n := 2; ; n++ { buf = strconv.AppendInt(buf[:base], int64(n), 10) sbuf := string(buf) if !token.Lookup(sbuf).IsKeyword() && !collides(sbuf) { return sbuf } } } // accessibleFrom reports whether node can be copied to wantPkg without // violating Go visibility rules. func accessibleFrom(info *types.Info, node ast.Node, wantPkg string) error { var unexportError error ast.Inspect(node, func(node ast.Node) bool { if unexportError != nil { return false } ident, ok := node.(*ast.Ident) if !ok { return true } obj := info.ObjectOf(ident) if _, ok := obj.(*types.PkgName); ok { // Local package names are fine, since we can just reimport them. return true } if pkg := obj.Pkg(); pkg != nil { if !ast.IsExported(ident.Name) && pkg.Path() != wantPkg { unexportError = fmt.Errorf("uses unexported identifier %s", obj.Name()) return false } if obj.Parent() != nil && obj.Parent() != pkg.Scope() { unexportError = fmt.Errorf("%s is not declared in package scope", obj.Name()) return false } } return true }) return unexportError } var ( errorType = types.Universe.Lookup("error").Type() cleanupType = types.NewSignature(nil, nil, nil, false) ) wire-0.4.0/internal/wire/wire_test.go000066400000000000000000000431141357423046500176130ustar00rootroot00000000000000// 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 ( "bytes" "context" "flag" "fmt" "go/build" "go/types" "io/ioutil" "os" "os/exec" "path/filepath" "strings" "testing" "unicode" "unicode/utf8" "github.com/google/go-cmp/cmp" ) var record = flag.Bool("record", false, "whether to run tests against cloud resources and record the interactions") func TestWire(t *testing.T) { const testRoot = "testdata" testdataEnts, err := ioutil.ReadDir(testRoot) // ReadDir sorts by name. if err != nil { t.Fatal(err) } // The marker function package source is needed to have the test cases // type check. loadTestCase places this file at the well-known import path. wireGo, err := ioutil.ReadFile(filepath.Join("..", "..", "wire.go")) if err != nil { t.Fatal(err) } tests := make([]*testCase, 0, len(testdataEnts)) for _, ent := range testdataEnts { name := ent.Name() if !ent.IsDir() || strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") { continue } test, err := loadTestCase(filepath.Join(testRoot, name), wireGo) if err != nil { t.Error(err) continue } tests = append(tests, test) } var goToolPath string if *record { goToolPath = filepath.Join(build.Default.GOROOT, "bin", "go") if _, err := os.Stat(goToolPath); err != nil { t.Fatal("go toolchain not available:", err) } } ctx := context.Background() for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() // Materialize a temporary GOPATH directory. gopath, err := ioutil.TempDir("", "wire_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(gopath) gopath, err = filepath.EvalSymlinks(gopath) if err != nil { t.Fatal(err) } if err := test.materialize(gopath); err != nil { t.Fatal(err) } wd := filepath.Join(gopath, "src", "example.com") gens, errs := Generate(ctx, wd, append(os.Environ(), "GOPATH="+gopath), []string{test.pkg}, &GenerateOptions{Header: test.header}) var gen GenerateResult if len(gens) > 1 { t.Fatalf("got %d generated files, want 0 or 1", len(gens)) } if len(gens) == 1 { gen = gens[0] if len(gen.Errs) > 0 { errs = append(errs, gen.Errs...) } if len(gen.Content) > 0 { defer t.Logf("wire_gen.go:\n%s", gen.Content) } } if len(errs) > 0 { gotErrStrings := make([]string, len(errs)) for i, e := range errs { t.Log(e.Error()) gotErrStrings[i] = scrubError(gopath, e.Error()) } if !test.wantWireError { t.Fatal("Did not expect errors. To -record an error, create want/wire_errs.txt.") } if *record { wireErrsFile := filepath.Join(testRoot, test.name, "want", "wire_errs.txt") if err := ioutil.WriteFile(wireErrsFile, []byte(strings.Join(gotErrStrings, "\n\n")), 0666); err != nil { t.Fatalf("failed to write wire_errs.txt file: %v", err) } } else { if diff := cmp.Diff(gotErrStrings, test.wantWireErrorStrings); diff != "" { t.Errorf("Errors didn't match expected errors from wire_errors.txt:\n%s", diff) } } return } if test.wantWireError { t.Fatal("wire succeeded; want error") } outPathSane := true if prefix := gopath + string(os.PathSeparator) + "src" + string(os.PathSeparator); !strings.HasPrefix(gen.OutputPath, prefix) { outPathSane = false t.Errorf("suggested output path = %q; want to start with %q", gen.OutputPath, prefix) } if *record { // Record ==> Build the generated Wire code, // check that the program's output matches the // expected output, save wire output on // success. if !outPathSane { return } if err := gen.Commit(); err != nil { t.Fatalf("failed to write wire_gen.go to test GOPATH: %v", err) } if err := goBuildCheck(goToolPath, gopath, test); err != nil { t.Fatalf("go build check failed: %v", err) } testdataWireGenPath := filepath.Join(testRoot, test.name, "want", "wire_gen.go") if err := ioutil.WriteFile(testdataWireGenPath, gen.Content, 0666); err != nil { t.Fatalf("failed to record wire_gen.go to testdata: %v", err) } } else { // Replay ==> Load golden file and compare to // generated result. This check is meant to // detect non-deterministic behavior in the // Generate function. if !bytes.Equal(gen.Content, test.wantWireOutput) { gotS, wantS := string(gen.Content), string(test.wantWireOutput) diff := cmp.Diff(strings.Split(gotS, "\n"), strings.Split(wantS, "\n")) t.Fatalf("wire output differs from golden file. If this change is expected, run with -record to update the wire_gen.go file.\n*** got:\n%s\n\n*** want:\n%s\n\n*** diff:\n%s", gotS, wantS, diff) } } }) } } func goBuildCheck(goToolPath, gopath string, test *testCase) error { // Run `go build`. testExePath := filepath.Join(gopath, "bin", "testprog") buildCmd := []string{"build", "-o", testExePath} buildCmd = append(buildCmd, test.pkg) cmd := exec.Command(goToolPath, buildCmd...) cmd.Dir = filepath.Join(gopath, "src", "example.com") cmd.Env = append(os.Environ(), "GOPATH="+gopath) if buildOut, err := cmd.CombinedOutput(); err != nil { if len(buildOut) > 0 { return fmt.Errorf("build: %v; output:\n%s", err, buildOut) } return fmt.Errorf("build: %v", err) } // Run the resulting program and compare its output to the expected // output. out, err := exec.Command(testExePath).Output() if err != nil { return fmt.Errorf("run compiled program: %v", err) } if !bytes.Equal(out, test.wantProgramOutput) { gotS, wantS := string(out), string(test.wantProgramOutput) diff := cmp.Diff(strings.Split(gotS, "\n"), strings.Split(wantS, "\n")) return fmt.Errorf("compiled program output doesn't match:\n*** got:\n%s\n\n*** want:\n%s\n\n*** diff:\n%s", gotS, wantS, diff) } return nil } func TestUnexport(t *testing.T) { tests := []struct { name string want string }{ {"", ""}, {"a", "a"}, {"ab", "ab"}, {"A", "a"}, {"AB", "ab"}, {"A_", "a_"}, {"ABc", "aBc"}, {"ABC", "abc"}, {"AB_", "ab_"}, {"foo", "foo"}, {"Foo", "foo"}, {"HTTPClient", "httpClient"}, {"IFace", "iFace"}, {"SNAKE_CASE", "snake_CASE"}, {"HTTP", "http"}, } for _, test := range tests { if got := unexport(test.name); got != test.want { t.Errorf("unexport(%q) = %q; want %q", test.name, got, test.want) } } } func TestExport(t *testing.T) { tests := []struct { name string want string }{ {"", ""}, {"a", "A"}, {"ab", "Ab"}, {"A", "A"}, {"AB", "AB"}, {"A_", "A_"}, {"ABc", "ABc"}, {"ABC", "ABC"}, {"AB_", "AB_"}, {"foo", "Foo"}, {"Foo", "Foo"}, {"HTTPClient", "HTTPClient"}, {"httpClient", "HttpClient"}, {"IFace", "IFace"}, {"iFace", "IFace"}, {"SNAKE_CASE", "SNAKE_CASE"}, {"HTTP", "HTTP"}, } for _, test := range tests { if got := export(test.name); got != test.want { t.Errorf("export(%q) = %q; want %q", test.name, got, test.want) } } } func TestTypeVariableName(t *testing.T) { var ( boolT = types.Typ[types.Bool] stringT = types.Typ[types.String] fooVarT = types.NewNamed(types.NewTypeName(0, nil, "foo", stringT), stringT, nil) nonameVarT = types.NewNamed(types.NewTypeName(0, nil, "", stringT), stringT, nil) barVarInFooPkgT = types.NewNamed(types.NewTypeName(0, types.NewPackage("my.example/foo", "foo"), "bar", stringT), stringT, nil) ) tests := []struct { description string typ types.Type defaultName string transformAppend string collides map[string]bool want string }{ {"basic type", boolT, "", "", map[string]bool{}, "bool"}, {"basic type with transform", boolT, "", "suffix", map[string]bool{}, "boolsuffix"}, {"basic type with collision", boolT, "", "", map[string]bool{"bool": true}, "bool2"}, {"basic type with transform and collision", boolT, "", "suffix", map[string]bool{"boolsuffix": true}, "boolsuffix2"}, {"a different basic type", stringT, "", "", map[string]bool{}, "string"}, {"named type", fooVarT, "", "", map[string]bool{}, "foo"}, {"named type with transform", fooVarT, "", "suffix", map[string]bool{}, "foosuffix"}, {"named type with collision", fooVarT, "", "", map[string]bool{"foo": true}, "foo2"}, {"named type with transform and collision", fooVarT, "", "suffix", map[string]bool{"foosuffix": true}, "foosuffix2"}, {"noname type", nonameVarT, "bar", "", map[string]bool{}, "bar"}, {"noname type with transform", nonameVarT, "bar", "s", map[string]bool{}, "bars"}, {"noname type with transform and collision", nonameVarT, "bar", "s", map[string]bool{"bars": true}, "bars2"}, {"var in pkg type", barVarInFooPkgT, "", "", map[string]bool{}, "bar"}, {"var in pkg type with collision", barVarInFooPkgT, "", "", map[string]bool{"bar": true}, "fooBar"}, {"var in pkg type with double collision", barVarInFooPkgT, "", "", map[string]bool{"bar": true, "fooBar": true}, "bar2"}, } for _, test := range tests { t.Run(fmt.Sprintf("%s: typeVariableName(%v, %q, %q, %v)", test.description, test.typ, test.defaultName, test.transformAppend, test.collides), func(t *testing.T) { got := typeVariableName(test.typ, test.defaultName, func(name string) string { return name + test.transformAppend }, func(name string) bool { return test.collides[name] }) if !isIdent(got) { t.Errorf("%q is not an identifier", got) } if got != test.want { t.Errorf("got %q want %q", got, test.want) } if test.collides[got] { t.Errorf("%q collides", got) } }) } } func TestDisambiguate(t *testing.T) { tests := []struct { name string want string collides map[string]bool }{ {"foo", "foo", nil}, {"foo", "foo2", map[string]bool{"foo": true}}, {"foo", "foo3", map[string]bool{"foo": true, "foo1": true, "foo2": true}}, {"foo1", "foo1_2", map[string]bool{"foo": true, "foo1": true, "foo2": true}}, {"foo\u0661", "foo\u0661", map[string]bool{"foo": true, "foo1": true, "foo2": true}}, {"foo\u0661", "foo\u06612", map[string]bool{"foo": true, "foo1": true, "foo2": true, "foo\u0661": true}}, {"select", "select2", nil}, {"var", "var2", nil}, } for _, test := range tests { t.Run(fmt.Sprintf("disambiguate(%q, %v)", test.name, test.collides), func(t *testing.T) { got := disambiguate(test.name, func(name string) bool { return test.collides[name] }) if !isIdent(got) { t.Errorf("%q is not an identifier", got) } if got != test.want { t.Errorf("got %q want %q", got, test.want) } if test.collides[got] { t.Errorf("%q collides", got) } }) } } func isIdent(s string) bool { if len(s) == 0 { return false } r, i := utf8.DecodeRuneInString(s) if !unicode.IsLetter(r) && r != '_' { return false } for i < len(s) { r, sz := utf8.DecodeRuneInString(s[i:]) if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '_' { return false } i += sz } return true } // scrubError rewrites the given string to remove occurrences of GOPATH/src, // rewrites OS-specific path separators to slashes, and any line/column // information to a fixed ":x:y". For example, if the gopath parameter is // "C:\GOPATH" and running on Windows, the string // "C:\GOPATH\src\foo\bar.go:15:4" would be rewritten to "foo/bar.go:x:y". func scrubError(gopath string, s string) string { sb := new(strings.Builder) query := gopath + string(os.PathSeparator) + "src" + string(os.PathSeparator) for { // Find next occurrence of source root. This indicates the next path to // scrub. start := strings.Index(s, query) if start == -1 { sb.WriteString(s) break } // Find end of file name (extension ".go"). fileStart := start + len(query) fileEnd := strings.Index(s[fileStart:], ".go") if fileEnd == -1 { // If no ".go" occurs to end of string, further searches will fail too. // Break the loop. sb.WriteString(s) break } fileEnd += fileStart + 3 // Advance to end of extension. // Write out file name and advance scrub position. file := s[fileStart:fileEnd] if os.PathSeparator != '/' { file = strings.Replace(file, string(os.PathSeparator), "/", -1) } sb.WriteString(s[:start]) sb.WriteString(file) s = s[fileEnd:] // Peek past to see if there is line/column info. linecol, linecolLen := scrubLineColumn(s) sb.WriteString(linecol) s = s[linecolLen:] } return sb.String() } func scrubLineColumn(s string) (replacement string, n int) { if !strings.HasPrefix(s, ":") { return "", 0 } // Skip first colon and run of digits. for n++; len(s) > n && '0' <= s[n] && s[n] <= '9'; { n++ } if n == 1 { // No digits followed colon. return "", 0 } // Start on column part. if !strings.HasPrefix(s[n:], ":") { return ":x", n } lineEnd := n // Skip second colon and run of digits. for n++; len(s) > n && '0' <= s[n] && s[n] <= '9'; { n++ } if n == lineEnd+1 { // No digits followed second colon. return ":x", lineEnd } return ":x:y", n } type testCase struct { name string pkg string header []byte goFiles map[string][]byte wantProgramOutput []byte wantWireOutput []byte wantWireError bool wantWireErrorStrings []string } // loadTestCase reads a test case from a directory. // // The directory structure is: // // root/ // // pkg // file containing the package name containing the inject function // (must also be package main) // // ... // any Go files found recursively placed under GOPATH/src/... // // want/ // // wire_errs.txt // Expected errors from the Wire Generate function, // missing if no errors expected. // Distinct errors are separated by a blank line, // and line numbers and line positions are scrubbed // (e.g. "$GOPATH/src/foo.go:52:8" --> "foo.go:x:y"). // // wire_gen.go // verified output of wire from a test run with // -record, missing if wire_errs.txt is present // // program_out.txt // expected output from the final compiled program, // missing if wire_errs.txt is present // func loadTestCase(root string, wireGoSrc []byte) (*testCase, error) { name := filepath.Base(root) pkg, err := ioutil.ReadFile(filepath.Join(root, "pkg")) if err != nil { return nil, fmt.Errorf("load test case %s: %v", name, err) } header, _ := ioutil.ReadFile(filepath.Join(root, "header")) var wantProgramOutput []byte var wantWireOutput []byte wireErrb, err := ioutil.ReadFile(filepath.Join(root, "want", "wire_errs.txt")) wantWireError := err == nil var wantWireErrorStrings []string if wantWireError { wantWireErrorStrings = strings.Split(string(wireErrb), "\n\n") } else { if !*record { wantWireOutput, err = ioutil.ReadFile(filepath.Join(root, "want", "wire_gen.go")) if err != nil { return nil, fmt.Errorf("load test case %s: %v, if this is a new testcase, run with -record to generate the wire_gen.go file", name, err) } } wantProgramOutput, err = ioutil.ReadFile(filepath.Join(root, "want", "program_out.txt")) if err != nil { return nil, fmt.Errorf("load test case %s: %v", name, err) } } goFiles := map[string][]byte{ "github.com/google/wire/wire.go": wireGoSrc, } err = filepath.Walk(root, func(src string, info os.FileInfo, err error) error { if err != nil { return err } rel, err := filepath.Rel(root, src) if err != nil { return err // unlikely } if info.Mode().IsDir() && rel == "want" { // The "want" directory should not be included in goFiles. return filepath.SkipDir } if !info.Mode().IsRegular() || filepath.Ext(src) != ".go" { return nil } data, err := ioutil.ReadFile(src) if err != nil { return err } goFiles["example.com/"+filepath.ToSlash(rel)] = data return nil }) if err != nil { return nil, fmt.Errorf("load test case %s: %v", name, err) } return &testCase{ name: name, pkg: string(bytes.TrimSpace(pkg)), header: header, goFiles: goFiles, wantWireOutput: wantWireOutput, wantProgramOutput: wantProgramOutput, wantWireError: wantWireError, wantWireErrorStrings: wantWireErrorStrings, }, nil } // materialize creates a new GOPATH at the given directory, which may or // may not exist. func (test *testCase) materialize(gopath string) error { for name, content := range test.goFiles { dst := filepath.Join(gopath, "src", filepath.FromSlash(name)) if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil { return fmt.Errorf("materialize GOPATH: %v", err) } if err := ioutil.WriteFile(dst, content, 0666); err != nil { return fmt.Errorf("materialize GOPATH: %v", err) } } // Add go.mod files to example.com and github.com/google/wire. const importPath = "example.com" const depPath = "github.com/google/wire" depLoc := filepath.Join(gopath, "src", filepath.FromSlash(depPath)) example := fmt.Sprintf("module %s\n\nrequire %s v0.1.0\nreplace %s => %s\n", importPath, depPath, depPath, depLoc) gomod := filepath.Join(gopath, "src", filepath.FromSlash(importPath), "go.mod") if err := ioutil.WriteFile(gomod, []byte(example), 0666); err != nil { return fmt.Errorf("generate go.mod for %s: %v", gomod, err) } if err := ioutil.WriteFile(filepath.Join(depLoc, "go.mod"), []byte("module "+depPath+"\n"), 0666); err != nil { return fmt.Errorf("generate go.mod for %s: %v", depPath, err) } return nil } wire-0.4.0/wire.go000066400000000000000000000171371357423046500140000ustar00rootroot00000000000000// 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 contains directives for Wire code generation. // For an overview of working with Wire, see the user guide at // https://github.com/google/wire/blob/master/docs/guide.md // // The directives in this package are used as input to the Wire code generation // tool. The entry point of Wire's analysis are injector functions: function // templates denoted by only containing a call to Build. The arguments to Build // describes a set of providers and the Wire code generation tool builds a // directed acylic graph of the providers' output types. The generated code will // fill in the function template by using the providers from the provider set to // instantiate any needed types. package wire // ProviderSet is a marker type that collects a group of providers. type ProviderSet struct{} // NewSet creates a new provider set that includes the providers in its // arguments. Each argument is a function value, a provider set, a call to // Struct, a call to Bind, a call to Value, a call to InterfaceValue or a call // to FieldsOf. // // Passing a function value to NewSet declares that the function's first // return value type will be provided by calling the function. The arguments // to the function will come from the providers for their types. As such, all // the function's parameters must be of non-identical types. The function may // optionally return an error as its last return value and a cleanup function // as the second return value. A cleanup function must be of type func() and is // guaranteed to be called before the cleanup function of any of the // provider's inputs. If any provider returns an error, the injector function // will call all the appropriate cleanup functions and return the error from // the injector function. // // Passing a ProviderSet to NewSet is the same as if the set's contents // were passed as arguments to NewSet directly. // // The behavior of passing the result of a call to other functions in this // package are described in their respective doc comments. // // For compatibility with older versions of Wire, passing a struct value of type // S to NewSet declares that both S and *S will be provided by creating a new // value of the appropriate type by filling in each field of S using the // provider of the field's type. This form is deprecated and will be removed in // a future version of Wire: new providers sets should use wire.Struct. func NewSet(...interface{}) ProviderSet { return ProviderSet{} } // Build is placed in the body of an injector function template to declare the // providers to use. The Wire code generation tool will fill in an // implementation of the function. The arguments to Build are interpreted the // same as NewSet: they determine the provider set presented to Wire's // dependency graph. Build returns an error message that can be sent to a call // to panic(). // // The parameters of the injector function are used as inputs in the dependency // graph. // // Similar to provider functions passed into NewSet, the first return value is // the output of the injector function, the optional second return value is a // cleanup function, and the optional last return value is an error. If any of // the provider functions in the injector function's provider set return errors // or cleanup functions, the corresponding return value must be present in the // injector function template. // // Examples: // // func injector(ctx context.Context) (*sql.DB, error) { // wire.Build(otherpkg.FooSet, myProviderFunc) // return nil, nil // } // // func injector(ctx context.Context) (*sql.DB, error) { // panic(wire.Build(otherpkg.FooSet, myProviderFunc)) // } func Build(...interface{}) string { return "implementation not generated, run wire" } // A Binding maps an interface to a concrete type. type Binding struct{} // Bind declares that a concrete type should be used to satisfy a dependency on // the type of iface. iface must be a pointer to an interface type, to must be a // pointer to a concrete type. // // Example: // // type Fooer interface { // Foo() // } // // type MyFoo struct{} // // func (MyFoo) Foo() {} // // var MySet = wire.NewSet( // wire.Struct(new(MyFoo)) // wire.Bind(new(Fooer), new(MyFoo))) func Bind(iface, to interface{}) Binding { return Binding{} } // bindToUsePointer is detected by the wire tool to indicate that Bind's second argument should take a pointer. // See https://github.com/google/wire/issues/120 for details. const bindToUsePointer = true // A ProvidedValue is an expression that is copied to the generated injector. type ProvidedValue struct{} // Value binds an expression to provide the type of the expression. // The expression may not be an interface value; use InterfaceValue for that. // // Example: // // var MySet = wire.NewSet(wire.Value([]string(nil))) func Value(interface{}) ProvidedValue { return ProvidedValue{} } // InterfaceValue binds an expression to provide a specific interface type. // The first argument is a pointer to the interface which user wants to provide. // The second argument is the actual variable value whose type implements the // interface. // // Example: // // var MySet = wire.NewSet(wire.InterfaceValue(new(io.Reader), os.Stdin)) func InterfaceValue(typ interface{}, x interface{}) ProvidedValue { return ProvidedValue{} } // A StructProvider represents a named struct. type StructProvider struct{} // Struct specifies that the given struct type will be provided by filling in // the fields in the struct that have the names given. // // The first argument must be a pointer to the struct type. For a struct type // Foo, Wire will use field-filling to provide both Foo and *Foo. The remaining // arguments are field names to fill in. As a special case, if a single name "*" // is given, then all of the fields in the struct will be filled in. // // For example: // // type S struct { // MyFoo *Foo // MyBar *Bar // } // var Set = wire.NewSet(wire.Struct(new(S), "MyFoo")) -> inject only S.MyFoo // var Set = wire.NewSet(wire.Struct(new(S), "*")) -> inject all fields func Struct(structType interface{}, fieldNames ...string) StructProvider { return StructProvider{} } // StructFields is a collection of the fields from a struct. type StructFields struct{} // FieldsOf declares that the fields named of the given struct type will be used // to provide the types of those fields. The structType argument must be a // pointer to the struct or a pointer to a pointer to the struct it wishes to reference. // // The following example would provide Foo and Bar using S.MyFoo and S.MyBar respectively: // // type S struct { // MyFoo Foo // MyBar Bar // } // // func NewStruct() S { /* ... */ } // var Set = wire.NewSet(wire.FieldsOf(new(S), "MyFoo", "MyBar")) // // or // // func NewStruct() *S { /* ... */ } // var Set = wire.NewSet(wire.FieldsOf(new(*S), "MyFoo", "MyBar")) // // If the structType argument is a pointer to a pointer to a struct, then FieldsOf // additionally provides a pointer to each field type (e.g., *Foo and *Bar in the // example above). func FieldsOf(structType interface{}, fieldNames ...string) StructFields { return StructFields{} }