Exemple #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));
 }
        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
        }
Exemple #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));
        }
            /// <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;
            }
Exemple #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)
                       ));
        }
Exemple #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));
            }
Exemple #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"
        }
 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);
 }
 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);
 }
 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));
 }
 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);
 }
            /// <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);
            }
            /// <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);
            }
            /// <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);
            }
Exemple #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));
 }
Exemple #16
0
 public static DynamicMetaObject/*!*/ Bind(DynamicMetaObject/*!*/ context, CreateInstanceBinder/*!*/ binder, DynamicMetaObject/*!*/ target,
     DynamicMetaObject/*!*/[]/*!*/ args, Fallback/*!*/ fallback) {
     return Bind(context, "new", binder.CallInfo, binder, target, args, fallback);
 }
Exemple #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);
        }
Exemple #18
0
 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);
 }
Exemple #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));
            }
Exemple #20
0
            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);
            }
 /// <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);
 }
Exemple #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);
 }
 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;
 }
 private IEnumerable <VideoInfoResponse.StreamInfo> GetAdaptiveStreams() => Fallback.ToEmpty(
     _root
     .GetProperty("args")
     .GetPropertyOrNull("adaptive_fmts")?
     .GetString()?
     .Split(",")
     .Select(Url.SplitQuery)
     .Select(d => new VideoInfoResponse.StreamInfo(d))
     );
Exemple #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)
                       ));
        }
Exemple #26
0
        public void TestFallback()
        {
            var fallback = new Fallback();

            Assert.That(fallback.GetDisplayString(), Is.EqualTo("fallback"));
        }
Exemple #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);
        }
Exemple #28
0
 /// <inheritdoc />
 public bool TryGetValue <T>(IPublishedProperty property, string culture, string segment, Fallback fallback, T defaultValue, out T value)
 {
     value = default;
     return(false);
 }
Exemple #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));
        }
Exemple #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);
 }
Exemple #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);
        }
Exemple #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);
 }
Exemple #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));
 }
 /// <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);
Exemple #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));
 }
        /// <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));
        }
Exemple #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);
            }
Exemple #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));
 }
Exemple #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);
            }
        }
Exemple #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);
            }
Exemple #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);
Exemple #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));
            }
            /// <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);
            }
Exemple #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));
        }
            /// <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);
            }
Exemple #46
0
            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;
            }