-
Notifications
You must be signed in to change notification settings - Fork 157
Package Mode: Use aliases when used in source #220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
v0.5.0 included uber-go#207, which replaced reflect mode with package mode. One issue with package mode that came up (ref: uber-go#216) was that generated mocks for interfaces that referred to alias types were referring to the aliases' underlying names instead. e.g., source: ```go import "github.com/tikv/client-go/v2/internal/apicodec" ... type Codec = apicodec.Codec type Foo interface{ Bar() Codec } ``` mock: ```go func (m *MockFoo) Bar() apicodec.Codec { // This is a problem, since apicodec is an internal package. // ... } ``` While technically this problem is solved in Go 1.23 with explicit alias types representation, (indeed, if you run mockgen on the example in the linked issue with `GODEBUG=gotypesalias=1`, you get the expected behavior) since we support the last two versions, we can't bump `go.mod` to 1.23 yet. This leaves us with the old behavior, where `go/types` does not track alias types. You can tell if an object is an alias, but not a type itself, and there is no way to retrieve the object of interest at the point where we are recursively parsing method types. This PR works around this issue (temporarily) by using syntax information to find all references to aliases in the source package. When we find one, we record it in a mapping of underlying type -> alias name. Later, while we parse the type tree, we replace any underlying types in the mapping with their alias names. The unexpected side effect of this is that _all_ references to the underlying type in the generated mocks will be replaced with the alias, even if the source used the underlying name. This is fine because: * If the alias is in the mapping, it was used at least once, which means its accessible. * From a type-checking perspective, aliases and their underlying types are equivalent. With this PR, the mocks get generated correctly now: ```go func (m *MockFoo) Bar() Codec { // ... } ``` Once we can bump `go.mod` to 1.23, we should definitely remove this, since the new type alias type nodes solve this problem automatically.
r-hang
reviewed
Oct 25, 2024
lverma14
approved these changes
Oct 25, 2024
Merged
apricote
pushed a commit
to hetznercloud/fleeting-plugin-hetzner
that referenced
this pull request
Apr 8, 2025
…eting-plugin-hetzner!238) This MR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [go.uber.org/mock](https://github.com/uber/mock) | require | patch | `v0.5.0` -> `v0.5.1` | --- ### Release Notes <details> <summary>uber/mock (go.uber.org/mock)</summary> ### [`v0.5.1`](https://github.com/uber-go/mock/releases/tag/v0.5.1) [Compare Source](uber-go/mock@v0.5.0...v0.5.1) #### 0.5.1 (7 Apr 2025) ##### Fixed - [#​220][]: Package mode will now generate code that uses aliases of types when they are used in the source. - [#​219][]: Fixed a collision between function argument names and package names in generated code. - [#​165][]: Fixed an issue where aliases specified by `-imports` were not being respected in generated code. [#​220]: uber-go/mock#220 [#​219]: uber-go/mock#219 [#​165]: uber-go/mock#165 Thanks to [@​mtoader](https://github.com/mtoader) and [@​bstncartwright](https://github.com/bstncartwright) for their contributions to this release. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever MR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMzUuMiIsInVwZGF0ZWRJblZlciI6IjM5LjIzNS4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
DennisRasey
pushed a commit
to DennisRasey/forgejo
that referenced
this pull request
Apr 8, 2025
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [go.uber.org/mock](https://github.com/uber/mock) | require | patch | `v0.5.0` -> `v0.5.1` | --- ### Release Notes <details> <summary>uber/mock (go.uber.org/mock)</summary> ### [`v0.5.1`](https://github.com/uber-go/mock/releases/tag/v0.5.1) [Compare Source](uber-go/mock@v0.5.0...v0.5.1) #### 0.5.1 (7 Apr 2025) ##### Fixed - [#​220][]: Package mode will now generate code that uses aliases of types when they are used in the source. - [#​219][]: Fixed a collision between function argument names and package names in generated code. - [#​165][]: Fixed an issue where aliases specified by `-imports` were not being respected in generated code. [#​220]: uber-go/mock#220 [#​219]: uber-go/mock#219 [#​165]: uber-go/mock#165 Thanks to [@​mtoader](https://github.com/mtoader) and [@​bstncartwright](https://github.com/bstncartwright) for their contributions to this release. </details> --- ### Configuration 📅 **Schedule**: Branch creation - "* 0-3 * * *" (UTC), Automerge - "* 0-3 * * *" (UTC). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMzMuNSIsInVwZGF0ZWRJblZlciI6IjM5LjIzMy41IiwidGFyZ2V0QnJhbmNoIjoiZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=--> Co-authored-by: Gusted <[email protected]> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7488 Reviewed-by: Earl Warren <[email protected]> Co-authored-by: Renovate Bot <[email protected]> Co-committed-by: Renovate Bot <[email protected]>
JacobOaks
added a commit
to JacobOaks/mock
that referenced
this pull request
Apr 21, 2025
Alias replacements derived from syntax were introduced in uber-go#220 as a way to ensure the aliases used in source code were also used. This helped ensure packages mode worked on go1.22, which didn't have explicit alias node support in the `go/types` package. Alias replacements have a couple issues: * They flat out replace any would-be references to an underlying type with an alias type. * They don't properly handle aliases to generic type instantiations (ref: uber-go#243) Now that go1.24 is released, we can bump `go.mod` to go1.23, which means we can ensure `go/types` has an explicit `types.Alias` node for type aliases, and we can remove the alias replacement logic.
JacobOaks
added a commit
to JacobOaks/mock
that referenced
this pull request
Apr 21, 2025
Alias replacements derived from syntax were introduced in uber-go#220 as a way to ensure the aliases used in source code were also used. This helped ensure packages mode worked on go1.22, which didn't have explicit alias node support in the `go/types` package. Alias replacements have a couple issues: * They flat out replace any would-be references to an underlying type with an alias type. * They don't properly handle aliases to generic type instantiations (ref: uber-go#243) Now that go1.24 is released, we can bump `go.mod` to go1.23, which means we can ensure `go/types` has an explicit `types.Alias` node for type aliases, and we can remove the alias replacement logic.
JacobOaks
added a commit
to JacobOaks/mock
that referenced
this pull request
Apr 21, 2025
Alias replacements derived from syntax were introduced in uber-go#220 as a way to ensure the aliases used in source code were also used. This helped ensure packages mode worked on go1.22, which didn't have explicit alias node support in the `go/types` package. Alias replacements have a couple issues: * They flat out replace any would-be references to an underlying type with an alias type. * They don't properly handle aliases to generic type instantiations (ref: uber-go#243) Now that go1.24 is released, we can bump `go.mod` to go1.23, which means we can ensure `go/types` has an explicit `types.Alias` node for type aliases, and we can remove the alias replacement logic.
JacobOaks
added a commit
to JacobOaks/mock
that referenced
this pull request
Apr 21, 2025
Alias replacements derived from syntax were introduced in uber-go#220 as a way to ensure the aliases used in source code were also used. This helped ensure packages mode worked on go1.22, which didn't have explicit alias node support in the `go/types` package. Alias replacements have a couple issues: * They flat out replace any would-be references to an underlying type with an alias type. * They don't properly handle aliases to generic type instantiations (ref: uber-go#243) Now that go1.24 is released, we can bump `go.mod` to go1.23, which means we can ensure `go/types` has an explicit `types.Alias` node for type aliases, and we can remove the alias replacement logic.
JacobOaks
added a commit
to JacobOaks/mock
that referenced
this pull request
Apr 21, 2025
Alias replacements derived from syntax were introduced in uber-go#220 as a way to ensure the aliases used in source code were also used. This helped ensure packages mode worked on go1.22, which didn't have explicit alias node support in the `go/types` package. Alias replacements have a couple issues: * They flat out replace any would-be references to an underlying type with an alias type. * They don't properly handle aliases to generic type instantiations (ref: uber-go#243) Now that go1.24 is released, we can bump `go.mod` to go1.23, which means we can ensure `go/types` has an explicit `types.Alias` node for type aliases, and we can remove the alias replacement logic.
JacobOaks
added a commit
that referenced
this pull request
Apr 28, 2025
Alias replacements derived from syntax were introduced in #220 as a way to ensure the aliases used in source code were also used. This helped ensure packages mode worked on go1.22, which didn't have explicit alias node support in the `go/types` package. Alias replacements have a couple issues: * They flat out replace any would-be references to an underlying type with an alias type. * They don't properly handle aliases to generic type instantiations (ref: #243) Now that go1.24 is released, we can bump `go.mod` to go1.23, which means we can ensure `go/types` has an explicit `types.Alias` node for type aliases, and we can remove the alias replacement logic.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
v0.5.0 included #207, which replaced reflect mode with package mode. One issue with package mode that came up (ref: #216) was that generated mocks for interfaces that referred to alias types were referring to the aliases' underlying names instead.
e.g.,
some package:
mockgen input:
mock:
While technically this problem is solved in Go 1.23 with explicit alias types representation, (indeed, if you run mockgen on the example in the linked issue with
GODEBUG=gotypesalias=1, you get the expected behavior) since we support the last two versions, we can't bumpgo.modto 1.23 yet. This leaves us with the old behavior, wherego/typesdoes not track alias types. You can tell if an object is an alias, but not a type itself, and there is no way to retrieve the object of interest at the point where we are recursively parsing method types.This PR works around this issue (temporarily) by using syntax information to find all references to aliases in the source package. When we find one, we record it in a mapping of underlying type -> alias name. Later, while we parse the type tree, we replace any underlying types in the mapping with their alias names.
The unexpected side effect of this is that all references to the underlying type in the generated mocks will be replaced with the alias, even if the source used the underlying name. This is fine because:
The nice exception to the side effect is when we explicitly request mock generation for an alias type, since at that point we are dealing with the object, not the type.
With this PR, the mocks get generated correctly now:
Once we can bump
go.modto 1.23, we should definitely remove this, since the new type alias type nodes solve this problem automatically.