Skip to content

Commit

Permalink
Add codegen support for binding Task and Task<T> return values
Browse files Browse the repository at this point in the history
  • Loading branch information
Rohansi committed Jun 6, 2024
1 parent e57026b commit 4fdd5f8
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Mond.SourceGenerator/MondSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,18 @@ private static string ConvertToMondValue(GeneratorExecutionContext context, stri
return $"({input} ?? MondValue.Undefined)";
}

if (SymbolEqualityComparer.Default.Equals(type, TypeLookup.Task))
{
return $"Mond.Libraries.AsyncUtil.ToObject({input});";
}

if (type is INamedTypeSymbol { Arity: 1 } namedType && SymbolEqualityComparer.Default.Equals(namedType.ConstructedFrom, TypeLookup.TaskOfT))
{
var returnType = namedType.TypeArguments[0];
var returnWrapper = ConvertToMondValue(context, "t.Result", returnType, typeSource);
return $"Mond.Libraries.AsyncUtil.ToObject({input}.ContinueWith(t => t.IsFaulted ? AsyncUtil.RethrowAsyncException(t.Exception) : {returnWrapper}));";
}

if (type.HasAttribute("MondClassAttribute"))
{
return $"MondValue.ClassInstance(state, {input}, \"{type.GetFullyQualifiedName()}\")";
Expand Down
6 changes: 6 additions & 0 deletions Mond.SourceGenerator/TypeLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ internal static class TypeLookup
public static INamedTypeSymbol Void { get; private set; }
public static INamedTypeSymbol String { get; private set; }
public static INamedTypeSymbol Bool { get; private set; }
public static INamedTypeSymbol Task { get; private set; }
public static INamedTypeSymbol TaskOfT { get; private set; }
public static INamedTypeSymbol MondValue { get; private set; }
public static INamedTypeSymbol MondValueNullable { get; private set; }
public static IArrayTypeSymbol MondValueArray { get; private set; }
Expand All @@ -34,6 +36,8 @@ public static bool Initialize(GeneratorExecutionContext context)
var stringSym = compilation.GetSpecialType(SpecialType.System_String);
var boolSym = compilation.GetSpecialType(SpecialType.System_Boolean);
var nullableSym = compilation.GetSpecialType(SpecialType.System_Nullable_T);
var taskSym = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
var taskOfTSym = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");

var mondValueSym = compilation.GetTypesByMetadataName("Mond.MondValue")
.SingleOrDefault(s => s.ContainingAssembly.Identity.Name == "Mond");
Expand All @@ -56,6 +60,8 @@ public static bool Initialize(GeneratorExecutionContext context)
Void = voidSym;
String = stringSym;
Bool = boolSym;
Task = taskSym;
TaskOfT = taskOfTSym;
MondValue = mondValueSym;
MondValueNullable = nullableSym.Construct(mondValueSym);
MondValueArray = compilation.CreateArrayTypeSymbol(mondValueSym);
Expand Down
14 changes: 14 additions & 0 deletions Mond.Tests/Binding/FunctionTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Mond.Binding;
using NUnit.Framework;

Expand Down Expand Up @@ -320,6 +321,19 @@ public static string Greet(ClassTests.Person person)
return person.GenerateGreeting();
}

[MondFunction]
public static async Task AsyncMethod(int ms)
{
await Task.Delay(ms);
}

[MondFunction]
public static async Task<int> AsyncMethodWithReturn(int ms)
{
await Task.Delay(ms);
return ms;
}

#if false
[MondFunction]
public static decimal UnsupportedReturn()
Expand Down
13 changes: 13 additions & 0 deletions Mond/Libraries/AsyncLibraries.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Mond.Libraries.Async;

namespace Mond.Libraries
Expand Down Expand Up @@ -137,5 +139,16 @@ public static Task<MondValue>[] ToTaskArray(MondState state, params MondValue[]

return token.CancellationToken;
}

/// <summary>
/// Used to rethrow exceptions thrown in async methods that have bindings generated for them.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never), UsedImplicitly]
public static MondValue RethrowAsyncException(AggregateException e)
{
var exception = e.InnerExceptions.Count != 1 ? e : e.InnerException ?? e;
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(exception).Throw();
throw exception;
}
}
}

0 comments on commit 4fdd5f8

Please sign in to comment.