Skip to content

Commit 2ad61c6

Browse files
authored
Replace casting with NodeType checks in Criteria ExpressionProcessor (#2492)
1 parent f98c463 commit 2ad61c6

File tree

1 file changed

+119
-154
lines changed

1 file changed

+119
-154
lines changed

src/NHibernate/Impl/ExpressionProcessor.cs

Lines changed: 119 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -292,22 +292,20 @@ public static ProjectionInfo FindMemberProjection(Expression expression)
292292
return FindMemberProjection(unwrapExpression);
293293
}
294294

295-
var methodCallExpression = expression as MethodCallExpression;
296-
if (methodCallExpression != null)
295+
if (expression.NodeType == ExpressionType.Call)
297296
{
297+
var methodCallExpression = (MethodCallExpression) expression;
298298
var signature = Signature(methodCallExpression.Method);
299-
Func<Expression, IProjection> processor;
300-
if (_customProjectionProcessors.TryGetValue(signature, out processor))
299+
if (_customProjectionProcessors.TryGetValue(signature, out var processor))
301300
{
302301
return ProjectionInfo.ForProjection(processor(methodCallExpression));
303302
}
304303
}
305-
var memberExpression = expression as MemberExpression;
306-
if (memberExpression != null)
304+
if (expression.NodeType == ExpressionType.MemberAccess)
307305
{
306+
var memberExpression = (MemberExpression) expression;
308307
var signature = Signature(memberExpression.Member);
309-
Func<Expression, IProjection> processor;
310-
if (_customProjectionProcessors.TryGetValue(signature, out processor))
308+
if (_customProjectionProcessors.TryGetValue(signature, out var processor))
311309
{
312310
return ProjectionInfo.ForProjection(processor(memberExpression));
313311
}
@@ -318,45 +316,27 @@ public static ProjectionInfo FindMemberProjection(Expression expression)
318316

319317
private static Expression UnwrapConvertExpression(Expression expression)
320318
{
321-
if (expression is UnaryExpression unaryExpression)
322-
{
323-
if (!IsConversion(unaryExpression.NodeType))
324-
{
325-
if (IsSupportedUnaryExpression(unaryExpression))
326-
return null;
327-
328-
throw new ArgumentException("Cannot interpret member from " + expression, nameof(expression));
329-
}
330-
return unaryExpression.Operand;
331-
}
332-
333-
return null;
334-
}
335-
336-
private static bool IsSupportedUnaryExpression(UnaryExpression expression)
337-
{
338-
return expression.NodeType == ExpressionType.Negate;
319+
return IsConversion(expression.NodeType)
320+
? ((UnaryExpression) expression).Operand
321+
: null;
339322
}
340323

341324
private static ProjectionInfo AsArithmeticProjection(Expression expression)
342325
{
343-
if (!(expression is BinaryExpression be))
326+
if (expression.NodeType == ExpressionType.Negate)
344327
{
345-
if (expression is UnaryExpression unary && unary.NodeType == ExpressionType.Negate)
346-
{
347-
return ProjectionInfo.ForProjection(
348-
new SqlFunctionProjection(_unaryNegateTemplate, TypeFactory.HeuristicType(unary.Type), FindMemberProjection(unary.Operand).AsProjection()));
349-
}
350-
351-
var unwrapExpression = UnwrapConvertExpression(expression);
352-
return unwrapExpression != null ? AsArithmeticProjection(unwrapExpression) : null;
328+
var unary = (UnaryExpression) expression;
329+
return ProjectionInfo.ForProjection(
330+
new SqlFunctionProjection(_unaryNegateTemplate, TypeFactory.HeuristicType(unary.Type), FindMemberProjection(unary.Operand).AsProjection()));
353331
}
354332

355-
if (!_binaryArithmethicTemplates.TryGetValue(be.NodeType, out var template))
333+
if (!_binaryArithmethicTemplates.TryGetValue(expression.NodeType, out var template))
356334
{
357-
return null;
335+
var unwrapExpression = UnwrapConvertExpression(expression);
336+
return unwrapExpression != null ? AsArithmeticProjection(unwrapExpression) : null;
358337
}
359338

339+
var be = (BinaryExpression) expression;
360340
return ProjectionInfo.ForProjection(
361341
new SqlFunctionProjection(
362342
template,
@@ -370,8 +350,11 @@ private static ProjectionInfo AsArithmeticProjection(Expression expression)
370350

371351
private static bool IsCompilerGeneratedMemberExpressionOfCompilerGeneratedClass(Expression expression)
372352
{
373-
var memberExpression = expression as MemberExpression;
374-
if (memberExpression != null && memberExpression.Member.DeclaringType != null)
353+
if (expression.NodeType != ExpressionType.MemberAccess)
354+
return false;
355+
356+
var memberExpression = (MemberExpression) expression;
357+
if (memberExpression.Member.DeclaringType != null)
375358
{
376359
return Attribute.GetCustomAttribute(memberExpression.Member.DeclaringType, typeof(CompilerGeneratedAttribute)) != null
377360
&& GeneratedMemberNameRegex.IsMatch(memberExpression.Member.Name);
@@ -388,64 +371,64 @@ private static bool IsCompilerGeneratedMemberExpressionOfCompilerGeneratedClass(
388371
/// <returns>The name of the member property</returns>
389372
public static string FindMemberExpression(Expression expression)
390373
{
391-
var memberExpression = expression as MemberExpression;
392-
if (memberExpression != null)
374+
switch (expression.NodeType)
393375
{
394-
var parentExpression = memberExpression.Expression;
395-
if (parentExpression != null)
376+
case ExpressionType.MemberAccess:
396377
{
397-
if (parentExpression.NodeType == ExpressionType.MemberAccess
398-
|| parentExpression.NodeType == ExpressionType.Call)
378+
var memberExpression = (MemberExpression) expression;
379+
var parentExpression = memberExpression.Expression;
380+
if (parentExpression != null)
399381
{
400-
if (memberExpression.Member.DeclaringType.IsNullable())
382+
if (parentExpression.NodeType == ExpressionType.MemberAccess
383+
|| parentExpression.NodeType == ExpressionType.Call)
401384
{
402-
// it's a Nullable<T>, so ignore any .Value
403-
if (memberExpression.Member.Name == "Value")
404-
return FindMemberExpression(parentExpression);
385+
if (memberExpression.Member.DeclaringType.IsNullable())
386+
{
387+
// it's a Nullable<T>, so ignore any .Value
388+
if (memberExpression.Member.Name == "Value")
389+
return FindMemberExpression(parentExpression);
390+
}
391+
392+
if (IsCompilerGeneratedMemberExpressionOfCompilerGeneratedClass(parentExpression))
393+
{
394+
return memberExpression.Member.Name;
395+
}
396+
397+
return FindMemberExpression(parentExpression) + "." + memberExpression.Member.Name;
405398
}
406-
407-
if (IsCompilerGeneratedMemberExpressionOfCompilerGeneratedClass(parentExpression))
399+
if (IsConversion(parentExpression.NodeType))
408400
{
409-
return memberExpression.Member.Name;
401+
return (FindMemberExpression(parentExpression) + "." + memberExpression.Member.Name).TrimStart('.');
410402
}
411-
412-
return FindMemberExpression(parentExpression) + "." + memberExpression.Member.Name;
413-
}
414-
if (IsConversion(parentExpression.NodeType))
415-
{
416-
return (FindMemberExpression(parentExpression) + "." + memberExpression.Member.Name).TrimStart('.');
417403
}
418-
}
419-
420-
return memberExpression.Member.Name;
421-
}
422-
423-
var unaryExpression = expression as UnaryExpression;
424-
if (unaryExpression != null)
425-
{
426-
if (!IsConversion(unaryExpression.NodeType))
427-
throw new ArgumentException("Cannot interpret member from " + expression, nameof(expression));
428404

429-
return FindMemberExpression(unaryExpression.Operand);
430-
}
405+
return memberExpression.Member.Name;
406+
}
431407

432-
var methodCallExpression = expression as MethodCallExpression;
433-
if (methodCallExpression != null)
434-
{
435-
if (methodCallExpression.Method.Name == "GetType")
436-
return ClassMember(methodCallExpression.Object);
408+
case ExpressionType.Call:
409+
{
410+
var methodCallExpression = (MethodCallExpression) expression;
437411

438-
if (methodCallExpression.Method.Name == "get_Item")
439-
return FindMemberExpression(methodCallExpression.Object);
412+
switch (methodCallExpression.Method.Name)
413+
{
414+
case "GetType":
415+
return ClassMember(methodCallExpression.Object);
416+
case "get_Item":
417+
return FindMemberExpression(methodCallExpression.Object);
418+
case "First":
419+
return FindMemberExpression(methodCallExpression.Arguments[0]);
420+
}
440421

441-
if (methodCallExpression.Method.Name == "First")
442-
return FindMemberExpression(methodCallExpression.Arguments[0]);
422+
throw new ArgumentException("Unrecognised method call in expression " + methodCallExpression, nameof(expression));
423+
}
443424

444-
throw new ArgumentException("Unrecognised method call in expression " + methodCallExpression, nameof(expression));
425+
case ExpressionType.Parameter:
426+
return string.Empty;
445427
}
446428

447-
if (expression is ParameterExpression)
448-
return "";
429+
var unwrapExpression = UnwrapConvertExpression(expression);
430+
if (unwrapExpression != null)
431+
return FindMemberExpression(unwrapExpression);
449432

450433
throw new ArgumentException("Could not determine member from " + expression, nameof(expression));
451434
}
@@ -468,10 +451,10 @@ public static string FindPropertyExpression(Expression expression)
468451
/// <returns>Evaluated detached criteria</returns>
469452
public static DetachedCriteria FindDetachedCriteria(Expression expression)
470453
{
471-
var methodCallExpression = expression as MethodCallExpression;
472-
if (methodCallExpression == null)
454+
if (expression.NodeType != ExpressionType.Call)
473455
throw new ArgumentException("right operand should be detachedQueryInstance.As<T>() - " + expression, nameof(expression));
474456

457+
var methodCallExpression = (MethodCallExpression) expression;
475458
return ((QueryOver) FindValue(methodCallExpression.Object)).DetachedCriteria;
476459
}
477460

@@ -482,10 +465,12 @@ private static bool EvaluatesToNull(Expression expression)
482465

483466
private static System.Type FindMemberType(Expression expression)
484467
{
485-
var memberExpression = expression as MemberExpression;
486-
if (memberExpression != null)
468+
switch (expression.NodeType)
487469
{
488-
return memberExpression.Type;
470+
case ExpressionType.MemberAccess:
471+
return expression.Type;
472+
case ExpressionType.Call:
473+
return ((MethodCallExpression) expression).Method.ReturnType;
489474
}
490475

491476
var unwrapExpression = UnwrapConvertExpression(expression);
@@ -494,68 +479,54 @@ private static System.Type FindMemberType(Expression expression)
494479
return FindMemberType(unwrapExpression);
495480
}
496481

497-
var methodCallExpression = expression as MethodCallExpression;
498-
if (methodCallExpression != null)
499-
{
500-
return methodCallExpression.Method.ReturnType;
501-
}
502-
503-
if (expression is BinaryExpression || expression is UnaryExpression)
482+
if (expression is UnaryExpression || expression is BinaryExpression)
504483
return expression.Type;
505484

506485
throw new ArgumentException("Could not determine member type from " + expression, nameof(expression));
507486
}
508487

509488
private static bool IsMemberExpression(Expression expression)
510489
{
511-
if (expression is ParameterExpression)
512-
return true;
513-
514-
var memberExpression = expression as MemberExpression;
515-
if (memberExpression != null)
490+
switch (expression.NodeType)
516491
{
517-
if (memberExpression.Expression == null)
518-
return false; // it's a member of a static class
519-
520-
if (IsMemberExpression(memberExpression.Expression))
492+
case ExpressionType.Parameter:
521493
return true;
522494

523-
// if the member has a null value, it was an alias
524-
return EvaluatesToNull(memberExpression.Expression);
525-
}
526-
527-
var unwrapExpression = UnwrapConvertExpression(expression);
528-
if (unwrapExpression != null)
529-
{
530-
return IsMemberExpression(unwrapExpression);
531-
}
532-
533-
var methodCallExpression = expression as MethodCallExpression;
534-
if (methodCallExpression != null)
535-
{
536-
string signature = Signature(methodCallExpression.Method);
537-
if (_customProjectionProcessors.ContainsKey(signature))
538-
return true;
495+
case ExpressionType.MemberAccess:
496+
var expr = ((MemberExpression) expression).Expression;
497+
return expr != null && // it's not a member of a static class
498+
IsMemberExpressionOrAlias(expr);
539499

540-
if (methodCallExpression.Method.Name == "First")
500+
case ExpressionType.Call:
541501
{
542-
if (IsMemberExpression(methodCallExpression.Arguments[0]))
543-
return true;
544-
545-
return EvaluatesToNull(methodCallExpression.Arguments[0]);
546-
}
502+
var methodCallExpression = (MethodCallExpression) expression;
547503

548-
if (methodCallExpression.Method.Name == "GetType"
549-
|| methodCallExpression.Method.Name == "get_Item")
550-
{
551-
if (IsMemberExpression(methodCallExpression.Object))
504+
string signature = Signature(methodCallExpression.Method);
505+
if (_customProjectionProcessors.ContainsKey(signature))
552506
return true;
553507

554-
return EvaluatesToNull(methodCallExpression.Object);
508+
switch (methodCallExpression.Method.Name)
509+
{
510+
case "First":
511+
return IsMemberExpressionOrAlias(methodCallExpression.Arguments[0]);
512+
case "GetType":
513+
case "get_Item":
514+
return IsMemberExpressionOrAlias(methodCallExpression.Object);
515+
}
516+
517+
return false;
555518
}
556519
}
557520

558-
return false;
521+
var unwrapExpression = UnwrapConvertExpression(expression);
522+
return unwrapExpression != null && IsMemberExpression(unwrapExpression);
523+
}
524+
525+
private static bool IsMemberExpressionOrAlias(Expression expr)
526+
{
527+
return IsMemberExpression(expr) ||
528+
// if the member has a null value, it was an alias
529+
EvaluatesToNull(expr);
559530
}
560531

561532
private static bool IsConversion(ExpressionType expressionType)
@@ -679,33 +650,27 @@ private static ICriterion ProcessBinaryExpression(BinaryExpression expression)
679650

680651
private static ICriterion ProcessBooleanExpression(Expression expression)
681652
{
682-
if (expression is MemberExpression)
683-
{
684-
return Restrictions.Eq(FindMemberExpression(expression), true);
685-
}
686-
687-
var unaryExpression = expression as UnaryExpression;
688-
if (unaryExpression != null)
653+
switch (expression.NodeType)
689654
{
690-
if (unaryExpression.NodeType != ExpressionType.Not)
691-
throw new ArgumentException("Cannot interpret member from " + expression, nameof(expression));
655+
case ExpressionType.MemberAccess:
656+
return Restrictions.Eq(FindMemberExpression(expression), true);
692657

693-
if (IsMemberExpression(unaryExpression.Operand))
694-
return Restrictions.Eq(FindMemberExpression(unaryExpression.Operand), false);
695-
else
696-
return Restrictions.Not(ProcessExpression(unaryExpression.Operand));
697-
}
658+
case ExpressionType.Not:
659+
{
660+
var unaryExpression = (UnaryExpression) expression;
661+
return IsMemberExpression(unaryExpression.Operand)
662+
? Restrictions.Eq(FindMemberExpression(unaryExpression.Operand), false)
663+
: Restrictions.Not(ProcessExpression(unaryExpression.Operand));
664+
}
698665

699-
var methodCallExpression = expression as MethodCallExpression;
700-
if (methodCallExpression != null)
701-
{
702-
return ProcessCustomMethodCall(methodCallExpression);
703-
}
666+
case ExpressionType.Call:
667+
return ProcessCustomMethodCall((MethodCallExpression) expression);
704668

705-
var typeBinaryExpression = expression as TypeBinaryExpression;
706-
if (typeBinaryExpression != null)
707-
{
708-
return Restrictions.Eq(ClassMember(typeBinaryExpression.Expression), typeBinaryExpression.TypeOperand.FullName);
669+
case ExpressionType.TypeIs:
670+
{
671+
var tbe = (TypeBinaryExpression) expression;
672+
return Restrictions.Eq(ClassMember(tbe.Expression), tbe.TypeOperand.FullName);
673+
}
709674
}
710675

711676
throw new ArgumentException(

0 commit comments

Comments
 (0)