private void MakeComparisonRule(OperatorInfo info) { // check the first type if it has an applicable method MethodInfo[] targets = GetApplicableMembers(info); if (targets.Length > 0 && TryMakeBindingTarget(targets)) { return; } // then check the 2nd type. targets = GetApplicableMembers(_types[1], info); if (targets.Length > 0 && TryMakeBindingTarget(targets)) { return; } // try Compare: cmp(x,y) (>, <, >=, <=, ==, !=) 0 if (TryNumericComparison(info)) { return; } // try inverting the operator & result (e.g. if looking for Equals try NotEquals, LessThan for GreaterThan)... Operators revOp = GetInvertedOperator(info.Operator); OperatorInfo revInfo = OperatorInfo.GetOperatorInfo(revOp); Debug.Assert(revInfo != null); // try the 1st type's opposite function result negated targets = GetApplicableMembers(revInfo); if (targets.Length > 0 && TryMakeInvertedBindingTarget(targets)) { return; } // then check the 2nd type. targets = GetApplicableMembers(_types[1], revInfo); if (targets.Length > 0 && TryMakeInvertedBindingTarget(targets)) { return; } // see if we're comparing to null w/ an object ref or a Nullable<T> if (TryMakeNullComparisonRule()) { return; } // see if this is a primitive type where we're comparing the two values. if (TryPrimitiveCompare()) { return; } SetErrorTarget(info); }
private MetaObject TryInplaceOperator(OperatorInfo info, Expression codeContext, MetaObject[] args) { Operators op = CompilerHelpers.InPlaceOperatorToOperator(info.Operator); if (op != Operators.None) { // recurse to try and get the non-inplace action... return(MakeOperatorRule(OperatorInfo.GetOperatorInfo(op), codeContext, args)); } return(null); }
private DynamicMetaObject TryInvertedComparison(OperatorInfo info, OverloadResolverFactory resolverFactory, DynamicMetaObject target, DynamicMetaObject[] args) { ExpressionType revOp = GetInvertedOperator(info.Operator); OperatorInfo revInfo = OperatorInfo.GetOperatorInfo(revOp); Debug.Assert(revInfo != null); // try the 1st type's opposite function result negated MethodBase[] targets = GetApplicableMembers(target.GetLimitType(), revInfo); if (targets.Length > 0) { return(TryMakeInvertedBindingTarget(resolverFactory, targets, args)); } return(null); }
/// <summary> /// Creates the meta object for the rest of the operations: comparisons and all other /// operators. If the operation cannot be completed a MetaObject which indicates an /// error will be returned. /// </summary> private MetaObject MakeGeneralOperatorRule(string operation, Expression codeContext, MetaObject[] args) { OperatorInfo info = OperatorInfo.GetOperatorInfo(operation); MetaObject res; if (CompilerHelpers.IsComparisonOperator(operation)) { res = MakeComparisonRule(info, codeContext, args); } else { res = MakeOperatorRule(info, codeContext, args); } return(res); }
private MetaObject TryInvertedComparison(OperatorInfo info, MetaObject target, MetaObject[] args) { Operators revOp = GetInvertedOperator(info.Operator); OperatorInfo revInfo = OperatorInfo.GetOperatorInfo(revOp); Debug.Assert(revInfo != null); // try the 1st type's opposite function result negated MethodBase[] targets = GetApplicableMembers(target.LimitType, revInfo); if (targets.Length > 0) { return(TryMakeInvertedBindingTarget(targets, args)); } return(null); }
public void MakeRule() { if (Action.Operation == Operators.GetItem || Action.Operation == Operators.SetItem) { // try default member first, then look for special name methods. if (MakeDefaultMemberRule(Action.Operation)) { return; } } OperatorInfo info = OperatorInfo.GetOperatorInfo(Action.Operation); if (Action.IsComparision) { MakeComparisonRule(info); } else { MakeOperatorRule(info); } }
/// <summary> /// Creates the meta object for the rest of the operations: comparisons and all other /// ExpressionType. If the operation cannot be completed a MetaObject which indicates an /// error will be returned. /// </summary> private DynamicMetaObject MakeGeneralOperatorRule(ExpressionType operation, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args) { OperatorInfo info = OperatorInfo.GetOperatorInfo(operation); return(MakeGeneratorOperatorRule(resolverFactory, args, info)); }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] // TODO: fix private void MakeOperatorRule(OperatorInfo info) { MethodInfo[] targets = GetApplicableMembers(info); if (targets.Length == 0) { targets = GetFallbackMembers(_types[0], info); } if (targets.Length > 0 && TryMakeBindingTarget(targets)) { return; } if (_types.Length > 1) { targets = GetApplicableMembers(_types[1], info); if (targets.Length > 0 && TryMakeBindingTarget(targets)) { return; } } Operators op = CompilerHelpers.InPlaceOperatorToOperator(info.Operator); if (op != Operators.None) { // recurse to try and get the non-inplace action... MakeOperatorRule(OperatorInfo.GetOperatorInfo(op)); return; } if (_types.Length == 2 && TypeUtils.GetNonNullableType(_types[0]) == TypeUtils.GetNonNullableType(_types[1]) && TypeUtils.IsArithmetic(_types[0])) { // TODO: Nullable<PrimitveType> Support Expression expr; switch (info.Operator) { case Operators.Add: expr = Ast.Add(Param0, Param1); break; case Operators.Subtract: expr = Ast.Subtract(Param0, Param1); break; case Operators.Divide: expr = Ast.Divide(Param0, Param1); break; case Operators.Mod: expr = Ast.Modulo(Param0, Param1); break; case Operators.Multiply: expr = Ast.Multiply(Param0, Param1); break; case Operators.LeftShift: expr = Ast.LeftShift(Param0, Param1); break; case Operators.RightShift: expr = Ast.RightShift(Param0, Param1); break; case Operators.BitwiseAnd: expr = Ast.And(Param0, Param1); break; case Operators.BitwiseOr: expr = Ast.Or(Param0, Param1); break; case Operators.ExclusiveOr: expr = Ast.ExclusiveOr(Param0, Param1); break; default: throw new InvalidOperationException(); } _rule.Target = _rule.MakeReturn(Binder, expr); return; } else if (_types.Length == 1 && TryMakeDefaultUnaryRule(info)) { return; } SetErrorTarget(info); }