protected override void WriteAsyncMethod( Method method, string declaringTypeFullName, string boundTypeFullName, bool isInterfaceMember, CodeWriter code) { string asyncReturnType = this.FindAsyncReturnType(boundTypeFullName, method.Name, declaringTypeFullName); string mappedAsyncReturnType = this.GetMemberTypeName(asyncReturnType, declaringTypeFullName, method.Name); string xamarinReturnType = this.MapTypeName(asyncReturnType); if (asyncReturnType == "java.util.UUID") { // TODO: This special case shouldn't be necessary here. xamarinReturnType = "Java.Util.UUID"; } string castFromType = xamarinReturnType; if (xamarinReturnType == null) { if (asyncReturnType.StartsWith("java.util.List<")) { // Java lists inside a Future don't get automatically converted to // the generic IList<> by Xamarin. xamarinReturnType = "System.Collections.IList"; string itemType = asyncReturnType.Substring(asyncReturnType.IndexOf('<') + 1); itemType = itemType.Substring(0, itemType.Length - 1); castFromType = xamarinReturnType + "<" + (this.MapTypeName(itemType) ?? itemType) + ">"; } else { xamarinReturnType = mappedAsyncReturnType; castFromType = xamarinReturnType; } } string context = this.GetImplicitContext(method, code); int skip = context != null ? 1 : 0; bool isAbstract = isInterfaceMember || method.IsAbstract; string parameters = String.Join(", ", method.Parameters.Skip(skip).Select( (p, i) => GetParameterTypeName(p.ParameterType, declaringTypeFullName, method.Name, i) + " " + p.Name)); code.Code($"{(isInterfaceMember ? "" : "public ")}{(method.IsStatic ? "static " : "")}" + $"{(isAbstract && !isInterfaceMember ? "abstract" : "async")} " + "System.Threading.Tasks.Task" + (mappedAsyncReturnType != "void" ? "<" + mappedAsyncReturnType + ">" : "") + $" {method.Name}({parameters}){(isAbstract ? ";" : "")}"); if (!isAbstract) { code.Code("{"); if (context != null && method.Parameters.Count > 1) { context += ", "; } string arguments = (context != null ? context : String.Empty) + String.Join(", ", method.Parameters.Skip(skip).Select( (p, i) => this.CastArgument( p.Name, this.GetParameterTypeName(p.ParameterType, declaringTypeFullName, method.Name, i), p.ParameterType))); string forward = (method.IsStatic ? boundTypeFullName : "Forward"); code.Code($"\tvar future = {forward}.{method.Name}({arguments});"); if (mappedAsyncReturnType == "void") { code.Code("\tawait Java.Util.Concurrent.IFutureExtensions.GetAsync(future);"); } else { code.Code($"\tvar result = ({xamarinReturnType})" + "await Java.Util.Concurrent.IFutureExtensions.GetAsync(future);"); code.Code($"\treturn " + this.CastArgument($"result", castFromType, mappedAsyncReturnType) + ";"); } code.Code("}"); } }