Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>

<PropertyGroup>
<VersionPrefix>1.0.15</VersionPrefix>
<VersionPrefix>1.0.16</VersionPrefix>
</PropertyGroup>

<Choose>
Expand Down
2 changes: 1 addition & 1 deletion GitHubReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes

GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.15.0
GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.16.0
37 changes: 37 additions & 0 deletions src/System.Linq.Dynamic.Core/Parser/EnumerationsFromMscorlib.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace System.Linq.Dynamic.Core.Parser
{
internal static class EnumerationsFromMscorlib
{
/// <summary>
/// Some enumeration types from mscorlib/netstandard.
/// </summary>
public static readonly IDictionary<Type, int> PredefinedEnumerationTypes = new ConcurrentDictionary<Type, int>(new Dictionary<Type, int> {
#if !(UAP10_0 || NETSTANDARD || NET35 || NETCOREAPP)
{ typeof(AppDomainManagerInitializationOptions), 0 },
{ typeof(Base64FormattingOptions), 0 },
{ typeof(ConsoleColor), 0 },
{ typeof(ConsoleKey), 0 },
{ typeof(ConsoleModifiers), 0 },
{ typeof(ConsoleSpecialKey), 0 },
{ typeof(ActivationContext.ContextForm), 0 },
{ typeof(EnvironmentVariableTarget), 0 },
{ typeof(GCNotificationStatus), 0 },
{ typeof(LoaderOptimization), 0 },
{ typeof(PlatformID), 0 },
{ typeof(Environment.SpecialFolder), 0 },
{ typeof(Environment.SpecialFolderOption), 0 },
#endif
{ typeof(AttributeTargets), 0 },
{ typeof(DateTimeKind), 0 },
{ typeof(DayOfWeek), 0 },
{ typeof(GCCollectionMode), 0 },
{ typeof(MidpointRounding), 0 },
{ typeof(StringComparison), 0 },
{ typeof(StringSplitOptions), 0 },
{ typeof(TypeCode), 0 }
});
}
}
17 changes: 16 additions & 1 deletion src/System.Linq.Dynamic.Core/Parser/KeywordsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ public KeywordsHelper(ParsingConfig config)

foreach (Type type in PredefinedTypesHelper.PredefinedTypes.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
{
_keywords[type.FullName] = type;
if (!string.IsNullOrEmpty(type.FullName))
{
_keywords[type.FullName] = type;
}
_keywords[type.Name] = type;
}

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

if (config.SupportEnumerationsFromSystemNamespace)
{
foreach (Type type in EnumerationsFromMscorlib.PredefinedEnumerationTypes.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
{
if (!string.IsNullOrEmpty(type.FullName))
{
_keywords[type.FullName] = type;
}
_keywords[type.Name] = type;
}
}

if (config.CustomTypeProvider != null)
{
foreach (Type type in config.CustomTypeProvider.GetCustomTypes())
Expand Down
6 changes: 6 additions & 0 deletions src/System.Linq.Dynamic.Core/ParsingConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,11 @@ public IQueryableAnalyzer QueryableAnalyzer
/// Default value is false.
/// </summary>
public bool ResolveTypesBySimpleName { get; set; } = false;

/// <summary>
/// Support enumeration-types from the System namespace in mscorelib. An example could be "StringComparison".
/// Default value is true.
/// </summary>
public bool SupportEnumerationsFromSystemNamespace { get; set; } = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -802,5 +802,22 @@ public void DynamicExpressionParser_ParseLambda_RenameParameterExpression(string
// Assert
Check.That(result).IsEqualTo(expected);
}

[Theory]
[InlineData(@"p0.Equals(""Testing"", 3)", "testinG", true)]
[InlineData(@"p0.Equals(""Testing"", StringComparison.InvariantCultureIgnoreCase)", "testinG", true)]
public void DynamicExpressionParser_ParseLambda_SupportEnumerationStringComparison(string expressionAsString, string testValue, bool expectedResult)
{
// Arrange
var p0 = Expression.Parameter(typeof(string), "p0");

// Act
var expression = DynamicExpressionParser.ParseLambda(new[] { p0 }, typeof(bool), expressionAsString);
Delegate del = expression.Compile();
bool? result = del.DynamicInvoke("testing") as bool?;

// Assert
Check.That(result).IsEqualTo(expectedResult);
}
}
}
6 changes: 4 additions & 2 deletions test/System.Linq.Dynamic.Core.Tests/QueryableTests.Select.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,13 @@ public void Select_Dynamic_IntoTypeWithNullableProperties1()
var dates = Enumerable.Repeat(0, 7)
.Select((d, i) => new DateTime(2000, 1, 1).AddDays(i).AddSeconds(i))
.AsQueryable();
var config = new ParsingConfig { SupportEnumerationsFromSystemNamespace = false };

// Act
IQueryable<Example> result = dates
.Select(d => new Example { Time = d, DOWNull = d.DayOfWeek, DOW = d.DayOfWeek, Sec = d.Second, SecNull = d.Second });
IQueryable<Example> resultDynamic = dates
.Select<Example>("new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");
.Select<Example>(config, "new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");

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

// Act
IQueryable<ExampleWithConstructor> result = dates
.Select(d => new ExampleWithConstructor(d, d.DayOfWeek, d.DayOfWeek, d.Second, d.Second));
IQueryable<ExampleWithConstructor> resultDynamic = dates
.Select<ExampleWithConstructor>("new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");
.Select<ExampleWithConstructor>(config, "new (it as Time, DayOfWeek as DOWNull, DayOfWeek as DOW, Second as Sec, int?(Second) as SecNull)");

// Assert
Check.That(resultDynamic.First()).Equals(result.First());
Expand Down