Skip to content

Commit 5456aef

Browse files
committed
Merge remote-tracking branch 'DotNetAnalyzers/stabilization'
2 parents e4a418c + 3c87756 commit 5456aef

4 files changed

Lines changed: 194 additions & 6 deletions

File tree

StyleCop.Analyzers/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
<ItemGroup>
4545
<PackageReference Include="AsyncUsageAnalyzers" Version="1.0.0-alpha003" PrivateAssets="all" />
4646
<PackageReference Include="DotNetAnalyzers.DocumentationAnalyzers" Version="1.0.0-beta.46" PrivateAssets="all" />
47-
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-rc.108" PrivateAssets="all" />
47+
<PackageReference Include="StyleCop.Analyzers" Version="1.1.1-rc.114" PrivateAssets="all" />
4848
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeStyle" Version="2.11.0-beta2-63603-03" PrivateAssets="all" />
4949
</ItemGroup>
5050

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

Lines changed: 24 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,16 @@ 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+
if (argumentList.IsEmpty)
107+
{
108+
return null;
109+
}
110+
111+
break;
101112
}
102113

103114
List<ParameterSyntax> parameters = GenerateUniqueParameterNames(semanticModel, anonymousMethod, argumentList);
@@ -107,12 +118,17 @@ private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, Anonymo
107118
: SyntaxFactory.SeparatedList<ParameterSyntax>();
108119

109120
parameterList = SyntaxFactory.ParameterList(newList)
110-
.WithLeadingTrivia(anonymousMethod.DelegateKeyword.LeadingTrivia)
121+
.WithLeadingTrivia(anonymousMethod.DelegateKeyword.LeadingTrivia);
122+
123+
arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken)
111124
.WithTrailingTrivia(anonymousMethod.DelegateKeyword.TrailingTrivia);
112125
}
113126
else
114127
{
115128
parameterList = parameterList.WithLeadingTrivia(anonymousMethod.DelegateKeyword.TrailingTrivia);
129+
130+
arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken)
131+
.WithTrailingTrivia(SyntaxFactory.ElasticSpace);
116132
}
117133

118134
foreach (var parameter in parameterList.Parameters)
@@ -123,9 +139,6 @@ private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, Anonymo
123139
}
124140
}
125141

126-
var arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken)
127-
.WithTrailingTrivia(SyntaxFactory.ElasticSpace);
128-
129142
if (parameterList.Parameters.Count == 1)
130143
{
131144
var parameterSyntax = RemoveType(parameterList.Parameters[0]);
@@ -193,6 +206,13 @@ private static ImmutableArray<string> GetEqualsArgumentList(SemanticModel semant
193206
return namedTypeSymbol.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray();
194207
}
195208

209+
private static ImmutableArray<string> GetMemberReturnTypeArgumentList(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod)
210+
{
211+
var enclosingSymbol = semanticModel.GetEnclosingSymbol(anonymousMethod.Parent.SpanStart);
212+
var returnType = ((IMethodSymbol)enclosingSymbol).ReturnType as INamedTypeSymbol;
213+
return (returnType == null) ? ImmutableArray<string>.Empty : returnType.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray();
214+
}
215+
196216
private static List<ParameterSyntax> GenerateUniqueParameterNames(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod, ImmutableArray<string> argumentNames)
197217
{
198218
var parameters = new List<ParameterSyntax>();

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp7/ReadabilityRules/SA1130CSharp7UnitTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,47 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp7.ReadabilityRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.ReadabilityRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.ReadabilityRules.SA1130UseLambdaSyntax,
13+
StyleCop.Analyzers.ReadabilityRules.SA1130CodeFixProvider>;
714

815
public class SA1130CSharp7UnitTests : SA1130UnitTests
916
{
17+
[Fact]
18+
[WorkItem(2902, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2902")]
19+
public async Task VerifyLocalFunctionAsync()
20+
{
21+
var testCode = @"using System;
22+
public class TestClass
23+
{
24+
public void TestMethod()
25+
{
26+
EventHandler LocalTestFunction() => delegate { };
27+
}
28+
}
29+
";
30+
31+
var fixedCode = @"using System;
32+
public class TestClass
33+
{
34+
public void TestMethod()
35+
{
36+
EventHandler LocalTestFunction() => (sender, e) => { };
37+
}
38+
}
39+
";
40+
41+
DiagnosticResult[] expected =
42+
{
43+
Diagnostic().WithLocation(6, 45),
44+
};
45+
46+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
47+
}
1048
}
1149
}

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

Lines changed: 131 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,135 @@ 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+
}
786+
787+
[Fact]
788+
[WorkItem(2902, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2902")]
789+
public async Task VerifyThatEventInitializersWorkAsExpectedAsync()
790+
{
791+
var testCode = @"using System;
792+
public class TestClass
793+
{
794+
public static event EventHandler StaticEvent = delegate { };
795+
public event EventHandler InstanceEvent = delegate { };
796+
}
797+
";
798+
799+
var fixedCode = @"using System;
800+
public class TestClass
801+
{
802+
public static event EventHandler StaticEvent = (sender, e) => { };
803+
public event EventHandler InstanceEvent = (sender, e) => { };
804+
}
805+
";
806+
807+
DiagnosticResult[] expected =
808+
{
809+
Diagnostic().WithLocation(4, 52),
810+
Diagnostic().WithLocation(5, 47),
811+
};
812+
813+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
814+
}
815+
816+
[Fact]
817+
[WorkItem(2902, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2902")]
818+
public async Task VerifyInvalidCodeConstructionsAsync()
819+
{
820+
var testCode = @"using System;
821+
public class TestClass
822+
{
823+
public static EventHandler[] TestMethod() => delegate { };
824+
}
825+
";
826+
827+
DiagnosticResult[] expected =
828+
{
829+
Diagnostic().WithSpan(4, 50, 4, 58),
830+
DiagnosticResult.CompilerError("CS1660").WithMessage("Cannot convert anonymous method to type 'EventHandler[]' because it is not a delegate type").WithSpan(4, 50, 4, 62),
831+
};
832+
833+
var test = new CSharpTest
834+
{
835+
TestCode = testCode,
836+
FixedCode = testCode,
837+
};
838+
839+
test.ExpectedDiagnostics.AddRange(expected);
840+
test.RemainingDiagnostics.AddRange(expected);
841+
await test.RunAsync(CancellationToken.None).ConfigureAwait(false);
842+
}
713843
}
714844
}

0 commit comments

Comments
 (0)