public override Expression /*!*/ Convert(DynamicMetaObject /*!*/ metaObject, Type restrictedType, ParameterInfo info, Type /*!*/ toType) { Expression expr = metaObject.Expression; Type fromType = restrictedType ?? expr.Type; // block: if (fromType == typeof(MissingBlockParam)) { Debug.Assert(toType == typeof(BlockParam) || toType == typeof(MissingBlockParam)); return(AstUtils.Constant(null)); } if (fromType == typeof(BlockParam) && toType == typeof(MissingBlockParam)) { return(AstUtils.Constant(null)); } // protocol conversions: if (info != null && info.IsDefined(typeof(DefaultProtocolAttribute), false)) { var action = RubyConversionAction.TryGetDefaultConversionAction(Context, toType); if (action != null) { // TODO: inline implicit conversions: return(AstUtils.LightDynamic(action, toType, expr)); } // Do not throw an exception here to allow generic type parameters to be used with D.P. attribute. // The semantics should be to use DP if available for the current instantiation and ignore it otherwise. } if (restrictedType != null) { if (restrictedType == typeof(DynamicNull)) { if (!toType.IsValueType || toType.IsGenericType && toType.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(AstUtils.Constant(null, toType)); } else if (toType == typeof(bool)) { return(AstUtils.Constant(false)); } } if (toType.IsAssignableFrom(restrictedType)) { // expr can be converted to restrictedType, which can be converted toType => we can convert expr to toType: return(AstUtils.Convert(expr, CompilerHelpers.GetVisibleType(toType))); } // if there is a simple conversion from restricted type, convert the expression to the restricted type and use that conversion: Type visibleRestrictedType = CompilerHelpers.GetVisibleType(restrictedType); if (Converter.CanConvertFrom(metaObject, visibleRestrictedType, toType, false, NarrowingLevel.None, false, false).IsConvertible) { expr = AstUtils.Convert(expr, visibleRestrictedType); } } return(Converter.ConvertExpression(expr, toType, _args.RubyContext, _args.MetaContext.Expression, _implicitProtocolConversions)); }
public CallSite <Func <CallSite, object, TResult> > /*!*/ GetSite(RubyConversionAction /*!*/ conversion) { return(RubyUtils.GetCallSite(ref Site, conversion)); }