/// <summary> /// Helper to wrap explicit conversion call into try/catch incase it throws an exception. If /// it throws the default value is returned. /// </summary> private Expression WrapForThrowingTry(bool isImplicit, Expression ret) { if (!isImplicit && Action.ResultKind == ConversionResultKind.ExplicitTry) { ret = AstUtils.Try(ret).Catch(typeof(Exception), CompilerHelpers.GetTryConvertReturnValue(Context, _rule)); } return(ret); }
/// <summary> /// Helper to produce the rule for converting T to Nullable of T /// </summary> private void MakeConvertingToTToNullableOfTTarget(Type toType) { Type valueType = toType.GetGenericArguments()[0]; // ConvertSelfToT -> Nullable<T> if (Action.ResultKind == ConversionResultKind.ExplicitCast) { var action = OldConvertToAction.Make(Binder, valueType, Action.ResultKind); var conversion = Expression.Dynamic(action, action.ToType, _rule.Context, _rule.Parameters[0]); // if the conversion to T fails we just throw _rule.Target = _rule.MakeReturn( Binder, Ast.New( toType.GetConstructor(new Type[] { valueType }), conversion ) ); } else { // if the conversion to T succeeds then produce the nullable<T>, otherwise return default(retType) var conversion = Expression.Dynamic(OldConvertToAction.Make(Binder, valueType, Action.ResultKind), typeof(object), _rule.Context, _rule.Parameters[0]); ParameterExpression tmp = _rule.GetTemporary(typeof(object), "tmp"); _rule.Target = AstUtils.If( Ast.NotEqual( Ast.Assign(tmp, conversion), Ast.Constant(null) ), _rule.MakeReturn( Binder, Ast.New( toType.GetConstructor(new Type[] { valueType }), Ast.Convert( tmp, valueType ) ) ) ).Else( CompilerHelpers.GetTryConvertReturnValue(Context, _rule) ); } }
/// <summary> /// Helper to produce an error when a conversion cannot occur /// </summary> private void MakeErrorTarget() { Expression target; switch (Action.ResultKind) { case ConversionResultKind.ImplicitCast: case ConversionResultKind.ExplicitCast: target = Binder.MakeConversionError(Action.ToType, _rule.Parameters[0]).MakeErrorForRule(_rule, Binder); break; case ConversionResultKind.ImplicitTry: case ConversionResultKind.ExplicitTry: target = CompilerHelpers.GetTryConvertReturnValue(Context, _rule); break; default: throw new InvalidOperationException(Action.ResultKind.ToString()); } _rule.Target = target; }