Skip to content

Commit 67110e8

Browse files
committed
Fixed SA1130 code fix for return statements and arrow expression clauses
1 parent cbec141 commit 67110e8

2 files changed

Lines changed: 94 additions & 5 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1130CodeFixProvider.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, Anonymo
7272
{
7373
var parameterList = anonymousMethod.ParameterList;
7474
SyntaxNode lambdaExpression;
75+
SyntaxToken arrowToken;
7576

7677
if (parameterList == null)
7778
{
@@ -98,6 +99,11 @@ private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, Anonymo
9899

99100
argumentList = list.Value;
100101
break;
102+
103+
case SyntaxKind.ArrowExpressionClause:
104+
case SyntaxKind.ReturnStatement:
105+
argumentList = GetMemberReturnTypeArgumentList(semanticModel, anonymousMethod);
106+
break;
101107
}
102108

103109
List<ParameterSyntax> parameters = GenerateUniqueParameterNames(semanticModel, anonymousMethod, argumentList);
@@ -107,12 +113,17 @@ private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, Anonymo
107113
: SyntaxFactory.SeparatedList<ParameterSyntax>();
108114

109115
parameterList = SyntaxFactory.ParameterList(newList)
110-
.WithLeadingTrivia(anonymousMethod.DelegateKeyword.LeadingTrivia)
116+
.WithLeadingTrivia(anonymousMethod.DelegateKeyword.LeadingTrivia);
117+
118+
arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken)
111119
.WithTrailingTrivia(anonymousMethod.DelegateKeyword.TrailingTrivia);
112120
}
113121
else
114122
{
115123
parameterList = parameterList.WithLeadingTrivia(anonymousMethod.DelegateKeyword.TrailingTrivia);
124+
125+
arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken)
126+
.WithTrailingTrivia(SyntaxFactory.ElasticSpace);
116127
}
117128

118129
foreach (var parameter in parameterList.Parameters)
@@ -123,9 +134,6 @@ private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, Anonymo
123134
}
124135
}
125136

126-
var arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken)
127-
.WithTrailingTrivia(SyntaxFactory.ElasticSpace);
128-
129137
if (parameterList.Parameters.Count == 1)
130138
{
131139
var parameterSyntax = RemoveType(parameterList.Parameters[0]);
@@ -193,6 +201,14 @@ private static ImmutableArray<string> GetEqualsArgumentList(SemanticModel semant
193201
return namedTypeSymbol.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray();
194202
}
195203

204+
private static ImmutableArray<string> GetMemberReturnTypeArgumentList(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod)
205+
{
206+
var enclosingSymbol = semanticModel.GetEnclosingSymbol(anonymousMethod.Parent.SpanStart);
207+
var returnType = (INamedTypeSymbol)((IMethodSymbol)enclosingSymbol).ReturnType;
208+
209+
return returnType.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray();
210+
}
211+
196212
private static List<ParameterSyntax> GenerateUniqueParameterNames(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod, ImmutableArray<string> argumentNames)
197213
{
198214
var parameters = new List<ParameterSyntax>();

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

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ public class TypeName
276276
{
277277
public void Test()
278278
{
279-
Action action1 = /*a*/()/*b*/ => { };
279+
Action action1 = /*a*/() =>/*b*/{ };
280280
Action action2 = /*a*//*b*/(/*c*/)/*d*/ => { };
281281
Action<int> action3 = /*a*//*b*//*c*//*d*/i/*e*//*f*/ => { };
282282
Action<List<int>> action4 = i => { };
@@ -710,5 +710,78 @@ static void Main(string[] args)
710710

711711
await VerifyCSharpFixAsync(testCode, expected, testCode, CancellationToken.None).ConfigureAwait(false);
712712
}
713+
714+
[Fact]
715+
[WorkItem(2902, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2902")]
716+
public async Task VerifyThatCodeFixDoesNotCrashOnDelegateReturnAsync()
717+
{
718+
var testCode = @"using System;
719+
public class TestClass
720+
{
721+
public static EventHandler TestMethod1()
722+
{
723+
return delegate
724+
{
725+
};
726+
}
727+
728+
public static EventHandler TestMethod2() => delegate
729+
{
730+
};
731+
732+
public static EventHandler TestProperty1
733+
{
734+
get
735+
{
736+
return delegate
737+
{
738+
};
739+
}
740+
}
741+
742+
public static EventHandler TestProperty2 => delegate
743+
{
744+
};
745+
}";
746+
747+
var fixedCode = @"using System;
748+
public class TestClass
749+
{
750+
public static EventHandler TestMethod1()
751+
{
752+
return (sender, e) =>
753+
{
754+
};
755+
}
756+
757+
public static EventHandler TestMethod2() => (sender, e) =>
758+
{
759+
};
760+
761+
public static EventHandler TestProperty1
762+
{
763+
get
764+
{
765+
return (sender, e) =>
766+
{
767+
};
768+
}
769+
}
770+
771+
public static EventHandler TestProperty2 => (sender, e) =>
772+
{
773+
};
774+
}";
775+
776+
DiagnosticResult[] expected =
777+
{
778+
Diagnostic().WithLocation(6, 16),
779+
Diagnostic().WithLocation(11, 49),
780+
Diagnostic().WithLocation(19, 20),
781+
Diagnostic().WithLocation(25, 49),
782+
};
783+
784+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
785+
}
713786
}
714787
}

0 commit comments

Comments
 (0)