Support renaming files with nested type naming convention (Outer.Inner.cs) #80728
+472
−7
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #60960
Summary
This PR adds support for renaming files that follow the nested type naming convention (e.g.,
Outer.Inner.cs
) when performing inline rename operations on types.Problem
Previously, when renaming a nested type in a file that followed the
Outer.Inner.cs
naming convention, the rename dialog would not offer to rename the file. This occurred because the file rename detection logic only checked if the simple type name matched the file name, not considering the nested type pattern.For example:
Outer.Inner.cs
containingclass Outer { class Inner { } }
Inner
toFoo
would not offer to rename the file toOuter.Foo.cs
Outer
toBar
would not offer to rename the file toBar.Inner.cs
Changes
Core Logic (
WorkspacePathUtilities.cs
)Added three new helper methods to handle nested type file naming:
TypeNameMatchesDocumentNameWithContainers()
- Detects if a document name matches a nested type's expected file name pattern (e.g.,Outer.Inner.cs
for typeInner
nested inOuter
)GetExpectedFileNameForSymbol()
- Builds the expected file name for a symbol based on its containership chain (e.g., returns"Outer.Inner"
for a typeInner
nested inOuter
)GetUpdatedDocumentNameForSymbolRename()
- Updates a document name when a type in its containership chain is renamed, preserving the rest of the file name structureInline Rename Integration
GetFileRenameInfo()
inAbstractEditorInlineRenameService.SymbolRenameInfo.cs
to check for both simple and nested type naming patternsRenameDocumentToMatchNewSymbol()
inMutableConflictResolution.cs
to use the new nested-type-aware logicTests
CSharpInlineRenameServiceTests.cs
covering various nested type scenariosWorkspacePathUtilitiesTests.cs
to verify the helper methods (7 currently passing)Examples
Before
After
Supported Scenarios
✅ Renaming nested types (e.g.,
Inner
→Foo
inOuter.Inner.cs
→Outer.Foo.cs
)✅ Renaming outer types (e.g.,
Outer
→Bar
inOuter.Inner.cs
→Bar.Inner.cs
)✅ Simple file names (e.g.,
Inner.cs
→Foo.cs
)✅ Deeply nested types (e.g.,
A.B.C.cs
)✅ Case-insensitive matching
Notes
This implementation follows the existing Roslyn patterns for file renaming and integrates seamlessly with the inline rename workflow. The feature respects user preferences for file renaming and only activates when the file name matches the expected pattern for the type being renamed.
Original prompt
Fixes #60054
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.