private CSharpGatewayExpressionBinder(CodeGenerationContext codeGenerationContext)
        {
            this.CodeGenerationContext = codeGenerationContext;

            this.httpClientType = FickleType.Define(this.CodeGenerationContext.Options.ServiceClientTypeName ?? "HttpClient");
            this.httpStreamSerializerType = FickleType.Define("IHttpStreamSerializer");
        }
        protected virtual MethodDefinitionExpression CreateCreateErrorResponseWithErrorCodeMethod()
        {
            var client    = Expression.Parameter(FickleType.Define("PKWebServiceClient"), "client");
            var errorCode = Expression.Parameter(typeof(string), "createErrorResponseWithErrorCode");
            var message   = Expression.Parameter(typeof(string), "andMessage");

            var parameters = new Expression[]
            {
                client,
                errorCode,
                message
            };

            var clientOptions     = FickleExpression.Property(client, FickleType.Define("NSDictionary"), "options");
            var response          = FickleExpression.Variable(FickleType.Define("id"), "response");
            var responseClass     = FickleExpression.Call(clientOptions, "Class", "objectForKey", "$ResponseClass");
            var responseStatus    = FickleExpression.Call(response, "ResponseStatus", "responseStatus", null);
            var newResponseStatus = FickleExpression.New("ResponseStatus", "init", null);

            var body = FickleExpression.Block
                       (
                new [] { response },
                Expression.Assign(response, FickleExpression.Call(FickleExpression.Call(responseClass, response.Type, "alloc", null), response.Type, "init", null)),
                Expression.IfThen(Expression.IsTrue(Expression.Equal(responseStatus, Expression.Constant(null, responseStatus.Type))), FickleExpression.Block(FickleExpression.Call(response, "setResponseStatus", newResponseStatus))),
                FickleExpression.StatementisedGroupedExpression
                (
                    FickleExpression.Call(responseStatus, typeof(string), "setErrorCode", errorCode),
                    FickleExpression.Call(responseStatus, typeof(string), "setMessage", message)
                ),
                Expression.Return(Expression.Label(), response)
                       );

            return(new MethodDefinitionExpression("webServiceClient", parameters.ToReadOnlyCollection(), FickleType.Define("id"), body, false, null));
        }
        protected virtual MethodDefinitionExpression CreateSerializeRequestMethod()
        {
            var error         = FickleExpression.Variable("NSError", "error");
            var retval        = FickleExpression.Variable("NSData", "retval");
            var client        = Expression.Parameter(FickleType.Define("PKWebServiceClient"), "client");
            var requestObject = Expression.Parameter(FickleType.Define("id"), "serializeRequest");
            var parameters    = new[] { new FickleParameterInfo(FickleType.Define("NSDictionary"), "obj"), new FickleParameterInfo(FickleType.Define("NSJSONWritingOptions", false, true), "options"), new FickleParameterInfo(FickleType.Define("NSError"), "error", true) };
            var methodInfo    = new FickleMethodInfo(FickleType.Define("NSJSONSerialization"), FickleType.Define("NSData"), "dataWithJSONObject", parameters, true);
            var nsDataType    = FickleType.Define("NSData");

            var body =
                Fx.Block(error, retval)
                .If(Expression.Equal(requestObject, Expression.Constant(null, requestObject.Type)))
                .Assign(retval, Expression.New(FickleType.Define("NSData")))
                .ElseIf(Expression.TypeIs(requestObject, typeof(string)))
                .Assign(retval, FickleExpression.Call(requestObject, typeof(string), "dataUsingEncoding", Expression.Variable(typeof(int), "NSUTF8StringEncoding")))
                .ElseIf(Expression.TypeIs(requestObject, nsDataType))
                .Assign(retval, Expression.Convert(requestObject, nsDataType))
                .Else()
                .Assign(retval, Expression.Call(methodInfo, requestObject, Expression.Convert(Expression.Variable(typeof(int), "NSJSONReadingAllowFragments"), FickleType.Define("NSJSONWritingOptions", false, true)), error))
                .EndIf()
                .Return(retval)
                .EndBlock();

            return(new MethodDefinitionExpression
                   (
                       "webServiceClient",
                       new [] { client, requestObject }.ToReadOnlyCollection(),
                       retval.Type,
                       body,
                       false,
                       null
                   ));
        }
        protected virtual MethodDefinitionExpression CreateCreateClientMethod()
        {
            var client         = Expression.Variable(FickleType.Define("PKWebServiceClient"), "client");
            var self           = FickleExpression.Variable(currentType, "self");
            var options        = FickleExpression.Parameter(FickleType.Define("NSDictionary"), "options");
            var url            = Expression.Parameter(typeof(string), "urlIn");
            var parameters     = new Expression[] { url, options };
            var operationQueue = FickleExpression.Call(options, "objectForKey", "OperationQueue");

            var variables = new [] { client };

            var body = FickleExpression.Block
                       (
                variables,
                Expression.Assign(client, FickleExpression.StaticCall("PKWebServiceClient", "PKWebServiceClient", "clientWithURL", new
            {
                url     = FickleExpression.New("NSURL", "initWithString", url),
                options = options,
                operationQueue
            })),
                Expression.Return(Expression.Label(), client)
                       );

            return(new MethodDefinitionExpression("createClientWithURL", parameters.ToReadOnlyCollection(), FickleType.Define("PKWebServiceClient"), body, false, null));
        }
Ejemplo n.º 5
0
        private Expression CreateDeserialiseStreamMethod()
        {
            var inputStream = Expression.Parameter(FickleType.Define("InputStream"), "in");

            var jsonReaderType = FickleType.Define("JsonReader");
            var jsonReader     = Expression.Variable(jsonReaderType, "reader");
            var result         = Expression.Variable(currentType, "result");

            var inputStreamReaderNew = FickleExpression.New(FickleType.Define("InputStreamReader"), "InputStreamReader", inputStream);

            var jsonReaderNew        = FickleExpression.New(jsonReaderType, "JsonReader", inputStreamReaderNew);
            var jsonReaderNextString = FickleExpression.Call(jsonReader, "nextString", null);
            var resultCreate         = Expression.Assign(result, FickleExpression.StaticCall(currentType, currentType, "deserialize", jsonReaderNextString)).ToStatement();

            var jsonReaderClose = FickleExpression.Call(jsonReader, "close", null).ToStatement();

            var exception          = Expression.Variable(typeof(Exception), "exception");;
            var errorCodesVariable = Expression.Constant("DeserializationError", typeof(String));

            var returnResult = FickleExpression.Return(result);

            var createErrorArguments = new
            {
                errorCode    = errorCodesVariable,
                errorMessage = FickleExpression.Call(exception, "getMessage", null),
                stackTrace   = FickleExpression.StaticCall(FickleType.Define("Log"), typeof(String), "getStackTraceString", exception),
            };

            var resultCreateErrorResponse = Expression.Assign(result, FickleExpression.StaticCall(currentType, currentType, "createErrorResponse", createErrorArguments)).ToStatement();

            var tryCatch = Expression.TryCatchFinally(
                resultCreate,
                jsonReaderClose,
                Expression.Catch(typeof(Exception), resultCreateErrorResponse));

            var methodVariables = new List <ParameterExpression>
            {
                result,
                jsonReader
            };

            var methodStatements = new List <Expression>
            {
                Expression.Assign(jsonReader, jsonReaderNew).ToStatement(),
                tryCatch,
                returnResult
            };

            var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray());

            return(new MethodDefinitionExpression("deserialize", new List <Expression>()
            {
                inputStream
            }, AccessModifiers.Public | AccessModifiers.Static, currentType, body, false, null, null, new List <Exception>()
            {
                new Exception()
            }));
        }
Ejemplo n.º 6
0
        public static Expression ToUrlEncodedExpression(Expression value)
        {
            var cfstring      = FickleType.Define("CFStringRef", isPrimitive: true);
            var charsToEncode = Expression.Convert(Expression.Constant("!*'\\\"();:@&= +$,/?%#[]% "), cfstring);

            var retval = Expression.Convert(FickleExpression.StaticCall((Type)null, cfstring, "CFURLCreateStringByAddingPercentEscapes", new { arg1 = (object)null, arg2 = Expression.Convert(value, cfstring), arg3 = (object)null, arg4 = charsToEncode, arg5 = Expression.Variable(typeof(int), "kCFStringEncodingUTF8") }), typeof(string));

            return(retval);
        }
        protected virtual MethodDefinitionExpression CreateParseResultMethod()
        {
            var client      = Expression.Parameter(FickleType.Define("PKWebServiceClient"), "client");
            var data        = Expression.Parameter(FickleType.Define("NSData"), "parseResult");
            var contentType = Expression.Parameter(typeof(string), "withContentType");
            var statusCode  = Expression.Parameter(typeof(int), "andStatusCode");
            var response    = FickleExpression.Variable("id", "response");
            var options     = FickleExpression.Property(client, "NSDictionary", "options");

            var parameters = new Expression[]
            {
                client,
                data,
                contentType,
                statusCode
            };

            var bodyExpressions = new List <Expression>();
            var delegateType    = new FickleDelegateType(FickleType.Define("id"), new FickleParameterInfo(client.Type, "client"), new FickleParameterInfo(FickleType.Define("NSData"), "data"));
            var block           = Expression.Variable(delegateType, "block");

            bodyExpressions.Add(Expression.Assign(block, FickleExpression.Call(options, FickleType.Define("id"), "objectForKey", Expression.Constant("$ParseResultBlock"))));
            bodyExpressions.Add(Expression.Assign(response, FickleExpression.Call(block, "id", "Invoke", new { client, data })).ToStatement());

            var setResponseStatus = Expression.IfThen
                                    (
                Expression.Equal(FickleExpression.Call(response, "id", "responseStatus", null), Expression.Constant(null, FickleType.Define("id"))),
                FickleExpression.Call(response, "setResponseStatus", FickleExpression.New("ResponseStatus", "init", null)).ToStatementBlock()
                                    );

            var populateResponseStatus = FickleExpression.Call(FickleExpression.Call(response, "id", "responseStatus", null), "setHttpStatus", statusCode);

            bodyExpressions.Add(setResponseStatus);
            bodyExpressions.Add(populateResponseStatus);
            bodyExpressions.Add(FickleExpression.Return(response));

            var body = FickleExpression.Block
                       (
                new[] { response, block },
                bodyExpressions.ToArray()
                       );

            return(new MethodDefinitionExpression
                   (
                       "webServiceClient",
                       parameters.ToReadOnlyCollection(),
                       FickleType.Define("id"),
                       body,
                       false,
                       null
                   ));
        }
Ejemplo n.º 8
0
        private Expression CreateSerializeMethod()
        {
            var self = Expression.Parameter(currentType, "this");

            var jsonBuilder = FickleType.Define("DefaultJsonBuilder");

            var jsonBuilderInstance = FickleExpression.StaticCall(jsonBuilder, "instance");

            var toJsonCall = FickleExpression.Call(jsonBuilderInstance, "toJson", self);

            var defaultBody = Expression.Return(Expression.Label(), toJsonCall).ToStatement();

            var body = FickleExpression.Block(defaultBody);

            return(new MethodDefinitionExpression("serialize", new List <Expression>(), AccessModifiers.Public, typeof(string), body, false, null));
        }
Ejemplo n.º 9
0
        private Expression CreateDeserializeReaderMethod()
        {
            var jsonReader = Expression.Parameter(FickleType.Define("JsonReader"), "reader");

            var conditionNull = Expression.MakeBinary(ExpressionType.Equal, FickleExpression.Call(jsonReader, typeof(Enum), "peek", null),
                                                      FickleExpression.Variable(typeof(Enum), "JsonToken.NULL"));

            var actionNull = FickleExpression.Block(
                new Expression[]
            {
                FickleExpression.Call(jsonReader, "skipValue", null),
                Expression.Continue(Expression.Label())
            });

            var self = FickleExpression.Variable(currentType, "this");

            var whileStatements = new List <Expression>
            {
                Expression.IfThen(conditionNull, actionNull),
                FickleExpression.Call(self, "deserializeElement", jsonReader)
            };

            var whileBody = FickleExpression.Block(whileStatements.ToArray());

            var whileExpression = FickleExpression.While(FickleExpression.Call(jsonReader, "hasNext", null), whileBody);

            var methodVariables = new List <ParameterExpression>();

            var methodStatements = new List <Expression>
            {
                FickleExpression.Call(jsonReader, "beginObject", null),
                whileExpression,
                FickleExpression.Call(jsonReader, "endObject", null),
            };

            var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray());

            return(new MethodDefinitionExpression("deserialize", new List <Expression>()
            {
                jsonReader
            }, AccessModifiers.Public, typeof(void), body, false, null, null, new List <Exception>()
            {
                new Exception()
            }));
        }
Ejemplo n.º 10
0
        private Expression CreateAllPropertiesAsDictionaryMethod(TypeDefinitionExpression expression)
        {
            var dictionaryType   = new FickleType("NSMutableDictionary");
            var retvalExpression = Expression.Parameter(dictionaryType, "retval");

            IEnumerable <ParameterExpression> variables = new[]
            {
                retvalExpression
            };

            var newDictionaryExpression    = Expression.Assign(retvalExpression, FickleExpression.New("NSMutableDictionary", "initWithCapacity", ExpressionTypeCounter.Count(expression, (ExpressionType)ServiceExpressionType.PropertyDefinition) * 2)).ToStatement();
            var makeDictionaryExpression   = PropertiesToDictionaryExpressionBinder.Build(expression, this.codeGenerationContext);
            var returnDictionaryExpression = Expression.Return(Expression.Label(), Expression.Parameter(dictionaryType, "retval")).ToStatement();

            var methodBody = Expression.Block(variables, GroupedExpressionsExpression.FlatConcat(GroupedExpressionsExpressionStyle.Wide, newDictionaryExpression, makeDictionaryExpression, returnDictionaryExpression));

            return(new MethodDefinitionExpression("allPropertiesAsDictionary", new List <Expression>().ToReadOnlyCollection(), dictionaryType, methodBody, false, null));
        }
        protected override Expression VisitPropertyDefinitionExpression(PropertyDefinitionExpression property)
        {
            var dictionaryType             = new FickleType("NSDictionary");
            var currentValueFromDictionary = Expression.Parameter(typeof(object), "currentValueFromDictionary");
            var objectForKeyCall           = Expression.Call(Expression.Parameter(dictionaryType, "properties"), new FickleMethodInfo(dictionaryType, typeof(object), "objectForKey", new ParameterInfo[] { new FickleParameterInfo(typeof(string), "key") }), Expression.Constant(property.PropertyName));
            var propertyExpression         = Expression.Property(Expression.Parameter(this.type, "self"), new FicklePropertyInfo(this.type, property.PropertyType, property.PropertyName));

            var expressions = new List <Expression>
            {
                FickleExpression.Comment(property.PropertyName),
                Expression.Assign(currentValueFromDictionary, objectForKeyCall).ToStatement(),
                GetDeserializeExpressionProcessValueDeserializer(property.PropertyType, currentValueFromDictionary, c => Expression.Assign(propertyExpression, c).ToStatement())
            };

            this.propertyGetterExpressions.Add(expressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide));

            return(property);
        }
Ejemplo n.º 12
0
        private Expression CreateAllPropertiesAsDictionaryMethod(TypeDefinitionExpression expression)
        {
            var dictionaryType = new FickleType("NSMutableDictionary");
            var retvalExpression = Expression.Parameter(dictionaryType, "retval");

            IEnumerable<ParameterExpression> variables = new[]
            {
                retvalExpression
            };

            var newDictionaryExpression = Expression.Assign(retvalExpression, FickleExpression.New("NSMutableDictionary", "initWithCapacity", ExpressionTypeCounter.Count(expression, (ExpressionType)ServiceExpressionType.PropertyDefinition) * 2)).ToStatement();
            var makeDictionaryExpression = PropertiesToDictionaryExpressionBinder.Build(expression, this.codeGenerationContext);
            var returnDictionaryExpression = Expression.Return(Expression.Label(), Expression.Parameter(dictionaryType, "retval")).ToStatement();

            var methodBody = Expression.Block(variables, GroupedExpressionsExpression.FlatConcat(GroupedExpressionsExpressionStyle.Wide, newDictionaryExpression, makeDictionaryExpression, returnDictionaryExpression));

            return new MethodDefinitionExpression("allPropertiesAsDictionary", new List<Expression>().ToReadOnlyCollection(), dictionaryType, methodBody, false, null);
        }
Ejemplo n.º 13
0
        private MethodDefinitionExpression CreateInitMethod(TypeDefinitionExpression expression)
        {
            var        type = expression.Type;
            Expression superInitExpression;

            var parameters = new List <Expression>
            {
                Expression.Parameter(new FickleType("NSDictionary"), "properties")
            };

            var methodBodyExpressions = new List <Expression>();

            if (type.BaseType.IsServiceType())
            {
                superInitExpression = Expression.Call(Expression.Parameter(type.BaseType, "super"), new FickleMethodInfo(type.BaseType, type, "initWithPropertyDictionary", new [] { new FickleParameterInfo(parameters[0].Type, "dictionary") }), parameters[0]);
            }
            else
            {
                superInitExpression = Expression.Call(Expression.Parameter(type.BaseType, "super"), new FickleMethodInfo(type.BaseType, type, "init", new ParameterInfo[0]));
            }

            var assignExpression        = Expression.Assign(Expression.Parameter(type, "self"), superInitExpression);
            var compareToNullExpression = Expression.ReferenceEqual(assignExpression, Expression.Constant(null, type));
            int count;

            methodBodyExpressions.Add(Expression.IfThen(compareToNullExpression, Expression.Block(Expression.Return(Expression.Label(), Expression.Constant(null)).ToStatement())));
            methodBodyExpressions.Add(PropertiesFromDictionaryExpressonBinder.Bind(expression, out count));
            methodBodyExpressions.Add(Expression.Return(Expression.Label(), Expression.Parameter(type, "self")).ToStatement());

            IEnumerable <ParameterExpression> variables;

            if (count > 0)
            {
                variables = new[] { Expression.Parameter(FickleType.Define("id"), "currentValueFromDictionary") };
            }
            else
            {
                variables = new ParameterExpression[0];
            }

            var methodBody = Expression.Block(variables, (Expression)methodBodyExpressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide));

            return(new MethodDefinitionExpression("initWithPropertyDictionary", parameters.ToReadOnlyCollection(), typeof(object), methodBody, false, null));
        }
Ejemplo n.º 14
0
        public static Expression CreateSerializeArrayMethod(Type arrayType)
        {
            var array = Expression.Parameter(new FickleListType(arrayType), "array");

            var jsonBuilder = FickleType.Define("DefaultJsonBuilder");

            var jsonBuilderInstance = FickleExpression.StaticCall(jsonBuilder, "instance");

            var toJsonCall = FickleExpression.Call(jsonBuilderInstance, "toJson", array);

            var defaultBody = Expression.Return(Expression.Label(), toJsonCall).ToStatement();

            var body = FickleExpression.Block(defaultBody);

            return(new MethodDefinitionExpression("serializeArray", new List <Expression>()
            {
                array
            }, AccessModifiers.Public | AccessModifiers.Static, typeof(string), body, false, null));
        }
Ejemplo n.º 15
0
        protected virtual MethodDefinitionExpression CreateCreateErrorResponseMethod()
        {
            var errorCode  = Expression.Parameter(typeof(string), "errorCode");
            var message    = Expression.Parameter(typeof(string), "errorMessage");
            var stackTrace = Expression.Parameter(typeof(string), "stackTrace");

            var parameters = new Expression[]
            {
                errorCode,
                message,
                stackTrace
            };

            var responseStatusType = FickleType.Define("ResponseStatus");

            var result         = FickleExpression.Variable(currentType, "result");
            var responseStatus = FickleExpression.Variable(responseStatusType, "responseStatus");

            var newResult         = Expression.Assign(result, Expression.New(currentType));
            var newResponseStatus = Expression.Assign(responseStatus, Expression.New(responseStatusType));

            var methodVariables = new List <ParameterExpression>
            {
                result,
                responseStatus
            };

            var methodStatements = new List <Expression>
            {
                newResponseStatus,
                FickleExpression.Call(responseStatus, "setErrorCode", errorCode),
                FickleExpression.Call(responseStatus, "setMessage", message),
                FickleExpression.Call(responseStatus, "setStackTrace", stackTrace),
                newResult,
                FickleExpression.Call(result, "setResponseStatus", responseStatus),
                Expression.Return(Expression.Label(), result)
            };

            var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray());

            return(new MethodDefinitionExpression("createErrorResponse", parameters.ToReadOnlyCollection(), AccessModifiers.Public | AccessModifiers.Static, currentType, body, false, null));
        }
Ejemplo n.º 16
0
        private Expression CreateDeserializeArrayMethod()
        {
            var jsonReader = Expression.Parameter(FickleType.Define("JsonReader"), "reader");

            var result = FickleExpression.Variable(new FickleListType(currentType), "result");

            var resultNew = FickleExpression.New(new FickleListType(currentType), "FickleListType", null);

            var jsonReaderNextString = FickleExpression.Call(jsonReader, "nextString", null);

            var whileBody = FickleExpression.Block(FickleExpression.Call(result, "add", FickleExpression.StaticCall(currentType, "deserialize", jsonReaderNextString)));

            var whileExpression = FickleExpression.While(FickleExpression.Call(jsonReader, "hasNext", null), whileBody);

            var returnResult = Expression.Return(Expression.Label(), result).ToStatement();

            var methodVariables = new List <ParameterExpression>
            {
                result
            };

            var methodStatements = new List <Expression>
            {
                Expression.Assign(result, resultNew).ToStatement(),
                FickleExpression.Call(jsonReader, "beginArray", null),
                whileExpression,
                FickleExpression.Call(jsonReader, "endArray", null),
                returnResult
            };

            var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray());

            return(new MethodDefinitionExpression("deserializeArray", new List <Expression>()
            {
                jsonReader
            }, AccessModifiers.Public | AccessModifiers.Static, new FickleListType(currentType), body, false, null, null, new List <Exception>()
            {
                new Exception()
            }));
        }
Ejemplo n.º 17
0
        private Expression CreateCopyWithZoneMethod(TypeDefinitionExpression expression)
        {
            var currentType = (FickleType)expression.Type;
            var zone        = FickleExpression.Parameter("NSZone", "zone");
            var self        = Expression.Parameter(currentType, "self");
            var theCopy     = Expression.Variable(expression.Type, "theCopy");

            Expression newExpression;

            if (expression.Type.BaseType == typeof(object))
            {
                newExpression = FickleExpression.Call(FickleExpression.Call(FickleExpression.Call(self, "Class", "class", null), "allocWithZone", zone), expression.Type, "init", null);
            }
            else
            {
                var super = FickleExpression.Variable(expression.Type.BaseType.Name, "super");

                newExpression = FickleExpression.Call(super, FickleType.Define("id"), "copyWithZone", zone);
            }

            var initTheCopy     = Expression.Assign(theCopy, newExpression).ToStatement();
            var returnStatement = Expression.Return(Expression.Label(), theCopy).ToStatement();
            var copyStatements  = PropertiesToCopyExpressionBinder.Bind(codeGenerationContext, expression, zone, theCopy);

            Expression methodBody = Expression.Block
                                    (
                new[] { theCopy },
                initTheCopy,
                FickleExpression.GroupedWide
                (
                    copyStatements,
                    returnStatement
                )
                                    );

            return(new MethodDefinitionExpression("copyWithZone", new Expression[] { zone }.ToReadOnlyCollection(), typeof(object), methodBody, false, null));
        }
Ejemplo n.º 18
0
 public static MemberExpression Property(Expression instance, string typeName, string propertyName)
 {
     return(FickleExpression.Property(instance, FickleType.Define(typeName), propertyName));
 }
Ejemplo n.º 19
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            currentTypeDefinitionExpression = expression;
            currentReturnTypes = new HashSet <Type>(ReturnTypesCollector.CollectReturnTypes(expression));

            var includeExpressions = new List <IncludeExpression>
            {
                FickleExpression.Include("java.util.ArrayList"),
                FickleExpression.Include("com.jaigo.androiddevkit.DefaultJsonBuilder"),
                FickleExpression.Include("com.jaigo.androiddevkit.RequestCallback"),
                FickleExpression.Include("com.jaigo.androiddevkit.utils.ConvertUtils"),
                FickleExpression.Include("com.jaigo.androiddevkit.WebServiceClient")
            };

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var client = new FieldDefinitionExpression("webServiceClient", webServiceClientType, AccessModifiers.Private | AccessModifiers.Constant);

            var body = GroupedExpressionsExpression.FlatConcat
                       (
                GroupedExpressionsExpressionStyle.Wide,
                client,
                CreateDefaultConstructor(),
                CreateParameterisedConstructor(),
                this.Visit(expression.Body)
                       );

            var singleValueResponseTypes = currentReturnTypes.Where(c => c.GetUnwrappedNullableType().IsPrimitive).Select(c => FickleType.Define(JavaBinderHelpers.GetValueResponseWrapperTypeName(c))).ToList();

            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(body).Concat(singleValueResponseTypes).Distinct().ToList();

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (lookup.Contains(typeof(FickleListType)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.ArrayList"));
            }

            if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.UUID"));
            }

            if (lookup.Contains(typeof(DateTime)) || lookup.Contains(typeof(DateTime?)))
            {
                includeExpressions.Add(FickleExpression.Include("java.util.Date"));
            }

            var headerGroup         = includeExpressions.Sorted(IncludeExpression.Compare).ToGroupedExpression();
            var namespaceExpression = new NamespaceExpression(CodeGenerationContext.Options.Namespace);

            var header = new Expression[] { comment, namespaceExpression, headerGroup }.ToGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes, expression.InterfaceTypes));
        }
Ejemplo n.º 20
0
 public static NewExpression New(string typeName)
 {
     return(Expression.New(FickleType.Define(typeName)));
 }
Ejemplo n.º 21
0
        private Expression CreateDeserializeStreamMethod()
        {
            var inputStream = Expression.Parameter(FickleType.Define("InputStream"), "in");

            var jsonReaderType = FickleType.Define("JsonReader");
            var jsonReader     = Expression.Variable(jsonReaderType, "reader");

            var inputStreamReaderNew = FickleExpression.New(FickleType.Define("InputStreamReader"), "InputStreamReader", inputStream);
            var jsonReaderNew        = FickleExpression.New(jsonReaderType, "JsonReader", inputStreamReaderNew);

            var self         = FickleExpression.Variable(currentType, "this");
            var resultCreate = FickleExpression.Call(self, currentType, "deserialize", jsonReader).ToStatement();

            var jsonReaderClose = FickleExpression.Call(jsonReader, "close", null).ToStatement();

            var exception = Expression.Variable(typeof(Exception), "exception");;

            Expression handleError;

            if (CurrentTypeIsResponseType())
            {
                var responseStatusType = FickleType.Define("ResponseStatus");
                var responseStatus     = FickleExpression.Variable(responseStatusType, "responseStatus");
                var newResponseStatus  = Expression.Assign(responseStatus, Expression.New(responseStatusType));

                handleError = FickleExpression.Grouped(new Expression[]
                {
                    newResponseStatus,
                    FickleExpression.Call(responseStatus, "setErrorCode", Expression.Constant("DeserializationError", typeof(String))),
                    FickleExpression.Call(responseStatus, "setMessage", FickleExpression.Call(exception, typeof(String), "getMessage", null)),
                    FickleExpression.Call(responseStatus, "setStackTrace", FickleExpression.StaticCall("Log", "getStackTraceString", exception))
                }.ToStatementisedGroupedExpression());
            }
            else
            {
                handleError = Expression.Throw(exception).ToStatement();
            }

            var tryCatch = Expression.TryCatchFinally(
                resultCreate,
                jsonReaderClose,
                Expression.Catch(typeof(Exception), handleError));

            var methodVariables = new List <ParameterExpression>
            {
                jsonReader
            };

            var methodStatements = new List <Expression>
            {
                Expression.Assign(jsonReader, jsonReaderNew).ToStatement(),
                tryCatch
            };

            var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray());

            return(new MethodDefinitionExpression("deserialize", new List <Expression>()
            {
                inputStream
            }, AccessModifiers.Public, typeof(void), body, false, null, null, new List <Exception>()
            {
                new Exception()
            }));
        }
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var includeExpressions = new List <IncludeExpression>();
            var importExpressions  = new List <Expression>();

            var optionsProperty        = new PropertyDefinitionExpression("options", FickleType.Define("NSDictionary"), true);
            var responseFilterProperty = new PropertyDefinitionExpression("responseFilter", FickleType.Define("FKGatewayResponseFilter", isInterface: true), true, new[] { "weak" });

            var body = FickleExpression.GroupedWide
                       (
                optionsProperty,
                responseFilterProperty,
                new GroupedExpressionsExpression(methods.Select(c => c.ChangePredeclaration(true)))
                       );

            var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(body);

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (!this.CodeGenerationContext.Options.ImportDependenciesAsFramework)
            {
                if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKUUID.h"));
                }

                if (lookup.Contains(typeof(TimeSpan)) || lookup.Contains(typeof(TimeSpan?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKTimeSpan.h"));
                }

                includeExpressions.Add(FickleExpression.Include("PKWebServiceClient.h"));
                includeExpressions.Add(FickleExpression.Include("PKDictionarySerializable.h"));
            }
            else
            {
                importExpressions.Add(new CodeLiteralExpression(c => c.WriteLine("@import PlatformKit;")));
            }

            includeExpressions.Add(FickleExpression.Include("FKGatewayResponseFilter.h"));

            var referencedUserTypes = referencedTypes
                                      .Where(c => (c is FickleType && ((FickleType)c).ServiceClass != null) || c is FickleType && ((FickleType)c).ServiceEnum != null)
                                      .Sorted((x, y) => x.Name.Length == y.Name.Length ? String.CompareOrdinal(x.Name, y.Name) : x.Name.Length - y.Name.Length);

            includeExpressions.AddRange(referencedUserTypes.Select(c => FickleExpression.Include(c.Name + ".h")));

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var header = new Expression[]
            {
                comment,
                importExpressions.Count == 0 ? null : importExpressions.ToStatementisedGroupedExpression(),
                includeExpressions.Sorted(IncludeExpression.Compare).ToStatementisedGroupedExpression()
            }.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var interfaceTypes = new List <Type>();

            if (expression.InterfaceTypes != null)
            {
                interfaceTypes.AddRange(expression.InterfaceTypes);
            }

            interfaceTypes.Add(FickleType.Define("PKWebServiceClientDelegate"));

            return(new TypeDefinitionExpression(expression.Type, header, body, true, expression.Attributes, interfaceTypes.ToReadOnlyCollection()));
        }
Ejemplo n.º 23
0
        private Expression CreateDeserializeElementMethod()
        {
            var jsonReader = Expression.Parameter(FickleType.Define("JsonReader"), "reader");

            var jsonElementName = Expression.Variable(typeof(String), "elementName");

            Expression ifThenElseExpression;

            if (currentTypeDefinition.Type.BaseType != null && currentTypeDefinition.Type.BaseType != typeof(Object))
            {
                var superType = currentTypeDefinition.Type.BaseType;
                var super     = Expression.Variable(superType, "super");

                ifThenElseExpression = FickleExpression.Block(FickleExpression.Call(super, "deserializeElement", jsonReader));
            }
            else
            {
                ifThenElseExpression = FickleExpression.Block(FickleExpression.Call(jsonReader, "skipValue", null));
            }

            var self = Expression.Variable(currentType, "this");

            foreach (var serviceProperty in ((FickleType)currentTypeDefinition.Type).ServiceClass.Properties)
            {
                Expression action = null;

                var propertyType = codeGenerationContext.ServiceModel.GetTypeFromName(serviceProperty.TypeName);

                if (propertyType is FickleListType)
                {
                    var listItemType = ((FickleListType)propertyType).ListElementType;

                    if (listItemType is FickleNullable)
                    {
                        listItemType = listItemType.GetUnderlyingType();
                    }

                    if (listItemType.IsEnum)
                    {
                        var convertDtoCall = FickleExpression.StaticCall(listItemType.Name, "deserializeArray", jsonReader);
                        action = FickleExpression.Block(FickleExpression.Call(self, "set" + serviceProperty.Name, convertDtoCall));
                    }
                    else
                    {
                        var result = FickleExpression.Variable(new FickleListType(listItemType), serviceProperty.Name.Uncapitalize());

                        var resultNew = FickleExpression.New(new FickleListType(listItemType), "FickleListType", null);

                        var jsonReaderNextString = FickleExpression.Call(jsonReader, typeof(String), "nextString", null);

                        Expression whileBody;

                        if (TypeSystem.IsPrimitiveType(listItemType))
                        {
                            whileBody = FickleExpression.Block(
                                FickleExpression.Call(result, "add", Expression.Convert(Expression.Convert(jsonReaderNextString, typeof(Object)), listItemType))
                                );
                        }
                        else
                        {
                            var objectToDeserialize = FickleExpression.Variable(listItemType, listItemType.Name.Uncapitalize());

                            var objectNew = Expression.Assign(objectToDeserialize, Expression.New(listItemType));

                            var whileVariables = new List <ParameterExpression>
                            {
                                objectToDeserialize
                            };

                            var whileStatements = new List <Expression>
                            {
                                objectNew,
                                FickleExpression.Call(objectToDeserialize, "deserialize", jsonReader),
                                FickleExpression.Call(result, "add", objectToDeserialize)
                            };

                            whileBody = FickleExpression.Block(whileVariables.ToArray(), whileStatements.ToArray());
                        }

                        var whileExpression = FickleExpression.While(FickleExpression.Call(jsonReader, "hasNext", null), whileBody);

                        var setResult = FickleExpression.Call(self, "set" + serviceProperty.Name, result).ToStatement();

                        var variables = new List <ParameterExpression>
                        {
                            result
                        };

                        var statements = new List <Expression>
                        {
                            Expression.Assign(result, resultNew).ToStatement(),
                            FickleExpression.Call(jsonReader, "beginArray", null),
                            whileExpression,
                            FickleExpression.Call(jsonReader, "endArray", null),
                            setResult
                        };

                        action = FickleExpression.Block(variables.ToArray(), statements.ToArray());
                    }
                }
                else if (TypeSystem.IsNotPrimitiveType(propertyType))
                {
                    var value = FickleExpression.Variable(propertyType, "value");

                    var valueNew = Expression.Assign(value, Expression.New(propertyType));

                    var convertDtoCall = FickleExpression.Call(value, "deserialize", jsonReader);

                    var variables = new List <ParameterExpression>
                    {
                        value
                    };

                    var statements = new List <Expression>
                    {
                        valueNew,
                        convertDtoCall,
                        FickleExpression.Call(self, "set" + serviceProperty.Name, value)
                    }.ToStatementisedGroupedExpression();

                    action = Expression.Block(variables.ToArray(), statements);
                }
                else if (propertyType.GetUnwrappedNullableType().IsEnum)
                {
                    var getPrimitiveElementCall = FickleExpression.Call(jsonReader, "nextString", null);
                    var convertDtoCall          = FickleExpression.StaticCall(serviceProperty.TypeName, "deserialize", getPrimitiveElementCall);
                    action = FickleExpression.Block(FickleExpression.Call(self, "set" + serviceProperty.Name, convertDtoCall));
                }
                else
                {
                    var getPrimitiveElementCall = FickleExpression.Call(jsonReader, "nextString", null);
                    var convertPrimitiveCall    = FickleExpression.StaticCall(propertyType, SourceCodeGenerator.ToObjectMethod, getPrimitiveElementCall);
                    action = FickleExpression.Block(FickleExpression.Call(self, "set" + serviceProperty.Name, convertPrimitiveCall));
                }

                var condition = FickleExpression.Call(jsonElementName, typeof(Boolean), "equals", Expression.Constant(serviceProperty.Name, typeof(String)));

                var currentExpression = Expression.IfThenElse(condition, action, ifThenElseExpression);

                ifThenElseExpression = currentExpression;
            }

            var methodVariables = new List <ParameterExpression>
            {
                jsonElementName
            };

            var methodStatements = new List <Expression>
            {
                Expression.Assign(jsonElementName, FickleExpression.Call(jsonReader, typeof(String), "nextName", null)).ToStatement(),
                ifThenElseExpression
            };

            var body = FickleExpression.Block(methodVariables.ToArray(), methodStatements.ToArray());

            return(new MethodDefinitionExpression("deserializeElement", new List <Expression>()
            {
                jsonReader
            }, AccessModifiers.Public, typeof(void), body, false, null, null, new List <Exception>()
            {
                new Exception()
            }));
        }
Ejemplo n.º 24
0
        protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression)
        {
            var includeExpressions = new List <IncludeExpression>();
            var importExpressions  = new List <Expression>();
            var referencedTypes    = ReferencedTypesCollector.CollectReferencedTypes(expression);

            referencedTypes.Sort((x, y) => String.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase));

            var lookup = new HashSet <Type>(referencedTypes.Where(TypeSystem.IsPrimitiveType));

            if (!this.codeGenerationContext.Options.ImportDependenciesAsFramework)
            {
                if (lookup.Contains(typeof(Guid)) || lookup.Contains(typeof(Guid?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKUUID.h"));
                }

                if (lookup.Contains(typeof(TimeSpan)) || lookup.Contains(typeof(TimeSpan?)))
                {
                    includeExpressions.Add(FickleExpression.Include("PKTimeSpan.h"));
                }

                includeExpressions.Add(FickleExpression.Include("PKDictionarySerializable.h"));
                includeExpressions.Add(FickleExpression.Include("PKFormEncodingSerializable.h"));
            }
            else
            {
                importExpressions.Add(new CodeLiteralExpression(c => c.WriteLine("@import PlatformKit;")));
            }

            if (ObjectiveBinderHelpers.TypeIsServiceClass(expression.Type.BaseType))
            {
                includeExpressions.Add(FickleExpression.Include(expression.Type.BaseType.Name + ".h"));
            }

            includeExpressions.AddRange(referencedTypes.Where(c => c.IsEnum).Select(c => FickleExpression.Include(c.Name + ".h")));

            includeExpressions.Sort(IncludeExpression.Compare);

            var comment = new CommentExpression("This file is AUTO GENERATED");

            var headerExpressions = new List <Expression>()
            {
                new[] { comment }.ToStatementisedGroupedExpression(),
                importExpressions.Count == 0 ? null : importExpressions.ToStatementisedGroupedExpression(),
                includeExpressions.ToStatementisedGroupedExpression()
            };

            var referencedTypeExpressions = referencedTypes
                                            .Where(ObjectiveBinderHelpers.TypeIsServiceClass)
                                            .Where(c => c != expression.Type.BaseType)
                                            .OrderBy(x => x.Name.Length)
                                            .ThenBy(x => x.Name)
                                            .Select(c => (Expression) new ReferencedTypeExpression(c)).ToList();

            if (referencedTypeExpressions.Count > 0)
            {
                headerExpressions.Add(referencedTypeExpressions.ToStatementisedGroupedExpression());
            }

            var header = headerExpressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide);

            var propertyBody = this.Visit(expression.Body);

            var interfaceTypes = new List <Type>
            {
                FickleType.Define("NSCopying"),
                FickleType.Define("PKDictionarySerializable"),
                FickleType.Define("PKFormEncodingSerializable")
            };

            return(new TypeDefinitionExpression(expression.Type, header, propertyBody, true, expression.Attributes, interfaceTypes.ToReadOnlyCollection()));
        }
        internal static Expression GetDeserializeExpressionProcessValueDeserializer(Type valueType, Expression value, Func <Expression, Expression> processOutputValue)
        {
            Expression outputValue;
            var        nsNull = FickleExpression.StaticCall("NSNull", FickleType.Define("id"), "null", null);

            if (TypeSystem.IsPrimitiveType(valueType))
            {
                ConditionalExpression ifExpression;
                var underlyingType = valueType.GetUnwrappedNullableType();

                if (underlyingType.IsNumericType() || underlyingType == typeof(bool))
                {
                    var typeToCompare = new FickleType("NSNumber");

                    if (underlyingType.IsEnum && valueType.GetUnderlyingType() == null)
                    {
                        outputValue = Expression.Convert(FickleExpression.Call(value, typeof(int), "intValue", null), valueType);
                    }
                    else
                    {
                        outputValue = Expression.Convert(value, valueType);
                    }

                    ifExpression = Expression.IfThen(Expression.TypeIs(value, typeToCompare), processOutputValue(outputValue).ToBlock());
                }
                else if (underlyingType.IsEnum)
                {
                    Expression firstIf;

                    if (valueType.IsNullable())
                    {
                        outputValue = Expression.Convert(value, valueType);

                        firstIf = Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSNumber")), processOutputValue(outputValue).ToBlock());
                    }
                    else
                    {
                        outputValue = Expression.Convert(FickleExpression.Call(value, typeof(int), "intValue", null), valueType);

                        firstIf = Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSNumber")), processOutputValue(outputValue).ToBlock());
                    }

                    var parsedValue = FickleExpression.Variable(underlyingType, "parsedValue");
                    var success     = Expression.Variable(typeof(bool), "success");

                    var parameters = new[] { new FickleParameterInfo(typeof(string), "value"), new FickleParameterInfo(underlyingType, "outValue", true) };
                    var methodInfo = new FickleMethodInfo(null, typeof(bool), TypeSystem.GetPrimitiveName(underlyingType, true) + "TryParse", parameters, true);

                    if (valueType.IsNullable())
                    {
                        outputValue = Expression.Convert(Expression.Condition(success, Expression.Convert(Expression.Convert(parsedValue, valueType), FickleType.Define("id")), Expression.Convert(FickleExpression.StaticCall(FickleType.Define("NSNull"), valueType, "null", null), FickleType.Define("id"))), valueType);
                    }
                    else
                    {
                        outputValue = Expression.Convert(parsedValue, valueType);
                    }

                    var secondIf = Expression.IfThenElse
                                   (
                        Expression.TypeIs(value, FickleType.Define("NSString")),
                        FickleExpression.Block
                        (
                            new ParameterExpression[]
                    {
                        parsedValue,
                        success
                    },
                            Expression.IfThen
                            (
                                Expression.Not(Expression.Assign(success, Expression.Call(null, methodInfo, Expression.Convert(value, typeof(string)), parsedValue))),
                                Expression.Assign(parsedValue, Expression.Convert(Expression.Constant(0), underlyingType)).ToStatementBlock()
                            ),
                            processOutputValue(outputValue)
                        ),
                        firstIf
                                   );

                    ifExpression = secondIf;
                }
                else
                {
                    ifExpression = Expression.IfThen(Expression.TypeIs(value, typeof(string)), processOutputValue(Expression.Convert(Expression.Convert(value, typeof(object)), valueType)).ToBlock());
                }

                if (valueType.IsNullable())
                {
                    ifExpression = Expression.IfThenElse
                                   (
                        Expression.Equal(value, nsNull),
                        processOutputValue(Expression.Convert(nsNull, valueType)).ToBlock(),
                        ifExpression
                                   );
                }

                return(ifExpression);
            }
            else if (valueType is FickleType && ((FickleType)valueType).ServiceClass != null)
            {
                outputValue = FickleExpression.New(valueType, "initWithPropertyDictionary", FickleExpression.Convert(value, "NSDictionary"));

                return(Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSDictionary")), processOutputValue(outputValue).ToBlock()));
            }
            else if (valueType is FickleType && ((FickleType)valueType).ServiceEnum != null)
            {
                return(Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSNumber")), processOutputValue(value).ToBlock()));
            }
            else if (valueType is FickleListType)
            {
                var listType = valueType as FickleListType;

                var arrayVar  = FickleExpression.Variable("NSMutableArray", "array");
                var variables = new[] { arrayVar };
                var arrayItem = FickleExpression.Parameter(FickleType.Define("id"), "arrayItem");

                var forEachBody = GetDeserializeExpressionProcessValueDeserializer(listType.ListElementType, arrayItem, c => FickleExpression.Call(arrayVar, "addObject", Expression.Convert(c, typeof(object))).ToStatement());

                var ifThen = Expression.IfThen
                             (
                    Expression.TypeIs(value, FickleType.Define("NSArray")),
                    FickleExpression.Block
                    (
                        variables,
                        Expression.Assign(arrayVar, FickleExpression.New("NSMutableArray", "initWithCapacity", FickleExpression.Call(Expression.Convert(value, FickleType.Define("NSArray")), typeof(int), "count", null))).ToStatement(),
                        FickleExpression.ForEach(arrayItem, value, FickleExpression.Block(forEachBody)),
                        processOutputValue(Expression.Convert(arrayVar, valueType))
                    )
                             );

                return(ifThen);
            }
            else
            {
                throw new InvalidOperationException("Unsupported property type: " + valueType);
            }
        }
Ejemplo n.º 26
0
        private GatewayExpressionBinder(CodeGenerationContext codeGenerationContext)
        {
            this.CodeGenerationContext = codeGenerationContext;

            this.webServiceClientType = FickleType.Define(this.CodeGenerationContext.Options.ServiceClientTypeName ?? "WebServiceClient");
        }
Ejemplo n.º 27
0
 public static MethodCallExpression StaticCall(string type, Type returnType, string methodName, object arguments)
 {
     return(Call(null, FickleType.Define(type), returnType, methodName, arguments, true));
 }
        protected Expression CreateGatewayCallMethod(MethodDefinitionExpression method, out ParameterExpression optionsParameter)
        {
            var methodName = method.Name.ToCamelCase();

            methodCount++;

            var self               = Expression.Variable(currentType, "self");
            var hostname           = Expression.Variable(typeof(string), "hostname");
            var port               = Expression.Variable(typeof(string), "port");
            var protocol           = Expression.Variable(typeof(string), "protocol");
            var optionsParam       = FickleExpression.Parameter("NSDictionary", "options");
            var localOptions       = FickleExpression.Variable("NSMutableDictionary", "localOptions");
            var requestObject      = FickleExpression.Variable("NSObject", "requestObject");
            var requestObjectValue = (Expression)Expression.Constant(null, typeof(object));
            var url                 = Expression.Variable(typeof(string), "url");
            var responseType        = ObjectiveBinderHelpers.GetWrappedResponseType(this.CodeGenerationContext, method.ReturnType);
            var variables           = new [] { url, localOptions, protocol, hostname, requestObject, port };
            var declaredHostname    = currentTypeDefinitionExpression.Attributes["Hostname"];
            var declaredPath        = method.Attributes["Path"];
            var path                = StringUriUtils.Combine("%@://%@%@", declaredPath);
            var httpMethod          = method.Attributes["Method"];
            var declaredProtocol    = Convert.ToBoolean(method.Attributes["Secure"]) ? "https" : "http";
            var retryBlockVariable  = Expression.Variable(new FickleDelegateType(typeof(void), new FickleParameterInfo(FickleType.Define("id"), "block")), "retryBlock");
            var retryBlockParameter = Expression.Variable(FickleType.Define("id"), "block");

            var parametersByName = method.Parameters.ToDictionary(c => ((ParameterExpression)c).Name, c => (ParameterExpression)c, StringComparer.InvariantCultureIgnoreCase);

            var formatInfo = ObjectiveStringFormatInfo.GetObjectiveStringFormatInfo(path, c => parametersByName[c]);

            var args       = formatInfo.ValueExpressions;
            var parameters = formatInfo.ParameterExpressions;

            var parameterInfos = new List <FickleParameterInfo>
            {
                new ObjectiveParameterInfo(typeof(string), "s"),
                new ObjectiveParameterInfo(typeof(string), "protocol", true),
                new ObjectiveParameterInfo(typeof(string), "hostname", true),
                new ObjectiveParameterInfo(typeof(string), "port", true),
            };

            parameterInfos.AddRange(parameters.Select(c => new ObjectiveParameterInfo(c.Type, c.Name, true)));

            var methodInfo = new FickleMethodInfo(typeof(string), typeof(string), "stringWithFormat", parameterInfos.ToArray(), true);

            args.InsertRange(0, new Expression[] { Expression.Constant(formatInfo.Format), protocol, hostname, port });

            var newParameters = new List <Expression>(method.Parameters)
            {
                optionsParam
            };
            var callback = Expression.Parameter(new FickleDelegateType(typeof(void), new FickleParameterInfo(responseType, "response")), "callback");

            newParameters.Add(callback);

            Expression blockArg = Expression.Parameter(FickleType.Define("id"), "arg1");

            var returnType = method.ReturnType;

            if (ObjectiveBinderHelpers.NeedsValueResponseWrapper(method.ReturnType))
            {
                returnType = FickleType.Define(ObjectiveBinderHelpers.GetValueResponseWrapperTypeName(method.ReturnType));
            }

            var responseFilter = FickleExpression.Property(self, "FKGatewayResponseFilter", "responseFilter");
            var conversion     = Expression.Convert(blockArg, returnType);

            var innerRetryBlockBody = FickleExpression.Block
                                      (
                FickleExpression.Call(Expression.Convert(retryBlockParameter, retryBlockVariable.Type), typeof(void), "Invoke", new { block = retryBlockParameter }).ToStatement()
                                      );

            var innerRetryBlock = (Expression)FickleExpression.SimpleLambda
                                  (
                typeof(void), innerRetryBlockBody, new Expression[0]
                                  );

            var body = FickleExpression.GroupedWide
                       (
                Expression.IfThen(Expression.NotEqual(responseFilter, Expression.Constant(null, responseFilter.Type)), Expression.Assign(blockArg, FickleExpression.Call(responseFilter, typeof(object), "gateway", new { value = self, receivedResponse = blockArg, fromRequestURL = url, withRequestObject = requestObject, retryBlock = innerRetryBlock, andOptions = localOptions })).ToStatementBlock()),
                Expression.IfThen
                (
                    Expression.AndAlso(Expression.NotEqual(blockArg, Expression.Constant(null, blockArg.Type)), Expression.NotEqual(callback, Expression.Constant(null, callback.Type))),
                    FickleExpression.Call(callback, "Invoke", conversion).ToStatementBlock()
                )
                       );

            var conversionBlock = FickleExpression.SimpleLambda(null, body, new Expression[0], blockArg);

            var error = FickleExpression.Variable("NSError", "error");

            Expression parseResultBlock;

            var nsdataParam = Expression.Parameter(FickleType.Define("NSData"), "data");
            var clientParam = Expression.Parameter(FickleType.Define("PKWebServiceClient"), "client");
            var jsonObjectWithDataParameters = new[] { new FickleParameterInfo(FickleType.Define("NSDictionary"), "obj"), new FickleParameterInfo(typeof(int), "options"), new FickleParameterInfo(FickleType.Define("NSError", true), "error", true) };
            var objectWithDataMethodInfo     = new FickleMethodInfo(FickleType.Define("NSJSONSerialization"), FickleType.Define("NSData"), "JSONObjectWithData", jsonObjectWithDataParameters, true);
            var deserializedValue            = Expression.Parameter(FickleType.Define("id"), "deserializedValue");

            var parseErrorResult = FickleExpression.Call(self, "webServiceClient", new
            {
                clientParam,
                createErrorResponseWithErrorCode = "JsonDeserializationError",
                andMessage = FickleExpression.Call(error, "localizedDescription", null)
            });

            if (method.ReturnType == typeof(void))
            {
                var responseObject = FickleExpression.Variable(responseType, "responseObject");

                parseResultBlock = FickleExpression.SimpleLambda
                                   (
                    FickleType.Define("id"),
                    FickleExpression.GroupedWide
                    (
                        Expression.Assign(responseObject, FickleExpression.New(responseType, "init", null)).ToStatement(),
                        Expression.Assign(deserializedValue, Expression.Call(objectWithDataMethodInfo, nsdataParam, FickleExpression.Variable(typeof(int), "NSJSONReadingAllowFragments"), error)).ToStatement(),
                        Expression.IfThen(Expression.Equal(deserializedValue, Expression.Constant(null)), FickleExpression.Return(parseErrorResult).ToStatementBlock()),
                        FickleExpression.Return(responseObject).ToStatement()
                    ),
                    new Expression[] { deserializedValue, responseObject, error },
                    clientParam, nsdataParam
                                   );
            }
            else if (TypeSystem.IsPrimitiveType(method.ReturnType) || method.ReturnType is FickleListType)
            {
                var responseObject = FickleExpression.Variable(responseType, "responseObject");
                var needToBoxValue = ObjectiveBinderHelpers.ValueResponseValueNeedsBoxing(method.ReturnType);

                parseResultBlock = FickleExpression.SimpleLambda
                                   (
                    FickleType.Define("id"),
                    FickleExpression.GroupedWide
                    (
                        Expression.Assign(responseObject, FickleExpression.New(responseType, "init", null)).ToStatement(),
                        Expression.Assign(deserializedValue, Expression.Call(objectWithDataMethodInfo, nsdataParam, FickleExpression.Variable(typeof(int), "NSJSONReadingAllowFragments"), error)).ToStatement(),
                        Expression.IfThen(Expression.Equal(deserializedValue, Expression.Constant(null)), FickleExpression.Return(parseErrorResult).ToStatementBlock()),
                        PropertiesFromDictionaryExpressonBinder.GetDeserializeExpressionProcessValueDeserializer(method.ReturnType, deserializedValue, c => FickleExpression.Call(responseObject, typeof(void), "setValue", needToBoxValue  ? Expression.Convert(c, typeof(object)) : c).ToStatement()),
                        FickleExpression.Return(responseObject).ToStatement()
                    ),
                    new Expression[] { deserializedValue, responseObject, error },
                    clientParam, nsdataParam
                                   );
            }
            else
            {
                parseResultBlock = FickleExpression.SimpleLambda
                                   (
                    FickleType.Define("id"),
                    FickleExpression.GroupedWide
                    (
                        Expression.Assign(deserializedValue, Expression.Call(objectWithDataMethodInfo, nsdataParam, FickleExpression.Variable(typeof(int), "NSJSONReadingAllowFragments"), error)).ToStatement(),
                        PropertiesFromDictionaryExpressonBinder.GetDeserializeExpressionProcessValueDeserializer(method.ReturnType, deserializedValue, c => FickleExpression.Return(c).ToStatement()),
                        FickleExpression.Return(parseErrorResult).ToStatement()
                    ),
                    new Expression[] { deserializedValue, error },
                    clientParam, nsdataParam
                                   );
            }

            var uniqueNameMaker = new UniqueNameMaker(c => newParameters.Cast <ParameterExpression>().Any(d => d.Name.EqualsIgnoreCaseInvariant(c)));

            var key = FickleExpression.Variable(typeof(string), uniqueNameMaker.Make("key"));

            var integrateOptions = FickleExpression.ForEach
                                   (
                key,
                optionsParam,
                FickleExpression.Call(localOptions, typeof(void), "setObject", new { value = FickleExpression.Call(optionsParam, typeof(object), "objectForKey", key), forKey = key }).ToStatementBlock()
                                   );

            parseResultBlock = FickleExpression.Call(parseResultBlock, parseResultBlock.Type, "copy", null);

            var client = Expression.Variable(FickleType.Define(this.CodeGenerationContext.Options.ServiceClientTypeName ?? "PKWebServiceClient"), "client");

            Expression clientCallExpression;

            if (httpMethod.Equals("get", StringComparison.InvariantCultureIgnoreCase))
            {
                clientCallExpression = FickleExpression.Call(client, "getWithCallback", conversionBlock);
            }
            else
            {
                var contentParameterName = method.Attributes["Content"];
                var contentFormat        = method.Attributes["ContentFormat"];

                if (string.IsNullOrEmpty(contentParameterName))
                {
                    clientCallExpression = FickleExpression.Call(client, "postWithRequestObject", new
                    {
                        requestObject,
                        andCallback = conversionBlock
                    });
                }
                else
                {
                    var content = parametersByName[contentParameterName];

                    requestObjectValue = content.Type == typeof(byte[]) ? (Expression)content : FickleExpression.Call(self, typeof(object), this.GetNormalizeRequestMethodName(content.Type, contentFormat), new { serializeRequest = Expression.Convert(content, typeof(object)), paramName = Expression.Constant(contentParameterName) });

                    clientCallExpression = FickleExpression.Call(client, "postWithRequestObject", new
                    {
                        requestObject,
                        andCallback = conversionBlock
                    });
                }
            }

            var retryBlock = (Expression)FickleExpression.SimpleLambda
                             (
                typeof(void),
                FickleExpression.StatementisedGroupedExpression
                (
                    Expression.Assign(client, FickleExpression.Call(Expression.Variable(currentType, "self"), "PKWebServiceClient", "createClientWithURL", new
            {
                url,
                options = localOptions
            })),
                    Expression.Assign(FickleExpression.Property(client, currentType, "delegate"), self),
                    clientCallExpression
                ),
                new Expression[] { client },
                retryBlockParameter
                             );

            retryBlock = FickleExpression.Call(retryBlock, retryBlock.Type, "copy", null);

            var block = FickleExpression.Block
                        (
                variables.Concat(retryBlockVariable).ToArray(),
                Expression.Assign(requestObject, requestObjectValue),
                Expression.Assign(callback, FickleExpression.Call(callback, callback.Type, "copy", null)),
                Expression.Assign(localOptions, FickleExpression.Call(FickleExpression.Property(self, FickleType.Define("NSDictionary"), "options"), "NSMutableDictionary", "mutableCopyWithZone", new
            {
                zone = Expression.Constant(null, FickleType.Define("NSZone"))
            })),
                Expression.IfThen(Expression.NotEqual(requestObject, Expression.Constant(null)), FickleExpression.Call(localOptions, typeof(void), "setObject", new { value = requestObject, forKey = "$RequestObject" }).ToStatementBlock()),
                FickleExpression.Call(localOptions, typeof(void), "setObject", new { value = FickleExpression.StaticCall(responseType, "class", null), forKey = "$ResponseClass" }).ToStatement(),
                Expression.Assign(hostname, FickleExpression.Call(localOptions, typeof(string), "objectForKey", Expression.Constant("hostname"))),
                Expression.IfThen(Expression.Equal(hostname, Expression.Constant(null)), Expression.Assign(hostname, Expression.Constant(declaredHostname)).ToStatementBlock()),
                Expression.Assign(protocol, FickleExpression.Call(localOptions, typeof(string), "objectForKey", Expression.Constant("protocol"))),
                Expression.IfThen(Expression.Equal(protocol, Expression.Constant(null)), Expression.Assign(protocol, Expression.Constant(declaredProtocol)).ToStatementBlock()),
                Expression.Assign(port, FickleExpression.Call(FickleExpression.Call(localOptions, FickleType.Define("NSNumber"), "objectForKey", Expression.Constant("port")), typeof(string), "stringValue", null)),
                Expression.IfThenElse(Expression.Equal(port, Expression.Constant(null)), Expression.Assign(port, Expression.Constant("")).ToStatementBlock(), Expression.Assign(port, FickleExpression.Call(Expression.Constant(":"), typeof(string), "stringByAppendingString", port)).ToStatementBlock()),
                FickleExpression.Grouped
                (
                    FickleExpression.Call(localOptions, "setObject", new
            {
                obj    = parseResultBlock,
                forKey = "$ParseResultBlock"
            }).ToStatement(),
                    method.ReturnType.GetUnwrappedNullableType() == typeof(bool) ?
                    FickleExpression.Call(localOptions, "setObject", new
            {
                obj = Expression.Convert(Expression.Constant(1), typeof(object))
            }).ToStatement() : null
                ),
                Expression.Assign(url, Expression.Call(null, methodInfo, args)),
                FickleExpression.Call(localOptions, typeof(void), "setObject", new { value = url, forKey = "$RequestURL" }).ToStatement(),
                integrateOptions,
                Expression.Assign(retryBlockVariable, retryBlock),
                FickleExpression.Call(retryBlockVariable, typeof(void), "Invoke", retryBlockVariable).ToStatement()
                        );

            optionsParameter = optionsParam;

            return(new MethodDefinitionExpression(methodName, newParameters.ToReadOnlyCollection(), typeof(void), block, false, null));
        }
Ejemplo n.º 29
0
        protected override Expression VisitUnary(UnaryExpression node)
        {
            if (node.NodeType == ExpressionType.Not)
            {
                this.Write('!');
                this.Write('(');
                this.Visit(node.Operand);
                this.Write(')');
            }
            else if (node.NodeType == ExpressionType.Convert)
            {
                if ((node.Type == typeof(Guid) || node.Type == typeof(Guid?)) &&
                    node.Operand.Type != FickleType.Define("id"))
                {
                    if (node.Operand.Type.GetUnwrappedNullableType() == typeof(Guid))
                    {
                        this.Visit(node.Operand);

                        return(node);
                    }

                    this.Write("[");
                    this.Write(typeof(Guid), true);
                    this.Write(" uuidFromString:");
                    if (node.Operand.Type != typeof(string))
                    {
                        this.Write("(NSString*)");
                    }
                    this.Visit(node.Operand);
                    this.Write("]");
                }
                else if ((node.Type.GetUnwrappedNullableType().IsNumericType() ||
                          node.Type.GetUnwrappedNullableType() == typeof(bool)) &&
                         (node.Operand.Type == typeof(object) ||
                          FickleNullable.GetUnderlyingType(node.Operand.Type) != null ||
                          node.Operand.Type.Name == "NSNumber" ||
                          node.Operand.Type.Name == "id"))
                {
                    var type = node.Type;

                    if (type == typeof(bool))
                    {
                        this.Write("(BOOL)((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").boolValue");
                    }
                    else if (type == typeof(bool?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(byte))
                    {
                        this.Write("(uint8_t)((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").intValue");
                    }
                    else if (type == typeof(byte?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(short))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").shortValue");
                    }
                    else if (type == typeof(short?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(ushort))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").unsignedShortValue");
                    }
                    else if (type == typeof(ushort?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(int))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").intValue");
                    }
                    else if (type == typeof(int?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(uint))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").unsignedIntValue");
                    }
                    else if (type == typeof(uint?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(long))
                    {
                        this.Write("(int64_t)((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").longLongValue");
                    }
                    else if (type == typeof(long?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(ulong))
                    {
                        this.Write("(int64_t)((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").unsignedLongLongValue");
                    }
                    else if (type == typeof(ulong?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(float))
                    {
                        this.Write("(float)((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").floatValue");
                    }
                    else if (type == typeof(float?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(double))
                    {
                        this.Write("(double)((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(").doubleValue");
                    }
                    else if (type == typeof(double?))
                    {
                        this.Write("((NSNumber*)");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else if (type == typeof(decimal))
                    {
                        this.Write("([NSDecimalNumber decimalNumberWithString:((NSString*)");
                        this.Visit(node.Operand);
                        this.Write(") ?: @\"0\"])");
                    }
                    else if (type == typeof(decimal?))
                    {
                        this.Write("(");
                        this.Visit(node.Operand);
                        this.Write(" == nil ? nil : [NSDecimalNumber decimalNumberWithString:((NSString*)");
                        this.Visit(node.Operand);
                        this.Write(")])");
                    }
                    else
                    {
                        throw new Exception("Unexpected type: " + node.Type.Name);
                    }
                }
                else if (node.Type == typeof(DateTime?) || node.Type == typeof(DateTime))
                {
                    this.Write("[jsDateFormatter dateFromString:(NSString*)currentValueFromDictionary] ?: [isoDateFormatter dateFromString:(NSString*)currentValueFromDictionary]");
                }
                else if ((node.Type == typeof(TimeSpan?) || node.Type == typeof(TimeSpan)) && node.Operand.Type != FickleType.Define("id"))
                {
                    this.Write("[");
                    this.Write(typeof(TimeSpan), true);
                    this.Write(" fromIsoString:");

                    if (node.Operand.Type != typeof(string))
                    {
                        this.Write("(NSString*)");
                    }

                    this.Visit(node.Operand);
                    this.Write("]");
                }
                else if ((node.Type.IsNullable() &&
                          node.Type.GetUnwrappedNullableType().IsEnum) &&
                         node.Operand.Type.IsEnum)
                {
                    this.Write("@(");
                    this.Visit(node.Operand);
                    this.Write(")");
                }
                else if (node.Type == typeof(object))
                {
                    if (!this.IsReferenceType(node.Operand.Type))
                    {
                        this.Write("@(");
                        this.Visit(node.Operand);
                        this.Write(")");
                    }
                    else
                    {
                        this.Visit(node.Operand);
                    }
                }
                else
                {
                    this.Write("((");

                    if (node.Operand.Type.IsPrimitive && node.Operand.Type.Name.StartsWith("CF"))
                    {
                        this.Write("__bridge ");
                    }

                    this.Write(node.Type);
                    this.Write(')');
                    this.Write('(');
                    this.Visit(node.Operand);
                    this.Write(')');
                    this.Write(')');
                }
            }
            else if (node.NodeType == ExpressionType.Quote)
            {
                this.Visit(node.Operand);
                this.WriteLine(';');
            }
            else if (node.NodeType == ExpressionType.IsTrue)
            {
                this.Visit(node.Operand);
            }
            else if (node.NodeType == ExpressionType.IsFalse)
            {
                this.Write('!');
                this.Visit(node.Operand);
            }

            return(node);
        }
Ejemplo n.º 30
0
        protected virtual Expression CreateTryParseMethod()
        {
            var value      = Expression.Parameter(typeof(string), "value");
            var methodName = currentTypeDefinition.Type.Name.Capitalize() + "TryParse";
            var result     = Expression.Parameter(currentTypeDefinition.Type.MakeByRefType(), "result");
            var retval     = Expression.Variable(currentTypeDefinition.Type, "retval");

            var parameters = new Expression[]
            {
                value,
                result
            };

            var parts     = Expression.Variable(FickleType.Define("NSArray"), "parts");
            var splitCall = FickleExpression.Call(value, FickleType.Define("NSArray"), "componentsSeparatedByString", new { value = Expression.Constant(",") });
            var part      = Expression.Variable(typeof(string), "part");
            var flagCases = new List <SwitchCase>();
            var number    = Expression.Variable(FickleType.Define("NSNumber"), "number");

            foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values)
            {
                flagCases.Add(Expression.SwitchCase(Expression.Assign(retval, Expression.Convert(Expression.Or(Expression.Convert(retval, typeof(int)), Expression.Constant((int)enumValue.Value)), currentTypeDefinition.Type)).ToStatement(), Expression.Constant(enumValue.Name)));
            }

            var foreachBody = FickleExpression.StatementisedGroupedExpression
                              (
                Expression.Switch(part, FickleExpression.Return(Expression.Constant(false)).ToStatement(), flagCases.ToArray())
                              ).ToBlock();

            var defaultBody = FickleExpression.StatementisedGroupedExpression
                              (
                GroupedExpressionsExpressionStyle.Wide,
                Expression.Assign(number, FickleExpression.Call(Expression.New(FickleType.Define("NSNumberFormatter")), number.Type, "numberFromString", value)),
                Expression.IfThen
                (
                    Expression.NotEqual(number, Expression.Constant(null, number.Type)),
                    FickleExpression.StatementisedGroupedExpression
                    (
                        GroupedExpressionsExpressionStyle.Wide,
                        Expression.Assign(result, Expression.Convert(FickleExpression.Call(number, typeof(int), "intValue", null), currentTypeDefinition.Type)),
                        Expression.Return(Expression.Label(), Expression.Constant(true))
                    ).ToBlock()
                ),
                Expression.Assign(parts, splitCall),
                Expression.Assign(retval, Expression.Convert(Expression.Constant(0), currentTypeDefinition.Type)),
                FickleExpression.ForEach(part, parts, foreachBody),
                Expression.Assign(result, retval),
                Expression.Return(Expression.Label(), Expression.Constant(true))
                              );

            var cases = new List <SwitchCase>();

            foreach (var enumValue in ((FickleType)currentTypeDefinition.Type).ServiceEnum.Values)
            {
                cases.Add(Expression.SwitchCase(Expression.Assign(result, Expression.Convert(Expression.Constant((int)enumValue.Value), currentTypeDefinition.Type)).ToStatement(), Expression.Constant(enumValue.Name)));
            }

            var switchStatement = Expression.Switch(value, defaultBody, cases.ToArray());

            var body = FickleExpression.Block(new[] { parts, number, retval }, switchStatement, Expression.Return(Expression.Label(), Expression.Constant(true)));

            return(new MethodDefinitionExpression(methodName, parameters.ToReadOnlyCollection(), AccessModifiers.Static | AccessModifiers.ClasseslessFunction, typeof(bool), body, false, "__unused", null));
        }
        internal static Expression GetSerializeExpression(Type valueType, Expression value, CodeGenerationOptions options, bool skipIfNull, Func <Expression, Expression> processOutputValue)
        {
            Expression expression;
            var        nsNull = FickleExpression.StaticCall("NSNull", "id", "null", null);

            if (valueType.GetUnwrappedNullableType().IsEnum)
            {
                expression = value;

                if (options.SerializeEnumsAsStrings)
                {
                    expression = FickleExpression.Call(Expression.Convert(expression, valueType), typeof(string), "ToString", null);
                }

                expression = processOutputValue(expression);
            }
            else if (valueType.GetUnwrappedNullableType() == typeof(Guid))
            {
                expression = FickleExpression.Call(Expression.Convert(value, valueType), typeof(string), "ToString", null);

                expression = processOutputValue(expression);
            }
            else if (valueType.GetUnwrappedNullableType() == typeof(TimeSpan))
            {
                expression = FickleExpression.Call(value, typeof(string), "ToString", null);

                expression = processOutputValue(expression);
            }
            else if (valueType.GetUnwrappedNullableType() == typeof(DateTime))
            {
                expression = FickleExpression.Call(value, typeof(string), "ToString", null);

                expression = processOutputValue(expression);
            }
            else if (valueType is FickleListType)
            {
                var listType = valueType as FickleListType;

                if (listType.ListElementType.GetUnwrappedNullableType().IsNumericType() ||
                    (listType.ListElementType.GetUnwrappedNullableType().IsEnum&& !options.SerializeEnumsAsStrings))
                {
                    return(processOutputValue(value));
                }
                else
                {
                    var arrayVar  = FickleExpression.Variable("NSMutableArray", "array");
                    var variables = new[] { arrayVar };
                    var arrayItem = FickleExpression.Parameter(FickleType.Define("id"), "arrayItem");

                    var supportsNull = listType.ListElementType.IsNullable() ||
                                       !listType.ListElementType.IsValueType;

                    var forEachBody = Expression.IfThenElse
                                      (
                        Expression.ReferenceEqual(arrayItem, nsNull),
                        supportsNull ? FickleExpression.Call(arrayVar, "addObject", Expression.Convert(nsNull, typeof(object))).ToStatementBlock() : Expression.Continue(Expression.Label()).ToStatementBlock(),
                        GetSerializeExpression(listType.ListElementType, arrayItem, options, true, c => FickleExpression.Call(arrayVar, "addObject", Expression.Convert(c, typeof(object))).ToStatement()).ToBlock()
                                      );

                    expression = FickleExpression.Block
                                 (
                        variables,
                        Expression.Assign(arrayVar, FickleExpression.New("NSMutableArray", "initWithCapacity", FickleExpression.Call(value, typeof(int), "count", null))).ToStatement(),
                        FickleExpression.ForEach(arrayItem, value, FickleExpression.Block(forEachBody)),
                        processOutputValue(Expression.Convert(arrayVar, valueType))
                                 );
                }
            }
            else if (valueType.IsServiceType())
            {
                expression = processOutputValue(FickleExpression.Call(value, value.Type, "allPropertiesAsDictionary", null));
            }
            else
            {
                expression = processOutputValue(value);
            }

            if (!skipIfNull)
            {
                if (!TypeSystem.IsPrimitiveType(valueType) || valueType.IsNullable() || valueType.IsClass)
                {
                    if (value.Type == FickleType.Define("id") || value.Type == typeof(object))
                    {
                        expression = Expression.IfThen
                                     (
                            Expression.And
                            (
                                Expression.ReferenceNotEqual(Expression.Convert(value, typeof(object)), Expression.Constant(null)),
                                Expression.ReferenceNotEqual(Expression.Convert(value, typeof(object)), nsNull)
                            ),
                            expression is BlockExpression ? expression : FickleExpression.Block(expression)
                                     );
                    }
                    else
                    {
                        if (valueType.IsClass)
                        {
                            expression = Expression.IfThen
                                         (
                                Expression.ReferenceNotEqual(Expression.Convert(value, typeof(object)), Expression.Constant(null)),
                                expression is BlockExpression ? expression : FickleExpression.Block(expression)
                                         );
                        }
                        else
                        {
                            expression = Expression.IfThen
                                         (
                                Expression.NotEqual(value, Expression.Constant(null, value.Type)),
                                expression is BlockExpression ? expression : FickleExpression.Block(expression)
                                         );
                        }
                    }
                }
            }

            return(expression);
        }
Ejemplo n.º 32
0
        protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method)
        {
            var methodName       = method.Name.Uncapitalize();
            var methodParameters = new List <Expression>(method.Parameters);
            var methodVariables  = new List <ParameterExpression>();
            var methodStatements = new List <Expression>();

            var requestParameters = new List <Expression>(method.Parameters);

            var httpMethod = method.Attributes["Method"];
            var hostname   = currentTypeDefinitionExpression.Attributes["Hostname"];
            var path       = "http://" + hostname + method.Attributes["Path"];

            var client   = Expression.Variable(webServiceClientType, "webServiceClient");
            var callback = Expression.Parameter(typeof(object), "onComplete");

            methodParameters.Add(callback);

            var url = Expression.Variable(typeof(string), "url");

            methodVariables.Add(url);
            methodStatements.Add(Expression.Assign(url, Expression.Constant(path)));

            Object serviceCallArguments;

            if (httpMethod.Equals("post", StringComparison.InvariantCultureIgnoreCase) ||
                httpMethod.Equals("put", StringComparison.InvariantCultureIgnoreCase))
            {
                var contentParameterName = method.Attributes["Content"];

                var contentParam = requestParameters.FirstOrDefault(x => ((ParameterExpression)x).Name.Equals(contentParameterName, StringComparison.InvariantCultureIgnoreCase));

                if (contentParam == null)
                {
                    throw new Exception("Post or Put method defined with null Content. You must define a @content field in your FicklefileKeyword");
                }

                requestParameters = requestParameters.Where(x => x != contentParam).ToList();

                var payloadVar = Expression.Variable(typeof(string), "requestPayload");

                methodVariables.Add(payloadVar);

                var jsonBuilder = FickleType.Define("DefaultJsonBuilder");

                var jsonBuilderInstance = FickleExpression.StaticCall(jsonBuilder, "instance");

                var toJsonCall = FickleExpression.Call(jsonBuilderInstance, typeof(String), "toJson", contentParam);

                var payloadAssign = Expression.Assign(payloadVar, toJsonCall);

                methodStatements.Add(payloadAssign);

                serviceCallArguments = new
                {
                    url,
                    payloadVar,
                    callback
                };
            }
            else
            {
                serviceCallArguments = new
                {
                    url,
                    callback
                };
            }

            foreach (var parameter in requestParameters)
            {
                var param = (ParameterExpression)parameter;

                if (param.Type is FickleNullable)
                {
                    param = FickleExpression.Parameter(param.Type.GetUnwrappedNullableType(), param.Name);
                }

                var valueToReplace = Expression.Constant("{" + param.Name + "}", typeof(String));
                var valueAsString  = FickleExpression.Call(param, param.Type, typeof(String), SourceCodeGenerator.ToStringMethod, parameter);

                var replaceArgs = new
                {
                    valueToReplace,
                    valueAsString
                };

                methodStatements.Add(Expression.Assign(url, FickleExpression.Call(url, typeof(String), "replace", replaceArgs)));
            }

            methodStatements.Add(FickleExpression.Call(client, httpMethod, serviceCallArguments));

            var methodBody = FickleExpression.Block
                             (
                methodVariables.ToArray(),
                methodStatements.ToArray()
                             );

            return(new MethodDefinitionExpression(methodName, methodParameters.ToReadOnlyCollection(), AccessModifiers.Public, typeof(void), methodBody, false, null));
        }
        protected override Expression VisitPropertyDefinitionExpression(PropertyDefinitionExpression property)
        {
            var dictionaryType = new FickleType("NSDictionary");
            var currentValueFromDictionary = Expression.Parameter(typeof(object), "currentValueFromDictionary");
            var objectForKeyCall = Expression.Call(Expression.Parameter(dictionaryType, "properties"), new FickleMethodInfo(dictionaryType, typeof(object), "objectForKey", new ParameterInfo[] { new FickleParameterInfo(typeof(string), "key") }), Expression.Constant(property.PropertyName));
            var propertyExpression = Expression.Property(Expression.Parameter(this.type, "self"), new FicklePropertyInfo(this.type, property.PropertyType, property.PropertyName));

            var expressions = new List<Expression>
            {
                FickleExpression.Comment(property.PropertyName),
                Expression.Assign(currentValueFromDictionary, objectForKeyCall).ToStatement(),
                GetDeserializeExpressionProcessValueDeserializer(property.PropertyType, currentValueFromDictionary, c => Expression.Assign(propertyExpression, c).ToStatement())
            };

            this.propertyGetterExpressions.Add(expressions.ToStatementisedGroupedExpression(GroupedExpressionsExpressionStyle.Wide));

            return property;
        }
Ejemplo n.º 34
0
        private GatewayExpressionBinder(CodeGenerationContext codeGenerationContext)
        {
            this.CodeGenerationContext = codeGenerationContext;

            webServiceClientType = FickleType.Define(this.CodeGenerationContext.Options.ServiceClientTypeName ?? "WebServiceClient");
        }
        internal static Expression GetDeserializeExpressionProcessValueDeserializer(Type valueType, Expression value, Func<Expression, Expression> processOutputValue)
        {
            Expression outputValue;
            var nsNull = FickleExpression.StaticCall("NSNull", FickleType.Define("id"), "null", null);

            if (TypeSystem.IsPrimitiveType(valueType))
            {
                ConditionalExpression ifExpression;
                var underlyingType = valueType.GetUnwrappedNullableType();

                if (underlyingType.IsNumericType() || underlyingType == typeof(bool))
                {
                    var typeToCompare = new FickleType("NSNumber");

                    if (underlyingType.IsEnum && valueType.GetUnderlyingType() == null)
                    {
                        outputValue = Expression.Convert(FickleExpression.Call(value, typeof(int), "intValue", null), valueType);
                    }
                    else
                    {
                        outputValue = Expression.Convert(value, valueType);
                    }

                    ifExpression = Expression.IfThen(Expression.TypeIs(value, typeToCompare), processOutputValue(outputValue).ToBlock());
                }
                else if (underlyingType.IsEnum)
                {
                    Expression firstIf;

                    if (valueType.IsNullable())
                    {
                        outputValue = Expression.Convert(value, valueType);

                        firstIf = Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSNumber")), processOutputValue(outputValue).ToBlock());
                    }
                    else
                    {
                        outputValue = Expression.Convert(FickleExpression.Call(value, typeof(int), "intValue", null), valueType);

                        firstIf = Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSNumber")), processOutputValue(outputValue).ToBlock());
                    }

                    var parsedValue = FickleExpression.Variable(underlyingType, "parsedValue");
                    var success = Expression.Variable(typeof(bool), "success");

                    var parameters = new[] { new FickleParameterInfo(typeof(string), "value"), new FickleParameterInfo(underlyingType, "outValue", true) };
                    var methodInfo = new FickleMethodInfo(null, typeof(bool), TypeSystem.GetPrimitiveName(underlyingType, true) + "TryParse", parameters, true);

                    if (valueType.IsNullable())
                    {
                        outputValue = Expression.Convert(Expression.Condition(success, Expression.Convert(Expression.Convert(parsedValue, valueType), FickleType.Define("id")), Expression.Convert(FickleExpression.StaticCall(FickleType.Define("NSNull"), valueType, "null", null), FickleType.Define("id"))), valueType);
                    }
                    else
                    {
                        outputValue = Expression.Convert(parsedValue, valueType);
                    }

                    var secondIf = Expression.IfThenElse
                    (
                        Expression.TypeIs(value, FickleType.Define("NSString")),
                        FickleExpression.Block
                        (
                            new ParameterExpression[]
                            {
                                parsedValue,
                                success
                            },
                            Expression.IfThen
                            (
                                Expression.Not(Expression.Assign(success, Expression.Call(null, methodInfo, Expression.Convert(value, typeof(string)), parsedValue))),
                                Expression.Assign(parsedValue, Expression.Convert(Expression.Constant(0), underlyingType)).ToStatementBlock()
                            ),
                            processOutputValue(outputValue)
                        ),
                        firstIf
                    );

                    ifExpression = secondIf;
                }
                else
                {
                    ifExpression = Expression.IfThen(Expression.TypeIs(value, typeof(string)), processOutputValue(Expression.Convert(Expression.Convert(value, typeof(object)), valueType)).ToBlock());
                }

                if (valueType.IsNullable())
                {
                    ifExpression = Expression.IfThenElse
                    (
                        Expression.Equal(value, nsNull),
                        processOutputValue(Expression.Convert(nsNull, valueType)).ToBlock(),
                        ifExpression
                    );
                }

                return ifExpression;
            }
            else if (valueType is FickleType && ((FickleType)valueType).ServiceClass != null)
            {
                outputValue = FickleExpression.New(valueType, "initWithPropertyDictionary", FickleExpression.Convert(value, "NSDictionary"));

                return Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSDictionary")), processOutputValue(outputValue).ToBlock());
            }
            else if (valueType is FickleType && ((FickleType)valueType).ServiceEnum != null)
            {
                return Expression.IfThen(Expression.TypeIs(value, FickleType.Define("NSNumber")), processOutputValue(value).ToBlock());
            }
            else if (valueType is FickleListType)
            {
                var listType = valueType as FickleListType;

                var arrayVar = FickleExpression.Variable("NSMutableArray", "array");
                var variables = new[] { arrayVar };
                var arrayItem = FickleExpression.Parameter(FickleType.Define("id"), "arrayItem");

                var forEachBody = GetDeserializeExpressionProcessValueDeserializer(listType.ListElementType, arrayItem, c => FickleExpression.Call(arrayVar, "addObject", Expression.Convert(c, typeof(object))).ToStatement());

                var ifThen = Expression.IfThen
                (
                    Expression.TypeIs(value, FickleType.Define("NSArray")),
                    FickleExpression.Block
                    (
                        variables,
                        Expression.Assign(arrayVar, FickleExpression.New("NSMutableArray", "initWithCapacity", FickleExpression.Call(Expression.Convert(value, FickleType.Define("NSArray")), typeof(int), "count", null))).ToStatement(),
                        FickleExpression.ForEach(arrayItem, value, FickleExpression.Block(forEachBody)),
                        processOutputValue(Expression.Convert(arrayVar, valueType))
                    )
                );

                return ifThen;
            }
            else
            {
                throw new InvalidOperationException("Unsupported property type: " + valueType);
            }
        }