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
Don't trigger rename of code element if filename has not been changed. #920
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a test for this?
@@ -68,6 +68,11 @@ public Task HintingAsync(IProjectChangeHint hint) | |||
|
|||
private void ScheduleRename(string oldFilePath, string newFilePath) | |||
{ | |||
if (Equals(Path.GetFileName(oldFilePath),Path.GetFileName(newFilePath))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
formatting nit: spacing between arguments.
will add tests |
016845b
to
2ff9551
Compare
@@ -23,7 +23,7 @@ public override bool CanHandleRename(string oldFileName, string newFileName) | |||
{ | |||
var oldNameBase = Path.GetFileNameWithoutExtension(oldFileName); | |||
var newNameBase = Path.GetFileNameWithoutExtension(newFileName); | |||
return SyntaxFacts.IsValidIdentifier(oldNameBase) && SyntaxFacts.IsValidIdentifier(newNameBase); | |||
return SyntaxFacts.IsValidIdentifier(oldNameBase) && SyntaxFacts.IsValidIdentifier(newNameBase) && !Equals(Path.GetFileName(oldNameBase), Path.GetFileName(newNameBase)); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is object.Equals, you should be using StringComparers.Path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it's by design that takes into account case? Unsure what I think about this - given most Windows file systems are case insensitive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this probably just represents the case of the <Compile Include="foo.cs" />
in the project file - and should this result in a rename for VB which is also case-insenstive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davkean , i am comparing the filename's not path . Have switched to using string.Compare.
I compared this with VS 14 and the rename is case sensitive. So rename is triggered if you change from Foo to foo. Let me know if you think otherwise
2ff9551
to
0eeac84
Compare
Spent some time about this, and I think this is what we should: For C#, case should be factored in and we should rename program -> Program and vice versa. This matches the legacy project system's behavior. We should try and do above in a language-agnostic way - ie by asking some service from Roslyn based on the document and see if that can tell us whether it's case or a case-insensitive language to avoid hard-coding a language. |
Okay, did some more research, basically, what you want to do is look at the doc and do something like: this.Document.GetLanguageService<ISyntaxFactsService>().IsCaseSensitive; |
@davkean thanks for taking a look, will add the conditional check |
@jinujoseph Can you see if this resolves #1063? It looks like we're kicking off a bunch of rename sessions when dragging a bunch of files around. |
@davkean: My understanding from @mavasani is that in order to use ISyntaxFactsService I need to have IVT access to Roslyn workspaces, so i will have to add IVT access, publish new nugetpackages for roslyn and add corresponding rolsyn dependencies to workspaces. Manish suggested i use compilation object instead [http://source.roslyn.io/#Microsoft.CodeAnalysis/Compilation/Compilation.cs,a12821839905319d,references ] , Let me know if you forsee any issue here. I will validate 1063 on big project. |
Note that Compilation.IsCaseSensitive will only work for projects supporting Compilation, i.e. VB and C# for now, which is probably fine until we support another language such as TypeScript which doesn't support compilation. |
Sounds fine. |
verified that this resolves #1063 |
{ | ||
var oldNameBase = Path.GetFileNameWithoutExtension(oldFileName); | ||
var newNameBase = Path.GetFileNameWithoutExtension(newFileName); | ||
return SyntaxFacts.IsValidIdentifier(oldNameBase) && SyntaxFacts.IsValidIdentifier(newNameBase); | ||
return SyntaxFacts.IsValidIdentifier(oldNameBase) && SyntaxFacts.IsValidIdentifier(newNameBase) && (string.Compare(Path.GetFileName(oldNameBase), Path.GetFileName(newNameBase), IsCaseSensitive) !=0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jinujoseph Can you fix this to not call into C# specific SyntaxFacts? You should create a C# and VB specific rename strategy in corresponding layers and use language specific SyntaxFacts in those projects.
{ | ||
IRenameStrategy[] strategies = new IRenameStrategy[] { | ||
new SimpleRenameStrategy(_threadingService, _userNotificationServices, _optionsSettings, _roslynServices) | ||
}; | ||
return strategies.FirstOrDefault(s => s.CanHandleRename(_oldFilePath, _newFilePath)); | ||
|
||
var compilation = await project.GetCompilationAsync().ConfigureAwait(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compilation can be null for projects not supporting compilation, you should add a null check.
@@ -77,15 +77,17 @@ internal sealed class Renamer | |||
|
|||
public Task RenameAsync(Project project) | |||
{ | |||
return GetStrategy()?.RenameAsync(project, _oldFilePath, _newFilePath) ?? Task.CompletedTask; | |||
return GetStrategyAsync(project).Result?.RenameAsync(project, _oldFilePath, _newFilePath) ?? Task.CompletedTask; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use await, not .Result
.
Additionally, you should do a null check as GetStrategyAsync can return null result.
@@ -19,11 +19,11 @@ public SimpleRenameStrategy(IProjectThreadingService threadingService, IUserNoti | |||
} | |||
|
|||
// For the SimpleRename, it can attempt to handle any situtation | |||
public override bool CanHandleRename(string oldFileName, string newFileName) | |||
public override bool CanHandleRename(string oldFileName, string newFileName, bool IsCaseSensitive) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
param casing: isCaseSensitive
{ | ||
var oldNameBase = Path.GetFileNameWithoutExtension(oldFileName); | ||
var newNameBase = Path.GetFileNameWithoutExtension(newFileName); | ||
return SyntaxFacts.IsValidIdentifier(oldNameBase) && SyntaxFacts.IsValidIdentifier(newNameBase); | ||
return SyntaxFacts.IsValidIdentifier(oldNameBase) && SyntaxFacts.IsValidIdentifier(newNameBase) && (string.Compare(Path.GetFileName(oldNameBase), Path.GetFileName(newNameBase), isCaseSensitive) !=0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does a cultural aware comparison, so "encyclopedia" == "encyclopædia" and will result in different results based on the user's current culture. You are dealing with paths here, so you want an ordinal comparison.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add tests cases for this? If I rename encyclopedia to encyclopædia it should still rename.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above.
@srivatsn for approval |
fixes #363 , fixes #1063
@davkean @srivatsn @dotnet/project-system