Skip to content

Commit

Permalink
General improvements:
Browse files Browse the repository at this point in the history
- Wrapped constructors are now named starting with "make" then "make_1" and so on.
- Improved case converter to account for non-alphanum+underscore characters.
- Tasks are now no longer awaited before being wrapped and are now wrapped like any other C# object.
- Added new method in CodeExecutor for adding wrappers to the context.
  • Loading branch information
Uralstech committed Nov 9, 2024
1 parent 697750f commit 62af557
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 43 deletions.
21 changes: 21 additions & 0 deletions src/Executor/CodeExecutor.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using EzrSquared.Runtime;
using EzrSquared.Runtime.Types.CSharpWrappers.Builtins;
using EzrSquared.Runtime.Types.CSharpWrappers.CompatWrappers;
using EzrSquared.Syntax;
using EzrSquared.Syntax.Errors;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace EzrSquared.Executor;

Expand Down Expand Up @@ -75,6 +77,25 @@ public static void AddToContext(Reference reference, string name)
RuntimeContext.Set(null, name, reference);
}

/// <summary>
/// Adds the given wrapped C# object to the runtime context.
/// </summary>
/// <exception cref="NullReferenceException">
/// Thrown if the runtime context is <see langword="null"/>.
/// Use <see cref="CreateRuntimeContext(string)"/> to initialize the runtime context.
/// </exception>
/// <param name="wrapper">The wrapped object to add.</param>
/// <param name="accessibilityModifiers">The accessibility modifiers for the reference. Defaults to <see cref="AccessMod.Constant"/>.</param>
/// <typeparam name="TMemberInfo">See <see cref="EzrSharpCompatibilityWrapper{TMemberInfo}"/>.</typeparam>
public static void AddToContext<TMemberInfo>(EzrSharpCompatibilityWrapper<TMemberInfo> wrapper, AccessMod accessibilityModifiers = AccessMod.Constant)
where TMemberInfo : MemberInfo
{
if (RuntimeContext is null)
throw new NullReferenceException($"{nameof(RuntimeContext)} is null! Call {nameof(CreateRuntimeContext)} to create it!");

RuntimeContext.Set(null, wrapper.SharpMemberName, ReferencePool.Get(wrapper, accessibilityModifiers));
}

/// <summary>
/// Executes the given script.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public EzrSharpCompatibilityType(
Context.Set(null, fieldObject.SharpMemberName, ReferencePool.Get(fieldObject, AccessMod.Constant));
}

int definedConstructors = 0;
ConstructorInfo[] publicConstructors = sharpType.GetConstructors();
for (int i = 0; i < publicConstructors.Length; i++)
{
Expand All @@ -108,7 +109,8 @@ public EzrSharpCompatibilityType(
if (!SharpAutoWrapperAttribute.ValidateMethod(constructor, constructorObject.AutoWrapperAttribute is null))
continue;

Context.Set(null, $"make_{i}", ReferencePool.Get(constructorObject, AccessMod.Constant));
Context.Set(null, definedConstructors == 0 ? "make" : $"make_{definedConstructors}", ReferencePool.Get(constructorObject, AccessMod.Constant));
definedConstructors++;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ public EzrSharpCompatibilityWrapper(TMemberInfo wrappedMember, object? instance,
/// 3. (?&lt;=[A-Z])(?=[A-Z][a-z]) - Add underscore between uppercase sequences followed by lowercase (e.g., "TCProtocol").
/// </remarks>
private static readonly Regex s_caseConverterRegex = new(@"(?<!^)(?=[A-Z][a-z])|(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])", RegexOptions.Compiled | RegexOptions.CultureInvariant);

/// <summary>
/// Regex for matching non-alphanumeric + underscore characters.
/// </summary>
private static readonly Regex s_alphaNumericUnderscoreOnlyFilterRegex = new(@"[^a-zA-Z0-9_]", RegexOptions.Compiled | RegexOptions.CultureInvariant);
#pragma warning restore SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.

/// <summary>
Expand All @@ -95,7 +100,8 @@ public EzrSharpCompatibilityWrapper(TMemberInfo wrappedMember, object? instance,
if (text.StartsWith('_'))
text = text[1..];

string snakeCase = s_caseConverterRegex.Replace(text, "_");
string alphaNumPlusUnderscoreFiltered = s_alphaNumericUnderscoreOnlyFilterRegex.Replace(text, string.Empty);
string snakeCase = s_caseConverterRegex.Replace(alphaNumPlusUnderscoreFiltered, "_");

// Convert entire string to lowercase
return snakeCase.ToLower();
Expand Down Expand Up @@ -363,9 +369,6 @@ protected internal void CSharpToEzrObject(object? value, RuntimeResult result)
case TypeCode.Object when typeof(IEzrObject).IsAssignableFrom(valueType):
result.Success(ReferencePool.Get((IEzrObject)value, AccessMod.PrivateConstant));
break;
case TypeCode.Object when typeof(Task).IsAssignableFrom(valueType):
HandleAsynchronousObjectToEzrObject(value, valueType, result);
break;
case TypeCode.Empty:
result.Success(NewNothingConstant());
break;
Expand Down Expand Up @@ -398,44 +401,6 @@ protected internal void HandleCSharpArrayToEzrObject(Array value, Type valueType
result.Success(NewArrayConstant(elements));
}

/// <summary>
/// Waits for a task to complete and returns the result as an ezr² object.
/// </summary>
/// <param name="value">The task to await.</param>
/// <param name="type">The type of the task.</param>
/// <param name="result">Runtime result for carrying the result and any errors.</param>
protected internal void HandleAsynchronousObjectToEzrObject(
object value,

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
Type type,

RuntimeResult result)
{
try
{
((Task)value).Wait();

// Get the Result property of the Task<TResult>
PropertyInfo? resultProperty = type.GetProperty("Result");

// Check if it's a Task<TResult>
if (resultProperty is not null)
{
// Get the value of the Result property
object taskResult = resultProperty.GetValue(value)!;

CSharpToEzrObject(taskResult, result);
}
else
result.Success(NewNothingConstant());
}
catch (Exception error)
{
result.Failure(new EzrWrapperExecutionError(error.InnerException?.Message ?? error.Message, Context, StartPosition, EndPosition));
}
}

/// <inheritdoc/>
public override void ComparisonEqual(IEzrObject other, RuntimeResult result)
{
Expand Down

0 comments on commit 62af557

Please sign in to comment.