Skip to content

Commit 69c94e7

Browse files
authored
Releases/3.2-Package
* Expression type tweak * Defaulting more ExpressionTypes to indicate a non-captured value ina MemberAccess, re: #101 * Handling fonts which the Font object cannot support, re: #102 * Test coverage for issue #103 * Support for translating ValueTuples * Updating package to v3.2 * Tidying * Fixing handling of reused ParameterExpression objects across different scopes * v3.2 Nuget package * Updating release notes * Updating copyright year
1 parent bc57e31 commit 69c94e7

30 files changed

+557
-120
lines changed

‎Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Company>AgileObjects Ltd</Company>
66
<Product>AgileObjects.ReadableExpressions</Product>
77
<Authors>Steve Wilkes</Authors>
8-
<Copyright>Copyright © AgileObjects Ltd 2021</Copyright>
8+
<Copyright>Copyright © AgileObjects Ltd 2022</Copyright>
99
<NeutralResourcesLanguage>en</NeutralResourcesLanguage>
1010
<RepositoryType>git</RepositoryType>
1111
<RepositoryUrl>https://.com/AgileObjects/ReadableExpressions</RepositoryUrl>
Binary file not shown.
Binary file not shown.

‎ReadableExpressions.UnitTests.NetCore3.1/ReadableExpressions.UnitTests.NetCore3.1.csproj

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
<IsPackable>false</IsPackable>
1616
</PropertyGroup>
1717

18+
<PropertyGroup>
19+
<DefineConstants>$(DefineConstants);TRACE;FEATURE_VALUE_TUPLE</DefineConstants>
20+
</PropertyGroup>
21+
1822
<ItemGroup>
1923
<Compile Include="..\ClsCompliant.cs">
2024
<Link>Properties\ClsCompliant.cs</Link>

‎ReadableExpressions.UnitTests/Extensions/WhenGettingFriendlyTypeNames.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Linq.Expressions;
77
using Common;
8+
using NetStandardPolyfills;
89
using ReadableExpressions.Extensions;
910
#if !NET35
1011
using Xunit;
@@ -55,7 +56,7 @@ public void ShouldNameAnAnonymousTypeWithAConfiguredNameFactory()
5556
{
5657
var anon = new { One = 1, Two = "two" };
5758

58-
var friendlyName = anon.GetType().GetFriendlyName(c => c.NameAnonymousTypesUsing(t => "object"));
59+
var friendlyName = anon.GetType().GetFriendlyName(c => c.NameAnonymousTypesUsing(_ => "object"));
5960

6061
friendlyName.ShouldBe("object");
6162
}
@@ -140,7 +141,7 @@ public void ShouldNameGenericGenericTypeArguments()
140141
public void ShouldNamePartClosedGenericTypeArrays()
141142
{
142143
var name = typeof(GenericTestHelper<>)
143-
.GetField("Keys").FieldType
144+
.GetPublicInstanceField("Keys").FieldType
144145
.GetFriendlyName();
145146

146147
name.ShouldBe("KeyValuePair<T, int>[]");

‎ReadableExpressions.UnitTests/ReadableExpressions.UnitTests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</PropertyGroup>
1111

1212
<PropertyGroup>
13-
<DefineConstants>$(DefineConstants);TRACE;FEATURE_EF;FEATURE_PARTIAL_TRUST;FEATURE_DYNAMIC;FEATURE_HTML</DefineConstants>
13+
<DefineConstants>$(DefineConstants);TRACE;FEATURE_EF;FEATURE_PARTIAL_TRUST;FEATURE_DYNAMIC;FEATURE_VALUE_TUPLE;FEATURE_HTML</DefineConstants>
1414
</PropertyGroup>
1515

1616
<ItemGroup>

‎ReadableExpressions.UnitTests/WhenFormattingCode.cs

+32-3
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,35 @@ public void ShouldVarAssignAVariableUsedInNestedConstructs()
487487
translated.ShouldBe(EXPECTED.TrimStart());
488488
}
489489

490+
[Fact]
491+
public void ShouldVarAssignAVariableReusedInASiblingBlock()
492+
{
493+
var intVariable = Variable(typeof(int), "i");
494+
var assignVariable1 = Assign(intVariable, Constant(1));
495+
var assignmentBlock = Block(new[] { intVariable }, assignVariable1);
496+
497+
var assignVariable2 = Assign(intVariable, Constant(2));
498+
var assignment2Block = Block(new[] { intVariable }, assignVariable2);
499+
500+
var assign1Or2 = IfThenElse(
501+
Constant(true),
502+
assignmentBlock,
503+
assignment2Block);
504+
505+
var translated = assign1Or2.ToReadableString();
506+
507+
const string EXPECTED = @"
508+
if (true)
509+
{
510+
var i = 1;
511+
}
512+
else
513+
{
514+
var i = 2;
515+
}";
516+
translated.ShouldBe(EXPECTED.TrimStart());
517+
}
518+
490519
[Fact]
491520
public void ShouldNotIndentParamsArrayArguments()
492521
{
@@ -620,10 +649,10 @@ public void ShouldNotRemoveParenthesesFromALambdaInvokeResultAssignment()
620649
public void ShouldNotIndentSingleArgumentBlockParameters()
621650
{
622651
var writeString = CreateLambda(() => Console.WriteLine("String!")).Body;
623-
652+
624653
var stringsBlock = Block(
625-
writeString,
626-
writeString,
654+
writeString,
655+
writeString,
627656
writeString,
628657
Constant("All done!"));
629658

‎ReadableExpressions.UnitTests/WhenTranslatingDynamicOperations.cs

+20-11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace AgileObjects.ReadableExpressions.UnitTests
33
{
44
using System;
5+
using System.Dynamic;
56
using System.Globalization;
67
using Common;
78
using Microsoft.CSharp.RuntimeBinder;
@@ -10,29 +11,37 @@ namespace AgileObjects.ReadableExpressions.UnitTests
1011

1112
public class WhenTranslatingDynamicOperations : TestClassBase
1213
{
14+
// See https://.com/agileobjects/ReadableExpressions/issues/103
1315
[Fact]
1416
public void ShouldTranslateAPropertyReadAccess()
1517
{
16-
var lengthGetterSiteBinder = Binder.GetMember(
18+
var dynamicNullableIntGetterSiteBinder = Binder.GetMember(
1719
CSharpBinderFlags.None,
18-
"Length",
19-
typeof(WhenTranslatingDynamicOperations),
20+
"NullableInt",
21+
typeof(object),
2022
new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
2123

22-
var dynamicParameter = Parameter(typeof(object), "obj");
24+
var expandoParameter = Parameter(typeof(ExpandoObject));
2325

24-
var dynamicLengthGetter = Dynamic(
25-
lengthGetterSiteBinder,
26+
var dynamicNullableIntGetter = Dynamic(
27+
dynamicNullableIntGetterSiteBinder,
2628
typeof(object),
27-
dynamicParameter);
29+
expandoParameter);
30+
31+
var convertedDynamicNullableInt =
32+
Convert(dynamicNullableIntGetter, typeof(int?));
33+
34+
var hasValueAccess = Property(convertedDynamicNullableInt, "HasValue");
2835

29-
var dynamicLengthLambda = Lambda<Func<object, object>>(dynamicLengthGetter, dynamicParameter);
36+
var dynamicNullableIntHasValueLambda =
37+
Lambda<Func<ExpandoObject, bool>>(hasValueAccess, expandoParameter);
3038

31-
dynamicLengthLambda.Compile();
39+
dynamicNullableIntHasValueLambda.Compile();
3240

33-
var translated = dynamicLengthLambda.ToReadableString();
41+
var translated = dynamicNullableIntHasValueLambda.ToReadableString();
3442

35-
translated.ShouldBe("obj => obj.Length");
43+
translated.ShouldBe(
44+
"expandoObject => ((int?)expandoObject.NullableInt).HasValue");
3645
}
3746

3847
[Fact]

‎ReadableExpressions.UnitTests/WhenTranslatingExtensions.cs

+7-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,13 @@ public void ShouldAnalyseACustomAnalysableExpression()
6060

6161
var analysis = ExpressionAnalysis.For(container, new TestTranslationSettings());
6262

63-
analysis.ShouldBeDeclaredInVariableList(intVariable1, variable1Block).ShouldBeFalse();
64-
analysis.ShouldBeDeclaredInVariableList(intVariable2, variable2Block).ShouldBeFalse();
63+
analysis.EnterScope(variable1Block);
64+
analysis.ShouldBeDeclaredInVariableList(intVariable1).ShouldBeFalse();
65+
analysis.ExitScope();
66+
67+
analysis.EnterScope(variable2Block);
68+
analysis.ShouldBeDeclaredInVariableList(intVariable2).ShouldBeFalse();
69+
analysis.ExitScope();
6570
}
6671

6772
#region Helper Members

‎ReadableExpressions.UnitTests/WhenTranslatingLambdas.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ public void ShouldTranslateQuotedLambdaWithAnAnnotation()
111111

112112
var quotedLambda = Quote(intToDouble);
113113

114-
var translated = quotedLambda.ToReadableString(stgs => stgs.ShowQuotedLambdaComments);
114+
var translated = quotedLambda.ToReadableString(stgs =>
115+
stgs.ShowQuotedLambdaComments);
115116

116117
const string EXPECTED = @"
117118
// Quoted to induce a closure:

‎ReadableExpressions.UnitTests/WhenTranslatingMemberAccesses.cs

+29
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,21 @@ public void ShouldTranslateAnInstanceMemberExpression()
133133
translated.ShouldBe("d => d.Day");
134134
}
135135

136+
// See https://.com/agileobjects/ReadableExpressions/issues/101
137+
[Fact]
138+
public void ShouldTranslateAnExtensionExpressionMemberExpression()
139+
{
140+
var extension = new ExtensionExpression(typeof(PropertiesHelper));
141+
142+
var extensionMemberAccess = Property(
143+
extension,
144+
nameof(PropertiesHelper.PublicInstance));
145+
146+
var translated = extensionMemberAccess.ToReadableString();
147+
148+
translated.ShouldBe($"{extension}.PublicInstance");
149+
}
150+
136151
[Fact]
137152
public void ShouldTranslateAStaticMemberExpression()
138153
{
@@ -996,5 +1011,19 @@ public IEnumerator GetEnumerator()
9961011
}
9971012
}
9981013

1014+
internal class ExtensionExpression : Expression
1015+
{
1016+
public ExtensionExpression(Type type)
1017+
{
1018+
Type = type;
1019+
}
1020+
1021+
public override string ToString() => "Extension_Expr";
1022+
1023+
public override Type Type { get; }
1024+
1025+
public override ExpressionType NodeType => ExpressionType.Extension;
1026+
}
1027+
9991028
#endregion
10001029
}

‎ReadableExpressions.UnitTests/WhenTranslatingObjectCreations.cs

+29-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,8 @@ public void ShouldTranslateAnAnonymousTypeCreationWithACustomFactory()
447447
// ReSharper disable once AssignNullToNotNullAttribute
448448
var creation = New(constructor, Constant(10));
449449

450-
var translated = creation.ToReadableString(stgs => stgs.NameAnonymousTypesUsing(t => "MyMagicObject"));
450+
var translated = creation.ToReadableString(stgs => stgs
451+
.NameAnonymousTypesUsing(_ => "MyMagicObject"));
451452

452453
translated.ShouldBe("new MyMagicObject { ValueInt = 10 }");
453454
}
@@ -465,6 +466,33 @@ public void ShouldTranslateAFullyQualfiedAnonymousTypeCreation()
465466

466467
translated.ShouldBe("new { Value = default(System.TimeSpan) }");
467468
}
469+
470+
#if FEATURE_VALUE_TUPLE
471+
[Fact]
472+
public void ShouldTranslateAValueTupleNewExpression()
473+
{
474+
var valueTuple = (default(int), default(string));
475+
var valueTupleType = valueTuple.GetType();
476+
477+
var valueTupleCtor = valueTupleType
478+
.GetPublicInstanceConstructor(typeof(int), typeof(string));
479+
480+
var stringEmpty = typeof(string)
481+
.GetPublicStaticField(nameof(string.Empty));
482+
483+
var newValueTuple = New(
484+
valueTupleCtor,
485+
Constant(123),
486+
Field(null, stringEmpty));
487+
488+
var tupleVariable = Variable(valueTupleType);
489+
var assignTuple = Assign(tupleVariable, newValueTuple);
490+
491+
var translated = assignTuple.ToReadableString();
492+
493+
translated.ShouldBe("intStringValueTuple = (123, string.Empty)");
494+
}
495+
#endif
468496
}
469497

470498
#region Helper Classes

‎ReadableExpressions.Visualizers.Dialog/Controls/FontFamilySelector.cs

+14-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public FontFamilySelector(VisualizerDialog dialog)
3636

3737
dialog.RegisterThemeable(this);
3838

39-
SelectedIndexChanged += (sender, args) =>
39+
SelectedIndexChanged += (sender, _) =>
4040
{
4141
var selector = (FontFamilySelector)sender;
4242
var font = (Font)selector.SelectedItem;
@@ -51,7 +51,19 @@ private static Font[] GetFonts()
5151
{
5252
return new InstalledFontCollection()
5353
.Families
54-
.Select(ff => new Font(ff, 10))
54+
.Select(ff =>
55+
{
56+
try
57+
{
58+
return new Font(ff, 10);
59+
}
60+
catch
61+
{
62+
// See https://.com/agileobjects/ReadableExpressions/issues/102
63+
return null;
64+
}
65+
})
66+
.Where(font => font != null)
5567
.ToArray();
5668
}
5769

0 commit comments

Comments
 (0)