Skip to content
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

x/tools/gopls: code action "Extract interface for type" #65721

Open
martskins opened this issue Feb 15, 2024 · 4 comments · May be fixed by golang/tools#478
Open

x/tools/gopls: code action "Extract interface for type" #65721

martskins opened this issue Feb 15, 2024 · 4 comments · May be fixed by golang/tools#478
Labels
FeatureRequest gopls Issues related to the Go language server, gopls. Refactoring Issues related to refactoring tools Tools This label describes issues relating to any tools in the x/tools repository.

Comments

@martskins
Copy link

gopls version

Irrelevant

go env

Irrelevant

What did you do?

Given the following code:

type Server struct {
    api *api.Client
}

func (s *Server) CreateUser(ctx context.Context, userID string) {
    err := s.api.CreateUser(ctx, userID)
    // ...
}

func (s *Server) DeleteUser(ctx context.Context, userID string) {
    err := s.api.DeleteUser(ctx, userID)
    // ...
}

What did you see happen?

It would be nice if gopls offered an action to extract an interface out of the used methods on the api field. So for the example given above, it would offer an edit to do something like this:

type Client interface {
    CreateUser(context.Context, string) error
    DeleteUser(context.Context, string) error
}

type Server struct {
    api Client
}

Where the method set of the generated interface is the methods that are called on the field that the action was initiated on, and if there are uses that are not method calls on that field then it would either error or just not offer the action.

What did you expect to see?

Nothing

Editor and settings

No response

Logs

No response

@martskins martskins added gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository. labels Feb 15, 2024
@gopherbot gopherbot added this to the Unreleased milestone Feb 15, 2024
@findleyr findleyr changed the title x/tools/gopls: code action "Extract interface" x/tools/gopls: code action "Extract interface for type" Feb 15, 2024
@findleyr
Copy link
Contributor

This looks very similar to #46665, though that is more about extracting the interface of an argument, not an entire type. I think both may be useful, so they are distinct issues.

@findleyr findleyr added Refactoring Issues related to refactoring tools FeatureRequest labels Feb 15, 2024
@findleyr findleyr modified the milestones: Unreleased, gopls/unplanned Feb 15, 2024
@martskins
Copy link
Author

Oh sorry! missed that one! It does look very similar, and I don't really see the difference to be honest! In any case, I'll probably take a stab at this one at some point in the next few days, so I'll send a CL your way once I have something that kinda works!

@adonovan
Copy link
Member

If the interface is to be based on the set of methods actually used, as opposed to all those defined, then this requires a global query on the field, analogous to a "references" query on a field, which is quite a complex operation and one not factored as a building block for other tasks. Embedding further complicates matters, because it's not enough to find all references to f in type S struct { f T }, you may have to find all places that embed an S as well.

In short, I don't think this is an easy project.

@martskins
Copy link
Author

@adonovan I didn't see your comment until now when I came back to fetch the link for the issue to add it to the PR description 😅

I opened a draft to try and get some feedback on it. I essentially re-used the references query you mentioned (actually the one that wraps that one). I didn't consider embedded fields to be honest, and it doesn't offer the action in that case now (not a conscious decision I took though). I'll take a look at embedded fields later though!

I'm sure re-using references like I did is far from ideal, so if you think that PR is very far from what you think is an acceptable implementation I'm happy to just close it and let someone with more experience take care of that one!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest gopls Issues related to the Go language server, gopls. Refactoring Issues related to refactoring tools Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants