Skip to content

Commit

Permalink
Merge pull request #9 from koculu/8-feature-create-an-interface-to-ex…
Browse files Browse the repository at this point in the history
…tract-meta-information-from-topazfunction

Add ITopazFunction interface to expose function functionality and meta information.
  • Loading branch information
koculu authored Dec 3, 2022
2 parents 6b18657 + 74f2f70 commit 3a3bba9
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 13 deletions.
36 changes: 36 additions & 0 deletions src/Tenray.Topaz.Test/FunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,40 @@ function f2(y) {
Assert.AreEqual(7, model.p);
Assert.AreEqual(14, model.q);
}

[Test]
public void FunctionInformation()
{
var engine = new TopazEngine();
dynamic model = new JsObject();
engine.SetValue("model", model);
engine.ExecuteScript(@"
function f1(a, b, c)
{
}
function f2(a, b=34, c)
{
}
model.f1 = f1
model.f2 = f2
");
var f1 = model.f1 as ITopazFunction;
var f2 = model.f2 as ITopazFunction;

Assert.AreEqual("f1", f1.Name);
Assert.AreEqual(3, f1.Length);
Assert.AreEqual("a", f1[0]);
Assert.AreEqual("b", f1[1]);
Assert.AreEqual("c", f1[2]);

Assert.AreEqual("f2", f2.Name);
Assert.AreEqual(3, f2.Length);
Assert.AreEqual("a", f2[0]);
Assert.AreEqual("b", f2[1]);
Assert.AreEqual("c", f2[2]);
f1.Invoke(new(), 1, 2, 3);
f2.Invoke(new(), 1, 2, 5.7);
f1.InvokeAsync(new(), 1, true, 3, 5);
f2.InvokeAsync(new(), "test", 2, 3);
}
}
4 changes: 2 additions & 2 deletions src/Tenray.Topaz/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<Authors>Ahmed Yasin Koculu</Authors>
<PackageId>Topaz</PackageId>
<Title>Topaz</Title>
<ProductVersion>1.2.7.0</ProductVersion>
<Version>1.2.7.0</Version>
<ProductVersion>1.2.8.0</ProductVersion>
<Version>1.2.8.0</Version>
<Authors>Ahmed Yasin Koculu</Authors>
<AssemblyTitle>Topaz</AssemblyTitle>
<Description>Multithreaded Javascript Engine for .NET</Description>
Expand Down
6 changes: 3 additions & 3 deletions src/Tenray.Topaz/ITopazEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface ITopazEngine
/// Engine Options.
/// </summary>
TopazEngineOptions Options { get; set; }

/// <summary>
/// Global Scope.
/// </summary>
Expand Down Expand Up @@ -132,14 +132,14 @@ public interface ITopazEngine
/// <param name="name"></param>
/// <param name="typeProxy"></param>
void AddType<T>(string name = null, ITypeProxy typeProxy = null);

/// <summary>
/// Adds a type to be used in Javascript.
/// </summary>
/// <param name="type"></param>
/// <param name="name"></param>
/// <param name="typeProxy"></param>
void AddType(Type type,string name = null, ITypeProxy typeProxy = null);
void AddType(Type type, string name = null, ITypeProxy typeProxy = null);

/// <summary>
/// Adds extension methods defined in type.
Expand Down
41 changes: 41 additions & 0 deletions src/Tenray.Topaz/ITopazFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Tenray.Topaz;

public interface ITopazFunction
{
/// <summary>
/// Gets name of the function.
/// </summary>
string Name { get; }

/// <summary>
/// Gets the number of arguments of the function.
/// </summary>
int Length { get; }

/// <summary>
/// Gets the nth argument name of the function.
/// </summary>
/// <param name="index">The index of the argument.</param>
/// <returns>Name of the argument.</returns>
string this[int index] { get; }

/// <summary>
/// Invokes the function using arguments.
/// </summary>
/// <param name="token">CancellationToken.</param>
/// <param name="args">Arguments.</param>
/// <returns>The object returned from function implementation.</returns>
object Invoke(CancellationToken token, params object[] args);

/// <summary>
/// Invokes the function asynchronously using arguments.
/// </summary>
/// <param name="args">Arguments.</param>
/// <param name="token">CancellationToken.</param>
/// <returns>The object returned from function implementation.</returns>
ValueTask<object> InvokeAsync(CancellationToken token, params object[] args);
}
65 changes: 57 additions & 8 deletions src/Tenray.Topaz/Wrappers/TopazFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@

namespace Tenray.Topaz;

internal sealed class TopazFunction : IConvertible
internal sealed class TopazFunction : IConvertible, ITopazFunction
{
internal ScriptExecutor ScriptExecutor { get; }

internal string Name { get; private set; }
public string Name { get; private set; }

public int Length => GetArgumentsLength();

public string this[int index] => GetArgumentName(index);

FunctionDeclaration expr1;

Expand Down Expand Up @@ -52,7 +56,7 @@ public object Execute(IReadOnlyList<object> args, CancellationToken token)
{
token.ThrowIfCancellationRequested();
var scriptExecutor = ScriptExecutor.NewFunctionInnerBlockScope();
var parameters =
var parameters =
expr1?.Params ??
expr2?.Params ??
expr3.Params;
Expand All @@ -76,7 +80,7 @@ public object Execute(IReadOnlyList<object> args, CancellationToken token)
p = r.Argument;
isRest = true;
}

if (p is ObjectPattern objectPattern)
{
// dont process Object Pattern for missing arguments!
Expand All @@ -97,8 +101,8 @@ public object Execute(IReadOnlyList<object> args, CancellationToken token)
if (isRest)
{
var restLen = args.Count - i;
var rested = restLen < 0 ?

var rested = restLen < 0 ?
Array.Empty<object>() :
new object[restLen];
for (var j = 0; j < restLen; ++j)
Expand All @@ -116,7 +120,7 @@ public object Execute(IReadOnlyList<object> args, CancellationToken token)
VariableKind.Var);
}
}

var result = scriptExecutor.ExecuteStatement(
expr1?.Body ??
expr2?.Body ??
Expand Down Expand Up @@ -308,7 +312,7 @@ public object ToType(Type conversionType, IFormatProvider provider)
{
if (!conversionType.IsSubclassOf(typeof(Delegate)))
throw new NotSupportedException();

var topazParameters =
expr1?.Params ??
expr2?.Params ??
Expand All @@ -324,4 +328,49 @@ public object ToType(Type conversionType, IFormatProvider provider)
return DynamicDelagateFactory.CreateDynamicDelegate(argTypes, returnType,
(args) => Execute(args, default), ScriptExecutor.TopazEngine.ValueConverter);
}

int GetArgumentsLength()
{
var parameters =
expr1?.Params ??
expr2?.Params ??
expr3.Params;
return parameters.Count;
}

string GetArgumentName(int index)
{
var parameters =
expr1?.Params ??
expr2?.Params ??
expr3.Params;
if (index < 0 || index >= parameters.Count)
return null;

var p = parameters[index];
if (p is AssignmentPattern assignmentPattern)
{
// ex: (x = 1) => x * x
p = assignmentPattern.Left;
}
else if (p is RestElement r)
{
p = r.Argument;
}

if (p is ObjectPattern)
{
// Object pattern argument string extraction is not supported!
return null;
}
var id = p as Identifier;
if (id == null)
return null;
return id.Name;
}

public object Invoke(CancellationToken token, params object[] args) => Execute(args, token);

public ValueTask<object> InvokeAsync(CancellationToken token, params object[] args)
=> ExecuteAsync(args, token);
}

0 comments on commit 3a3bba9

Please sign in to comment.