One of the things that really set ReScript apart from the alternatives is its incredible type system. The characteristics of it feels like it should lend itself well to advanced refactoring features that would be hard or impossible in other, weaker type systems.
Me and @cristianoc have been chatting a bit about this and related topics, and it would be very interesting for us as a community to start throwing ideas around for refactoring features that can be explored.
So, let us throw some ideas around for refactoring features that could be helpful for our day to day work using ReScript! I suggest we try and focus on features that’d be as impactful as possible, but any idea is of course welcome, small as large. This is a really interesting space, and I’m sure we as a community can come up with a ton of interesting features that can eventually be considered for implementation.
Removing a variant member, including all pattern matches for it. Same rationale as adding a new variant member - removes a bunch of manual work in removing pattern matches.
// Before
type someVariant = FirstMember | SecondMember(int)
let someFunc = value => switch value {
| FirstMember => "Hello!"
| SecondMember(someInt) => "Hello " ++ string_of_int(someInt)
}
// After doing "remove variant member" on SecondMember
type someVariant = FirstMember
let someFunc = value => switch value {
| FirstMember => "Hello!"
}
A note about refactoring with placeholders.
I don’t like automatic adding of patterns on several places since you can easily ignore those patterns (a todo comment is not useful here IMO).
I prefer having an action (codelens action in vscode) on non exhaustive warnings saying “hey this pattern matching is not exhaustive do you want me to add missing patterns”?
Great topic! I’d like “simple” things like renaming to work across a project (the one recently added in the vs code extension is not always working for me).
Random ideas for some vs code refactoring actions:
Rewrite if / else to a switch and maybe the other way around as well.
Add inferred type to the code on fields, functions etc…
Add missing branches in a switch.
Delete refactoring to remove all usages of a field / Module / etc…
Maybe an advanced feature could be to identify all the types / records / objects with a similar structure. I sometimes find types in different places with the same content but different names. Not a big problem, but could be useful to stay DRY.
I wonder if automatically removing variants from pattern matching is harmless. Your example is trivial, but what if some of those matches will actually show you how that variant was useful, or will require some thoughtful refactoring on the consuming side?
Yeah I can agree on that for sure, although I see them as distinct/separate features. One wouldn’t need to exclude the other, and in my style of development I can see me using both quite extensively.
I’m not quite sure I follow what you mean, could you perhaps examplify? Also note that one could of course simply decide to not use the refactoring functionality, and instead just remove the variant member manually. This would be for the cases when it does make sense to remove all of the matches.
The thing I would appreciate being automated is module refactoring when you want to move a submodule to its own file or the other way around when you want to move a file-level module to a submodule in some other file. I’m pretty sure this is “easily” doable.