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 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 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)); }
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() })); }
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 )); }
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)); }
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() })); }
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)); }
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)); }
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)); }
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() })); }
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)); }
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)); }
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() })); }
public static NewExpression New(string typeName) { return(Expression.New(FickleType.Define(typeName))); }
private GatewayExpressionBinder(CodeGenerationContext codeGenerationContext) { this.CodeGenerationContext = codeGenerationContext; this.webServiceClientType = FickleType.Define(this.CodeGenerationContext.Options.ServiceClientTypeName ?? "WebServiceClient"); }
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); }
private MethodDefinitionExpression CreateInitWithOptionsMethod() { var self = FickleExpression.Variable(currentType, "self"); var super = FickleExpression.Variable(currentType, "super"); var options = FickleExpression.Parameter("NSDictionary", "options"); var superinit = FickleExpression.Call(super, currentType, "init", null); var initBlock = FickleExpression.Block(Expression.Assign(FickleExpression.Property(self, "NSDictionary", "options"), options)); var body = FickleExpression.Block(Expression.IfThen(Expression.NotEqual(Expression.Assign(self, superinit), Expression.Constant(null, this.currentType)), initBlock), Expression.Return(Expression.Label(), self)); return(new MethodDefinitionExpression("initWithOptions", new Expression[] { options }.ToReadOnlyCollection(), FickleType.Define("id"), body, false, null)); }
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())); }
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); }
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())); }
public static MethodCallExpression StaticCall(string type, Type returnType, string methodName, object arguments) { return(Call(null, FickleType.Define(type), returnType, methodName, arguments, true)); }
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)); }
protected override Expression VisitTypeDefinitionExpression(TypeDefinitionExpression expression) { this.currentType = expression.Type; this.currentTypeDefinitionExpression = expression; this.currentReturnTypes = new HashSet <Type>(ReturnTypesCollector.CollectReturnTypes(expression)); var includeExpressions = new List <IncludeExpression> { FickleExpression.Include(expression.Type.Name + ".h"), FickleExpression.Include("PKWebServiceClient.h"), FickleExpression.Include("NSArray+PKExtensions.h"), FickleExpression.Include(this.CodeGenerationContext.Options.ResponseStatusTypeName + ".h") }; var comment = new CommentExpression("This file is AUTO GENERATED"); var expressions = new List <Expression> { CreateCreateClientMethod(), CreateInitMethod(), CreateInitWithOptionsMethod() }; var rawParameterTypes = ParameterTypesCollector .Collect(expression, c => c.Attributes["Method"].EqualsIgnoreCase("post") && c.Attributes.ContainsKey("Content")) .Select(c => new Tuple <Type, string>(c.Item1.GetFickleListElementType() ?? c.Item1, c.Item2)) .Select(c => new Tuple <Type, string>(c.Item1.GetUnwrappedNullableType(), c.Item2)) .Distinct(); foreach (var value in rawParameterTypes .Select(c => new { Type = c.Item1, Name = this.GetNormalizeRequestMethodName(c.Item1, c.Item2), Format = c.Item2 }) .GroupBy(c => c.Name) .Select(c => c.First())) { var type = value.Type; var format = value.Format; expressions.Add(this.CreateNormalizeRequestObjectMethod(type, format)); } expressions.Add(this.Visit(expression.Body)); if (methodCount > 0) { expressions.Add(this.CreateCreateErrorResponseWithErrorCodeMethod()); expressions.Add(this.CreateParseResultMethod()); } expressions.Add(this.CreateSerializeRequestMethod()); var body = GroupedExpressionsExpression.FlatConcat ( GroupedExpressionsExpressionStyle.Wide, expressions.ToArray() ); var singleValueResponseTypes = currentReturnTypes.Where(c => c.GetUnwrappedNullableType().IsPrimitive).Select(c => FickleType.Define(ObjectiveBinderHelpers.GetValueResponseWrapperTypeName(c))).ToList(); var referencedTypes = ReferencedTypesCollector.CollectReferencedTypes(body).Concat(singleValueResponseTypes).Distinct().ToList(); referencedTypes.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase)); foreach (var referencedType in referencedTypes.Where(c => (c as FickleType)?.ServiceClass != null)) { includeExpressions.Add(FickleExpression.Include(referencedType.Name + ".h")); } var headerGroup = includeExpressions.Sorted(IncludeExpression.Compare).ToGroupedExpression(); var header = new Expression[] { comment, headerGroup }.ToGroupedExpression(GroupedExpressionsExpressionStyle.Wide); this.currentType = null; return(new TypeDefinitionExpression(expression.Type, header, body, false, expression.Attributes)); }
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() })); }
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 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); } }
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)); }
public static MemberExpression Property(Expression instance, string typeName, string propertyName) { return(FickleExpression.Property(instance, FickleType.Define(typeName), propertyName)); }