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

Add basic support for move function refactoring #226

Merged
merged 7 commits into from
Mar 24, 2020

Conversation

jmbockhorst
Copy link
Member

@jmbockhorst jmbockhorst commented Mar 20, 2020

Part of #194. It adds basic support for a new code action to move a function to a new file. It is a fair amount of changes so I wanted to get your feedback to make sure it was a good direction.

Because this type of refactoring requires client support (quick pick for the destination file),
I added a new extendedCapabilites property to the client settings that the client can initialize. Right now the only property is moveFunctionRefactoringSupport, but more can easily be added.

I also added a protocol.ts that defines the custom requests between the server and client.

Currently, in vscode, you can move a function to a new file and it adds new imports to all files with references. Dependent on elm-tooling/elm-language-client-vscode#88.

@razzeee
Copy link
Member

razzeee commented Mar 20, 2020

Approach looks okay to me, it's unfortunate, that it needs client support, but that's how it is with language server at the moment. Until this moves further microsoft/language-server-protocol#764

Can you please install and use prettier via https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
You seem to be using tabs and some other styling that is inconsistent to our prettier rules.

@jmbockhorst jmbockhorst marked this pull request as ready for review March 21, 2020 00:51
@jmbockhorst
Copy link
Member Author

The core functionality is complete. Moving a function properly updates the module exposing values for the old and new files, and removes and adds the proper imports for all references. I tested this for a while and it seemed to work pretty well, but there is sure to be an edge case that could break it.

@jmbockhorst jmbockhorst requested a review from razzeee March 21, 2020 00:54
@razzeee
Copy link
Member

razzeee commented Mar 22, 2020

  1. I'm not convinced, auto exposing it in every file is the way to go, especially if it was never used like this.

  2. If it has been fully referenced e.g. Feed.viewPagination doesn't get changed to xxx.viewPagination.

  3. Doc comments doesn't seem to be moved together with the function.

I think we should at least fix 1 and 3 before we merge this.

@jmbockhorst
Copy link
Member Author

What do you mean by 1? Auto exposing the moved function in the destination file? Currently it only gets exposed if there is an external reference that needs it.

@razzeee
Copy link
Member

razzeee commented Mar 22, 2020

Kinda correct, it correlates with 2, as you don't seem to differentiate between fully qualified (Feed.viewPagination) and exposed (viewPagination)

I tested it with the elm-spa-example https://github.com/rtfeldman/elm-spa-example/blob/master/src/Article/Feed.elm#L172

@jmbockhorst
Copy link
Member Author

We also need to update references or add imports for any functions or types used within the moved function.

@razzeee
Copy link
Member

razzeee commented Mar 22, 2020

Yes, would be nice, but I think it would already be useful without, as Elm will just complain to you about it :)

@jmbockhorst
Copy link
Member Author

So to be clear, if a file only has fully qualified references to the function (xxx.function), we don't need to expose it (just import). Only expose it if we need it, when there is an exposed reference to it in the file (function).

@razzeee
Copy link
Member

razzeee commented Mar 23, 2020 via email

@jmbockhorst
Copy link
Member Author

It now properly handles fully qualified references:

  • Don't expose the import if all uses are fully qualified
  • Change the module name of all fully qualified references

@razzeee
Copy link
Member

razzeee commented Mar 23, 2020

So I ended up with this as a module declaration :)
module Session exposing (Session, changes, cred, fromViewer, navKey, viewer), viewPagination

@razzeee
Copy link
Member

razzeee commented Mar 23, 2020

So I ended up with this as a module declaration :)
module Session exposing (Session, changes, cred, fromViewer, navKey, viewer), viewPagination

Not able to do that again, but every time I use the declaration (not the type declaration) to initalize the move on viewPagination to the Session module I end up with module Session exposing (Session, changes, cred, fromViewer, navKey, viewer, viewPagination toMsg page (Model feed))

@jmbockhorst
Copy link
Member Author

Thanks, I think I fixed it.

if (node?.parent?.type == "function_call_expr" && node.parent.firstNamedChild) {
const parameterIndex = node.parent.namedChildren.map(c => c.text).indexOf(node.text) - 1;
if (
node?.parent?.type == "function_call_expr" &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

=== please

@razzeee
Copy link
Member

razzeee commented Mar 24, 2020

Merging this now, will address some of the smaller stuff in one of the next commits.

Thank you so much! 🌈

@razzeee razzeee merged commit 727d42c into elm-tooling:master Mar 24, 2020
@jmbockhorst jmbockhorst deleted the moveFunction branch March 24, 2020 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants