-
-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make ExpressionPromoter plugable #212
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -3,9 +3,9 @@ | |||||
|
||||||
namespace System.Linq.Dynamic.Core.Parser | ||||||
{ | ||||||
internal static class ExpressionPromoter | ||||||
internal class ExpressionPromoter : IExpressionPromoter | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
{ | ||||||
public static Expression Promote(Expression expr, Type type, bool exact, bool convertExpr) | ||||||
public Expression Promote(Expression expr, Type type, bool exact, bool convertExpr) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add |
||||||
{ | ||||||
if (expr.Type == type) | ||||||
{ | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.Linq.Expressions; | ||
|
||
namespace System.Linq.Dynamic.Core.Parser | ||
{ | ||
/// <summary> | ||
/// Expression promoter is used whe matching | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo and maybe add some more text to explain what this is doing. |
||
/// </summary> | ||
public interface IExpressionPromoter | ||
{ | ||
/// <summary> | ||
/// Promote an expression | ||
/// </summary> | ||
/// <param name="expr">Source expression.</param> | ||
/// <param name="type">Destionation data type to promote to.</param> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typo |
||
/// <param name="exact">If the match must be exact.</param> | ||
/// <param name="convertExpr">Convert expression.</param> | ||
/// <returns></returns> | ||
Expression Promote(Expression expr, Type type, bool exact, bool convertExpr); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,14 +4,28 @@ | |
|
||
namespace System.Linq.Dynamic.Core.Parser.SupportedMethods | ||
{ | ||
internal static class MethodFinder | ||
internal class MethodFinder | ||
{ | ||
public static bool ContainsMethod(Type type, string methodName, bool staticAccess, Expression[] args) | ||
/// <summary> | ||
/// The parsing config | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment is not required for private |
||
/// </summary> | ||
private ParsingConfig _parsingConfig; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. private readonly |
||
|
||
/// <summary> | ||
/// Get an instance | ||
/// </summary> | ||
/// <param name="parsingConfig"></param> | ||
public MethodFinder(ParsingConfig parsingConfig) | ||
{ | ||
this._parsingConfig = parsingConfig; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
public bool ContainsMethod(Type type, string methodName, bool staticAccess, Expression[] args) | ||
{ | ||
return FindMethod(type, methodName, staticAccess, args, out var _) == 1; | ||
} | ||
|
||
public static int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method) | ||
public int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method) | ||
{ | ||
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD) | ||
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | (staticAccess ? BindingFlags.Static : BindingFlags.Instance); | ||
|
@@ -39,7 +53,7 @@ public static int FindMethod(Type type, string methodName, bool staticAccess, Ex | |
return 0; | ||
} | ||
|
||
public static int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method) | ||
public int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method) | ||
{ | ||
MethodData[] applicable = methods. | ||
Select(m => new MethodData { MethodBase = m, Parameters = m.GetParameters() }). | ||
|
@@ -73,7 +87,7 @@ public static int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] a | |
return applicable.Length; | ||
} | ||
|
||
public static int FindIndexer(Type type, Expression[] args, out MethodBase method) | ||
public int FindIndexer(Type type, Expression[] args, out MethodBase method) | ||
{ | ||
foreach (Type t in SelfAndBaseTypes(type)) | ||
{ | ||
|
@@ -99,7 +113,7 @@ public static int FindIndexer(Type type, Expression[] args, out MethodBase metho | |
return 0; | ||
} | ||
|
||
static bool IsApplicable(MethodData method, Expression[] args) | ||
bool IsApplicable(MethodData method, Expression[] args) | ||
{ | ||
if (method.Parameters.Length != args.Length) | ||
{ | ||
|
@@ -115,7 +129,7 @@ static bool IsApplicable(MethodData method, Expression[] args) | |
return false; | ||
} | ||
|
||
Expression promoted = ExpressionPromoter.Promote(args[i], pi.ParameterType, false, method.MethodBase.DeclaringType != typeof(IEnumerableSignatures)); | ||
Expression promoted = this._parsingConfig.ExpressionPromoter.Promote(args[i], pi.ParameterType, false, method.MethodBase.DeclaringType != typeof(IEnumerableSignatures)); | ||
if (promoted == null) | ||
{ | ||
return false; | ||
|
@@ -126,7 +140,7 @@ static bool IsApplicable(MethodData method, Expression[] args) | |
return true; | ||
} | ||
|
||
static bool IsBetterThan(Expression[] args, MethodData first, MethodData second) | ||
bool IsBetterThan(Expression[] args, MethodData first, MethodData second) | ||
{ | ||
bool better = false; | ||
for (int i = 0; i < args.Length; i++) | ||
|
@@ -158,7 +172,7 @@ static bool IsBetterThan(Expression[] args, MethodData first, MethodData second) | |
// Return "First" if s -> t1 is a better conversion than s -> t2 | ||
// Return "Second" if s -> t2 is a better conversion than s -> t1 | ||
// Return "Both" if neither conversion is better | ||
static CompareConversionType CompareConversions(Type source, Type first, Type second) | ||
CompareConversionType CompareConversions(Type source, Type first, Type second) | ||
{ | ||
if (first == second) | ||
{ | ||
|
@@ -197,7 +211,7 @@ static CompareConversionType CompareConversions(Type source, Type first, Type se | |
return CompareConversionType.Both; | ||
} | ||
|
||
static IEnumerable<Type> SelfAndBaseTypes(Type type) | ||
IEnumerable<Type> SelfAndBaseTypes(Type type) | ||
{ | ||
if (type.GetTypeInfo().IsInterface) | ||
{ | ||
|
@@ -208,7 +222,7 @@ static IEnumerable<Type> SelfAndBaseTypes(Type type) | |
return SelfAndBaseClasses(type); | ||
} | ||
|
||
static IEnumerable<Type> SelfAndBaseClasses(Type type) | ||
IEnumerable<Type> SelfAndBaseClasses(Type type) | ||
{ | ||
while (type != null) | ||
{ | ||
|
@@ -217,7 +231,7 @@ static IEnumerable<Type> SelfAndBaseClasses(Type type) | |
} | ||
} | ||
|
||
static void AddInterface(List<Type> types, Type type) | ||
void AddInterface(List<Type> types, Type type) | ||
{ | ||
if (!types.Contains(type)) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
using System.Linq.Dynamic.Core.CustomTypeProviders; | ||
using System.Linq.Dynamic.Core.Parser; | ||
|
||
namespace System.Linq.Dynamic.Core | ||
{ | ||
|
@@ -20,8 +21,16 @@ public class ParsingConfig | |
EvaluateGroupByAtDatabase = true | ||
}; | ||
|
||
/// <summary> | ||
/// The custom type provider. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment is not required for private |
||
/// </summary> | ||
private IDynamicLinkCustomTypeProvider _customTypeProvider; | ||
|
||
/// <summary> | ||
/// The expression promoter. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. comment is not required for private |
||
/// </summary> | ||
private IExpressionPromoter _expressionPromoter; | ||
|
||
/// <summary> | ||
/// Gets or sets the <see cref="IDynamicLinkCustomTypeProvider"/>. | ||
/// </summary> | ||
|
@@ -46,6 +55,25 @@ public IDynamicLinkCustomTypeProvider CustomTypeProvider | |
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the <see cref="IExpressionPromoter"/>. | ||
/// </summary> | ||
public IExpressionPromoter ExpressionPromoter | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add a unit test where you implement a different |
||
{ | ||
get | ||
{ | ||
return _expressionPromoter ?? (_expressionPromoter = new ExpressionPromoter()); | ||
} | ||
|
||
set | ||
{ | ||
if (_expressionPromoter != value) | ||
{ | ||
_expressionPromoter = value; | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Determines if the context keywords (it, parent, and root) are valid and usable inside a Dynamic Linq string expression. | ||
/// Does not affect the usability of the equivalent context symbols ($, ^ and ~). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove this empty line.