Skip to content

Move static members to a New Type#55204

Merged
Soreloser2 merged 21 commits intodotnet:features/MoveStaticMembersfrom
Soreloser2:MoveStaticMembersNewType
Aug 10, 2021
Merged

Move static members to a New Type#55204
Soreloser2 merged 21 commits intodotnet:features/MoveStaticMembersfrom
Soreloser2:MoveStaticMembersNewType

Conversation

@Soreloser2
Copy link
Contributor

@Soreloser2 Soreloser2 commented Jul 28, 2021

Part of #55127.
This initial feature will include a text box to input the desired class name, and will generate a new static class in a new file (in the same folder and namespace as the file the action was invoked from).

MoveStaticMembersDemo.mp4

Soren Dahl added 7 commits July 14, 2021 11:19
No behavior created after dialog exited
Still working on destination type/filename selection formatting
…ox, assuming new class (c# only, no automated tests yet)
Copy link
Member

@JoeRobich JoeRobich left a comment

Choose a reason for hiding this comment

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

Good start. Can you add some screenshots or a gif to the PR description?

Comment on lines +48 to +49
var optionsService = _service ?? _document.Project.Solution.Workspace.Services.GetRequiredService<IMoveStaticMembersOptionsService>();
return optionsService.GetMoveMembersToTypeOptions(_document, _selectedType, _selectedMember);
Copy link
Member

Choose a reason for hiding this comment

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

This never sets _ service so you don't get any benefit of caching the lookup.

Suggested change
var optionsService = _service ?? _document.Project.Solution.Workspace.Services.GetRequiredService<IMoveStaticMembersOptionsService>();
return optionsService.GetMoveMembersToTypeOptions(_document, _selectedType, _selectedMember);
_service ??= _document.Project.Solution.Workspace.Services.GetRequiredService<IMoveStaticMembersOptionsService>();
return _service.GetMoveMembersToTypeOptions(_document, _selectedType, _selectedMember);

@@ -0,0 +1,105 @@
<vs:DialogWindow
Copy link
Member

Choose a reason for hiding this comment

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

We should run the dialog through our accessibility check tool. Reach out to me or @ryzngard this week to talk you through it.

@@ -0,0 +1,94 @@
<UserControl x:Class="Microsoft.VisualStudio.LanguageServices.Implementation.MoveStaticMembers.StaticMemberSelection"
Copy link
Member

Choose a reason for hiding this comment

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

We should investigate the effort to unify the member selector controls and selectively hide unnecessary components.

/// Test purpose only.
/// </summary>
[SuppressMessage("RoslynDiagnosticsReliability", "RS0034:Exported parts should have [ImportingConstructor]", Justification = "Used incorrectly by tests")]
public CSharpMoveStaticMembersCodeRefactoringProvider(IMoveStaticMembersOptionsService service) : base(service)
Copy link
Member

Choose a reason for hiding this comment

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

I wonder do we have a new MEF framework to get rid of the test accessor constructor? @sharwell might know more about this.

@@ -0,0 +1,105 @@
<vs:DialogWindow
xmlns:vs="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Copy link
Member

Choose a reason for hiding this comment

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

Dialog in VS has to meet some standards. (I don't if any folks in UX has mentioned to you)
Please check this and make sure your xaml meets it
https://devdivdesignguide.azurewebsites.net/windows/dialog-and-window-patterns/dialogs/

Also plz share a screenshot : )


namespace Microsoft.CodeAnalysis.MoveStaticMembers
{
internal class MoveStaticMembersOptions
Copy link
Member

Choose a reason for hiding this comment

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

readonly struct?

private readonly ImmutableDictionary<ISymbol, Task<ImmutableArray<ISymbol>>> _symbolToDependentsMap;
private readonly ImmutableDictionary<ISymbol, SymbolViewModel<ISymbol>> _symbolToMemberViewMap;

public StaticMemberSelectionViewModel(
Copy link
Member

Choose a reason for hiding this comment

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

Not necessarily needed in this PR. But please make sure after all the UI details completes, add some ViewModel test.
exmaple: https://sourceroslyn.io/#Microsoft.VisualStudio.LanguageServices.UnitTests/PullMemberUp/PullMemberUpViewModelTest.vb,a6d70fd2561a2e76

var fileBanner = syntaxFacts.GetFileBanner(root);

// add annotations to the symbols that we selected so we can find them later to pull up
var memberNodes = moveOptions.SelectedMembers.SelectAsArray(symbol => symbol.Locations.Single().FindNode(cancellationToken));
Copy link
Member

Choose a reason for hiding this comment

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

What guarantees that .Single() won't throw?

@Soreloser2 Soreloser2 requested a review from a team as a code owner August 3, 2021 23:53

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MoveStaticMembers
{
public class CSharpMoveStaticMembersTests : AbstractCSharpCodeActionTest
Copy link
Member

Choose a reason for hiding this comment

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

Better to use the new testing framework. We want to get rid of these legacy tests.

Comment on lines +18 to +24
/// <summary>
/// Test purpose only.
/// </summary>
[SuppressMessage("RoslynDiagnosticsReliability", "RS0034:Exported parts should have [ImportingConstructor]", Justification = "Used incorrectly by tests")]
public CSharpMoveStaticMembersCodeRefactoringProvider(IMoveStaticMembersOptionsService? service) : base(service)
{
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if this is okay.


var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();

var action = new MoveStaticMembersWithDialogCodeAction(document, span, _service, selectedType, selectedMember: selectedMembers[0]);
Copy link
Member

Choose a reason for hiding this comment

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

Can't we get the service via document.GetRequiredLanguageService<IMoveStaticMembersOptionsService>()?

// just return all the selected members
return new MoveStaticMembersOptions(
_filename,
string.Join(".", selectedType.ContainingNamespace.ToDisplayString(), _destinationType),
Copy link
Member

Choose a reason for hiding this comment

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

You're doing string.Join, then splitting it back in the constructor. Why not pass them separately?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My idea was that the user could include a additional nested namespace(s) when they defined the type. For example, if they were moving a member from a class called SomeNamespace.InnerNamespace.Class1, and wanted to move it to a separate utility namespace, they could write Utilities.Class1Helpers in the destination selection box, and the new created class would be fully qualified as SomeNamespace.InnerNamespace.Utilities.Class1Helpers.

I think splitting the extra namespaces from the destination box (Utilities in the example) and adding them on to the containing namespace, then passing in both separately would work as well.

@Soreloser2
Copy link
Contributor Author

Tests are not passing because Pull Members Up is not pulling entire methods in VB. Fixing at #55450.

@JoeRobich JoeRobich force-pushed the features/MoveStaticMembers branch from 71183e2 to 845e2f4 Compare August 9, 2021 17:02
@JoeRobich
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@JoeRobich
Copy link
Member

Although GitHub checks haven't updated. Integration CI is passing https://dev.azure.com/dnceng/public/_build/results?buildId=1283655&view=results

{
return false;
}
public static int TestMethodInt()
Copy link
Member

Choose a reason for hiding this comment

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

The lack of whitespace here may be an issue with the member puller.

{
static class Class1Helpers
{

Copy link
Member

Choose a reason for hiding this comment

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

We should open an issue for the leading whitespace in these classes.

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 believe it is an extension of #54847. We can add a formatter annotation to the new class in this case, but this will still be an issue when moving to existing types

Copy link
Member

@JoeRobich JoeRobich left a comment

Choose a reason for hiding this comment

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

Would be handy to test extracting from other types like static and abstract classes. Tests for extracting from records as well. These can come in a follow up.

@Soreloser2 Soreloser2 merged commit 6fbd753 into dotnet:features/MoveStaticMembers Aug 10, 2021
Comment on lines +18 to +24
/// <summary>
/// Test purpose only.
/// </summary>
[SuppressMessage("RoslynDiagnosticsReliability", "RS0034:Exported parts should have [ImportingConstructor]", Justification = "Used incorrectly by tests")]
public CSharpMoveStaticMembersRefactoringProvider(IMoveStaticMembersOptionsService? service) : base(service)
{
}
Copy link
Member

Choose a reason for hiding this comment

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

This constructor is incorrect based on dotnet/roslyn-analyzers#5358:

MEF-exported types should have at most one public constructor, which should either have no parameters or be marked [ImportingConstructor]

FYI @sharwell :)

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'll be meeting with him to change the test framework, it will be addressed in a follow-up PR 👍

Soreloser2 added a commit that referenced this pull request Sep 2, 2021
* Move static members to a New Type (#55204)

* WIP Dialog work

* Rename + refactor

* WIP rename, add xaml elements

* WIP dialog/VM work

* WIP, Reverted Pull Member up change, updated destination selection, not working bc of a few bugs

* Refactoring provider now shows up and launches dialog

No behavior created after dialog exited
Still working on destination type/filename selection formatting

* Rename/Refactor name to MoveStaticMembers. Feature working with textbox, assuming new class (c# only, no automated tests yet)

* Accessibility, theming, resources, and sizing retweaks

* Added VB refactoring provider. Currently does not trigger on fields, as the semantic model cannot get the symbol for VB declared fields from the node. Fields are added as part of the dialog box however.

* Addressing some of the feedback

* Fixed fields not being able to trigger dialog in VB

* Remove unnecessary usings

* Fixed nullable error

* Added test classes for view model and C# impl, made VB able to get dependents

* Finished Writing impl tests for C# and VB. VB tests are currently failing due to the way AddMembers reuses syntax. Fixed a few bugs

* Fixed resources and removed nullable disable annotation

* Adress small feedback points

* Small test fix. Works with generator changes (sepearate PR)

Co-authored-by: msftbot[bot] <48340428+msftbot[bot]@users.noreply.github.com>

* Test framework movement (#55586)

* WIP Dialog work

* Rename + refactor

* WIP rename, add xaml elements

* WIP dialog/VM work

* WIP, Reverted Pull Member up change, updated destination selection, not working bc of a few bugs

* Refactoring provider now shows up and launches dialog

No behavior created after dialog exited
Still working on destination type/filename selection formatting

* Rename/Refactor name to MoveStaticMembers. Feature working with textbox, assuming new class (c# only, no automated tests yet)

* Accessibility, theming, resources, and sizing retweaks

* Added VB refactoring provider. Currently does not trigger on fields, as the semantic model cannot get the symbol for VB declared fields from the node. Fields are added as part of the dialog box however.

* Addressing some of the feedback

* Fixed fields not being able to trigger dialog in VB

* Remove unnecessary usings

* Fixed nullable error

* Added test classes for view model and C# impl, made VB able to get dependents

* Finished Writing impl tests for C# and VB. VB tests are currently failing due to the way AddMembers reuses syntax. Fixed a few bugs

* Fixed resources and removed nullable disable annotation

* Adress small feedback points

* Small test fix. Works with generator changes (sepearate PR)

* WIP untested, refactoring references to moved members

* Added tests for refactoring and extensions for C#. Will add tests for refactoring in VB, but unsure about extensions since we do not generate a module.

* Make module now for VB, add refactor tests

* Updated C# tests to a new framework. May need to rewrite VB test file in C# to set some readonly properties

* Changed VB tests to new Framework. Revealed an error in the way vb members are moved

* Fixed VB tests by removing shared modifier when moving to a module

* Fixed more tests to account for member spacing innaccuracy

* Refactored tests, added vb extension tests

* Added tests for file banner and moving from a static class/module

* Added tests to enure operator and static constructors are not able to be selected or trigger refactoring

* Make service field readonly

* Fixed some code warnings and reverted to before member refactoring, removing a few tests in the process

Co-authored-by: msftbot[bot] <48340428+msftbot[bot]@users.noreply.github.com>

* Fix api change

* Update FeatureResources xlf

* Changed tests to use new default accessibility modifier for new documents

* Move Static Members: Refactor moved member references (#55581)

* WIP Dialog work

* Rename + refactor

* WIP rename, add xaml elements

* WIP dialog/VM work

* WIP, Reverted Pull Member up change, updated destination selection, not working bc of a few bugs

* Refactoring provider now shows up and launches dialog

No behavior created after dialog exited
Still working on destination type/filename selection formatting

* Rename/Refactor name to MoveStaticMembers. Feature working with textbox, assuming new class (c# only, no automated tests yet)

* Accessibility, theming, resources, and sizing retweaks

* Added VB refactoring provider. Currently does not trigger on fields, as the semantic model cannot get the symbol for VB declared fields from the node. Fields are added as part of the dialog box however.

* Addressing some of the feedback

* Fixed fields not being able to trigger dialog in VB

* Remove unnecessary usings

* Fixed nullable error

* Added test classes for view model and C# impl, made VB able to get dependents

* Finished Writing impl tests for C# and VB. VB tests are currently failing due to the way AddMembers reuses syntax. Fixed a few bugs

* Fixed resources and removed nullable disable annotation

* Adress small feedback points

* Small test fix. Works with generator changes (sepearate PR)

* WIP untested, refactoring references to moved members

* Added tests for refactoring and extensions for C#. Will add tests for refactoring in VB, but unsure about extensions since we do not generate a module.

* Make module now for VB, add refactor tests

* Updated C# tests to a new framework. May need to rewrite VB test file in C# to set some readonly properties

* Changed VB tests to new Framework. Revealed an error in the way vb members are moved

* Fixed VB tests by removing shared modifier when moving to a module

* Fixed more tests to account for member spacing innaccuracy

* Refactored tests, added vb extension tests

* Added tests for file banner and moving from a static class/module

* Added tests to enure operator and static constructors are not able to be selected or trigger refactoring

* Make service field readonly

* Added support for alias refactoring + tests

* Refactored references on source type. Added simplifier annotation to remove unnecessary qualifications.

* Now correctly refactors references using symbol annotations and expansions for extension methods, should address conflicting imports issues

* Fixed simplifier incorrectly simplifying references inside moved members

* Added more tests, generic class refactoring currently isn't working

* Added support for generic class member access, copying only the type arguments we moved from the methods

* Fixed tests by adding accesibility modifier

* Addressed feedback, fixed multiple extension method bug by using docEditor

* Changed new type to create the same kind (class/Module) as the source type, refactored tests

Co-authored-by: msftbot[bot] <48340428+msftbot[bot]@users.noreply.github.com>

* Move Static Members: Show destination name (#55650)

* Now shows the fully qualified name when creating a new type.

Discovered an issue with duplicating a root namespace, not fixed here.

* Reformatted new type name message

* Write tests that utilize root namespace. One is failing as it depends on reference refactoring, and is not merged with the reference refactoring branch currently

* Changed way file names are generated so added namespaces aren't included, refactored options getting for tests

* Moved destination selection box a little bit to the right to align with message

* Changed tests to reflect module changes

* Removed theming (#56013)

* Move static members Root Namespace + OK button enabled fixes (#56035)

* Added tests and changed root namespace filtering. Removes crash bug.

* Disabled "OK" button when destination is invalid. Added ability to select no members (will create a new empty class)

Co-authored-by: msftbot[bot] <48340428+msftbot[bot]@users.noreply.github.com>
Co-authored-by: Joey Robichaud <jorobich@microsoft.com>
Co-authored-by: Joey Robichaud <joseph.robichaud@microsoft.com>
Co-authored-by: dotnet bot <dotnet-bot@dotnetfoundation.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants