Skip to content

Commit 137e535

Browse files
committed
Add tests for remaining expression-bodied members
1 parent f48250c commit 137e535

11 files changed

Lines changed: 217 additions & 64 deletions
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.CSharp7.Lightup
5+
{
6+
using Microsoft.CodeAnalysis.CSharp;
7+
using StyleCop.Analyzers.Lightup;
8+
using Xunit;
9+
10+
public class BaseMethodDeclarationSyntaxExtensionsTests
11+
{
12+
[Fact]
13+
public void TestExpressionBody()
14+
{
15+
var syntax = SyntaxFactory.ConstructorDeclaration(SyntaxFactory.Identifier("Anything"))
16+
.WithExpressionBody(SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)));
17+
Assert.Same(syntax.ExpressionBody, BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
18+
}
19+
}
20+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.CSharp7.Lightup
5+
{
6+
using Microsoft.CodeAnalysis.CSharp;
7+
using StyleCop.Analyzers.Lightup;
8+
using Xunit;
9+
10+
public class ConstructorDeclarationSyntaxExtensionsTests
11+
{
12+
[Fact]
13+
public void TestWithExpressionBody()
14+
{
15+
var syntax = SyntaxFactory.ConstructorDeclaration(SyntaxFactory.Identifier("Anything"));
16+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
17+
var syntaxWithBody = ConstructorDeclarationSyntaxExtensions.WithExpressionBody(syntax, expressionBody);
18+
Assert.Null(syntax.ExpressionBody);
19+
Assert.NotNull(syntaxWithBody.ExpressionBody);
20+
Assert.Equal(SyntaxKind.NullLiteralExpression, syntaxWithBody.ExpressionBody.Expression.Kind());
21+
}
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.CSharp7.Lightup
5+
{
6+
using Microsoft.CodeAnalysis.CSharp;
7+
using StyleCop.Analyzers.Lightup;
8+
using Xunit;
9+
10+
public class DestructorDeclarationSyntaxExtensionsTests
11+
{
12+
[Fact]
13+
public void TestWithExpressionBody()
14+
{
15+
var syntax = SyntaxFactory.DestructorDeclaration(SyntaxFactory.Identifier("Anything"));
16+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
17+
var syntaxWithBody = DestructorDeclarationSyntaxExtensions.WithExpressionBody(syntax, expressionBody);
18+
Assert.Null(syntax.ExpressionBody);
19+
Assert.NotNull(syntaxWithBody.ExpressionBody);
20+
Assert.Equal(SyntaxKind.NullLiteralExpression, syntaxWithBody.ExpressionBody.Expression.Kind());
21+
}
22+
}
23+
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp7/StyleCop.Analyzers.Test.CSharp7.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@
195195
</ItemGroup>
196196
<ItemGroup>
197197
<Compile Include="Lightup\AccessorDeclarationSyntaxExtensionsTests.cs" />
198+
<Compile Include="Lightup\BaseMethodDeclarationSyntaxExtensionsTests.cs" />
199+
<Compile Include="Lightup\ConstructorDeclarationSyntaxExtensionsTests.cs" />
200+
<Compile Include="Lightup\DestructorDeclarationSyntaxExtensionsTests.cs" />
198201
<Compile Include="Properties\AssemblyInfo.cs" />
199202
</ItemGroup>
200203
<ItemGroup>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.Lightup
5+
{
6+
using Microsoft.CodeAnalysis.CSharp;
7+
using StyleCop.Analyzers.Lightup;
8+
using Xunit;
9+
10+
public class BaseMethodDeclarationSyntaxExtensionsTests
11+
{
12+
[Fact]
13+
public void TestExpressionBody_Constructor()
14+
{
15+
var syntax = SyntaxFactory.ConstructorDeclaration(SyntaxFactory.Identifier("Anything"));
16+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
17+
}
18+
19+
[Fact]
20+
public void TestExpressionBody_Destructor()
21+
{
22+
var syntax = SyntaxFactory.DestructorDeclaration(SyntaxFactory.Identifier("Anything"));
23+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
24+
}
25+
26+
[Fact]
27+
public void TestExpressionBody_Operator()
28+
{
29+
var syntax = SyntaxFactory.OperatorDeclaration(
30+
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
31+
SyntaxFactory.Token(SyntaxKind.PlusToken));
32+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
33+
34+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
35+
syntax = syntax.WithExpressionBody(expressionBody);
36+
Assert.NotNull(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
37+
Assert.Equal(SyntaxKind.NullLiteralExpression, BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax).Expression.Kind());
38+
}
39+
40+
[Fact]
41+
public void TestExpressionBody_ConversionOperator()
42+
{
43+
var syntax = SyntaxFactory.ConversionOperatorDeclaration(
44+
SyntaxFactory.Token(SyntaxKind.ExplicitKeyword),
45+
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)));
46+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
47+
48+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
49+
syntax = syntax.WithExpressionBody(expressionBody);
50+
Assert.NotNull(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
51+
Assert.Equal(SyntaxKind.NullLiteralExpression, BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax).Expression.Kind());
52+
}
53+
54+
[Fact]
55+
public void TestExpressionBody_Method()
56+
{
57+
var syntax = SyntaxFactory.MethodDeclaration(
58+
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
59+
SyntaxFactory.Identifier("Anything"));
60+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
61+
62+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
63+
syntax = syntax.WithExpressionBody(expressionBody);
64+
Assert.NotNull(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax));
65+
Assert.Equal(SyntaxKind.NullLiteralExpression, BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntax).Expression.Kind());
66+
}
67+
}
68+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.Lightup
5+
{
6+
using System;
7+
using Microsoft.CodeAnalysis.CSharp;
8+
using StyleCop.Analyzers.Lightup;
9+
using Xunit;
10+
11+
public class ConstructorDeclarationSyntaxExtensionsTests
12+
{
13+
[Fact]
14+
public void TestWithExpressionBody()
15+
{
16+
var syntax = SyntaxFactory.ConstructorDeclaration(SyntaxFactory.Identifier("Anything"));
17+
18+
// With default value is allowed
19+
var syntaxWithDefaultBody = ConstructorDeclarationSyntaxExtensions.WithExpressionBody(syntax, null);
20+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntaxWithDefaultBody));
21+
22+
// Non-default throws an exception
23+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
24+
Assert.Throws<NotSupportedException>(() => ConstructorDeclarationSyntaxExtensions.WithExpressionBody(syntax, expressionBody));
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.Lightup
5+
{
6+
using System;
7+
using Microsoft.CodeAnalysis.CSharp;
8+
using StyleCop.Analyzers.Lightup;
9+
using Xunit;
10+
11+
public class DestructorDeclarationSyntaxExtensionsTests
12+
{
13+
[Fact]
14+
public void TestWithExpressionBody()
15+
{
16+
var syntax = SyntaxFactory.DestructorDeclaration(SyntaxFactory.Identifier("Anything"));
17+
18+
// With default value is allowed
19+
var syntaxWithDefaultBody = DestructorDeclarationSyntaxExtensions.WithExpressionBody(syntax, null);
20+
Assert.Null(BaseMethodDeclarationSyntaxExtensions.ExpressionBody(syntaxWithDefaultBody));
21+
22+
// Non-default throws an exception
23+
var expressionBody = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
24+
Assert.Throws<NotSupportedException>(() => DestructorDeclarationSyntaxExtensions.WithExpressionBody(syntax, expressionBody));
25+
}
26+
}
27+
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/StyleCop.Analyzers.Test.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@
236236
<Compile Include="LayoutRules\SA1519UnitTests.cs" />
237237
<Compile Include="LayoutRules\SA1520UnitTests.cs" />
238238
<Compile Include="Lightup\AccessorDeclarationSyntaxExtensionsTests.cs" />
239+
<Compile Include="Lightup\BaseMethodDeclarationSyntaxExtensionsTests.cs" />
240+
<Compile Include="Lightup\ConstructorDeclarationSyntaxExtensionsTests.cs" />
241+
<Compile Include="Lightup\DestructorDeclarationSyntaxExtensionsTests.cs" />
239242
<Compile Include="LinqHelpers\SyntaxTriviaListEnumerableTests.cs" />
240243
<Compile Include="MaintainabilityRules\DebugMessagesUnitTestsBase.cs" />
241244
<Compile Include="MaintainabilityRules\FileMayOnlyContainTestBase.cs" />

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/BaseMethodDeclarationSyntaxExtensions.cs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
namespace StyleCop.Analyzers.Lightup
55
{
66
using System;
7-
using System.Linq.Expressions;
8-
using System.Reflection;
7+
using Microsoft.CodeAnalysis.CSharp;
98
using Microsoft.CodeAnalysis.CSharp.Syntax;
109

1110
internal static class BaseMethodDeclarationSyntaxExtensions
@@ -14,24 +13,30 @@ internal static class BaseMethodDeclarationSyntaxExtensions
1413

1514
static BaseMethodDeclarationSyntaxExtensions()
1615
{
17-
if (LightupHelpers.SupportsCSharp7)
18-
{
19-
var expressionBodyProperty = typeof(BaseMethodDeclarationSyntax).GetTypeInfo().GetDeclaredProperty(nameof(ExpressionBody));
20-
var syntaxParameter = Expression.Parameter(typeof(BaseMethodDeclarationSyntax), "syntax");
21-
Expression<Func<BaseMethodDeclarationSyntax, ArrowExpressionClauseSyntax>> expression =
22-
Expression.Lambda<Func<BaseMethodDeclarationSyntax, ArrowExpressionClauseSyntax>>(
23-
Expression.Call(syntaxParameter, expressionBodyProperty.GetMethod),
24-
syntaxParameter);
25-
ExpressionBodyAccessor = expression.Compile();
26-
}
27-
else
28-
{
29-
ExpressionBodyAccessor = syntax => null;
30-
}
16+
ExpressionBodyAccessor = LightupHelpers.CreateSyntaxPropertyAccessor<BaseMethodDeclarationSyntax, ArrowExpressionClauseSyntax>(typeof(BaseMethodDeclarationSyntax), nameof(ExpressionBody));
3117
}
3218

3319
public static ArrowExpressionClauseSyntax ExpressionBody(this BaseMethodDeclarationSyntax syntax)
3420
{
21+
if (!LightupHelpers.SupportsCSharp7)
22+
{
23+
// Prior to C# 7, the ExpressionBody properties did not override a base method.
24+
switch (syntax.Kind())
25+
{
26+
case SyntaxKind.MethodDeclaration:
27+
return ((MethodDeclarationSyntax)syntax).ExpressionBody;
28+
29+
case SyntaxKind.OperatorDeclaration:
30+
return ((OperatorDeclarationSyntax)syntax).ExpressionBody;
31+
32+
case SyntaxKind.ConversionOperatorDeclaration:
33+
return ((ConversionOperatorDeclarationSyntax)syntax).ExpressionBody;
34+
35+
default:
36+
break;
37+
}
38+
}
39+
3540
return ExpressionBodyAccessor(syntax);
3641
}
3742
}

StyleCop.Analyzers/StyleCop.Analyzers/Lightup/ConstructorDeclarationSyntaxExtensions.cs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
namespace StyleCop.Analyzers.Lightup
55
{
66
using System;
7-
using System.Linq;
8-
using System.Linq.Expressions;
9-
using System.Reflection;
107
using Microsoft.CodeAnalysis.CSharp.Syntax;
118

129
internal static class ConstructorDeclarationSyntaxExtensions
@@ -15,27 +12,7 @@ internal static class ConstructorDeclarationSyntaxExtensions
1512

1613
static ConstructorDeclarationSyntaxExtensions()
1714
{
18-
if (LightupHelpers.SupportsCSharp7)
19-
{
20-
var withExpressionBodyMethod = typeof(ConstructorDeclarationSyntax).GetTypeInfo().GetDeclaredMethods(nameof(WithExpressionBody))
21-
.Single(method => method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(ArrowExpressionClauseSyntax));
22-
var syntaxParameter = Expression.Parameter(typeof(ConstructorDeclarationSyntax), "syntax");
23-
var expressionBodyParameter = Expression.Parameter(typeof(ArrowExpressionClauseSyntax), "expressionBody");
24-
Expression<Func<ConstructorDeclarationSyntax, ArrowExpressionClauseSyntax, ConstructorDeclarationSyntax>> expression =
25-
Expression.Lambda<Func<ConstructorDeclarationSyntax, ArrowExpressionClauseSyntax, ConstructorDeclarationSyntax>>(
26-
Expression.Call(syntaxParameter, withExpressionBodyMethod, expressionBodyParameter),
27-
syntaxParameter,
28-
expressionBodyParameter);
29-
WithExpressionBodyAccessor = expression.Compile();
30-
}
31-
else
32-
{
33-
WithExpressionBodyAccessor =
34-
(syntax, expressionBody) =>
35-
{
36-
throw new NotSupportedException("Expression-bodied constructors are only available in C# 7+.");
37-
};
38-
}
15+
WithExpressionBodyAccessor = LightupHelpers.CreateSyntaxWithPropertyAccessor<ConstructorDeclarationSyntax, ArrowExpressionClauseSyntax>(typeof(ConstructorDeclarationSyntax), nameof(BaseMethodDeclarationSyntaxExtensions.ExpressionBody));
3916
}
4017

4118
public static ConstructorDeclarationSyntax WithExpressionBody(this ConstructorDeclarationSyntax syntax, ArrowExpressionClauseSyntax expressionBody)

0 commit comments

Comments
 (0)