Skip to content

Commit 92ad652

Browse files
committed
Update SA1302 conflict resolution to handle nested types
1 parent ca2ab10 commit 92ad652

2 files changed

Lines changed: 72 additions & 4 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/NamingRules/SA1302CodeFixProvider.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,21 @@ private static async Task<Solution> CreateChangedSolutionAsync(Document document
5757
INamedTypeSymbol interfaceType = declaredSymbol as INamedTypeSymbol;
5858
if (interfaceType != null)
5959
{
60-
var containingNamespace = semanticModel.Compilation.GetCompilationNamespace(interfaceType.ContainingNamespace);
61-
while (containingNamespace.GetMembers(newName).Any())
60+
var containingSymbol = interfaceType.ContainingSymbol as INamespaceOrTypeSymbol;
61+
var containingNamespace = containingSymbol as INamespaceSymbol;
62+
if (containingNamespace != null)
6263
{
63-
index++;
64-
newName = baseName + index;
64+
// Make sure to use the compilation namespace so interfaces in referenced assemblies are considered
65+
containingSymbol = semanticModel.Compilation.GetCompilationNamespace(containingNamespace);
66+
}
67+
68+
if (containingSymbol != null)
69+
{
70+
while (containingSymbol.GetMembers(newName).Any())
71+
{
72+
index++;
73+
newName = baseName + index;
74+
}
6575
}
6676
}
6777

StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1302UnitTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,64 @@ public interface IFoo { }";
208208
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
209209
}
210210

211+
[Fact]
212+
public async Task TestNestedInterfaceDeclarationDoesNotStartWithIWithConflictAsync()
213+
{
214+
string testCode = @"
215+
public class Outer
216+
{
217+
public interface Foo
218+
{
219+
}
220+
221+
public interface IFoo { }
222+
}";
223+
string fixedCode = @"
224+
public class Outer
225+
{
226+
public interface IFoo1
227+
{
228+
}
229+
230+
public interface IFoo { }
231+
}";
232+
233+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(4, 22);
234+
235+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
236+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
237+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
238+
}
239+
240+
[Fact]
241+
public async Task TestNestedInterfaceDeclarationDoesNotStartWithIWithNonInterfaceConflictAsync()
242+
{
243+
string testCode = @"
244+
public class Outer
245+
{
246+
public interface Foo
247+
{
248+
}
249+
250+
private int IFoo => 0;
251+
}";
252+
string fixedCode = @"
253+
public class Outer
254+
{
255+
public interface IFoo1
256+
{
257+
}
258+
259+
private int IFoo => 0;
260+
}";
261+
262+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(4, 22);
263+
264+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
265+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
266+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
267+
}
268+
211269
[Fact]
212270
public async Task TestInterfaceDeclarationDoesNotStartWithIWithConflictInAnotherAssemblyAsync()
213271
{

0 commit comments

Comments
 (0)