提交 968da597 编写于 作者: D David Poeschl

Handle rename decl conflicts when decl file contains no refs

Fixes #2352

This change fixes a rename crash that would occur when a method
declaration conflict was introduced in a file with no references to that
symbol, but where at least one other document in the same project had a
reference to that symbol.

When processing an individual project in ResolveConflictsAsync, we start
with the full set of documents from _documentsIdsToBeCheckedForConflict
related to that project. But, each rename phase can adjust this set of
documents (called documentIdsThatGetsAnnotatedAndRenamed locally) to
whatever documents are represented by the current set of
_conflictLocations, which can exclude the
_documentIdOfRenameSymbolDeclaration itself if it contains no
references. Now, when documentIdsThatGetsAnnotatedAndRenamed is
recalculated we make sure to keep the
_documentIdOfRenameSymbolDeclaration in the set if we're processing the
project that contains it.
上级 130c62c2
......@@ -3344,5 +3344,72 @@ class {|conflict:C$$|} { }
result.AssertLabeledSpansAre("conflict", renameTo, RelatedLocationType.UnresolvedConflict)
End Using
End Sub
<WorkItem(2352, "https://github.com/dotnet/roslyn/issues/2352")>
<Fact>
<Trait(Traits.Feature, Traits.Features.Rename)>
Public Sub DeclarationConflictInFileWithoutReferences_SameProject()
Using result = RenameEngineResult.Create(
<Workspace>
<Project Language="C#" CommonReferences="true">
<Document FilePath="Test1.cs">
class Program
{
internal void [|A$$|]() { }
internal void {|conflict:B|}() { }
}
</Document>
<Document FilePath="Test2.cs">
class Program2
{
void M()
{
Program p = null;
p.{|conflict:A|}();
p.{|conflict:B|}();
}
}
</Document>
</Project>
</Workspace>, renameTo:="B")
result.AssertLabeledSpansAre("conflict", "B", RelatedLocationType.UnresolvedConflict)
End Using
End Sub
<WorkItem(2352, "https://github.com/dotnet/roslyn/issues/2352")>
<Fact>
<Trait(Traits.Feature, Traits.Features.Rename)>
Public Sub DeclarationConflictInFileWithoutReferences_DifferentProjects()
Using result = RenameEngineResult.Create(
<Workspace>
<Project Language="C#" CommonReferences="true" AssemblyName="CSAssembly1">
<Document FilePath="Test1.cs">
public class Program
{
public void [|A$$|]() { }
public void {|conflict:B|}() { }
}
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="CSAssembly2">
<ProjectReference>CSAssembly1</ProjectReference>
<Document FilePath="Test2.cs">
class Program2
{
void M()
{
Program p = null;
p.{|conflict:A|}();
p.{|conflict:B|}();
}
}
</Document>
</Project>
</Workspace>, renameTo:="B")
result.AssertLabeledSpansAre("conflict", "B", RelatedLocationType.UnresolvedConflict)
End Using
End Sub
End Class
End Namespace
......@@ -170,6 +170,14 @@ public async Task<ConflictResolution> ResolveConflictsAsync()
// Note that we need to get the conflictLocations here since we're going to remove some locations below if phase == 2
documentIdsThatGetsAnnotatedAndRenamed = new HashSet<DocumentId>(_conflictLocations.Select(l => l.DocumentId));
// Include the declaration document if we are processing its project to
// ensure declaration conflicts are calculated correctly when the
// declaration document does not contain any references.
if (documentsByProject.Key == _documentIdOfRenameSymbolDeclaration.ProjectId)
{
documentIdsThatGetsAnnotatedAndRenamed.Add(_documentIdOfRenameSymbolDeclaration);
}
if (phase == 2)
{
// After phase 2, if there are still conflicts then remove the conflict locations from being expanded
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册