Skip to content

Commit 4de63e9

Browse files
committed
Merge pull request #2808 from pdelvo/sa1130params
Fix that SA1130 crashes on params
2 parents 20bb5a2 + 0c26aa1 commit 4de63e9

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1130UnitTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,5 +404,47 @@ public void Test()
404404

405405
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
406406
}
407+
408+
[Fact]
409+
public async Task TestParamsAsync()
410+
{
411+
var testCode = @"
412+
using System;
413+
public class TypeName
414+
{
415+
public void Test(params Action[] argument)
416+
{
417+
418+
}
419+
420+
public void Test()
421+
{
422+
Test(delegate { }, delegate { });
423+
}
424+
}";
425+
426+
string fixedCode = @"
427+
using System;
428+
public class TypeName
429+
{
430+
public void Test(params Action[] argument)
431+
{
432+
433+
}
434+
435+
public void Test()
436+
{
437+
Test(() => { }, () => { });
438+
}
439+
}";
440+
441+
var expected = new[]
442+
{
443+
Diagnostic().WithLocation(12, 14),
444+
Diagnostic().WithLocation(12, 28),
445+
};
446+
447+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
448+
}
407449
}
408450
}

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1130UseLambdaSyntax.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,25 @@ public override void Initialize(AnalysisContext context)
5555
/// <returns>A parameter list for the delegate parameters.</returns>
5656
internal static ParameterListSyntax GetDelegateParameterList(IMethodSymbol methodSymbol, int argumentIndex)
5757
{
58-
var delegateType = (INamedTypeSymbol)methodSymbol.Parameters[argumentIndex].Type;
58+
var realIndex = Math.Min(argumentIndex, methodSymbol.Parameters.Length - 1);
59+
60+
var type = methodSymbol.Parameters[realIndex].Type;
61+
62+
if (methodSymbol.Parameters[realIndex].IsParams)
63+
{
64+
if (type is IArrayTypeSymbol arrayTypeSymbol)
65+
{
66+
type = arrayTypeSymbol.ElementType;
67+
}
68+
else
69+
{
70+
// Just to make sure that we do not crash if in future versions of the compiler other types are allowed for params.
71+
// This if statement should be extended if e.g. Span params are introduced into the language.
72+
return null;
73+
}
74+
}
75+
76+
var delegateType = (INamedTypeSymbol)type;
5977
var delegateParameters = delegateType.DelegateInvokeMethod.Parameters;
6078

6179
var syntaxParameters = GetSyntaxParametersFromSymbolParameters(delegateParameters);
@@ -95,8 +113,7 @@ private static bool HandleMethodInvocation(SemanticModel semanticModel, Anonymou
95113
// invocation -> argument list -> argument -> anonymous method
96114
var argumentListSyntax = argumentSyntax?.Parent as ArgumentListSyntax;
97115

98-
var originalInvocationExpression = argumentListSyntax?.Parent as InvocationExpressionSyntax;
99-
if (originalInvocationExpression != null)
116+
if (argumentListSyntax?.Parent is InvocationExpressionSyntax originalInvocationExpression)
100117
{
101118
SymbolInfo originalSymbolInfo = semanticModel.GetSymbolInfo(originalInvocationExpression);
102119

@@ -113,6 +130,12 @@ private static bool HandleMethodInvocation(SemanticModel semanticModel, Anonymou
113130
// Determine the parameter list from the method that is invoked, as delegates without parameters are allowed, but they cannot be replaced by a lambda without parameters.
114131
var parameterList = GetDelegateParameterList((IMethodSymbol)originalSymbolInfo.Symbol, argumentIndex);
115132

133+
if (parameterList == null)
134+
{
135+
// This might happen if the call was using params witha type unknown to the analyzer, e.g. params Span<T>.
136+
return false;
137+
}
138+
116139
// In some cases passing a delegate as an argument to a method is required to call the right overload
117140
// When there is an other overload that takes an expression.
118141
var lambdaExpression = SyntaxFactory.ParenthesizedLambdaExpression(

0 commit comments

Comments
 (0)