Skip to content

Commit 1b6e1c0

Browse files
committed
Additional tests and fixes for qualified using directives
1 parent e9c8dc5 commit 1b6e1c0

3 files changed

Lines changed: 88 additions & 22 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1135UnitTests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace StyleCop.Analyzers.Test.ReadabilityRules
55
{
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis;
89
using Microsoft.CodeAnalysis.Testing;
910
using StyleCop.Analyzers.ReadabilityRules;
1011
using Xunit;
@@ -320,6 +321,67 @@ namespace MyNamespace {
320321
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
321322
}
322323

324+
[Fact]
325+
[WorkItem(2879, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2879")]
326+
public async Task TestOmittedTypeInGenericAsync()
327+
{
328+
var testCode = @"
329+
namespace TestNamespace
330+
{
331+
using Example = System.Collections.Generic.List<>;
332+
}
333+
";
334+
335+
var expected = new DiagnosticResult("CS7003", DiagnosticSeverity.Error).WithLocation(4, 48).WithMessage("Unexpected use of an unbound generic name");
336+
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
337+
}
338+
339+
[Fact]
340+
[WorkItem(2879, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2879")]
341+
public async Task TestNullableTypeInGenericAsync()
342+
{
343+
var testCode = @"
344+
namespace TestNamespace
345+
{
346+
using Example = System.Collections.Generic.List<int?>;
347+
}
348+
";
349+
350+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
351+
}
352+
353+
[Fact]
354+
[WorkItem(2879, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2879")]
355+
public async Task TestGlobalQualifiedTypeInGenericAsync()
356+
{
357+
var testCode = @"
358+
namespace TestNamespace
359+
{
360+
using Example = System.Collections.Generic.List<global::System.Int32>;
361+
}
362+
";
363+
364+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
365+
}
366+
367+
[Fact]
368+
[WorkItem(2879, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2879")]
369+
public async Task TestTypeInGlobalNamespaceAsync()
370+
{
371+
var testCode = @"
372+
namespace TestNamespace
373+
{
374+
using Example = MyClass;
375+
}
376+
377+
class MyClass
378+
{
379+
}
380+
";
381+
382+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
383+
}
384+
323385
[Fact]
324386
[WorkItem(2879, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2879")]
325387
public async Task TestAliasTypeNestedInGenericAsync()

StyleCop.Analyzers/StyleCop.Analyzers/Helpers/SymbolNameHelpers.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace StyleCop.Analyzers.Helpers
55
{
66
using System.Text;
77
using Microsoft.CodeAnalysis;
8+
using Microsoft.CodeAnalysis.CSharp;
89
using Microsoft.CodeAnalysis.CSharp.Syntax;
910
using StyleCop.Analyzers.Lightup;
1011

@@ -36,17 +37,19 @@ public static string ToQualifiedString(this ISymbol symbol, NameSyntax name)
3637

3738
private static bool AppendQualifiedSymbolName(StringBuilder builder, ISymbol symbol, TypeSyntax type)
3839
{
39-
switch (symbol)
40+
switch (symbol.Kind)
4041
{
41-
case IArrayTypeSymbol arraySymbol:
42+
case SymbolKind.ArrayType:
43+
var arraySymbol = (IArrayTypeSymbol)symbol;
4244
AppendQualifiedSymbolName(builder, arraySymbol.ElementType, (type as ArrayTypeSyntax)?.ElementType);
4345
builder
4446
.Append("[")
4547
.Append(',', arraySymbol.Rank - 1)
4648
.Append("]");
4749
return true;
4850

49-
case INamespaceSymbol namespaceSymbol:
51+
case SymbolKind.Namespace:
52+
var namespaceSymbol = (INamespaceSymbol)symbol;
5053
if (namespaceSymbol.IsGlobalNamespace)
5154
{
5255
return false;
@@ -55,7 +58,8 @@ private static bool AppendQualifiedSymbolName(StringBuilder builder, ISymbol sym
5558
builder.Append(namespaceSymbol.ToDisplayString());
5659
return true;
5760

58-
case INamedTypeSymbol namedTypeSymbol:
61+
case SymbolKind.NamedType:
62+
var namedTypeSymbol = (INamedTypeSymbol)symbol;
5963
if (SpecialTypeHelper.TryGetPredefinedType(namedTypeSymbol.SpecialType, out var specialTypeSyntax))
6064
{
6165
builder.Append(specialTypeSyntax.ToFullString());
@@ -94,6 +98,12 @@ private static bool AppendQualifiedSymbolName(StringBuilder builder, ISymbol sym
9498
return AppendQualifiedSymbolName(builder, namedTypeSymbol.TupleUnderlyingType(), type);
9599
}
96100
}
101+
else if (namedTypeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
102+
{
103+
AppendQualifiedSymbolName(builder, namedTypeSymbol.TypeArguments[0], (type as NullableTypeSyntax)?.ElementType);
104+
builder.Append("?");
105+
return true;
106+
}
97107
else
98108
{
99109
if (AppendQualifiedSymbolName(builder, symbol.ContainingSymbol, (type as QualifiedNameSyntax)?.Left))
@@ -113,14 +123,17 @@ private static bool AppendQualifiedSymbolName(StringBuilder builder, ISymbol sym
113123
for (int i = 0; i < arguments.Length; i++)
114124
{
115125
var argument = arguments[i];
116-
var argumentType = argumentTypes.Arguments.Count > i ? argumentTypes.Arguments[i] : null;
126+
var argumentType = argumentTypes != null && argumentTypes.Arguments.Count > i ? argumentTypes.Arguments[i] : null;
117127

118128
if (i > 0)
119129
{
120130
builder.Append(GenericSeparator);
121131
}
122132

123-
AppendQualifiedSymbolName(builder, argument, argumentType);
133+
if (!argumentType.IsKind(SyntaxKind.OmittedTypeArgument))
134+
{
135+
AppendQualifiedSymbolName(builder, argument, argumentType);
136+
}
124137
}
125138

126139
builder.Append(GenericTypeParametersClose);
@@ -130,8 +143,13 @@ private static bool AppendQualifiedSymbolName(StringBuilder builder, ISymbol sym
130143
}
131144

132145
default:
133-
builder.Append(symbol.Name);
134-
return true;
146+
if (symbol != null)
147+
{
148+
builder.Append(symbol.Name);
149+
return true;
150+
}
151+
152+
return false;
135153
}
136154
}
137155
}

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1135UsingDirectivesMustBeQualified.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
namespace StyleCop.Analyzers.ReadabilityRules
55
{
6-
using System;
76
using System.Collections.Immutable;
87
using System.Text;
98
using Microsoft.CodeAnalysis;
@@ -215,19 +214,6 @@ private static bool AppendCanonicalString(StringBuilder builder, TypeSyntax type
215214
builder.Append(")");
216215
return true;
217216
}
218-
else if (RefTypeSyntaxWrapper.IsInstance(type))
219-
{
220-
var refType = (RefTypeSyntaxWrapper)type;
221-
builder.Append(refType.RefKeyword.Text);
222-
if (refType.ReadOnlyKeyword.IsKind(SyntaxKind.ReadOnlyKeyword))
223-
{
224-
builder.Append(" ").Append(refType.ReadOnlyKeyword.Text);
225-
}
226-
227-
builder.Append(" ");
228-
AppendCanonicalString(builder, refType.Type);
229-
return true;
230-
}
231217
else
232218
{
233219
return false;

0 commit comments

Comments
 (0)