protected virtual MethodDefinitionExpression CreateNormalizeRequestObjectMethod(Type forType, string format)
        {
            var requestObject = Expression.Parameter(FickleType.Define("id"), "serializeRequest");
            var paramName     = Expression.Parameter(typeof(string), "paramName");
            var newArray      = FickleExpression.Variable("NSMutableArray", "newArray");
            var name          = this.GetNormalizeRequestMethodName(forType, format);
            var value         = FickleExpression.Variable("id", "value");
            var item          = Expression.Variable(FickleType.Define("id"), "item");
            var formatIsForm  = format == "form";

            var complexType = ((forType as FickleType)?.ServiceClass != null);

            Expression processing;

            if (forType == typeof(TimeSpan))
            {
                processing = FickleExpression.Call(Expression.Convert(item, typeof(TimeSpan)), typeof(string), "ToString", null);
            }
            else if (forType == typeof(Guid))
            {
                processing = FickleExpression.Call(Expression.Convert(item, typeof(Guid)), typeof(string), "ToString", null);
            }
            else if (forType.IsEnum)
            {
                processing = Expression.Convert(FickleExpression.Call(item, typeof(int), "intValue", null), forType);

                if (this.CodeGenerationContext.Options.SerializeEnumsAsStrings)
                {
                    processing = FickleExpression.StaticCall((Type)null, typeof(string), forType.Name + "ToString", processing);
                }
                else
                {
                    processing = Expression.Convert(processing, typeof(object));
                }
            }
            else if (forType == typeof(bool))
            {
                processing = Expression.Condition
                             (
                    Expression.Equal(FickleExpression.Call(item, typeof(bool), "boolValue", null), Expression.Constant(true)),
                    Expression.Constant("true"),
                    Expression.Constant("false")
                             );
            }
            else if (forType.IsNumericType())
            {
                processing = Expression.Convert(item, FickleType.Define("NSNumber"));

                if (formatIsForm)
                {
                    processing = FickleExpression.Call(processing, "stringValue", null);
                }
            }
            else
            {
                if (formatIsForm)
                {
                    processing = FickleExpression.Call(item, "NSDictionary", "scalarPropertiesAsFormEncodedString", null);
                }
                else
                {
                    processing = FickleExpression.Call(item, "NSString", "allPropertiesAsDictionary", null);
                }
            }

            var isArray         = Expression.Variable(typeof(bool), "isArray");
            var array           = Expression.Variable(FickleType.Define("NSArray"), "array");
            var urlEncodedValue = ObjectiveExpression.ToUrlEncodedExpression(processing);
            var joined          = FickleExpression.Call(newArray, typeof(string), "componentsJoinedByString", Expression.Constant("&"));

            if (formatIsForm && !complexType)
            {
                processing = FickleExpression.Call(FickleExpression.Call(paramName, "stringByAppendingString", Expression.Constant("=")), typeof(string), "stringByAppendingString", urlEncodedValue);
            }

            var arrayProcessing = processing;

            if (formatIsForm)
            {
                arrayProcessing = FickleExpression.Call(FickleExpression.Call(paramName, "stringByAppendingString", Expression.Constant("=")), typeof(string), "stringByAppendingString", urlEncodedValue);
            }

            processing = Expression.IfThenElse
                         (
                isArray,
                FickleExpression.Block
                (
                    new [] { newArray },
                    Expression.Assign(array, requestObject),
                    Expression.Assign(newArray, FickleExpression.New("NSMutableArray", "initWithCapacity", FickleExpression.Call(array, typeof(int), "count", null))),
                    FickleExpression.ForEach
                    (
                        item,
                        array,
                        FickleExpression.Call(newArray, typeof(void), "addObject", arrayProcessing).ToStatementBlock()
                    ),
                    Expression.Assign(value, formatIsForm ? joined : (Expression)newArray),
                    FickleExpression.Return(value)
                ),
                FickleExpression.Block
                (
                    new [] { item },
                    Expression.Assign(item, requestObject),
                    Expression.Assign(value, processing),
                    FickleExpression.Return(value)
                )
                         );

            var body = FickleExpression.Block
                       (
                new[] { array, isArray, value },
                Expression.Assign(isArray, Expression.TypeIs(requestObject, typeof(Array))),
                processing
                       );

            return(new MethodDefinitionExpression
                   (
                       name,
                       new[] { requestObject, paramName }.ToReadOnlyCollection(),
                       FickleType.Define("id"),
                       body,
                       false,
                       null
                   ));
        }
Example #2
0
        public static ObjectiveStringFormatInfo GetObjectiveStringFormatInfo(string path, Func <string, Expression> valueByKey, Func <string, Type, string> transformFormatSpecifier = null, Func <Expression, Expression> transformStringArg = null)
        {
            var args       = new List <Expression>();
            var parameters = new List <ParameterExpression>();

            if (transformFormatSpecifier == null)
            {
                transformFormatSpecifier = (s, t) => s;
            }

            var format = tempateStringRegex.Replace(path, delegate(Match match)
            {
                var name = match.Groups[1].Value;

                var parameter = valueByKey(name);
                var type      = parameter.Type;

                if (type == typeof(byte) || type == typeof(short) || type == typeof(int))
                {
                    parameters.Add(Expression.Parameter(parameter.Type, name));
                    args.Add(parameter);

                    return(transformFormatSpecifier("%d", type));
                }
                else if (type == typeof(long))
                {
                    parameters.Add(Expression.Parameter(parameter.Type, name));
                    args.Add(parameter);

                    return("%lld");
                }
                else if (type == typeof(float) || type == typeof(double))
                {
                    parameters.Add(Expression.Parameter(parameter.Type, name));
                    args.Add(parameter);

                    return(transformFormatSpecifier("%f", type));
                }
                else if (type == typeof(char))
                {
                    parameters.Add(Expression.Parameter(parameter.Type, name));
                    args.Add(parameter);

                    return(transformFormatSpecifier("%C", type));
                }
                else if (type == typeof(int))
                {
                    parameters.Add(Expression.Parameter(parameter.Type, name));
                    args.Add(parameter);

                    return(transformFormatSpecifier("%d", type));
                }
                else if (type == typeof(Guid))
                {
                    parameters.Add(Expression.Parameter(typeof(string), name));
                    var arg = FickleExpression.Call(parameter, typeof(string), "ToString", null);

                    args.Add(Expression.Condition(Expression.Equal(Expression.Convert(parameter, type.MakeNullable()), Expression.Constant(null)), Expression.Constant(""), arg));

                    return(transformFormatSpecifier("%@", typeof(string)));
                }
                else
                {
                    parameters.Add(Expression.Parameter(typeof(string), name));
                    var originalArg = (Expression)FickleExpression.Call(parameter, typeof(string), "ToString", null);

                    var arg = ObjectiveExpression.ToUrlEncodedExpression(originalArg);

                    if (transformStringArg != null)
                    {
                        arg = transformStringArg(arg);
                    }

                    if (type.IsNullable() || !type.IsValueType)
                    {
                        args.Add(Expression.Condition(Expression.Equal(parameter, Expression.Constant(null, type)), Expression.Constant(""), arg));
                    }
                    else
                    {
                        args.Add(arg);
                    }

                    return(transformFormatSpecifier("%@", typeof(string)));
                }
            });

            return(new ObjectiveStringFormatInfo(format, args, parameters));
        }