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

Move to Folder Refactoring #5438

Merged
merged 13 commits into from
Mar 31, 2020

Conversation

MDoerner
Copy link
Contributor

@MDoerner MDoerner commented Mar 21, 2020

Closes #3332
Closes #5159

This PR introduces MoveToFolderRefactoring, MoveContainingFolderRefactoring and CodeExplorerMoveToFolderCommand allowing to move components and folders around in the folder hierarchy. The target is derived from the selected component for the refactorings and from the selected folder or component view model for the CE command. The target folder is selected in a dialog I borrowed from Rename.

This PR also extracts the user interaction part from the InteractiveRefactoringBase into a different class then injected back. This allows to reuse the interaction elsewhere, e.g. in CE commands. (Sorry for any conflicts.)

The backing refactoring actions and interactions for the refactorings allow to process multiple modules or folders at once. However, I had to realize that the CE does not allow multi-selection. Thus, the CE command does not deal with multiple selected nodes so far. Should we change our stand on multi-select in the CE, adapting the command to this, should be comparatively easy.

We have drag and drop now as well.

Component move via dialog:
MoveToFolder_Component_Dialog

Folder move via dialog:
MoveToFolder_Folder_Dialog

Component move via drag and drop:
MoveToFolder_Component_DragAndDrop

Folder move via drag and drop:
MoveToFolder_Folder_DragAndDrop

Also correctly converts folder annotation arguments to the string content and back. This also removes the parentheses around folders.
It did not consider that there could be a getter in another module with the same name.
It moves the containing folder into another folder.

Also fixes ToVbaStringLiteral. (It was missing the surrounding quotes.)
Also adds members to get the initial model to InteractiveRefactoringTestsBase.
There are already tests for the involved refactoring actions.
This moves interactive refactorings from using inheritance to deal with the interaction to composition. Consequently, the interaction can be reused elsewhere.
This combines MoveToFolder and MoveFolder, selecting based on the selected node of the CE.
In principle, the backing refactoring actions are capable of dealing with multiple nodes at once. However, the CE only allows selecting single items at the moment and the command reflects that when deriving the models to pass to the refactoring actions.
@MDoerner MDoerner added the PR-Status: WIP Pull request is work-in-progress, more commits should be expected. label Mar 21, 2020
@codecov
Copy link

codecov bot commented Mar 21, 2020

Codecov Report

Merging #5438 into next will decrease coverage by 0.35%.
The diff coverage is 32.30%.

@@            Coverage Diff             @@
##             next    #5438      +/-   ##
==========================================
- Coverage   61.49%   61.14%   -0.35%     
==========================================
  Files        1194     1222      +28     
  Lines       40595    41003     +408     
  Branches     8666     8749      +83     
==========================================
+ Hits        24961    25070     +109     
- Misses      13790    14080     +290     
- Partials     1844     1853       +9     
Impacted Files Coverage Δ
...e/Navigation/CodeExplorer/CodeExplorerViewModel.cs 58.97% <0.00%> (-0.51%) ⬇️
...UI/CodeExplorer/CodeExplorerAddComponentService.cs 22.22% <0.00%> (-2.34%) ⬇️
...duck.Core/UI/CodeExplorer/CodeExplorerControl.xaml 0.00% <0.00%> (ø)
...k.Core/UI/CodeExplorer/CodeExplorerControl.xaml.cs 0.00% <0.00%> (ø)
...ds/Abstract/CodeExplorerMoveToFolderCommandBase.cs 0.00% <0.00%> (ø)
...plorer/Commands/CodeExplorerMoveToFolderCommand.cs 0.00% <0.00%> (ø)
...Drop/CodeExplorerMoveToFolderDragAndDropCommand.cs 0.00% <0.00%> (ø)
...PaneRefactorMoveContainingFolderCommandMenuItem.cs 0.00% <0.00%> (ø)
...ems/CodePaneRefactorMoveToFolderCommandMenuItem.cs 0.00% <0.00%> (ø)
...nd/MenuItems/ParentMenus/RefactoringsParentMenu.cs 0.00% <ø> (ø)
... and 70 more

The exception is moving into the project folder. This simply adds the explicit folder annotation.
@MDoerner MDoerner removed the PR-Status: WIP Pull request is work-in-progress, more commits should be expected. label Mar 22, 2020
@MDoerner MDoerner marked this pull request as ready for review March 22, 2020 22:06
Comment on lines 32 to 34
return target != null
&& target is ModuleDeclaration
&& !_state.IsNewOrModified(target.QualifiedModuleName);
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't the null-check be redundant with target is ModuleDeclaration module?

e.g.

return target is ModuleDeclaration module && !_state.IsNewOrModified(module.QualifiedModuleName);

Copy link
Member

Choose a reason for hiding this comment

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

Actually the null-check is redundant even without a module variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will remove the null check.

Comment on lines 12 to 16
Loaded += (o, e) =>
{
MoveToFolderTextBox.Focus();
MoveToFolderTextBox.SelectAll();
};
Copy link
Member

Choose a reason for hiding this comment

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

How does the inline EventHandler delegate get de-registered?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have to admit that I simply copied this from the Rename dialog. Maybe, whoever wrote that can answer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it simply gets unregistered when the view gets GCed. Remember, it is the event that keeps the handler alive, not the other way around.

I will add explicit de-registration, nonetheless.

Comment on lines 12 to 16
Loaded += (o, e) =>
{
MoveToFolderTextBox.Focus();
MoveToFolderTextBox.SelectAll();
};
Copy link
Member

Choose a reason for hiding this comment

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

Worrying about handler holding up GC here too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could we simply unregister the handler in the handler itself?

Comment on lines +3 to +4
public interface IMoveMultipleFoldersPresenter : IRefactoringPresenter<MoveMultipleFoldersModel>
{}
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this marker interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we use it as the type parameter in the presenter and dialog setup.

Comment on lines +3 to +4
public interface IMoveMultipleToFolderPresenter : IRefactoringPresenter<MoveMultipleToFolderModel>
{}
Copy link
Member

Choose a reason for hiding this comment

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

Marker interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above.

@@ -74,6 +74,25 @@ End Property
Assert.AreEqual(0, InspectionResultsForModules(("MyClass", inputCode, ComponentType.ClassModule)).Count());
}

[Test]
[Category("Inspections")]
public void WriteOnlyProperty_ReturnsResult_GetInOtherModule()
Copy link
Member

Choose a reason for hiding this comment

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

👍

Copy link
Member

@retailcoder retailcoder left a comment

Choose a reason for hiding this comment

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

LGTM - just curious about the marker interfaces for the generic presenters, and I think the inline EventHandler delegates in .xaml code-behinds would be better off not-inlined and explicitly de-registered, but if it's not causing any problems it's probably a non-issue.

@retailcoder
Copy link
Member

This is awesome BTW, well done!

A test was there, but the assert was wrong.
This is done in Rename-, MoveMultipleToFolder- and Move MultipleFoldersView.
Also addresses one more review comment to PR rubberduck-vba#5438.
@retailcoder retailcoder merged commit 5fec4ad into rubberduck-vba:next Mar 31, 2020
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.

Drag and drop for navigation folders, please! RD needs a move to folder command
2 participants