コード例 #1
0
 /// <inheritdoc />
 public bool TryGetValue(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, object defaultValue, out object value, out IPublishedProperty noValueProperty)
 {
     return(TryGetValue <object>(content, alias, culture, segment, fallback, defaultValue, out value, out noValueProperty));
 }
コード例 #2
0
        public override void Read(AssetReader reader)
        {
            if (IsSerialized(reader.Version))
            {
                ReadNamedObject(reader);

                ParsedForm.Read(reader);
                Platforms = reader.ReadArray((t) => (GPUPlatform)t);
                if (IsDoubleArray(reader.Version))
                {
                    uint[][] offsets             = reader.ReadUInt32ArrayArray();
                    uint[][] compressedLengths   = reader.ReadUInt32ArrayArray();
                    uint[][] decompressedLengths = reader.ReadUInt32ArrayArray();
                    byte[]   compressedBlob      = reader.ReadByteArray();
                    reader.AlignStream();

                    UnpackSubProgramBlobs(reader.Layout, offsets, compressedLengths, decompressedLengths, compressedBlob);
                }
                else
                {
                    uint[] offsets             = reader.ReadUInt32Array();
                    uint[] compressedLengths   = reader.ReadUInt32Array();
                    uint[] decompressedLengths = reader.ReadUInt32Array();
                    byte[] compressedBlob      = reader.ReadByteArray();
                    reader.AlignStream();

                    UnpackSubProgramBlobs(reader.Layout, offsets, compressedLengths, decompressedLengths, compressedBlob);
                }
            }
            else
            {
                base.Read(reader);

                if (HasBlob(reader.Version))
                {
                    uint   decompressedSize = reader.ReadUInt32();
                    byte[] compressedBlob   = reader.ReadByteArray();
                    reader.AlignStream();

                    UnpackSubProgramBlobs(reader.Layout, 0, (uint)compressedBlob.Length, decompressedSize, compressedBlob);
                }

                if (HasFallback(reader.Version))
                {
                    Fallback.Read(reader);
                }
                if (HasDefaultProperties(reader.Version))
                {
                    DefaultProperties.Read(reader);
                }
                if (HasStaticProperties(reader.Version))
                {
                    StaticProperties.Read(reader);
                }
            }

            if (HasDependencies(reader.Version))
            {
                Dependencies = reader.ReadAssetArray <PPtr <Shader> >();
            }
            if (HasNonModifiableTextures(reader.Version))
            {
                NonModifiableTextures = new Dictionary <string, PPtr <Texture> >();
                NonModifiableTextures.Read(reader);
            }
            if (HasShaderIsBaked(reader.Version))
            {
                ShaderIsBaked = reader.ReadBoolean();
                reader.AlignStream();
            }

#if UNIVERSAL
            if (HasErrors(reader.Version, reader.Flags))
            {
                Errors = reader.ReadAssetArray <ShaderError>();
            }
            if (HasDefaultTextures(reader.Version, reader.Flags))
            {
                DefaultTextures = new Dictionary <string, PPtr <Texture> >();
                DefaultTextures.Read(reader);
            }
            if (HasCompileInfo(reader.Version, reader.Flags))
            {
                CompileInfo.Read(reader);
            }
#endif
        }
コード例 #3
0
        /// <summary>
        /// Helper method for generating a MetaObject which calls a
        /// specific method on Dynamic, but uses one of the arguments for
        /// the result.
        /// </summary>
        private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
        {
            //
            // First, call fallback to do default binding
            // This produces either an error or a call to a .NET member
            //
            DynamicMetaObject fallbackResult = fallback(null);

            //
            // Build a new expression like:
            // {
            //   object result;
            //   TrySetMember(payload, result = value) ? result : fallbackResult
            // }
            //
            ParameterExpression result = Expression.Parameter(typeof(object), null);

            IList <Expression> callArgs = new List <Expression>();

            callArgs.Add(Expression.Convert(Expression, typeof(T)));
            callArgs.Add(Constant(binder));
            callArgs.AddRange(args);
            callArgs[args.Length + 1] = Expression.Assign(result, callArgs[args.Length + 1]);

            DynamicMetaObject callDynamic = new DynamicMetaObject(
                Expression.Block(
                    new[] { result },
                    Expression.Condition(
                        Expression.Call(
                            Expression.Constant(_proxy),
                            typeof(DynamicProxy <T>).GetMethod(methodName),
                            callArgs
                            ),
                        result,
                        fallbackResult.Expression,
                        typeof(object)
                        )
                    ),
                GetRestrictions().Merge(fallbackResult.Restrictions)
                );

            //
            // Now, call fallback again using our new MO as the error
            // When we do this, one of two things can happen:
            //   1. Binding will succeed, and it will ignore our call to
            //      the dynamic method, OR
            //   2. Binding will fail, and it will use the MO we created
            //      above.
            //
            return(_dontFallbackFirst ? callDynamic : fallback(callDynamic));
        }
コード例 #4
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on DynamicObject that returns a result.
            /// 
            /// args is either an array of arguments to be passed
            /// to the method as an object[] or NoArgs to signify that
            /// the target method takes no parameters.
            /// </summary>
            private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke) {
                if (!IsOverridden(methodName)) {
                    return fallbackResult;
                }

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
                // }
                //
                var result = Expression.Parameter(typeof(object), null);
                ParameterExpression callArgs = methodName != "TryBinaryOperation" ? Expression.Parameter(typeof(object[]), null) : Expression.Parameter(typeof(object), null);
                var callArgsValue = GetConvertedArgs(args);

                var resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);

                // Need to add a conversion if calling TryConvert
                if (binder.ReturnType != typeof(object)) {
                    Debug.Assert(binder is ConvertBinder && fallbackInvoke == null);

                    var convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
                    // will always be a cast or unbox
                    Debug.Assert(convert.Method == null);

#if !SILVERLIGHT
                    // Prepare a good exception message in case the convert will fail
                    string convertFailed = Strings.DynamicObjectResultNotAssignable(
                        "{0}",
                        this.Value.GetType(),
                        binder.GetType(),
                        binder.ReturnType
                    );

                    Expression condition;
                    // If the return type can not be assigned null then just check for type assignablity otherwise allow null.
                    if (binder.ReturnType.IsValueType && Nullable.GetUnderlyingType(binder.ReturnType) == null) {
                        condition = Expression.TypeIs(resultMO.Expression, binder.ReturnType);
                    }
                    else {
                        condition = Expression.OrElse(
                                        Expression.Equal(resultMO.Expression, Expression.Constant(null)),
                                        Expression.TypeIs(resultMO.Expression, binder.ReturnType));
                    }

                    var checkedConvert = Expression.Condition(
                        condition,
                        convert,
                        Expression.Throw(
                            Expression.New(typeof(InvalidCastException).GetConstructor(new Type[]{typeof(string)}),
                                Expression.Call(
                                    typeof(string).GetMethod("Format", new Type[] {typeof(string), typeof(object[])}),
                                    Expression.Constant(convertFailed),
                                    Expression.NewArrayInit(typeof(object), 
                                        Expression.Condition(
                                            Expression.Equal(resultMO.Expression, Expression.Constant(null)),
                                            Expression.Constant("null"),
                                            Expression.Call(
                                                resultMO.Expression,
                                                typeof(object).GetMethod("GetType")
                                            ),
                                            typeof(object)
                                        )
                                    )
                                )
                            ),
                            binder.ReturnType
                        ),
                        binder.ReturnType
                    );
#else
                    var checkedConvert = convert;
#endif

                    resultMO = new DynamicMetaObject(checkedConvert, resultMO.Restrictions);
                }

                if (fallbackInvoke != null) {
                    resultMO = fallbackInvoke(resultMO);
                }

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { result, callArgs },
                        methodName != "TryBinaryOperation" ? Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)) : Expression.Assign(callArgs, callArgsValue[0]),
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                BuildCallArgs(
                                    binder,
                                    args,
                                    callArgs,
                                    result
                                )
                            ),
                            Expression.Block(
                                methodName != "TryBinaryOperation" ? ReferenceArgAssign(callArgs, args) : Expression.Empty(),
                                resultMO.Expression
                            ),
                            fallbackResult.Expression,
                            binder.ReturnType
                        )
                    ),
                    GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
                );
                return callDynamic;
            }
コード例 #5
0
        /// <summary>
        /// Helper method for generating a MetaObject which calls a
        /// specific method on Dynamic, but uses one of the arguments for
        /// the result.
        /// </summary>
        private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, IEnumerable <Expression> args, Fallback fallback)
        {
            //
            // First, call fallback to do default binding
            // This produces either an error or a call to a .NET member
            //
            DynamicMetaObject fallbackResult = fallback(null);

            //
            // Build a new expression like:
            // {
            //   object result;
            //   TrySetMember(payload, result = value) ? result : fallbackResult
            // }
            //
            ParameterExpression result = Expression.Parameter(typeof(object), null);

            IList <Expression> callArgs = new List <Expression>();

            callArgs.Add(Expression.Convert(Expression, typeof(T)));
            callArgs.Add(Constant(binder));
            callArgs.AddRange(args);
            callArgs[callArgs.Count - 1] = Expression.Assign(result, callArgs[callArgs.Count - 1]);

            return(new DynamicMetaObject(
                       Expression.Block(
                           new[] { result },
                           Expression.Condition(
                               Expression.Call(
                                   Expression.Constant(_proxy),
                                   typeof(DynamicProxy <T>).GetMethod(methodName),
                                   callArgs
                                   ),
                               result,
                               fallbackResult.Expression,
                               typeof(object)
                               )
                           ),
                       GetRestrictions().Merge(fallbackResult.Restrictions)
                       ));
        }
コード例 #6
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic that returns a result
            /// </summary>
            private DynamicMetaObject CallMethodWithResult <TBinder>(string methodName, TBinder binder, Expression[] args, Fallback <TBinder> fallback, Fallback <TBinder> fallbackInvoke)
                where TBinder : DynamicMetaObjectBinder
            {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(this, binder, null);

                DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);

                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return(fallback(this, binder, callDynamic));
            }
コード例 #7
0
        public static object Value(this IPublishedProperty property, string culture = null, string segment = null, Fallback fallback = default, object defaultValue = default)
        {
            if (property.HasValue(culture, segment))
            {
                return(property.GetValue(culture, segment));
            }

            return(PublishedValueFallback.TryGetValue(property, culture, segment, fallback, defaultValue, out var value)
                ? value
                : property.GetValue(culture, segment)); // give converter a chance to return it's own vision of "no value"
        }
コード例 #8
0
 private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
 {
     DynamicMetaObject obj2 = fallback(null);
     ParameterExpression left = Expression.Parameter(typeof(object), null);
     Expression[] arguments = args.AddFirst<Expression>(Constant(binder));
     arguments[args.Length] = Expression.Assign(left, arguments[args.Length]);
     DynamicMetaObject errorSuggestion = new DynamicMetaObject(Expression.Block(new ParameterExpression[] { left }, new Expression[] { Expression.Condition(Expression.Call(this.GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), arguments), left, obj2.Expression, typeof(object)) }), this.GetRestrictions().Merge(obj2.Restrictions));
     return fallback(errorSuggestion);
 }
コード例 #9
0
 private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke)
 {
     DynamicMetaObject fallbackResult = fallback(null);
     DynamicMetaObject errorSuggestion = this.BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
     return fallback(errorSuggestion);
 }
コード例 #10
0
 private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
 {
     if (!this.IsOverridden(methodName))
     {
         return fallbackResult;
     }
     ParameterExpression expression = Expression.Parameter(typeof(object), null);
     Expression[] destinationArray = new Expression[args.Length + 2];
     Array.Copy(args, 0, destinationArray, 1, args.Length);
     destinationArray[0] = Constant(binder);
     destinationArray[destinationArray.Length - 1] = expression;
     DynamicMetaObject errorSuggestion = new DynamicMetaObject(expression, BindingRestrictions.Empty);
     if (binder.ReturnType != typeof(object))
     {
         errorSuggestion = new DynamicMetaObject(Expression.Convert(errorSuggestion.Expression, binder.ReturnType), errorSuggestion.Restrictions);
     }
     if (fallbackInvoke != null)
     {
         errorSuggestion = fallbackInvoke(errorSuggestion);
     }
     return new DynamicMetaObject(Expression.Block(new ParameterExpression[] { expression }, new Expression[] { Expression.Condition(Expression.Call(this.GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), destinationArray), errorSuggestion.Expression, fallbackResult.Expression, binder.ReturnType) }), this.GetRestrictions().Merge(errorSuggestion.Restrictions).Merge(fallbackResult.Restrictions));
 }
コード例 #11
0
 private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
 {
     DynamicMetaObject obj2 = fallback(null);
     DynamicMetaObject errorSuggestion = new DynamicMetaObject(Expression.Condition(Expression.Call(this.GetLimitedSelf(), typeof(DynamicObject).GetMethod(methodName), args.AddFirst<Expression>(Constant(binder))), Expression.Empty(), obj2.Expression, typeof(void)), this.GetRestrictions().Merge(obj2.Restrictions));
     return fallback(errorSuggestion);
 }
コード例 #12
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic, but uses one of the arguments for
            /// the result.
            /// </summary>
            private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(null);

                //
                // Build a new expression like:
                //   if (TryDeleteMember(payload)) { } else { fallbackResult }
                //
                var callDynamic = new DynamicMetaObject(
                    Expression.Condition(
                        Expression.Call(
                            GetLimitedSelf(),
                            typeof(DynamicObject).GetMethod(methodName),
                            args.AddFirst(Constant(binder))
                        ),
                        Expression.Empty(),
                        fallbackResult.Expression,
                        typeof(void)
                    ),
                    GetRestrictions().Merge(fallbackResult.Restrictions)
                );

                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return fallback(callDynamic);
            }
コード例 #13
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic, but uses one of the arguments for
            /// the result.
            /// </summary>
            private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(null);

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TrySetMember(payload, result = value) ? result : fallbackResult
                // }
                //

                var result = Expression.Parameter(typeof(object), null);
                var callArgs = args.AddFirst(Constant(binder));
                callArgs[args.Length] = Expression.Assign(result, callArgs[args.Length]);

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { result },
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                callArgs
                            ),
                            result,
                            fallbackResult.Expression,
                            typeof(object)
                        )
                    ),
                    GetRestrictions().Merge(fallbackResult.Restrictions)
                );

                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return fallback(callDynamic);
            }
コード例 #14
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic that returns a result
            /// </summary>
            private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke) {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(null);

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
                // }
                //
                var result = Expression.Parameter(typeof(object), null);

                var callArgs = new Expression[args.Length + 2];
                Array.Copy(args, 0, callArgs, 1, args.Length);
                callArgs[0] = Constant(binder);
                callArgs[callArgs.Length - 1] = result;

                var resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);

                // Need to add a conversion if calling TryConvert
                if (binder.ReturnType != typeof(object)) {
                    Debug.Assert(binder is ConvertBinder && fallbackInvoke == null);

                    var convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
                    // will always be a cast or unbox
                    Debug.Assert(convert.Method == null);

                    resultMO = new DynamicMetaObject(convert, resultMO.Restrictions);
                }

                if (fallbackInvoke != null) {
                    resultMO = fallbackInvoke(resultMO);
                }

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { result },
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                callArgs
                            ),
                            resultMO.Expression,
                            fallbackResult.Expression,
                            binder.ReturnType
                        )
                    ),
                    GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
                );
                
                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return fallback(callDynamic);
            }
コード例 #15
0
 /// <inheritdoc />
 public bool TryGetValue(IPublishedProperty property, string culture, string segment, Fallback fallback, object defaultValue, out object value)
 {
     return(TryGetValue <object>(property, culture, segment, fallback, defaultValue, out value));
 }
コード例 #16
0
ファイル: InteropBinder.cs プロジェクト: tnachen/ironruby
 public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, CreateInstanceBinder/*!*/ binder, DynamicMetaObject/*!*/ target,
     DynamicMetaObject/*!*/[]/*!*/ args, Fallback/*!*/ fallback) {
     return Bind(context, "new", binder.CallInfo, binder, target, args, fallback);
 }
コード例 #17
0
        /// <inheritdoc />
        public bool TryGetValue <T>(IPublishedElement content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value)
        {
            var propertyType = content.ContentType.GetPropertyType(alias);

            if (propertyType == null)
            {
                value = default;
                return(false);
            }

            _variationContextAccessor.ContextualizeVariation(propertyType.Variations, ref culture, ref segment);

            foreach (var f in fallback)
            {
                switch (f)
                {
                case Fallback.None:
                    continue;

                case Fallback.DefaultValue:
                    value = defaultValue;
                    return(true);

                case Fallback.Language:
                    if (TryGetValueWithLanguageFallback(content, alias, culture, segment, out value))
                    {
                        return(true);
                    }
                    break;

                default:
                    throw NotSupportedFallbackMethod(f, "element");
                }
            }

            value = default;
            return(false);
        }
コード例 #18
0
ファイル: InteropBinder.cs プロジェクト: tnachen/ironruby
 public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, InvokeMemberBinder/*!*/ binder, DynamicMetaObject/*!*/ target,
     DynamicMetaObject/*!*/[]/*!*/ args, Fallback/*!*/ fallback) {
     return Bind(context, binder.Name, binder.CallInfo, binder, target, args, fallback);
 }
コード例 #19
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic, but uses one of the arguments for
            /// the result.
            ///
            /// args is either an array of arguments to be passed
            /// to the method as an object[] or NoArgs to signify that
            /// the target method takes no parameters.
            /// </summary>
            private DynamicMetaObject CallMethodNoResult <TBinder>(string methodName, TBinder binder, Expression[] args, Fallback <TBinder> fallback)
                where TBinder : DynamicMetaObjectBinder
            {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject               fallbackResult = fallback(this, binder, null);
                ParameterExpression             callArgs       = Expression.Parameter(typeof(object[]), null);
                ReadOnlyCollection <Expression> callArgsValue  = GetConvertedArgs(args);

                //
                // Build a new expression like:
                //   if (TryDeleteMember(payload)) { } else { fallbackResult }
                //
                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new TrueReadOnlyCollection <ParameterExpression>(callArgs),
                        new TrueReadOnlyCollection <Expression>(
                            Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)),
                            Expression.Condition(
                                Expression.Call(
                                    GetLimitedSelf(),
                                    typeof(DynamicObject).GetMethod(methodName),
                                    BuildCallArgs(
                                        binder,
                                        args,
                                        callArgs,
                                        null
                                        )
                                    ),
                                Expression.Block(
                                    ReferenceArgAssign(callArgs, args),
                                    AstUtils.Empty
                                    ),
                                fallbackResult.Expression,
                                typeof(void)
                                )
                            )
                        ),
                    GetRestrictions().Merge(fallbackResult.Restrictions)
                    );

                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return(fallback(this, binder, callDynamic));
            }
コード例 #20
0
ファイル: InteropBinder.cs プロジェクト: tnachen/ironruby
            public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, string/*!*/ methodName, CallInfo/*!*/ callInfo, 
                DynamicMetaObjectBinder/*!*/ binder, DynamicMetaObject/*!*/ target, DynamicMetaObject/*!*/[]/*!*/ args, Fallback/*!*/ fallback) {
                Debug.Assert(fallback != null);

                var metaBuilder = new MetaObjectBuilder();
                var callArgs = new CallArguments(context, target, args, RubyCallSignature.Simple(callInfo.ArgumentCount));

                if (!RubyCallAction.Build(metaBuilder, methodName, callArgs, false)) {
                    metaBuilder.SetMetaResult(fallback(target, args), false);
                }
                return metaBuilder.CreateMetaObject(binder);
            }
コード例 #21
0
 /// <summary>
 /// Helper method for generating a MetaObject which calls a
 /// specific method on Dynamic that returns a result
 /// </summary>
 private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) {
     return CallMethodWithResult(methodName, binder, args, fallback, null);
 }
コード例 #22
0
 /// <inheritdoc />
 public bool TryGetValue <T>(IPublishedContent content, string alias, string?culture, string?segment, Fallback fallback, T defaultValue, out T?value, out IPublishedProperty?noValueProperty)
 {
     value           = default;
     noValueProperty = default;
     return(false);
 }
コード例 #23
0
 public static new Collator Create(string localeId, Fallback fallback)
 {
     var instance = new RuleBasedCollator();
     ErrorCode status;
     instance._handle = NativeMethods.ucol_open(localeId, out status);
     if (status == ErrorCode.UsingFallbackWarning && fallback == Fallback.NoFallback)
     {
         throw new ArgumentException("Could only create Collator by falling back to '" + instance._Id +
                                     "'. You can use the fallback option to create this.");
     }
     if (status == ErrorCode.InternalProgramError && fallback == Fallback.FallbackAllowed)
         instance = new RuleBasedCollator(string.Empty); // fallback to UCA
     else
     {
         try
         {
             status.ThrowIfError();
         }
         catch (Exception e)
         {
             throw new ArgumentException(
                 "Unable to create a collator using the given localeId.\nThis is likely because the ICU data file was created without collation rules for this locale. You can provide the rules yourself or replace the data dll.",
                 e);
         }
     }
     return instance;
 }
コード例 #24
0
 private IEnumerable <VideoInfoResponse.StreamInfo> GetAdaptiveStreams() => Fallback.ToEmpty(
     _root
     .GetProperty("args")
     .GetPropertyOrNull("adaptive_fmts")?
     .GetString()?
     .Split(",")
     .Select(Url.SplitQuery)
     .Select(d => new VideoInfoResponse.StreamInfo(d))
     );
コード例 #25
0
        /// <summary>
        /// Helper method for generating a MetaObject which calls a
        /// specific method on Dynamic, but uses one of the arguments for
        /// the result.
        /// </summary>
        private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
        {
            //
            // First, call fallback to do default binding
            // This produces either an error or a call to a .NET member
            //
            DynamicMetaObject fallbackResult = fallback(null);

            IList <Expression> callArgs = new List <Expression>();

            callArgs.Add(Expression.Convert(Expression, typeof(T)));
            callArgs.Add(Constant(binder));
            callArgs.AddRange(args);

            //
            // Build a new expression like:
            //   if (TryDeleteMember(payload)) { } else { fallbackResult }
            //
            return(new DynamicMetaObject(
                       Expression.Condition(
                           Expression.Call(
                               Expression.Constant(_proxy),
                               typeof(DynamicProxy <T>).GetMethod(methodName),
                               callArgs
                               ),
                           Expression.Empty(),
                           fallbackResult.Expression,
                           typeof(void)
                           ),
                       GetRestrictions().Merge(fallbackResult.Restrictions)
                       ));
        }
コード例 #26
0
ファイル: DisplayStringTest.cs プロジェクト: Game4all/osu
        public void TestFallback()
        {
            var fallback = new Fallback();

            Assert.That(fallback.GetDisplayString(), Is.EqualTo("fallback"));
        }
コード例 #27
0
        private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
        {
            //
            // Build a new expression like:
            // {
            //   object result;
            //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
            // }
            //
            ParameterExpression result = Expression.Parameter(typeof(object), null);

            IList <Expression> callArgs = new List <Expression>();

            callArgs.Add(Expression.Convert(Expression, typeof(T)));
            callArgs.Add(Constant(binder));
            callArgs.AddRange(args);
            callArgs.Add(result);

            DynamicMetaObject resultMetaObject = new DynamicMetaObject(result, BindingRestrictions.Empty);

            // Need to add a conversion if calling TryConvert
            if (binder.ReturnType != typeof(object))
            {
                UnaryExpression convert = Expression.Convert(resultMetaObject.Expression, binder.ReturnType);
                // will always be a cast or unbox

                resultMetaObject = new DynamicMetaObject(convert, resultMetaObject.Restrictions);
            }

            if (fallbackInvoke != null)
            {
                resultMetaObject = fallbackInvoke(resultMetaObject);
            }

            DynamicMetaObject callDynamic = new DynamicMetaObject(
                Expression.Block(
                    new[] { result },
                    Expression.Condition(
                        Expression.Call(
                            Expression.Constant(_proxy),
                            typeof(DynamicProxy <T>).GetMethod(methodName),
                            callArgs
                            ),
                        resultMetaObject.Expression,
                        fallbackResult.Expression,
                        binder.ReturnType
                        )
                    ),
                GetRestrictions().Merge(resultMetaObject.Restrictions).Merge(fallbackResult.Restrictions)
                );

            return(callDynamic);
        }
コード例 #28
0
 /// <inheritdoc />
 public bool TryGetValue <T>(IPublishedProperty property, string culture, string segment, Fallback fallback, T defaultValue, out T value)
 {
     value = default;
     return(false);
 }
コード例 #29
0
        /// <summary>
        /// Helper method for generating a MetaObject which calls a
        /// specific method on Dynamic, but uses one of the arguments for
        /// the result.
        /// </summary>
        private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
        {
            //
            // First, call fallback to do default binding
            // This produces either an error or a call to a .NET member
            //
            DynamicMetaObject fallbackResult = fallback(null);

            IList <Expression> callArgs = new List <Expression>();

            callArgs.Add(Expression.Convert(Expression, typeof(T)));
            callArgs.Add(Constant(binder));
            callArgs.AddRange(args);

            //
            // Build a new expression like:
            //   if (TryDeleteMember(payload)) { } else { fallbackResult }
            //
            DynamicMetaObject callDynamic = new DynamicMetaObject(
                Expression.Condition(
                    Expression.Call(
                        Expression.Constant(_proxy),
                        typeof(DynamicProxy <T>).GetMethod(methodName),
                        callArgs
                        ),
                    Expression.Empty(),
                    fallbackResult.Expression,
                    typeof(void)
                    ),
                GetRestrictions().Merge(fallbackResult.Restrictions)
                );

            //
            // Now, call fallback again using our new MO as the error
            // When we do this, one of two things can happen:
            //   1. Binding will succeed, and it will ignore our call to
            //      the dynamic method, OR
            //   2. Binding will fail, and it will use the MO we created
            //      above.
            //
            return(_dontFallbackFirst ? callDynamic : fallback(callDynamic));
        }
コード例 #30
0
 /// <inheritdoc />
 public bool TryGetValue(IPublishedElement content, string alias, string culture, string segment, Fallback fallback, object defaultValue, out object value)
 {
     value = default;
     return(false);
 }
コード例 #31
0
        /// <inheritdoc />
        public virtual bool TryGetValue <T>(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value, out IPublishedProperty noValueProperty)
        {
            noValueProperty = default;

            var propertyType = content.ContentType.GetPropertyType(alias);

            if (propertyType != null)
            {
                _variationContextAccessor.ContextualizeVariation(propertyType.Variations, content.Id, ref culture, ref segment);
                noValueProperty = content.GetProperty(alias);
            }

            // note: we don't support "recurse & language" which would walk up the tree,
            // looking at languages at each level - should someone need it... they'll have
            // to implement it.

            foreach (var f in fallback)
            {
                switch (f)
                {
                case Fallback.None:
                    continue;

                case Fallback.DefaultValue:
                    value = defaultValue;
                    return(true);

                case Fallback.Language:
                    if (propertyType == null)
                    {
                        continue;
                    }
                    if (TryGetValueWithLanguageFallback(content, alias, culture, segment, out value))
                    {
                        return(true);
                    }
                    break;

                case Fallback.Ancestors:
                    if (TryGetValueWithAncestorsFallback(content, alias, culture, segment, out value, ref noValueProperty))
                    {
                        return(true);
                    }
                    break;

                default:
                    throw NotSupportedFallbackMethod(f, "content");
                }
            }

            value = default;
            return(false);
        }
コード例 #32
0
 /// <inheritdoc />
 public bool TryGetValue <T>(IPublishedContent content, string alias, string culture, string segment, Fallback fallback, T defaultValue, out T value)
 {
     value = default;
     return(false);
 }
コード例 #33
0
 /// <inheritdoc />
 public bool TryGetValue(IPublishedElement content, string alias, string culture, string segment, Fallback fallback, object defaultValue, out object value)
 {
     return(TryGetValue <object>(content, alias, culture, segment, fallback, defaultValue, out value));
 }
コード例 #34
0
 /// <summary>
 /// Gets the value of a content's property identified by its alias, converted to a specified type.
 /// </summary>
 /// <typeparam name="T">The target property type.</typeparam>
 /// <param name="content">The content.</param>
 /// <param name="alias">The property alias.</param>
 /// <param name="culture">The variation language.</param>
 /// <param name="segment">The variation segment.</param>
 /// <param name="fallback">Optional fallback strategy.</param>
 /// <param name="defaultValue">The default value.</param>
 /// <returns>The value of the content's property identified by the alias, converted to the specified type.</returns>
 public static T?Value <T>(this IPublishedContent content, string alias, string?culture = null, string?segment = null, Fallback fallback = default, T?defaultValue = default)
 => content.Value <T>(PublishedValueFallback, alias, culture, segment, fallback, defaultValue);
コード例 #35
0
 /// <summary>
 /// Helper method for generating a MetaObject which calls a
 /// specific method on Dynamic that returns a result
 /// </summary>
 private DynamicMetaObject CallMethodWithResult <TBinder>(string methodName, TBinder binder, Expression[] args, Fallback <TBinder> fallback)
     where TBinder : DynamicMetaObjectBinder
 {
     return(CallMethodWithResult(methodName, binder, args, fallback, null));
 }
コード例 #36
0
        /// <summary>
        /// Gets the value of a content's property identified by its alias.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="culture">The variation language.</param>
        /// <param name="segment">The variation segment.</param>
        /// <param name="fallback">Optional fallback strategy.</param>
        /// <param name="defaultValue">The default value.</param>
        /// <returns>The value of the content's property identified by the alias, if it exists, otherwise a default value.</returns>
        /// <remarks>
        /// <para>The value comes from <c>IPublishedProperty</c> field <c>Value</c> ie it is suitable for use when rendering content.</para>
        /// <para>If no property with the specified alias exists, or if the property has no value, returns <paramref name="defaultValue"/>.</para>
        /// <para>If eg a numeric property wants to default to 0 when value source is empty, this has to be done in the converter.</para>
        /// <para>The alias is case-insensitive.</para>
        /// </remarks>
        public static object Value(this IPublishedElement content, string alias, string culture = null, string segment = null, Fallback fallback = default, object defaultValue = default)
        {
            var property = content.GetProperty(alias);

            // if we have a property, and it has a value, return that value
            if (property != null && property.HasValue(culture, segment))
            {
                return(property.GetValue(culture, segment));
            }

            // else let fallback try to get a value
            if (PublishedValueFallback.TryGetValue(content, alias, culture, segment, fallback, defaultValue, out var value))
            {
                return(value);
            }

            // else... if we have a property, at least let the converter return its own
            // vision of 'no value' (could be an empty enumerable) - otherwise, default
            return(property?.GetValue(culture, segment));
        }
コード例 #37
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on DynamicObject that returns a result.
            ///
            /// args is either an array of arguments to be passed
            /// to the method as an object[] or NoArgs to signify that
            /// the target method takes no parameters.
            /// </summary>
            private DynamicMetaObject BuildCallMethodWithResult <TBinder>(string methodName, TBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback <TBinder> fallbackInvoke)
                where TBinder : DynamicMetaObjectBinder
            {
                if (!IsOverridden(methodName))
                {
                    return(fallbackResult);
                }

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
                // }
                //
                ParameterExpression             result        = Expression.Parameter(typeof(object), null);
                ParameterExpression             callArgs      = methodName != nameof(DynamicObject.TryBinaryOperation) ? Expression.Parameter(typeof(object[]), null) : Expression.Parameter(typeof(object), null);
                ReadOnlyCollection <Expression> callArgsValue = GetConvertedArgs(args);

                var resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);

                // Need to add a conversion if calling TryConvert
                if (binder.ReturnType != typeof(object))
                {
                    Debug.Assert(binder is ConvertBinder && fallbackInvoke == null);

                    UnaryExpression convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
                    // will always be a cast or unbox
                    Debug.Assert(convert.Method == null);

                    // Prepare a good exception message in case the convert will fail
                    string convertFailed = System.Linq.Expressions.Strings.DynamicObjectResultNotAssignable(
                        "{0}",
                        this.Value.GetType(),
                        binder.GetType(),
                        binder.ReturnType
                        );

                    Expression condition;
                    // If the return type can not be assigned null then just check for type assignability otherwise allow null.
                    if (binder.ReturnType.GetTypeInfo().IsValueType&& Nullable.GetUnderlyingType(binder.ReturnType) == null)
                    {
                        condition = Expression.TypeIs(resultMO.Expression, binder.ReturnType);
                    }
                    else
                    {
                        condition = Expression.OrElse(
                            Expression.Equal(resultMO.Expression, AstUtils.Null),
                            Expression.TypeIs(resultMO.Expression, binder.ReturnType));
                    }

                    Expression checkedConvert = Expression.Condition(
                        condition,
                        convert,
                        Expression.Throw(
                            Expression.New(
                                InvalidCastException_Ctor_String,
                                new TrueReadOnlyCollection <Expression>(
                                    Expression.Call(
                                        String_Format_String_ObjectArray,
                                        Expression.Constant(convertFailed),
                                        Expression.NewArrayInit(
                                            typeof(object),
                                            new TrueReadOnlyCollection <Expression>(
                                                Expression.Condition(
                                                    Expression.Equal(resultMO.Expression, AstUtils.Null),
                                                    Expression.Constant("null"),
                                                    Expression.Call(
                                                        resultMO.Expression,
                                                        Object_GetType
                                                        ),
                                                    typeof(object)
                                                    )
                                                )
                                            )
                                        )
                                    )
                                ),
                            binder.ReturnType
                            ),
                        binder.ReturnType
                        );

                    resultMO = new DynamicMetaObject(checkedConvert, resultMO.Restrictions);
                }

                if (fallbackInvoke != null)
                {
                    resultMO = fallbackInvoke(this, binder, resultMO);
                }

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new TrueReadOnlyCollection <ParameterExpression>(result, callArgs),
                        new TrueReadOnlyCollection <Expression>(
                            methodName != nameof(DynamicObject.TryBinaryOperation) ? Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)) : Expression.Assign(callArgs, callArgsValue[0]),
                            Expression.Condition(
                                Expression.Call(
                                    GetLimitedSelf(),
                                    typeof(DynamicObject).GetMethod(methodName),
                                    BuildCallArgs(
                                        binder,
                                        args,
                                        callArgs,
                                        result
                                        )
                                    ),
                                Expression.Block(
                                    methodName != nameof(DynamicObject.TryBinaryOperation) ? ReferenceArgAssign(callArgs, args) : AstUtils.Empty,
                                    resultMO.Expression
                                    ),
                                fallbackResult.Expression,
                                binder.ReturnType
                                )
                            )
                        ),
                    GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
                    );

                return(callDynamic);
            }
コード例 #38
0
 /// <summary>
 /// Helper method for generating a MetaObject which calls a
 /// specific method on Dynamic that returns a result
 /// </summary>
 private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
 {
     return(CallMethodWithResult(methodName, binder, args, fallback, null));
 }
コード例 #39
0
        public override void Read(AssetReader reader)
        {
            if (IsSerialized(reader.Version))
            {
                ReadBase(reader);

                ParsedForm.Read(reader);

                m_platforms = reader.ReadEnum32Array((t) => (GPUPlatform)t);
                uint[] offsets             = reader.ReadUInt32Array();
                uint[] compressedLengths   = reader.ReadUInt32Array();
                uint[] decompressedLengths = reader.ReadUInt32Array();
                byte[] compressedBlob      = reader.ReadByteArray();
                reader.AlignStream(AlignType.Align4);

                m_subProgramBlobs = new ShaderSubProgramBlob[m_platforms.Length];
                using (MemoryStream memStream = new MemoryStream(compressedBlob))
                {
                    for (int i = 0; i < m_platforms.Length; i++)
                    {
                        uint offset             = offsets[i];
                        uint compressedLength   = compressedLengths[i];
                        uint decompressedLength = decompressedLengths[i];

                        memStream.Position = offset;
                        byte[] decompressedBuffer = new byte[decompressedLength];
                        using (Lz4Stream lz4Stream = new Lz4Stream(memStream, (int)compressedLength))
                        {
                            int read = lz4Stream.Read(decompressedBuffer, 0, decompressedBuffer.Length);
                            if (read != decompressedLength)
                            {
                                throw new Exception($"Can't properly decode shader blob. Read {read} but expected {decompressedLength}");
                            }
                        }

                        using (MemoryStream blobMem = new MemoryStream(decompressedBuffer))
                        {
                            using (AssetReader blobReader = new AssetReader(blobMem, reader.Version, reader.Platform, reader.Flags))
                            {
                                ShaderSubProgramBlob blob = new ShaderSubProgramBlob();
                                blob.Read(blobReader);
                                m_subProgramBlobs[i] = blob;
                            }
                        }
                    }
                }
            }
            else
            {
                base.Read(reader);

                if (IsEncoded(reader.Version))
                {
                    uint decompressedSize = reader.ReadUInt32();
                    int  comressedSize    = reader.ReadInt32();

                    byte[] subProgramBlob = new byte[comressedSize];
                    reader.Read(subProgramBlob, 0, comressedSize);
                    reader.AlignStream(AlignType.Align4);

                    if (comressedSize > 0 && decompressedSize > 0)
                    {
                        byte[] decompressedBuffer = new byte[decompressedSize];
                        using (MemoryStream memStream = new MemoryStream(subProgramBlob))
                        {
                            using (Lz4Stream lz4Stream = new Lz4Stream(memStream))
                            {
                                int read = lz4Stream.Read(decompressedBuffer, 0, decompressedBuffer.Length);
                                if (read != decompressedSize)
                                {
                                    throw new Exception($"Can't properly decode sub porgram blob. Read {read} but expected {decompressedSize}");
                                }
                            }
                        }

                        using (MemoryStream memStream = new MemoryStream(decompressedBuffer))
                        {
                            using (AssetReader blobReader = new AssetReader(memStream, reader.Version, reader.Platform, reader.Flags))
                            {
                                SubProgramBlob.Read(blobReader);
                            }
                        }
                    }
                }

                if (IsReadFallback(reader.Version))
                {
                    Fallback.Read(reader);
                }
                if (IsReadDefaultProperties(reader.Version))
                {
                    DefaultProperties.Read(reader);
                }
                if (IsReadStaticProperties(reader.Version))
                {
                    StaticProperties.Read(reader);
                }
            }

            if (IsReadDependencies(reader.Version))
            {
                m_dependencies = reader.ReadArray <PPtr <Shader> >();
            }
            if (IsReadNonModifiableTextures(reader.Version))
            {
                m_nonModifiableTextures = reader.ReadArray <PPtr <Texture> >();
            }
            if (IsReadShaderIsBaked(reader.Version))
            {
                ShaderIsBaked = reader.ReadBoolean();
                reader.AlignStream(AlignType.Align4);
            }
        }
コード例 #40
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on DynamicObject that returns a result.
            ///
            /// args is either an array of arguments to be passed
            /// to the method as an object[] or NoArgs to signify that
            /// the target method takes no parameters.
            /// </summary>
            private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke)
            {
                if (!IsOverridden(methodName))
                {
                    return(fallbackResult);
                }

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
                // }
                //
                var result = Expression.Parameter(typeof(object), null);
                ParameterExpression callArgs = methodName != "TryBinaryOperation" ? Expression.Parameter(typeof(object[]), null) : Expression.Parameter(typeof(object), null);
                var callArgsValue            = GetConvertedArgs(args);

                var resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);

                // Need to add a conversion if calling TryConvert
                if (binder.ReturnType != typeof(object))
                {
                    Debug.Assert(binder is ConvertBinder && fallbackInvoke == null);

                    var convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
                    // will always be a cast or unbox
                    Debug.Assert(convert.Method == null);

                    // Prepare a good exception message in case the convert will fail
                    string convertFailed = Strings.DynamicObjectResultNotAssignable(
                        "{0}",
                        this.Value.GetType(),
                        binder.GetType(),
                        binder.ReturnType
                        );

                    var checkedConvert = Expression.Condition(
                        Expression.TypeIs(resultMO.Expression, binder.ReturnType),
                        convert,
                        Expression.Throw(
                            Expression.New(typeof(InvalidCastException).GetConstructor(new Type[] { typeof(string) }),
                                           Expression.Call(
                                               typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) }),
                                               Expression.Constant(convertFailed),
                                               Expression.Condition(
                                                   Expression.Equal(resultMO.Expression, Expression.Constant(null)),
                                                   Expression.Constant("null"),
                                                   Expression.Call(
                                                       resultMO.Expression,
                                                       typeof(object).GetMethod("GetType")
                                                       ),
                                                   typeof(object)
                                                   )
                                               )
                                           ),
                            binder.ReturnType
                            ),
                        binder.ReturnType
                        );

                    resultMO = new DynamicMetaObject(checkedConvert, resultMO.Restrictions);
                }

                if (fallbackInvoke != null)
                {
                    resultMO = fallbackInvoke(resultMO);
                }

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { result, callArgs },
                        methodName != "TryBinaryOperation" ? Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)) : Expression.Assign(callArgs, callArgsValue[0]),
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                BuildCallArgs(
                                    binder,
                                    args,
                                    callArgs,
                                    result
                                    )
                                ),
                            Expression.Block(
                                methodName != "TryBinaryOperation" ? ReferenceArgAssign(callArgs, args) : Expression.Empty(),
                                resultMO.Expression
                                ),
                            fallbackResult.Expression,
                            binder.ReturnType
                            )
                        ),
                    GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
                    );

                return(callDynamic);
            }
コード例 #41
0
        public static T Value <T>(this IPublishedProperty property, string culture = null, string segment = null, Fallback fallback = default, T defaultValue = default)
        {
            if (property.HasValue(culture, segment))
            {
                // we have a value
                // try to cast or convert it
                var value = property.GetValue(culture, segment);
                if (value is T valueAsT)
                {
                    return(valueAsT);
                }

                var valueConverted = value.TryConvertTo <T>();
                if (valueConverted)
                {
                    return(valueConverted.Result);
                }

                // cannot cast nor convert the value, nothing we can return but 'default'
                // note: we don't want to fallback in that case - would make little sense
                return(default);
コード例 #42
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic, but uses one of the arguments for
            /// the result.
            ///
            /// args is either an array of arguments to be passed
            /// to the method as an object[] or NoArgs to signify that
            /// the target method takes no parameters.
            /// </summary>
            private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Expression value, Fallback fallback)
            {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(null);

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TrySetMember(payload, result = value) ? result : fallbackResult
                // }
                //

                var result        = Expression.Parameter(typeof(object), null);
                var callArgs      = Expression.Parameter(typeof(object[]), null);
                var callArgsValue = GetConvertedArgs(args);

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { result, callArgs },
                        Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)),
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                BuildCallArgs(
                                    binder,
                                    args,
                                    callArgs,
                                    Expression.Assign(result, Expression.Convert(value, typeof(object)))
                                    )
                                ),
                            Expression.Block(
                                ReferenceArgAssign(callArgs, args),
                                result
                                ),
                            fallbackResult.Expression,
                            typeof(object)
                            )
                        ),
                    GetRestrictions().Merge(fallbackResult.Restrictions)
                    );

                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return(fallback(callDynamic));
            }
コード例 #43
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic that returns a result
            /// </summary>
            private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke) {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(null);

                var callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke);
                
                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return fallback(callDynamic);
            }
コード例 #44
0
        /// <summary>
        /// Helper method for generating a MetaObject which calls a
        /// specific method on Dynamic that returns a result
        /// </summary>
        private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, IEnumerable <Expression> args, Fallback fallback, Fallback fallbackInvoke = null)
        {
            //
            // First, call fallback to do default binding
            // This produces either an error or a call to a .NET member
            //
            DynamicMetaObject fallbackResult = fallback(null);

            return(BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke));
        }
コード例 #45
0
            /// <summary>
            /// Helper method for generating a MetaObject which calls a
            /// specific method on Dynamic, but uses one of the arguments for
            /// the result.
            /// 
            /// args is either an array of arguments to be passed
            /// to the method as an object[] or NoArgs to signify that
            /// the target method takes no parameters.
            /// </summary>
            private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) {
                //
                // First, call fallback to do default binding
                // This produces either an error or a call to a .NET member
                //
                DynamicMetaObject fallbackResult = fallback(null);
                var callArgs = Expression.Parameter(typeof(object[]), null);
                var callArgsValue = GetConvertedArgs(args);

                //
                // Build a new expression like:
                //   if (TryDeleteMember(payload)) { } else { fallbackResult }
                //
                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { callArgs },
                        Expression.Assign(callArgs, Expression.NewArrayInit(typeof(object), callArgsValue)),
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                BuildCallArgs(
                                    binder,
                                    args,
                                    callArgs,
                                    null
                                )
                            ),
                            Expression.Block(
                                ReferenceArgAssign(callArgs, args),
                                Expression.Empty()
                            ),
                            fallbackResult.Expression,
                            typeof(void)
                        )
                    ),
                    GetRestrictions().Merge(fallbackResult.Restrictions)
                );

                //
                // Now, call fallback again using our new MO as the error
                // When we do this, one of two things can happen:
                //   1. Binding will succeed, and it will ignore our call to
                //      the dynamic method, OR
                //   2. Binding will fail, and it will use the MO we created
                //      above.
                //
                return fallback(callDynamic);
            }
コード例 #46
0
ファイル: DynamicObject.cs プロジェクト: madpilot/ironruby
            private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke) {
                if (!IsOverridden(methodName)) {
                    return fallbackResult;
                }

                //
                // Build a new expression like:
                // {
                //   object result;
                //   TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult
                // }
                //
                var result = Expression.Parameter(typeof(object), null);

                var callArgs = new Expression[args.Length + 2];
                Array.Copy(args, 0, callArgs, 1, args.Length);
                callArgs[0] = Constant(binder);
                callArgs[callArgs.Length - 1] = result;

                var resultMO = new DynamicMetaObject(result, BindingRestrictions.Empty);

                // Need to add a conversion if calling TryConvert
                if (binder.ReturnType != typeof(object)) {
                    Debug.Assert(binder is ConvertBinder && fallbackInvoke == null);

                    var convert = Expression.Convert(resultMO.Expression, binder.ReturnType);
                    // will always be a cast or unbox
                    Debug.Assert(convert.Method == null);

                    resultMO = new DynamicMetaObject(convert, resultMO.Restrictions);
                }

                if (fallbackInvoke != null) {
                    resultMO = fallbackInvoke(resultMO);
                }

                var callDynamic = new DynamicMetaObject(
                    Expression.Block(
                        new[] { result },
                        Expression.Condition(
                            Expression.Call(
                                GetLimitedSelf(),
                                typeof(DynamicObject).GetMethod(methodName),
                                callArgs
                            ),
                            resultMO.Expression,
                            fallbackResult.Expression,
                            binder.ReturnType
                        )
                    ),
                    GetRestrictions().Merge(resultMO.Restrictions).Merge(fallbackResult.Restrictions)
                );
                return callDynamic;
            }