From 8d9a4d4a333432097618d4cab82a6bd31afcb85e Mon Sep 17 00:00:00 2001 From: hosch250 Date: Sun, 21 Feb 2016 11:40:12 -0600 Subject: [PATCH 1/3] Close #400 and #406 --- .../UseAliasesInsteadOfConcreteTypeTests.cs | 118 +++++++++++++++++- ...UseAliasesInsteadOfConcreteTypeAnalyzer.cs | 7 +- 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs b/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs index 21b5070..5521e14 100644 --- a/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs +++ b/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs @@ -1075,7 +1075,6 @@ public class Program VerifyFix(original, result, allowNewCompilerDiagnostics: true); } - [TestMethod] public void UseAliasesInsteadOfConcreteType_Int32BecomesInt_Int32DotMaxValue() { @@ -1453,5 +1452,122 @@ void Method() VerifyDiagnostic(original, string.Format(UseAliasesInsteadOfConcreteTypeAnalyzer.Rule.MessageFormat.ToString(), "string", "String")); VerifyFix(original, result, allowNewCompilerDiagnostics: true); } + + [TestMethod] + public void UseAliasesInsteadOfConcreteType_DoesNotCatchLinqSingle() + { + var original = @" +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + List list = new List { ""test"", ""test1"" }; + string str = list.Single(s => s == ""test""); + } + } +}"; + + VerifyDiagnostic(original); + } + + [TestMethod] + public void UseAliasesInsteadOfConcreteType_DoesNotCatchEnumValuesWithSameNameAsAliasableType() + { + var original = @" +using System; +using System.Linq; + +namespace ConsoleApplication1 +{ + public enum TypeCode + { + Object = 1, + DBNull = 2, + Boolean = 3, + Char = 4, + SByte = 5, + Byte = 6, + } + + class MyClass + { + void Method() + { + var type = TypeCode.Boolean; + if (type == TypeCode.Boolean) {} + } + } +}"; + + VerifyDiagnostic(original); + } + + [TestMethod] + public void UseAliasesInsteadOfConcreteType_DoesNotCatchVariablesWithSameNameAsAliasableType() + { + var original = @" +using System; +using System.Linq; + +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var Boolean = ""Boolean""; + } + } +}"; + + VerifyDiagnostic(original); + } + + [TestMethod] + public void UseAliasesInsteadOfConcreteType_DoesNotCatchClassWithSameNameAsAliasableType() + { + var original = @" +using System; + +namespace ConsoleApplication1 +{ + class Single + { + } + + class Foo + { + void Method() + { + Single bar = new Single(); + } + } +}"; + + VerifyDiagnostic(original); + } + + [TestMethod] + public void UseAliasesInsteadOfConcreteType_DoesNotCatchUsingDirective() + { + var original = @" +using Single = System.Single; + +namespace ConsoleApplication1 +{ + class Foo + { + static void Main() { } + } +}"; + + VerifyDiagnostic(original); + } } } \ No newline at end of file diff --git a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs index e08b4e1..cbd50a6 100644 --- a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs +++ b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs @@ -50,7 +50,7 @@ private void AnalyzeSymbol(SyntaxNodeAnalysisContext context) } var typeSymbol = identifierSymbol.Symbol as INamedTypeSymbol; - if (typeSymbol != null && typeSymbol.SpecialType == SpecialType.None) + if (typeSymbol == null || typeSymbol.SpecialType == SpecialType.None) { return; } @@ -60,6 +60,11 @@ private void AnalyzeSymbol(SyntaxNodeAnalysisContext context) // This will make sure that we accept the entire qualified name in the code fix var location = identifier.GetLocation(); var qualifiedName = identifier.AncestorsAndSelf().OfType().FirstOrDefault(); + if (qualifiedName?.Parent is UsingDirectiveSyntax) + { + return; + } + if (qualifiedName != null) { location = qualifiedName.GetLocation(); From c98fbceb207751335a19d484c8ab6671066b6a99 Mon Sep 17 00:00:00 2001 From: hosch250 Date: Sun, 21 Feb 2016 12:21:13 -0600 Subject: [PATCH 2/3] Close #408 --- .../UseAliasesInsteadOfConcreteTypeAnalyzer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs index cbd50a6..3bce106 100644 --- a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs +++ b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs @@ -71,7 +71,7 @@ private void AnalyzeSymbol(SyntaxNodeAnalysisContext context) } string alias; - if (identifier.Identifier.Text.HasAlias(out alias)) + if (typeSymbol.MetadataName.HasAlias(out alias)) { context.ReportDiagnostic(Diagnostic.Create(Rule, location, alias, identifier.Identifier.ValueText)); } From f34492c57f5fe160bb6d04a029e93b69faa21cc4 Mon Sep 17 00:00:00 2001 From: hosch250 Date: Sun, 21 Feb 2016 12:49:12 -0600 Subject: [PATCH 3/3] Properly close #408 --- .../UseAliasesInsteadOfConcreteTypeTests.cs | 35 +++++++++++++++++++ ...UseAliasesInsteadOfConcreteTypeAnalyzer.cs | 4 +-- .../VSDiagnostics/Utilities/Extensions.cs | 10 ++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs b/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs index 5521e14..4bbc275 100644 --- a/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs +++ b/VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs @@ -1569,5 +1569,40 @@ class Foo VerifyDiagnostic(original); } + + [TestMethod] + public void UseAliasesInsteadOfConcreteType_DisplaysCorrectWarning() + { + var original = @" +using Single = System.String; + +namespace ConsoleApplication1 +{ + class Foo + { + static void Main() + { + Single bar = ""test""; + } + } +}"; + + var result = @" +using Single = System.String; + +namespace ConsoleApplication1 +{ + class Foo + { + static void Main() + { + string bar = ""test""; + } + } +}"; + + VerifyDiagnostic(original, string.Format(UseAliasesInsteadOfConcreteTypeAnalyzer.Rule.MessageFormat.ToString(), "string", "String")); + VerifyFix(original, result, allowNewCompilerDiagnostics: true); + } } } \ No newline at end of file diff --git a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs index 3bce106..be418b9 100644 --- a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs +++ b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs @@ -71,9 +71,9 @@ private void AnalyzeSymbol(SyntaxNodeAnalysisContext context) } string alias; - if (typeSymbol.MetadataName.HasAlias(out alias)) + if (identifier.Identifier.Text.HasAlias() && typeSymbol.MetadataName.HasAlias(out alias)) { - context.ReportDiagnostic(Diagnostic.Create(Rule, location, alias, identifier.Identifier.ValueText)); + context.ReportDiagnostic(Diagnostic.Create(Rule, location, alias, typeSymbol.MetadataName)); } } } diff --git a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Utilities/Extensions.cs b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Utilities/Extensions.cs index 3ef8b73..142e4b3 100644 --- a/VSDiagnostics/VSDiagnostics/VSDiagnostics/Utilities/Extensions.cs +++ b/VSDiagnostics/VSDiagnostics/VSDiagnostics/Utilities/Extensions.cs @@ -135,6 +135,16 @@ public static bool HasAlias(this string type, out string alias) return AliasMapping.TryGetValue(type, out alias); } + public static bool HasAlias(this string type) + { + if (type == null) + { + throw new ArgumentNullException(nameof(type)); + } + + return AliasMapping.Keys.Contains(type); + } + /// /// Determines whether or not the specified is the symbol of an asynchronous method. This /// can be a method declared as async (e.g. returning or ), or a method