Skip to content

Commit e0f0f0a

Browse files
authored
Support Enumerations from System Namespace (e.g. StringComparison) (#275)
* SupportEnumerationsFromSystemNamespace * fix xml comments
1 parent 254a65e commit e0f0f0a

File tree

7 files changed

+82
-5
lines changed

7 files changed

+82
-5
lines changed

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
</PropertyGroup>
55

66
<PropertyGroup>
7-
<VersionPrefix>1.0.15</VersionPrefix>
7+
<VersionPrefix>1.0.16</VersionPrefix>
88
</PropertyGroup>
99

1010
<Choose>

GitHubReleaseNotes.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
https://github.com/StefH/GitHubReleaseNotes
22

3-
GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.15.0
3+
GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.16.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Collections.Concurrent;
2+
using System.Collections.Generic;
3+
4+
namespace System.Linq.Dynamic.Core.Parser
5+
{
6+
internal static class EnumerationsFromMscorlib
7+
{
8+
/// <summary>
9+
/// Some enumeration types from mscorlib/netstandard.
10+
/// </summary>
11+
public static readonly IDictionary<Type, int> PredefinedEnumerationTypes = new ConcurrentDictionary<Type, int>(new Dictionary<Type, int> {
12+
#if !(UAP10_0 || NETSTANDARD || NET35 || NETCOREAPP)
13+
{ typeof(AppDomainManagerInitializationOptions), 0 },
14+
{ typeof(Base64FormattingOptions), 0 },
15+
{ typeof(ConsoleColor), 0 },
16+
{ typeof(ConsoleKey), 0 },
17+
{ typeof(ConsoleModifiers), 0 },
18+
{ typeof(ConsoleSpecialKey), 0 },
19+
{ typeof(ActivationContext.ContextForm), 0 },
20+
{ typeof(EnvironmentVariableTarget), 0 },
21+
{ typeof(GCNotificationStatus), 0 },
22+
{ typeof(LoaderOptimization), 0 },
23+
{ typeof(PlatformID), 0 },
24+
{ typeof(Environment.SpecialFolder), 0 },
25+
{ typeof(Environment.SpecialFolderOption), 0 },
26+
#endif
27+
{ typeof(AttributeTargets), 0 },
28+
{ typeof(DateTimeKind), 0 },
29+
{ typeof(DayOfWeek), 0 },
30+
{ typeof(GCCollectionMode), 0 },
31+
{ typeof(MidpointRounding), 0 },
32+
{ typeof(StringComparison), 0 },
33+
{ typeof(StringSplitOptions), 0 },
34+
{ typeof(TypeCode), 0 }
35+
});
36+
}
37+
}

src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs

+16-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ public KeywordsHelper(ParsingConfig config)
5151

5252
foreach (Type type in PredefinedTypesHelper.PredefinedTypes.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
5353
{
54-
_keywords[type.FullName] = type;
54+
if (!string.IsNullOrEmpty(type.FullName))
55+
{
56+
_keywords[type.FullName] = type;
57+
}
5558
_keywords[type.Name] = type;
5659
}
5760

@@ -60,6 +63,18 @@ public KeywordsHelper(ParsingConfig config)
6063
_keywords.Add(pair.Key, pair.Value);
6164
}
6265

66+
if (config.SupportEnumerationsFromSystemNamespace)
67+
{
68+
foreach (Type type in EnumerationsFromMscorlib.PredefinedEnumerationTypes.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
69+
{
70+
if (!string.IsNullOrEmpty(type.FullName))
71+
{
72+
_keywords[type.FullName] = type;
73+
}
74+
_keywords[type.Name] = type;
75+
}
76+
}
77+
6378
if (config.CustomTypeProvider != null)
6479
{
6580
foreach (Type type in config.CustomTypeProvider.GetCustomTypes())

src/System.Linq.Dynamic.Core/ParsingConfig.cs

+6
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,11 @@ public IQueryableAnalyzer QueryableAnalyzer
139139
/// Default value is false.
140140
/// </summary>
141141
public bool ResolveTypesBySimpleName { get; set; } = false;
142+
143+
/// <summary>
144+
/// Support enumeration-types from the System namespace in mscorelib. An example could be "StringComparison".
145+
/// Default value is true.
146+
/// </summary>
147+
public bool SupportEnumerationsFromSystemNamespace { get; set; } = true;
142148
}
143149
}

test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs

+17
Original file line numberDiff line numberDiff line change
@@ -802,5 +802,22 @@ public void DynamicExpressionParser_ParseLambda_RenameParameterExpression(string
802802
// Assert
803803
Check.That(result).IsEqualTo(expected);
804804
}
805+
806+
[Theory]
807+
[InlineData(@"p0.Equals(""Testing"", 3)", "testinG", true)]
808+
[InlineData(@"p0.Equals(""Testing"", StringComparison.InvariantCultureIgnoreCase)", "testinG", true)]
809+
public void DynamicExpressionParser_ParseLambda_SupportEnumerationStringComparison(string expressionAsString, string testValue, bool expectedResult)
810+
{
811+
// Arrange
812+
var p0 = Expression.Parameter(typeof(string), "p0");
813+
814+
// Act
815+
var expression = DynamicExpressionParser.ParseLambda(new[] { p0 }, typeof(bool), expressionAsString);
816+
Delegate del = expression.Compile();
817+
bool? result = del.DynamicInvoke("testing") as bool?;
818+
819+
// Assert
820+
Check.That(result).IsEqualTo(expectedResult);
821+
}
805822
}
806823
}

test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,13 @@ public void Select_Dynamic_IntoTypeWithNullableProperties1()
234234
var dates = Enumerable.Repeat(0, 7)
235235
.Select((d, i) => new DateTime(2000, 1, 1).AddDays(i).AddSeconds(i))
236236
.AsQueryable();
237+
var config = new ParsingConfig { SupportEnumerationsFromSystemNamespace = false };
237238

238239
// Act
239240
IQueryable<Example> result = dates
240241
.Select(d => new Example { Time = d, DOWNull = d.DayOfWeek, DOW = d.DayOfWeek, Sec = d.Second, SecNull = d.Second });
241242
IQueryable<Example> resultDynamic = dates
242-
.Select<Example>("new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");
243+
.Select<Example>(config, "new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");
243244

244245
// Assert
245246
Check.That(resultDynamic.First()).Equals(result.First());
@@ -253,12 +254,13 @@ public void Select_Dynamic_IntoTypeWithNullableProperties2()
253254
var dates = Enumerable.Repeat(0, 7)
254255
.Select((d, i) => new DateTime(2000, 1, 1).AddDays(i).AddSeconds(i))
255256
.AsQueryable();
257+
var config = new ParsingConfig { SupportEnumerationsFromSystemNamespace = false };
256258

257259
// Act
258260
IQueryable<ExampleWithConstructor> result = dates
259261
.Select(d => new ExampleWithConstructor(d, d.DayOfWeek, d.DayOfWeek, d.Second, d.Second));
260262
IQueryable<ExampleWithConstructor> resultDynamic = dates
261-
.Select<ExampleWithConstructor>("new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");
263+
.Select<ExampleWithConstructor>(config, "new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");
262264

263265
// Assert
264266
Check.That(resultDynamic.First()).Equals(result.First());

0 commit comments

Comments
 (0)