Add move method to parent class refactor
Add a new code action to move the selected method implementation to the parent class. For example:
# BEFORE
class Parent
end
class Child < Parent
def foo
end
end
# AFTER
class Parent
def foo
end
end
class Child < Parent
end
Here's an example PR adding a refactor end to end https://github.com/Shopify/ruby-lsp/pull/2372.
I'd suggest calling this "Pull Up Method" to match the naming in https://refactoring.com/catalog/
Hi there,
I have a working implementation of this, but I had a few questions related to it. There's going to be two separate paths here for definition where the superclass will be defined in the same file or the superclass is defined in a different file. There's a few usability issues with situations where it's in a separate file:
-
Triggering the opening of the edited file after the edit command. I can't seem to find a standard way to trigger an open event for a file that's supported. I can send vscode specific commands and it works great, but the solution here has to be agnostic because other editors use
ruby-lspas well. Modifying multiple buffers seems to open a bit of a can of worms from a UX/DX perspective. -
Certainty around the definition file. I'm currently using the index to locate the superclass, which is fine if there's just one located for it I think, but there's no way for gathering additional context through code actions in VSCode currently as far as I can see (through the extension or otherwise)
It may make sense for now to just have this work when it's in the same file, but I'm still getting familiar with the codebase and wanted to check before I get too in the weeds here.
Hello!
- There are two steps to this. The code action will need to use a workspace edit to make modifications across different files. And then you can use the show document notification to request that the resource be opened by the client. Notice that not every editor supports that, so you will need to handle the client capability. Also, it's more than acceptable to start with an implementation that only handles the first part and then we can follow up with the rest
- This problem is kind of intrinsic to Ruby. There's no right answer here because you can have as many re-openings of the parent class as you like. In terms of the resulting code, putting the extracted in any of them will produce valid code, but you won't be able to guess in which file the user wanted the extraction to land on. IMO, the implementation will need to check if any of the available parent class re-openings are currently opened by the client and then we prefer those (since the user is already interacting with those files). If none is found, then just pick any that are inside the current workspace