Skip to content

Commit 4df6833

Browse files
committed
Merge pull request #487 from Hosch250/Issue269
Close issue #269
2 parents 70acab4 + 1918974 commit 4df6833

File tree

4 files changed

+14
-68
lines changed

4 files changed

+14
-68
lines changed

VSDiagnostics/VSDiagnostics/VSDiagnostics.Test/Tests/General/UseAliasesInsteadOfConcreteTypeTests.cs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ namespace ConsoleApplication1
940940
{
941941
class MyClass
942942
{
943-
public static explicit operator int(MyClass c)
943+
public static explicit operator int (MyClass c)
944944
{
945945
return 5;
946946
}
@@ -1571,7 +1571,7 @@ static void Main() { }
15711571
}
15721572

15731573
[TestMethod]
1574-
public void UseAliasesInsteadOfConcreteType_DisplaysCorrectWarning()
1574+
public void UseAliasesInsteadOfConcreteType_DoesNotDisplayWarningWithAlias()
15751575
{
15761576
var original = @"
15771577
using Single = System.String;
@@ -1587,22 +1587,7 @@ static void Main()
15871587
}
15881588
}";
15891589

1590-
var result = @"
1591-
using Single = System.String;
1592-
1593-
namespace ConsoleApplication1
1594-
{
1595-
class Foo
1596-
{
1597-
static void Main()
1598-
{
1599-
string bar = ""test"";
1600-
}
1601-
}
1602-
}";
1603-
1604-
VerifyDiagnostic(original, string.Format(UseAliasesInsteadOfConcreteTypeAnalyzer.Rule.MessageFormat.ToString(), "string", "String"));
1605-
VerifyFix(original, result, allowNewCompilerDiagnostics: true);
1590+
VerifyDiagnostic(original);
16061591
}
16071592
}
16081593
}

VSDiagnostics/VSDiagnostics/VSDiagnostics/Diagnostics/General/UseAliasesInsteadOfConcreteType/UseAliasesInsteadOfConcreteTypeAnalyzer.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ private void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
4444

4545
// If we're dealing with a self-defined type 'Char' then we ignore it
4646
var identifierSymbol = context.SemanticModel.GetSymbolInfo(identifier);
47-
if (identifierSymbol.Symbol == null)
48-
{
49-
return;
50-
}
5147

5248
var typeSymbol = identifierSymbol.Symbol as INamedTypeSymbol;
5349
if (typeSymbol == null || typeSymbol.SpecialType == SpecialType.None)
@@ -70,10 +66,14 @@ private void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
7066
location = qualifiedName.GetLocation();
7167
}
7268

73-
string alias;
74-
if (identifier.Identifier.Text.HasAlias() && typeSymbol.MetadataName.HasAlias(out alias))
69+
// This ensures that we are not using aliases. Both the identifier and the actual type must have a registered alias.
70+
// If the identifier alias and the alias for the actual type do not match (as when `using Single = System.String`),
71+
// the aliases do not match, so we do not create a diagnostic because the Simplifier does not create an alias in this case.
72+
string identifierAlias;
73+
string metadataAlias;
74+
if (identifier.Identifier.Text.HasAlias(out identifierAlias) && typeSymbol.MetadataName.HasAlias(out metadataAlias) && identifierAlias == metadataAlias)
7575
{
76-
context.ReportDiagnostic(Diagnostic.Create(Rule, location, alias, typeSymbol.MetadataName));
76+
context.ReportDiagnostic(Diagnostic.Create(Rule, location, metadataAlias, typeSymbol.MetadataName));
7777
}
7878
}
7979
}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Collections.Immutable;
1+
using System.Collections.Immutable;
42
using System.Composition;
53
using System.Linq;
64
using System.Threading.Tasks;
75
using Microsoft.CodeAnalysis;
86
using Microsoft.CodeAnalysis.CodeActions;
97
using Microsoft.CodeAnalysis.CodeFixes;
10-
using Microsoft.CodeAnalysis.CSharp;
11-
using Microsoft.CodeAnalysis.CSharp.Syntax;
12-
using Microsoft.CodeAnalysis.Formatting;
8+
using Microsoft.CodeAnalysis.Simplification;
139

1410
namespace VSDiagnostics.Diagnostics.General.UseAliasesInsteadOfConcreteType
1511
{
@@ -36,35 +32,10 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
3632

3733
private async Task<Solution> UseAliasAsync(Document document, SyntaxNode root, SyntaxNode statement)
3834
{
39-
var semanticModel = await document.GetSemanticModelAsync();
40-
var typeName = semanticModel.GetSymbolInfo(statement).Symbol.MetadataName;
41-
var aliasToken = MapConcreteTypeToPredefinedTypeAlias[typeName];
42-
43-
var newExpression = SyntaxFactory.PredefinedType(SyntaxFactory.Token(aliasToken)).WithTriviaFrom(statement);
44-
var newRoot = root.ReplaceNode(statement, newExpression);
45-
var newDocument = document.WithSyntaxRoot(newRoot);
35+
var newRoot = root.ReplaceNode(statement, statement.WithAdditionalAnnotations(Simplifier.Annotation));
36+
var newDocument = await Simplifier.ReduceAsync(document.WithSyntaxRoot(newRoot));
4637

4738
return newDocument.Project.Solution;
4839
}
49-
50-
private static readonly Dictionary<string, SyntaxKind> MapConcreteTypeToPredefinedTypeAlias =
51-
new Dictionary<string, SyntaxKind>
52-
{
53-
{nameof(Int16), SyntaxKind.ShortKeyword},
54-
{nameof(Int32), SyntaxKind.IntKeyword},
55-
{nameof(Int64), SyntaxKind.LongKeyword},
56-
{nameof(UInt16), SyntaxKind.UShortKeyword},
57-
{nameof(UInt32), SyntaxKind.UIntKeyword},
58-
{nameof(UInt64), SyntaxKind.ULongKeyword},
59-
{nameof(Object), SyntaxKind.ObjectKeyword},
60-
{nameof(Byte), SyntaxKind.ByteKeyword},
61-
{nameof(SByte), SyntaxKind.SByteKeyword},
62-
{nameof(Char), SyntaxKind.CharKeyword},
63-
{nameof(Boolean), SyntaxKind.BoolKeyword},
64-
{nameof(Single), SyntaxKind.FloatKeyword},
65-
{nameof(Double), SyntaxKind.DoubleKeyword},
66-
{nameof(Decimal), SyntaxKind.DecimalKeyword},
67-
{nameof(String), SyntaxKind.StringKeyword}
68-
};
6940
}
7041
}

VSDiagnostics/VSDiagnostics/VSDiagnostics/Utilities/Extensions.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,6 @@ public static bool HasAlias(this string type, out string alias)
135135
return AliasMapping.TryGetValue(type, out alias);
136136
}
137137

138-
public static bool HasAlias(this string type)
139-
{
140-
if (type == null)
141-
{
142-
throw new ArgumentNullException(nameof(type));
143-
}
144-
145-
return AliasMapping.Keys.Contains(type);
146-
}
147-
148138
/// <summary>
149139
/// Determines whether or not the specified <see cref="IMethodSymbol" /> is the symbol of an asynchronous method. This
150140
/// can be a method declared as async (e.g. returning <see cref="Task" /> or <see cref="Task{TResult}" />), or a method

0 commit comments

Comments
 (0)