Skip to content

Commit 1422aca

Browse files
authored
Merge pull request #27 from koculu/24-feature-add-an-interface-to-customize-retrieving-type-members
Add await expression handler interface.
2 parents 848c987 + 44df8aa commit 1422aca

File tree

7 files changed

+81
-4
lines changed

7 files changed

+81
-4
lines changed

src/Topaz.Test/AwaitTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Linq;
66
using System.Reflection;
7+
using System.Threading;
78
using System.Threading.Tasks;
89
using Tenray.Topaz.API;
910
using Tenray.Topaz.Interop;
@@ -150,6 +151,54 @@ public void AsyncEnumerator()
150151
");
151152
Assert.That(model.result2, Is.EqualTo(5));
152153
}
154+
155+
[Test]
156+
public void CustomAwaitHandler()
157+
{
158+
var engine = new TopazEngine(new TopazEngineSetup { AwaitExpressionHandler = new CustomAwaitExpressionHandler() });
159+
dynamic model = new JsObject();
160+
engine.SetValue("test", this);
161+
engine.SetValue("model", model);
162+
engine.ExecuteScriptAsync(@"
163+
model.result1 = await test.GenericTask();
164+
").Wait();
165+
Assert.That(model.result1, Is.EqualTo(33));
166+
engine.ExecuteScript(@"
167+
model.result2 = await test.GenericTask();
168+
");
169+
Assert.That(model.result2, Is.EqualTo(33));
170+
}
171+
172+
[Test]
173+
public void CustomAwaitHandler2()
174+
{
175+
var engine = new TopazEngine(new TopazEngineSetup { AwaitExpressionHandler = new CustomAwaitExpressionHandler() });
176+
dynamic model = new JsObject();
177+
engine.SetValue("test", this);
178+
engine.SetValue("model", model);
179+
engine.ExecuteScriptAsync(@"
180+
var t = test.GenericTask();
181+
model.result1 = await t;
182+
").Wait();
183+
Assert.That(model.result1, Is.EqualTo(33));
184+
engine.ExecuteScript(@"
185+
var t = test.GenericTask();
186+
model.result2 = await t;
187+
");
188+
Assert.That(model.result2, Is.EqualTo(33));
189+
}
190+
}
191+
192+
class CustomAwaitExpressionHandler : IAwaitExpressionHandler
193+
{
194+
public async Task<object> HandleAwaitExpression(object awaitObject, CancellationToken token)
195+
{
196+
if (awaitObject is Task<int> task)
197+
{
198+
return await task;
199+
}
200+
return awaitObject;
201+
}
153202
}
154203

155204
class CustomMemberInfoProvider : IMemberInfoProvider

src/Topaz/AstHandlers/AsyncHandlers/Expressions/AwaitExpressionHandler.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ internal static partial class AwaitExpressionHandler
1010
internal async static ValueTask<object> ExecuteAsync(ScriptExecutor scriptExecutor, Node expression, CancellationToken token)
1111
{
1212
var expr = (AwaitExpression)expression;
13-
var result = await scriptExecutor.ExecuteStatementAsync(expr.Argument, token);
13+
var result = await scriptExecutor.ExecuteExpressionAndGetValueAsync(expr.Argument, token);
1414
if (result == null)
1515
return null;
16+
var awaitHandler = scriptExecutor.TopazEngine.AwaitExpressionHandler;
17+
if (awaitHandler != null)
18+
{
19+
return await awaitHandler.HandleAwaitExpression(result, token);
20+
}
1621
if (result is Task task)
1722
{
1823
var type = task.GetType();

src/Topaz/AstHandlers/Expressions/AwaitExpressionHandler.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,16 @@ internal static partial class AwaitExpressionHandler
1111
internal static object Execute(ScriptExecutor scriptExecutor, Node expression, CancellationToken token)
1212
{
1313
var expr = (AwaitExpression)expression;
14-
var result = scriptExecutor.ExecuteStatement(expr.Argument, token);
14+
var result = scriptExecutor.ExecuteExpressionAndGetValue(expr.Argument, token);
15+
var awaitHandler = scriptExecutor.TopazEngine.AwaitExpressionHandler;
16+
if (result == null)
17+
return null;
18+
if (awaitHandler != null)
19+
{
20+
var task1 = awaitHandler.HandleAwaitExpression(result, token);
21+
task1.Wait(token);
22+
return task1.Result;
23+
}
1524
if (result is Task task)
1625
{
1726
task.Wait(token);

src/Topaz/Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<Authors>Ahmed Yasin Koculu</Authors>
66
<PackageId>Topaz</PackageId>
77
<Title>Topaz</Title>
8-
<ProductVersion>1.3.8.0</ProductVersion>
9-
<Version>1.3.8.0</Version>
8+
<ProductVersion>1.3.9.0</ProductVersion>
9+
<Version>1.3.9.0</Version>
1010
<Authors>Ahmed Yasin Koculu</Authors>
1111
<AssemblyTitle>Topaz</AssemblyTitle>
1212
<Description>Multithreaded Javascript Engine for .NET</Description>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
4+
namespace Tenray.Topaz.Interop;
5+
6+
public interface IAwaitExpressionHandler
7+
{
8+
Task<object> HandleAwaitExpression(object awaitObject, CancellationToken token);
9+
}

src/Topaz/TopazEngine.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public sealed class TopazEngine : ITopazEngine
3737

3838
public IMemberInfoProvider MemberInfoProvider { get; }
3939

40+
public IAwaitExpressionHandler AwaitExpressionHandler { get; }
41+
4042
internal ScriptExecutorPool ScriptExecutorPool = new();
4143

4244
public TopazEngine(TopazEngineSetup setup = null)
@@ -52,6 +54,7 @@ public TopazEngine(TopazEngineSetup setup = null)
5254
ObjectProxyRegistry = setup.ObjectProxyRegistry ?? new DictionaryObjectProxyRegistry();
5355
extensionMethodRegistry = new();
5456
MemberInfoProvider = setup.MemberInfoProvider ?? new MemberInfoProvider();
57+
AwaitExpressionHandler = setup.AwaitExpressionHandler;
5558
ValueConverter = setup.ValueConverter ?? new DefaultValueConverter();
5659
DefaultObjectProxy = setup.DefaultObjectProxy ?? new ObjectProxyUsingReflection(null, extensionMethodRegistry, ValueConverter, MemberInfoProvider);
5760
DelegateInvoker = setup.DelegateInvoker ?? new DelegateInvoker(ValueConverter);

src/Topaz/TopazEngineSetup.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ public sealed class TopazEngineSetup
2424
public IValueConverter ValueConverter { get; set; }
2525

2626
public IMemberInfoProvider MemberInfoProvider { get; set; }
27+
28+
public IAwaitExpressionHandler AwaitExpressionHandler { get; set; }
2729
}

0 commit comments

Comments
 (0)