-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[Feature Request] New refactoring: convert positional parameters to named ones #45675
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
Comments
Oh and I want to thank the team to have added the 'extract local variable' into the LSP. I was badly missing it :-) |
Only 16 days old and this is currently our 4th most upvoted request. @bwilkerson I'm thinking of tackling this one; never written a refactoring, but looking at This is easier to implement for a pre-null safety library than a null safe library; less to worry about. With null safety, we can send clear signals about requirability; pre-null safety, we could use I'm tempted to just implement the second request ("convert ALL positional parameters to named") because the first request ("convert THIS positional parameter to named") would not be possible if there are any remaining optional params ( Then again, if you only want to convert all of your optional positional parameters to be named, and you also have non-optional positional parameters which you'd like to remain positional, the second request doesn't help you a lot, because you'd have to manually undo the change to those parameters. :( Let's look at some examples, assuming null safety: - void m1(int a);
+ void m1({required int a});
- void m2(int a, [int? b]);
+ void m2({required int a, int? b});
- void m3(int a, [int b = 1]);
+ void m3({required int a, int b = 1});
- void m3(int a, {int? b});
+ void m3({required int a, int? b}); Not too tricky:
|
I would propose the following rules:
|
@srawlins I would love to see some progress along these lines, but I have a few comments for you to consider. First, in LSP we can implement some refactorings as code actions, but only those for which no additional input is required from the user. That's how we implemented 'extract local variable'. I suspect that in this case that's sufficient because we can use the selection to indicate the range of parameters to be converted. But in the legacy protocol, used by IntelliJ, we have to do work in both the server and the client in order to implement a refactoring. I have an idea for removing that limitation, and would be happy to discuss it if you're interested, but you need to be aware that we can't support a refactoring in all our clients without a bit more work than it might first appear to require. Second, I'll note that this is a subset of a larger and more powerful refactoring to change the signature of a method / function. We have most of the implementation for the larger refactoring as part of the data-driven fixes work, so implementing the more general refactoring would primarily require refactoring some of that implementation to make it more reusable. I'd really like to be able to support the fully featured refactoring, but the limitations described above have so far prevented us (we'd need user feedback to specify the changes). It's probably the case that we should just implement the smaller refactorings (subsets of the 'change signature' refactoring) rather than wait for a hoped future ability to implement the full feature set, but I thought it worth mentioning. Third, and related to the second, I think we need to be careful to not end up with so many smaller refactorings that the user interface becomes unusable. We're certainly nowhere near that point now, of course, but we should think strategically about whether there is overlap that could be avoided. (I don't see a better alternative in these cases, but I haven't spent much time thinking about it.) Caveats aside, yes, a refactoring is similar to a quick fix. A refactoring can spend the time to search the whole code base for, for example, invocations of the method being refactored in order to clean them up. Quick fixes and quick assists can't. And that's really the only significant difference: the performance characteristics. I do have one request: it has been a long-standing goal to convert the refactorings over to using
I think we should implement this for null-safe libraries only, at least for the first round. The community appears to be moving quickly to null safety, so there might not be as much value to users in implementing support for pre-null-safe libraries. The one think I'll note is that refactorings can (like quick fixes) add imports when necessary (so we could always use |
I agree that this looks like a great candidate for code actions.
I think that implementing these various signature-refactoring ideas one-at-a-time might be a great way to incrementally get to a state where we look at converting to a big "Change signature" refactor which requires UI etc. So whether we get there or not, the individual refactorings help users as they land.
Ack.
Ack, will do.
Ack. |
Bug: #45675 Change-Id: I396228ec9306353b4bd269abedd3879d0c10a02f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306160 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]>
https://dart-review.googlesource.com/c/sdk/+/308841 This CL adds it to VS Code. |
@scheglov That's nice, but what about if we want to refactor only a single parameter? |
This is a beginning, I plan to add a family of commands that manipulate formal parameters.
Unfortunately, this is what we have to do in text editors (like VS Code) that don't support dialogs. |
Bug: #45675 Change-Id: I611648a47bb59acd2db55e7cd77c2504ff83c4cb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308841 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]>
That looks epic! It'll change the life of many devs for sure |
Absolutely awesome. Unfortunately two weeks too late for a big refactoring that was almost completely about converting positional to named parameters. Great to know that this will be easier in future now |
Is this still an open issue? It looks like https://dart-review.googlesource.com/c/sdk/+/310764 was merged and that commit was part of the 3.1.0 dart sdk. So it seems like this is done, but we're using dart 3.1.2 and flutter 3.13.5 but I don't see this refactoring option in Android studio or VSCode. Should we be seeing it? If not, what can we can help do to move this forward? |
Turns out it's available, but as an experiment. Searching "refactor" in the latest VSCode settings will show the option to enable experimental refactors. Haven't figured out how to do it in Android Studio yet. |
Hi,
when maintaining a project for a longer time its easy to happen that the number of positional parameters grow with new features and suddenly you are faced with 10 positional parameters. Changing them to named ones especially where the function is invoked is a tedious process, so you probably add an 11 positional the next time.
So it would be great if the language server would support two additional options:
This would be extremely helpful
The text was updated successfully, but these errors were encountered: