Skip to content

Commit 00da276

Browse files
committed
Support expression-bodied accessors via light-up
1 parent 36d2485 commit 00da276

8 files changed

Lines changed: 686 additions & 0 deletions
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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.Lightup
5+
{
6+
using System;
7+
using System.Linq;
8+
using System.Linq.Expressions;
9+
using System.Reflection;
10+
using Microsoft.CodeAnalysis.CSharp.Syntax;
11+
12+
internal static class AccessorDeclarationSyntaxExtensions
13+
{
14+
private static readonly Func<AccessorDeclarationSyntax, ArrowExpressionClauseSyntax> ExpressionBodyAccessor;
15+
private static readonly Func<AccessorDeclarationSyntax, ArrowExpressionClauseSyntax, AccessorDeclarationSyntax> WithExpressionBodyAccessor;
16+
17+
static AccessorDeclarationSyntaxExtensions()
18+
{
19+
if (LightupHelpers.SupportsCSharp7)
20+
{
21+
{
22+
var expressionBodyProperty = typeof(AccessorDeclarationSyntax).GetTypeInfo().GetDeclaredProperty(nameof(ExpressionBody));
23+
var syntaxParameter = Expression.Parameter(typeof(AccessorDeclarationSyntax), "syntax");
24+
Expression<Func<AccessorDeclarationSyntax, ArrowExpressionClauseSyntax>> expression =
25+
Expression.Lambda<Func<AccessorDeclarationSyntax, ArrowExpressionClauseSyntax>>(
26+
Expression.Call(syntaxParameter, expressionBodyProperty.GetMethod),
27+
syntaxParameter);
28+
ExpressionBodyAccessor = expression.Compile();
29+
}
30+
31+
{
32+
var withExpressionBodyMethod = typeof(AccessorDeclarationSyntax).GetTypeInfo().GetDeclaredMethods(nameof(WithExpressionBody))
33+
.Single(method => method.GetParameters().Length == 1 && method.GetParameters()[0].ParameterType == typeof(ArrowExpressionClauseSyntax));
34+
var syntaxParameter = Expression.Parameter(typeof(AccessorDeclarationSyntax), "syntax");
35+
var expressionBodyParameter = Expression.Parameter(typeof(ArrowExpressionClauseSyntax), "expressionBody");
36+
Expression<Func<AccessorDeclarationSyntax, ArrowExpressionClauseSyntax, AccessorDeclarationSyntax>> expression =
37+
Expression.Lambda<Func<AccessorDeclarationSyntax, ArrowExpressionClauseSyntax, AccessorDeclarationSyntax>>(
38+
Expression.Call(syntaxParameter, withExpressionBodyMethod, expressionBodyParameter),
39+
syntaxParameter,
40+
expressionBodyParameter);
41+
WithExpressionBodyAccessor = expression.Compile();
42+
}
43+
}
44+
else
45+
{
46+
ExpressionBodyAccessor = syntax => null;
47+
WithExpressionBodyAccessor =
48+
(syntax, expressionBody) =>
49+
{
50+
throw new NotSupportedException("Expression-bodied accessors are only available in C# 7+.");
51+
};
52+
}
53+
}
54+
55+
public static ArrowExpressionClauseSyntax ExpressionBody(this AccessorDeclarationSyntax syntax)
56+
{
57+
return ExpressionBodyAccessor(syntax);
58+
}
59+
60+
public static AccessorDeclarationSyntax WithExpressionBody(this AccessorDeclarationSyntax syntax, ArrowExpressionClauseSyntax expressionBody)
61+
{
62+
return WithExpressionBodyAccessor(syntax, expressionBody);
63+
}
64+
}
65+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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.Lightup
5+
{
6+
using System;
7+
using System.Linq.Expressions;
8+
using System.Reflection;
9+
using Microsoft.CodeAnalysis.CSharp.Syntax;
10+
11+
internal static class BaseMethodDeclarationSyntaxExtensions
12+
{
13+
private static readonly Func<BaseMethodDeclarationSyntax, ArrowExpressionClauseSyntax> ExpressionBodyAccessor;
14+
15+
static BaseMethodDeclarationSyntaxExtensions()
16+
{
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+
}
31+
}
32+
33+
public static ArrowExpressionClauseSyntax ExpressionBody(this BaseMethodDeclarationSyntax syntax)
34+
{
35+
return ExpressionBodyAccessor(syntax);
36+
}
37+
}
38+
}

0 commit comments

Comments
 (0)