|
| 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 | +} |
0 commit comments