From ab113bf8d10b83dd0d0467f422e5bf5dad17ec11 Mon Sep 17 00:00:00 2001 From: Robert van Gent Date: Fri, 2 Nov 2018 13:58:15 -0700 Subject: [PATCH] wire: allow wire.Value to use values with no parent (i.e., struct fields) (google/go-cloud#596) --- README.md | 6 +++- .../wire/testdata/UnexportedStruct/bar/bar.go | 21 ++++++++++++++ .../wire/testdata/UnexportedStruct/foo/foo.go | 21 ++++++++++++++ .../testdata/UnexportedStruct/foo/wire.go | 28 +++++++++++++++++++ internal/wire/testdata/UnexportedStruct/pkg | 1 + .../UnexportedStruct/want/wire_errs.txt | 1 + .../wire/testdata/UnexportedValue/foo/wire.go | 1 + .../wire/testdata/ValueIsStruct/foo/foo.go | 28 +++++++++++++++++++ .../wire/testdata/ValueIsStruct/foo/wire.go | 26 +++++++++++++++++ internal/wire/testdata/ValueIsStruct/pkg | 1 + .../ValueIsStruct/want/program_out.txt | 1 + .../testdata/ValueIsStruct/want/wire_gen.go | 17 +++++++++++ internal/wire/wire.go | 2 +- 13 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 internal/wire/testdata/UnexportedStruct/bar/bar.go create mode 100644 internal/wire/testdata/UnexportedStruct/foo/foo.go create mode 100644 internal/wire/testdata/UnexportedStruct/foo/wire.go create mode 100644 internal/wire/testdata/UnexportedStruct/pkg create mode 100644 internal/wire/testdata/UnexportedStruct/want/wire_errs.txt create mode 100644 internal/wire/testdata/ValueIsStruct/foo/foo.go create mode 100644 internal/wire/testdata/ValueIsStruct/foo/wire.go create mode 100644 internal/wire/testdata/ValueIsStruct/pkg create mode 100644 internal/wire/testdata/ValueIsStruct/want/program_out.txt create mode 100644 internal/wire/testdata/ValueIsStruct/want/wire_gen.go diff --git a/README.md b/README.md index 065a7cd..98058c7 100644 --- a/README.md +++ b/README.md @@ -327,9 +327,13 @@ The generated injector would look like this: ```go func injectFoo() Foo { - foo := Foo{X: 42} + foo := _wireFooValue return foo } + +var ( + _wireFooValue = Foo{X: 42} +) ``` It's important to note that the expression will be copied to the injector's diff --git a/internal/wire/testdata/UnexportedStruct/bar/bar.go b/internal/wire/testdata/UnexportedStruct/bar/bar.go new file mode 100644 index 0000000..430d2fb --- /dev/null +++ b/internal/wire/testdata/UnexportedStruct/bar/bar.go @@ -0,0 +1,21 @@ +// Copyright 2018 The Go Cloud Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 +} + + diff --git a/internal/wire/testdata/UnexportedStruct/foo/foo.go b/internal/wire/testdata/UnexportedStruct/foo/foo.go new file mode 100644 index 0000000..61e3f91 --- /dev/null +++ b/internal/wire/testdata/UnexportedStruct/foo/foo.go @@ -0,0 +1,21 @@ +// Copyright 2018 The Go Cloud Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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()) +} diff --git a/internal/wire/testdata/UnexportedStruct/foo/wire.go b/internal/wire/testdata/UnexportedStruct/foo/wire.go new file mode 100644 index 0000000..88b3785 --- /dev/null +++ b/internal/wire/testdata/UnexportedStruct/foo/wire.go @@ -0,0 +1,28 @@ +// Copyright 2018 The Go Cloud Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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/go-cloud/wire" +) + +func injectedBar() string { + // Fails because bar.foo is unexported. + wire.Build(bar.foo.X) + return "" +} diff --git a/internal/wire/testdata/UnexportedStruct/pkg b/internal/wire/testdata/UnexportedStruct/pkg new file mode 100644 index 0000000..f7a5c8c --- /dev/null +++ b/internal/wire/testdata/UnexportedStruct/pkg @@ -0,0 +1 @@ +example.com/foo diff --git a/internal/wire/testdata/UnexportedStruct/want/wire_errs.txt b/internal/wire/testdata/UnexportedStruct/want/wire_errs.txt new file mode 100644 index 0000000..36f9cc7 --- /dev/null +++ b/internal/wire/testdata/UnexportedStruct/want/wire_errs.txt @@ -0,0 +1 @@ +/wire_gopath/src/example.com/foo/wire.go:x:y: foo not exported by package bar \ No newline at end of file diff --git a/internal/wire/testdata/UnexportedValue/foo/wire.go b/internal/wire/testdata/UnexportedValue/foo/wire.go index e51f468..691014c 100644 --- a/internal/wire/testdata/UnexportedValue/foo/wire.go +++ b/internal/wire/testdata/UnexportedValue/foo/wire.go @@ -22,6 +22,7 @@ import ( ) func injectedMessage() string { + // Fails because bar.Value references unexported bar.privateMsg. wire.Build(bar.Value) return "" } diff --git a/internal/wire/testdata/ValueIsStruct/foo/foo.go b/internal/wire/testdata/ValueIsStruct/foo/foo.go new file mode 100644 index 0000000..cc9c682 --- /dev/null +++ b/internal/wire/testdata/ValueIsStruct/foo/foo.go @@ -0,0 +1,28 @@ +// Copyright 2018 The Go Cloud Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 +} diff --git a/internal/wire/testdata/ValueIsStruct/foo/wire.go b/internal/wire/testdata/ValueIsStruct/foo/wire.go new file mode 100644 index 0000000..07881ec --- /dev/null +++ b/internal/wire/testdata/ValueIsStruct/foo/wire.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Cloud Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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/go-cloud/wire" +) + +func injectFoo() Foo { + wire.Build(wire.Value(Foo{X: 42})) + return Foo{} +} diff --git a/internal/wire/testdata/ValueIsStruct/pkg b/internal/wire/testdata/ValueIsStruct/pkg new file mode 100644 index 0000000..f7a5c8c --- /dev/null +++ b/internal/wire/testdata/ValueIsStruct/pkg @@ -0,0 +1 @@ +example.com/foo diff --git a/internal/wire/testdata/ValueIsStruct/want/program_out.txt b/internal/wire/testdata/ValueIsStruct/want/program_out.txt new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/internal/wire/testdata/ValueIsStruct/want/program_out.txt @@ -0,0 +1 @@ +42 diff --git a/internal/wire/testdata/ValueIsStruct/want/wire_gen.go b/internal/wire/testdata/ValueIsStruct/want/wire_gen.go new file mode 100644 index 0000000..5448a5c --- /dev/null +++ b/internal/wire/testdata/ValueIsStruct/want/wire_gen.go @@ -0,0 +1,17 @@ +// 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} +) diff --git a/internal/wire/wire.go b/internal/wire/wire.go index ef748cb..a44da21 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -845,7 +845,7 @@ func accessibleFrom(info *types.Info, node ast.Node, wantPkg string) error { unexportError = fmt.Errorf("uses unexported identifier %s", obj.Name()) return false } - if obj.Parent() != pkg.Scope() { + if obj.Parent() != nil && obj.Parent() != pkg.Scope() { unexportError = fmt.Errorf("%s is not declared in package scope", obj.Name()) return false }