protected override Expression VisitPropertyDefinitionExpression(PropertyDefinitionExpression property) { var name = property.PropertyName.Uncapitalize(); fieldDefinitionsForProperties.Add(new FieldDefinitionExpression(name, property.PropertyType, AccessModifiers.Protected)); var thisProperty = FickleExpression.Variable(property.PropertyType, "this." + name); var getterBody = FickleExpression.Block ( new Expression[] { FickleExpression.Return(thisProperty) } ); var setterParam = FickleExpression.Parameter(property.PropertyType, name); var setterBody = FickleExpression.Block ( new Expression[] { Expression.Assign(thisProperty, setterParam) } ); var propertyGetter = new MethodDefinitionExpression("get" + property.PropertyName, new List <Expression>(), AccessModifiers.Public, property.PropertyType, getterBody, false); var propertySetter = new MethodDefinitionExpression("set" + property.PropertyName, new List <Expression> { setterParam }, AccessModifiers.Public, typeof(void), setterBody, false); return(new Expression[] { propertyGetter, propertySetter }.ToStatementisedGroupedExpression()); }
protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { WriteLine(); this.Write(AccessModifiersToString(method.AccessModifiers)); if (method.ReturnType != null) //null for constructors { this.Write(method.ReturnType); this.Write(" "); } this.Write(method.Name); this.Write("("); for (var i = 0; i < method.Parameters.Count; i++) { var parameter = (ParameterExpression)method.Parameters[i]; if (parameter.Type is FickleNullable) { this.Write(parameter.Type.GetUnwrappedNullableType()); } else { this.Write(parameter.Type); } this.Write(" "); this.Write(parameter.Name); if (i != method.Parameters.Count - 1) { this.Write(", "); } } this.Write(")"); if (method.Exceptions != null && method.Exceptions.Count > 0) { this.Write(" throws"); foreach (var exception in method.Exceptions) { this.Write(" "); this.Write(exception.GetType()); } } this.WriteLine(); this.Visit(method.Body); return(method); }
protected virtual Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { var expressions = this.VisitExpressionList(method.Parameters); var body = this.Visit(method.Body); if (expressions != method.Parameters || body != method.Body) { return(new MethodDefinitionExpression(method.Name, expressions, method.AccessModifiers, method.ReturnType, body, method.IsPredeclaration, method.RawAttributes, method.Attributes)); } return(method); }
protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { this.WriteLine(); this.Write(AccessModifiersToString(method.AccessModifiers)); if (method.ReturnType != null) //null for constructors { var fickleTaskReturnType = method.ReturnType as CSharpAwaitedTaskType; if (fickleTaskReturnType != null) { this.Write("async "); } this.Write(method.ReturnType); this.Write(" "); } this.Write(method.Name); this.Write("("); for (var i = 0; i < method.Parameters.Count; i++) { var parameter = (ParameterExpression)method.Parameters[i]; if (parameter.Type is FickleNullable) { this.Write(parameter.Type.GetUnwrappedNullableType()); } else { this.Write(parameter.Type); } this.Write(" "); this.Write(parameter.Name); if (i != method.Parameters.Count - 1) { this.Write(", "); } } this.Write(")"); this.WriteLine(); this.Visit(method.Body); return(method); }
protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { ParameterExpression optionsParameter; var self = Expression.Variable(currentType, "self"); var gatewayCall = (MethodDefinitionExpression)this.CreateGatewayCallMethod(method, out optionsParameter); var newArgs = gatewayCall.Parameters.Select(c => c != optionsParameter ? c : Expression.Constant(null, c.Type)).ToList(); var newMethodParams = gatewayCall.Parameters.Where(c => c != optionsParameter).ToList(); var methodInfo = new FickleMethodInfo(self.Type, gatewayCall.ReturnType, gatewayCall.Name, gatewayCall.Parameters.Cast <ParameterExpression>().Select(c => new FickleParameterInfo(c.Type, c.Name)).ToArray()); var newBody = Expression.Call(self, methodInfo, newArgs).ToStatementBlock(); var gatewayCallMethodWithoutOptions = new MethodDefinitionExpression(gatewayCall.Name, newMethodParams, gatewayCall.ReturnType, newBody, false, gatewayCall.RawAttributes, gatewayCall.Attributes); return(new GroupedExpressionsExpression(new [] { gatewayCall, gatewayCallMethodWithoutOptions }, GroupedExpressionsExpressionStyle.Wide)); }
protected override Expression VisitPropertyDefinitionExpression(PropertyDefinitionExpression property) { var name = property.PropertyName.ToCamelCase(); var propertyDefinition = new PropertyDefinitionExpression(name, property.PropertyType, true, property.Modifiers); if (name.StartsWith("new")) { var attributedPropertyGetter = new MethodDefinitionExpression(name, new Expression[0], property.PropertyType, Expression.Empty(), true, "(objc_method_family(none))", null); return(new Expression[] { propertyDefinition, attributedPropertyGetter }.ToStatementisedGroupedExpression()); } else { return(propertyDefinition); } }
protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { if (this.acceptMethod(method)) { try { this.currentMethod = method; return(base.VisitMethodDefinitionExpression(method)); } finally { this.currentMethod = null; } } return(method); }
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 VisitMethodDefinitionExpression(MethodDefinitionExpression method) { AddType(method.ReturnType); return(base.VisitMethodDefinitionExpression(method)); }
protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { if ((method.AccessModifiers & AccessModifiers.ClasseslessFunction) != 0) { if ((method.AccessModifiers & AccessModifiers.Static) != 0) { this.Write("static "); } if (method.RawAttributes != null) { this.Write(method.RawAttributes); this.Write(' '); } this.Write(method.ReturnType); this.Write(" "); this.Write(method.Name); this.Write("("); for (var i = 0; i < method.Parameters.Count; i++) { var parameter = (ParameterExpression)method.Parameters[i]; this.Write(parameter.Type); this.Write(" "); this.Write(parameter.Name); if (i != method.Parameters.Count - 1) { this.Write(", "); } } this.Write(")"); if (method.IsPredeclaration) { this.Write(";"); return(method); } this.WriteLine(); this.Visit(method.Body); this.WriteLine(); } else { if ((method.AccessModifiers & AccessModifiers.Static) == AccessModifiers.Static) { this.Write("+"); } else { this.Write("-"); } this.Write('('); this.Write(method.ReturnType); this.Write(')'); this.WriteSpace(); this.Write(method.Name); for (var i = 0; i < method.Parameters.Count; i++) { var parameter = (ParameterExpression)method.Parameters[i]; if (i != 0) { this.Write(parameter.Name); } this.Write(':'); this.Write('('); this.Write(parameter.Type); this.Write(')'); this.Write(parameter.Name); if (i != method.Parameters.Count - 1) { this.Write(" "); } } if (!string.IsNullOrEmpty(method.RawAttributes) && method.IsPredeclaration) { this.Write(" __attribute__({0})", method.RawAttributes); } if (method.IsPredeclaration) { this.WriteLine(';'); } else { this.WriteLine(); this.Visit(method.Body); this.WriteLine(); } } return(method); }
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)); }
protected override Expression VisitMethodDefinitionExpression(MethodDefinitionExpression method) { var client = Expression.Variable(this.fickleApiClientType, FickleApiClientFieldName); var apiCallGenericTypes = new List <Type>(); var returnTaskType = FickleType.Define("Task"); if (method.ReturnType != typeof(void)) { returnTaskType.MakeGenericType(method.ReturnType); } var methodParameters = new List <Expression>(method.Parameters); var methodVariables = new List <ParameterExpression>(); var methodStatements = new List <Expression>(); var requestUrl = Expression.Variable(typeof(InterpolatedString), "fickleRequestUrl"); methodVariables.Add(requestUrl); methodStatements.Add(Expression.Assign(requestUrl, Expression.Constant(new InterpolatedString(method.Attributes["Path"])))); var httpMethod = Expression.Constant(method.Attributes["Method"]); var isSecure = Expression.Constant(method.Attributes["Secure"] == "True"); var isAuthenticated = Expression.Constant(method.Attributes["Authenticated"] == "True"); var returnFormat = Expression.Constant(method.Attributes["ReturnFormat"]); if (method.ReturnType != typeof(void)) { apiCallGenericTypes.Add(method.ReturnType); } object apiArgs; var contentParameterName = method.Attributes["Content"]; if (!string.IsNullOrEmpty(contentParameterName)) { var contentParam = method.Parameters.FirstOrDefault(x => ((ParameterExpression)x).Name.Equals(contentParameterName, StringComparison.InvariantCultureIgnoreCase)); if (contentParam == null) { throw new Exception("Content paramter not found"); } apiCallGenericTypes.Add(contentParam.Type); apiArgs = new { requestUrl, httpMethod, isSecure, isAuthenticated, returnFormat, contentParam }; } else { apiArgs = new { requestUrl, httpMethod, isSecure, isAuthenticated, returnFormat }; } var clientCall = FickleExpression.Call(client, returnTaskType, "ExecuteAsync", apiArgs); if (apiCallGenericTypes.Count > 0) { clientCall.Method.MakeGenericMethod(apiCallGenericTypes.ToArray()); } var result = Expression.Variable(returnTaskType, "fickleResult"); methodVariables.Add(result); methodStatements.Add(Expression.Assign(result, clientCall)); methodStatements.Add(FickleExpression.Return(result)); var methodBody = FickleExpression.Block ( methodVariables.ToArray(), methodStatements.ToArray() ); return(new MethodDefinitionExpression(method.Name, methodParameters.ToReadOnlyCollection(), AccessModifiers.Public, returnTaskType, methodBody, false, null)); }