Skip to content

Commit 30751a3

Browse files
committed
Simplify SA1410 overload analysis using the speculative semantic model
1 parent 0b48abd commit 30751a3

2 files changed

Lines changed: 30 additions & 32 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1410UnitTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public void TestMethod()
121121
});
122122
123123
this.TestMethod2(delegate() { return true; });
124+
this.TestMethod3(delegate() { return true; });
124125
}
125126
126127
public void TestMethod2(Delegate1 d)
@@ -131,6 +132,17 @@ public void TestMethod2(Delegate2 d)
131132
{
132133
}
133134
}
135+
136+
public static class TestClassExtensions
137+
{
138+
public static void TestMethod3(this TestClass obj, TestClass.Delegate1 d)
139+
{
140+
}
141+
142+
public static void TestMethod3(this TestClass obj, TestClass.Delegate2 d)
143+
{
144+
}
145+
}
134146
";
135147

136148
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
@@ -155,6 +167,7 @@ public void TestMethod()
155167
this.TestMethod3(0, delegate() { return true; });
156168
this.TestMethod4(delegate() { return true; }, 1);
157169
this.TestMethod5(delegate() { return true; });
170+
this.TestMethod6(delegate() { return true; });
158171
}
159172
160173
public void TestMethod2(Delegate1 d)
@@ -188,6 +201,17 @@ public void TestMethod5(Delegate1 d)
188201
public void TestMethod5(Delegate2 d, double x)
189202
{
190203
}
204+
205+
public void TestMethod6(Delegate1 d)
206+
{
207+
}
208+
}
209+
210+
public static class TestClassExtensions
211+
{
212+
public static void TestMethod6(this TestClass obj, TestClass.Delegate2 d)
213+
{
214+
}
191215
}
192216
";
193217

@@ -197,6 +221,7 @@ public void TestMethod5(Delegate2 d, double x)
197221
this.CSharpDiagnostic().WithLocation(9, 37),
198222
this.CSharpDiagnostic().WithLocation(10, 34),
199223
this.CSharpDiagnostic().WithLocation(11, 34),
224+
this.CSharpDiagnostic().WithLocation(12, 34),
200225
};
201226

202227
await this.VerifyCSharpDiagnosticAsync(testCode, expectedResults, CancellationToken.None).ConfigureAwait(false);

StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1410RemoveDelegateParenthesisWhenPossible.cs

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ namespace StyleCop.Analyzers.MaintainabilityRules
55
{
66
using System;
77
using System.Collections.Immutable;
8-
using System.Linq;
9-
using System.Threading;
108
using Microsoft.CodeAnalysis;
119
using Microsoft.CodeAnalysis.CSharp;
1210
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -93,7 +91,7 @@ private static void HandleAnonymousMethodExpression(SyntaxNodeAnalysisContext co
9391
{
9492
case SyntaxKind.ObjectCreationExpression:
9593
case SyntaxKind.InvocationExpression:
96-
if (HasAmbiguousOverload(context, argumentListSyntax.Arguments.IndexOf(argumentSyntax), argumentListSyntax.Parent))
94+
if (HasAmbiguousOverload(context, syntax, argumentListSyntax.Parent))
9795
{
9896
return;
9997
}
@@ -106,36 +104,11 @@ private static void HandleAnonymousMethodExpression(SyntaxNodeAnalysisContext co
106104
context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.ParameterList.GetLocation()));
107105
}
108106

109-
private static bool HasAmbiguousOverload(SyntaxNodeAnalysisContext context, int parameterIndex, SyntaxNode methodCallSyntax)
107+
private static bool HasAmbiguousOverload(SyntaxNodeAnalysisContext context, AnonymousMethodExpressionSyntax anonymousMethodExpression, SyntaxNode methodCallSyntax)
110108
{
111-
var methodSymbol = (IMethodSymbol)context.SemanticModel.GetSymbolInfo(methodCallSyntax, context.CancellationToken).Symbol;
112-
113-
var nameOverloads = methodSymbol.ContainingType.GetMembers(methodSymbol.Name);
114-
var parameterCountMatchingOverloads = nameOverloads.OfType<IMethodSymbol>().Where(symbol => (symbol != methodSymbol) && (symbol.Parameters.Length == methodSymbol.Parameters.Length));
115-
116-
foreach (var overload in parameterCountMatchingOverloads)
117-
{
118-
var isAmbiguousOverload = true;
119-
120-
for (var i = 0; isAmbiguousOverload && (i < methodSymbol.Parameters.Length); i++)
121-
{
122-
if (i == parameterIndex)
123-
{
124-
isAmbiguousOverload = overload.Parameters[i].Type.TypeKind == TypeKind.Delegate;
125-
}
126-
else
127-
{
128-
isAmbiguousOverload = methodSymbol.Parameters[i].Type == overload.Parameters[i].Type;
129-
}
130-
}
131-
132-
if (isAmbiguousOverload)
133-
{
134-
return true;
135-
}
136-
}
137-
138-
return false;
109+
var nodeForSpeculation = methodCallSyntax.ReplaceNode(anonymousMethodExpression, anonymousMethodExpression.WithParameterList(null));
110+
var speculativeSymbolInfo = context.SemanticModel.GetSpeculativeSymbolInfo(methodCallSyntax.SpanStart, nodeForSpeculation, SpeculativeBindingOption.BindAsExpression);
111+
return speculativeSymbolInfo.Symbol == null;
139112
}
140113
}
141114
}

0 commit comments

Comments
 (0)