Skip to content

Commit

Permalink
Update to .Net 9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviersolau committed Dec 12, 2024
1 parent 6886d38 commit 68a8d8d
Show file tree
Hide file tree
Showing 25 changed files with 247 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 7.0.100
dotnet-version: 9.0.101
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 7.0.100
dotnet-version: 9.0.101
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
1 change: 1 addition & 0 deletions src/SharedProperties.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

<!--<Nullable>enable</Nullable>-->

<NoWarn>$(NoWarn),CA1515</NoWarn>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace SoloX.ExpressionTools.Examples
/// <summary>
/// This class shows how to use the ParameterInliner.
/// </summary>
public static class BasicInlinerExample
internal static class BasicInlinerExample
{
/// <summary>
/// Let's in-line a lambda expression into one-another: a => a + 1 into b => b * 2 giving us a => (a + 1) * 2.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace SoloX.ExpressionTools.Examples
/// <summary>
/// This class shows how to use the ExpressionParser.
/// </summary>
public static class BasicParserExample
internal static class BasicParserExample
{
/// <summary>
/// Let's parse a self described lambda expression like "(int x) => x + 1".
Expand Down Expand Up @@ -126,7 +126,7 @@ public static void ParseASimpleLambdaWithACustomTypeNameResolver2()
/// <summary>
/// IFoo interface to take as a custom type.
/// </summary>
public interface IFoo
internal interface IFoo
{
/// <summary>
///
Expand Down
2 changes: 1 addition & 1 deletion src/examples/SoloX.ExpressionTools.Examples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace SoloX.ExpressionTools.Examples
/// <summary>
/// Example program.
/// </summary>
public static class Program
internal static class Program
{
/// <summary>
/// Main program entry point.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<Import Project="..\..\SharedProperties.props" />

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SoloX.CodeQuality.Prod" Version="2.0.16">
<PackageReference Include="SoloX.CodeQuality.Prod" Version="2.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public Type ResolveTypeName(string typeName)
var idx = typeName.IndexOf('.');
while (idx >= 0)
{
typeName = typeName.Substring(idx + 1, typeName.Length - idx - 1);
typeName = typeName.Substring(idx + 1);

type = ResolveTypeName(typeName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal sealed class LambdaVisitor : CSharpSyntaxVisitor<LambdaVisitorAttribute
private readonly Stack<LambdaVisitorAttribute> attributes = new Stack<LambdaVisitorAttribute>();

private readonly TypeVisitor typeVisitor;
private readonly ITypeNameResolver defaultSystemTypeNameResolver;
private readonly NameSpaceTypeNameResolver defaultSystemTypeNameResolver;

/// <summary>
/// Initializes a new instance of the <see cref="LambdaVisitor"/> class.
Expand Down Expand Up @@ -334,7 +334,7 @@ private static MethodInfo TryLoadResultingMethod(Type[] argumentTypes, string me
{
var resultingMethodInfo = type.GetMethod(memberName, argumentTypes);

if (resultingMethodInfo == null && type.IsInterface && memberName == nameof(Object.ToString) && !argumentTypes.Any())
if (resultingMethodInfo == null && type.IsInterface && memberName == nameof(Object.ToString) && (argumentTypes.Length == 0))
{
resultingMethodInfo = typeof(object).GetMethod(memberName);
}
Expand Down Expand Up @@ -582,6 +582,9 @@ public override LambdaVisitorAttribute VisitLiteralExpression(LiteralExpressionS
case SyntaxKind.NullLiteralExpression:
attribute.ResultingExpression = Expression.Default(typeof(object));
break;
case SyntaxKind.CharacterLiteralExpression:
attribute.ResultingExpression = Expression.Constant(node.Token.Value);
break;
default:
throw new FormatException($"unsupported operator {node.Token.ValueText}");
}
Expand All @@ -606,7 +609,7 @@ public override LambdaVisitorAttribute VisitConditionalExpression(ConditionalExp
return attribute;
}

private static Expression CreateBinaryExpression(SyntaxKind kind, Expression le, Expression re, BinaryExpressionSyntax node)
private static BinaryExpression CreateBinaryExpression(SyntaxKind kind, Expression le, Expression re, BinaryExpressionSyntax node)
{
switch (kind)
{
Expand Down Expand Up @@ -647,7 +650,7 @@ private static Expression CreateBinaryExpression(SyntaxKind kind, Expression le,
}
}

private static Expression CreatePrefixUnaryExpression(SyntaxKind kind, Expression exp, PrefixUnaryExpressionSyntax node)
private static UnaryExpression CreatePrefixUnaryExpression(SyntaxKind kind, Expression exp, PrefixUnaryExpressionSyntax node)
{
switch (kind)
{
Expand Down Expand Up @@ -688,19 +691,19 @@ private static Expression ConvertIfNeeded(Expression expression, Type targetType
return Expression.Convert(expression, targetType);
}

private static IEnumerable<Expression> ConvertTypeForConstructorCall(IReadOnlyList<Expression> args, ConstructorInfo constructorInfo)
private static Expression[] ConvertTypeForConstructorCall(IReadOnlyList<Expression> args, ConstructorInfo constructorInfo)
{
var parameters = constructorInfo.GetParameters();
return ConvertArgumentsForCall(args, parameters);
}

private static IEnumerable<Expression> ConvertTypeForMethodCall(IReadOnlyList<Expression> args, MethodInfo methodInfo)
private static Expression[] ConvertTypeForMethodCall(IReadOnlyList<Expression> args, MethodInfo methodInfo)
{
var parameters = methodInfo.GetParameters();
return ConvertArgumentsForCall(args, parameters);
}

private static IEnumerable<Expression> ConvertArgumentsForCall(IReadOnlyList<Expression> args, ParameterInfo[] parameters)
private static Expression[] ConvertArgumentsForCall(IReadOnlyList<Expression> args, ParameterInfo[] parameters)
{
var argCount = args.Count;
var convertedArgs = new Expression[argCount];
Expand All @@ -725,7 +728,7 @@ private static IEnumerable<Expression> ConvertArgumentsForCall(IReadOnlyList<Exp

private LambdaVisitorAttribute VisitWithNewAttribute(Action<LambdaVisitorAttribute> action)
{
var attribute = new LambdaVisitorAttribute(this.attributes.Any() ? this.attributes.Peek() : null);
var attribute = new LambdaVisitorAttribute(this.attributes.Count > 0 ? this.attributes.Peek() : null);
this.attributes.Push(attribute);
action(attribute);
return this.attributes.Pop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace SoloX.ExpressionTools.Parser.Impl.Visitor
/// </summary>
internal sealed class TypeVisitor : CSharpSyntaxVisitor<Type>
{
private static readonly IReadOnlyDictionary<string, Type> PredefinedTypeMap = new Dictionary<string, Type>()
private static readonly Dictionary<string, Type> PredefinedTypeMap = new Dictionary<string, Type>()
{
{ "float", typeof(float) },
{ "double", typeof(double) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SoloX.CodeQuality.Prod" Version="2.0.16">
<PackageReference Include="SoloX.CodeQuality.Prod" Version="2.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
</ItemGroup>

</Project>
26 changes: 26 additions & 0 deletions src/libs/SoloX.ExpressionTools.Transform/IPropertyNameResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,31 @@ public interface IPropertyNameResolver
/// <returns>The name of the property.</returns>
/// <remarks>It will throw an exception if the lambda is unexpected.</remarks>
string GetPropertyName(LambdaExpression expression);

/// <summary>
/// Return the name of the method used in the lambda expression.
/// </summary>
/// <typeparam name="TElement">Type of the root element.</typeparam>
/// <typeparam name="TDelegate">The delegate type Action or Func.</typeparam>
/// <param name="expression">The lambda expression to get the method name from.</param>
/// <returns>The name of the method.</returns>
/// <remarks>It will throw an exception if the lambda is unexpected.</remarks>
string GetMethodName<TElement, TDelegate>(Expression<Func<TElement, TDelegate>> expression);

/// <summary>
/// Return the name of the method used in the lambda expression.
/// </summary>
/// <typeparam name="TElement">Type of the root element.</typeparam>
/// <param name="expression">The lambda expression to get the method name from.</param>
/// <returns>The name of the method.</returns>
/// <remarks>It will throw an exception if the lambda is unexpected.</remarks>
string GetMethodName<TElement>(Expression<Func<TElement, Delegate>> expression);

/// <summary>
/// Return the name of the method used in the lambda expression.
/// </summary>
/// <param name="expression">The lambda expression to get the method name from.</param>
/// <returns>The name of the method.</returns>
string GetMethodName(LambdaExpression expression);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,64 @@ public class PropertyNameResolver : IPropertyNameResolver
/// <inheritdoc/>
public string GetPropertyName<TElement, TResult>(Expression<Func<TElement, TResult>> expression)
{
var visitor = new PropertyNameResolverVisitor();
var visitor = new PropertyOrMethodNameResolverVisitor(false);
visitor.Visit(expression);

var name = visitor.PropertyName;
var name = visitor.PropertyOrMethodName;

if (string.IsNullOrEmpty(name))
{
throw new ArgumentException($"unable to get the property name from the given expression.");
}

return visitor.PropertyName;
return visitor.PropertyOrMethodName;
}

/// <inheritdoc/>
public string GetPropertyName(LambdaExpression expression)
{
var visitor = new PropertyNameResolverVisitor();
var visitor = new PropertyOrMethodNameResolverVisitor(false);
visitor.Visit(expression);

return visitor.PropertyName;
return visitor.PropertyOrMethodName;
}

/// <inheritdoc/>
public string GetMethodName<TElement, TDelegate>(Expression<Func<TElement, TDelegate>> expression)
{
var visitor = new PropertyOrMethodNameResolverVisitor(true);
visitor.Visit(expression);

var name = visitor.PropertyOrMethodName;

if (string.IsNullOrEmpty(name))
{
throw new ArgumentException($"unable to get the method name from the given expression.");
}

return visitor.PropertyOrMethodName;
}

/// <inheritdoc/>
public string GetMethodName<TElement>(Expression<Func<TElement, Delegate>> expression)
{
return GetMethodName<TElement, Delegate>(expression);
}

/// <inheritdoc/>
public string GetMethodName(LambdaExpression expression)
{
var visitor = new PropertyOrMethodNameResolverVisitor(true);
visitor.Visit(expression);

var name = visitor.PropertyOrMethodName;

if (string.IsNullOrEmpty(name))
{
throw new ArgumentException($"unable to get the method name from the given expression.");
}

return visitor.PropertyOrMethodName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace SoloX.ExpressionTools.Transform.Impl.Visitor
internal sealed class InlinerVisitor : ExpressionVisitor
{
private readonly IParameterResolver parameterResolver;
private readonly IDictionary<ParameterExpression, LambdaExpression> parameterMap;
private readonly Dictionary<ParameterExpression, LambdaExpression> parameterMap;

/// <summary>
/// Initializes a new instance of the <see cref="InlinerVisitor"/> class.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ----------------------------------------------------------------------
// <copyright file="PropertyNameResolverVisitor.cs" company="Xavier Solau">
// <copyright file="PropertyOrMethodNameResolverVisitor.cs" company="Xavier Solau">
// Copyright © 2019 Xavier Solau.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
Expand All @@ -8,15 +8,22 @@

using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace SoloX.ExpressionTools.Transform.Impl.Visitor
{
internal sealed class PropertyNameResolverVisitor : ExpressionVisitor
internal sealed class PropertyOrMethodNameResolverVisitor : ExpressionVisitor
{
private readonly StringBuilder name = new StringBuilder();
private readonly bool enableMethod;
private bool isSet;

public PropertyOrMethodNameResolverVisitor(bool enableMethod)
{
this.enableMethod = enableMethod;
}

public override Expression Visit(Expression node)
{
return base.Visit(node);
Expand All @@ -42,7 +49,18 @@ protected override Expression VisitMember(MemberExpression node)

protected override Expression VisitMethodCall(MethodCallExpression node)
{
throw new ArgumentException($"Unexpected use of the method {node.Method.Name} in the given expression.");
var mi = typeof(MethodInfo).GetMethod("CreateDelegate", [typeof(Type), typeof(object)]);

if (node.Method == mi && this.enableMethod)
{
Visit(node.Object);

return node;
}
else
{
throw new ArgumentException($"Unexpected use of the method {node.Method.Name} in the given expression.");
}
}

protected override SwitchCase VisitSwitchCase(SwitchCase node)
Expand Down Expand Up @@ -72,7 +90,25 @@ protected override Expression VisitConditional(ConditionalExpression node)

protected override Expression VisitConstant(ConstantExpression node)
{
throw new ArgumentException($"Unexpected use of constant in the given expression.");
if (node.Type == typeof(MethodInfo) && this.enableMethod)
{
if (this.isSet)
{
this.name.Append('.');
}
else
{
this.isSet = true;
}

this.name.Append(((MethodInfo)node.Value).Name);

return base.VisitConstant(node);
}
else
{
throw new ArgumentException($"Unexpected use of constant in the given expression.");
}
}

protected override Expression VisitDebugInfo(DebugInfoExpression node)
Expand Down Expand Up @@ -167,9 +203,16 @@ protected override Expression VisitTypeBinary(TypeBinaryExpression node)

protected override Expression VisitUnary(UnaryExpression node)
{
throw new ArgumentException($"Unexpected use of unary in the given expression.");
if (node.NodeType == ExpressionType.Convert && this.enableMethod)
{
return base.VisitUnary(node);
}
else
{
throw new ArgumentException($"Unexpected use of unary in the given expression.");
}
}

public string PropertyName => this.name.ToString();
public string PropertyOrMethodName => this.name.ToString();
}
}
Loading

0 comments on commit 68a8d8d

Please sign in to comment.