Skip to content

Commit

Permalink
v4.1.1 (#132)
Browse files Browse the repository at this point in the history
* Fixing static method access when showing captured value / Translating enum comparisons as enum constants re: #129

* Updating version number

* v4.1.1 NuGet package

---------

Co-authored-by: Steve Wilkes <[email protected]>
  • Loading branch information
SteveWilkes and SteveWilkes authored Oct 14, 2023
1 parent 8b3b4a0 commit 6b9aa2c
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 24 deletions.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static bool IsCapturedValue(

case Call:
var methodCall = (MethodCallExpression)expression;
expression = methodCall.Object;
expression = methodCall.GetSubject();
capturedMemberAccesses.Add(methodCall.Method);
continue;

Expand Down
17 changes: 6 additions & 11 deletions src/ReadableExpressions/ReadableExpressions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.0' ">1.6.1</NetStandardImplicitPackageVersion>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netstandard1.0' ">$(PackageTargetFallback);dnxcore50</PackageTargetFallback>

<AssemblyVersion>4.1.0.0</AssemblyVersion>
<FileVersion>4.1.0.0</FileVersion>
<VersionPrefix>4.1.0</VersionPrefix>
<Version>4.1.0</Version>
<AssemblyVersion>4.1.1.0</AssemblyVersion>
<FileVersion>4.1.1.0</FileVersion>
<VersionPrefix>4.1.1</VersionPrefix>
<Version>4.1.1</Version>

<PackageId>AgileObjects.ReadableExpressions</PackageId>
<Title>AgileObjects.ReadableExpressions</Title>
Expand All @@ -26,13 +26,8 @@
<PackageIcon>./Icon.png</PackageIcon>
<PackageTags>ExpressionTrees Debugging DebuggerVisualizers Linq DLR</PackageTags>
<PackageProjectUrl>https://github.com/AgileObjects/ReadableExpressions</PackageProjectUrl>
<PackageReleaseNotes>- Fixing Guid constant translation, re: #119
- Fixing various string concatenation issues, re: #120, 123
- Rendering string.Concat(Object) calls as method calls, not concatenation, re: #116
- Fixing custom method conversion unary translation, re: #117
- Including cast parentheses in cast index access subject, re: #122
- Removing some redundant parentheses in chained binary operations
- Adding setting to translate all string.Concat() calls as method calls, not concatenation
<PackageReleaseNotes>- Fixing static method access when showing captured values re: #129
- Translating enum comparisons as enum constants
</PackageReleaseNotes>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageOutputPath>../../NuGet</PackageOutputPath>
Expand Down
78 changes: 71 additions & 7 deletions src/ReadableExpressions/Translations/BinaryTranslation.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
namespace AgileObjects.ReadableExpressions.Translations;

using System;
#if NET35
using Microsoft.Scripting.Ast;
using static Microsoft.Scripting.Ast.ExpressionType;
#else
using System.Linq.Expressions;
#endif
using Extensions;
using NetStandardPolyfills;
#if NET35
using static Microsoft.Scripting.Ast.ExpressionType;
#else
using static System.Linq.Expressions.ExpressionType;
#endif

Expand Down Expand Up @@ -124,17 +130,75 @@ public static INodeTranslation For(

case Equal:
case NotEqual:
if (StandaloneEqualityComparisonTranslation.TryGetTranslation(binary, context, out var translation))
if (BoolEqualityComparisonTranslation.TryGetTranslation(binary, context, out var boolComparison))
{
return translation;
return boolComparison;
}

goto default;

default:
TryGetEnumComparisonExpression(ref binary);
break;
}

return new BinaryTranslation(binary, context);
}

public static void TryGetEnumComparisonExpression(
ref BinaryExpression comparison)
{
var leftOperandIsEnum =
IsEnumType(comparison.Left, out var leftExpression);

var rightOperandIsEnum =
IsEnumType(comparison.Right, out var rightExpression);

if (leftOperandIsEnum || rightOperandIsEnum)
{
var enumType = leftOperandIsEnum
? leftExpression.Type : rightExpression.Type;

comparison = comparison.Update(
GetEnumValue(leftExpression, enumType),
comparison.Conversion,
GetEnumValue(rightExpression, enumType));
}
}

private static bool IsEnumType(
Expression expression,
out Expression enumExpression)
{
if (expression.NodeType.IsCast())
{
expression = expression.GetUnaryOperand();
}

if (expression.Type.GetNonNullableType().IsEnum())
{
enumExpression = expression;
return true;
}

enumExpression = expression;
return false;
}

private static Expression GetEnumValue(
Expression expression,
Type enumType)
{
if (expression.NodeType != Constant)
{
return expression;
}

var value = ((ConstantExpression)expression).Value;
var enumValue = Enum.Parse(enumType, value.ToString());
return Expression.Constant(enumValue, enumType);
}

#endregion

public static bool IsBinary(ExpressionType nodeType)
Expand Down Expand Up @@ -173,13 +237,13 @@ public void WriteTo(TranslationWriter writer)
protected override bool IsMultiStatement()
=> _leftOperandTranslation.IsMultiStatement() || _rightOperandTranslation.IsMultiStatement();

private class StandaloneEqualityComparisonTranslation : INodeTranslation
private class BoolEqualityComparisonTranslation : INodeTranslation
{
private readonly ITranslationContext _context;
private readonly StandaloneBoolean _standaloneBoolean;
private readonly INodeTranslation _operandTranslation;

private StandaloneEqualityComparisonTranslation(
private BoolEqualityComparisonTranslation(
ExpressionType nodeType,
Expression boolean,
ExpressionType @operator,
Expand All @@ -199,7 +263,7 @@ public static bool TryGetTranslation(
{
if (IsBooleanConstant(comparison.Right))
{
translation = new StandaloneEqualityComparisonTranslation(
translation = new BoolEqualityComparisonTranslation(
comparison.NodeType,
comparison.Left,
comparison.NodeType,
Expand All @@ -211,7 +275,7 @@ public static bool TryGetTranslation(

if (IsBooleanConstant(comparison.Left))
{
translation = new StandaloneEqualityComparisonTranslation(
translation = new BoolEqualityComparisonTranslation(
comparison.NodeType,
comparison.Right,
comparison.NodeType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
using Xunit;
using static System.Linq.Expressions.Expression;
#else
using Microsoft.Scripting.Ast;
using Fact = NUnit.Framework.TestAttribute;
using static Microsoft.Scripting.Ast.Expression;
using Microsoft.Scripting.Ast;
using Fact = NUnit.Framework.TestAttribute;
using static Microsoft.Scripting.Ast.Expression;

[NUnit.Framework.TestFixture]
[NUnit.Framework.TestFixture]
#endif
public class WhenTranslatingMemberAccesses : TestClassBase
{
Expand Down Expand Up @@ -350,7 +350,7 @@ public void ShouldTranslateMultiParameterCallParamsArrayArgument()

// string.Join(string, string[]) in .NET 3.5 doesn't take a params array:
#if NET35
const string EXPECTED = @"
const string EXPECTED = @"
string.Join(string.Empty, new[] { ""Value["", ""0"", ""]"" })";
#else
const string EXPECTED = @"
Expand Down Expand Up @@ -660,6 +660,20 @@ public void ShouldIncludeCapturedStaticPropertyValues()
translated.ShouldBe("helper.PublicInstance == 456");
}

// See https://github.com/agileobjects/ReadableExpressions/issues/129
[Fact]
public void ShouldHandleComplexTypeCollectionAccessWithCapturedValues()
{
var capturedLocalVariableLamda = CreateLambda(
(IEnumerable<PropertiesHelper> helpers) =>
helpers.First().PublicEnumInstance == OddNumber.One);

var translated = capturedLocalVariableLamda.Body
.ToReadableString(stgs => stgs.ShowCapturedValues);

translated.ShouldBe("helpers.First().PublicEnumInstance == OddNumber.One");
}

[Fact]
public void ShouldIncludeOutParameterKeywords()
{
Expand Down Expand Up @@ -996,6 +1010,8 @@ internal class PropertiesHelper

public int PublicInstance { get; set; }

public OddNumber PublicEnumInstance { get; set; }

internal static int NonPublicStatic { get; set; }

internal int NonPublicInstance { get; set; }
Expand Down
Binary file not shown.

0 comments on commit 6b9aa2c

Please sign in to comment.