Skip to content

Commit

Permalink
MASSIVE overhaul for the wrapper systems.
Browse files Browse the repository at this point in the history
  • Loading branch information
Uralstech committed Nov 3, 2024
1 parent 15a0d76 commit 0394832
Show file tree
Hide file tree
Showing 22 changed files with 361 additions and 738 deletions.
2 changes: 1 addition & 1 deletion src/EzrSquared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
<Title>ezr² Portable Library</Title>
<Description>The ezr² programming language, as a portable class library! This can be used to integrate ezr² as an embedded scripting language in your apps, websites and more!</Description>

<PackageVersion>0.8.5-unstable</PackageVersion>
<PackageVersion>0.9.0-unstable</PackageVersion>

<Authors>Udayshankar Ravikumar</Authors>
<Company>URAV ADVANCED LEARNING SYSTEMS PRIVATE LIMITED</Company>
Expand Down
4 changes: 2 additions & 2 deletions src/Runtime/Collections/RuntimeEzrObjectDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class RuntimeEzrObjectDictionary : IMutable<RuntimeEzrObjectDictionary>
/// <summary>
/// The number of <see cref="IEzrObject"/>s in the <see cref="RuntimeEzrObjectDictionary"/>.
/// </summary>
[SharpAutoCompatibilityWrapper(IsReadOnly = true)]
[SharpAutoWrapper(IsReadOnly = true)]
public int Length => _items.Count;

/// <summary>
Expand Down Expand Up @@ -103,7 +103,7 @@ public bool Remove(IEzrObject key, RuntimeResult result)
/// </remarks>
/// <param name="key">The key (hash) to be removed.</param>
/// <returns><see langword="true"/> if the operation was successful, <see langword="false"/> if not.</returns>
[SharpAutoCompatibilityWrapper(Name = "remove_by_hash")]
[SharpAutoWrapper(Name = "remove_by_hash")]
public bool RemoveHash(int key)
{
return _items.Remove(key);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using EzrSquared.Runtime.Types.Core.Errors;
using EzrSquared.Runtime.Types.CSharpWrappers.CompatWrappers.ObjectMembers;
using EzrSquared.Runtime.Types.CSharpWrappers.CompatWrappers.ObjectMembers;
using EzrSquared.Runtime.Types.CSharpWrappers.CompatWrappers.ObjectMembers.Executables;
using EzrSquared.Util;
using System;
Expand All @@ -25,45 +24,37 @@ public class EzrSharpCompatibilityObjectInstance : EzrSharpCompatibilityWrapper
/// </summary>
public readonly object Instance;

/// <summary>
/// The name of the type of the wrapped instance, in ezr² (snake_case) format.
/// </summary>
public readonly string InstanceTypeName;

/// <summary>
/// Creates a new <see cref="EzrSharpCompatibilityObjectInstance"/>.
/// </summary>
/// <param name="typeName">The name of the type of the wrapped instance, in ezr² (snake_case) format.</param>
/// <param name="instance">The object to wrap.</param>
/// <param name="instanceType">The type of the wrapped instance</param>
/// <param name="instanceType">The C# object's type.</param>
/// <param name="result">Runtime result for carrying any errors.</param>
/// <param name="parentContext">The context in which this object was created.</param>
/// <param name="startPosition">The starting position of the object.</param>
/// <param name="endPosition">The ending position of the object.</param>
public EzrSharpCompatibilityObjectInstance(
string typeName,
object instance,

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)]
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicMethods
| DynamicallyAccessedMemberTypes.NonPublicMethods
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.NonPublicProperties
| DynamicallyAccessedMemberTypes.PublicFields
| DynamicallyAccessedMemberTypes.NonPublicFields)]
Type instanceType,

RuntimeResult result, Context parentContext, Position startPosition, Position endPosition) : base(parentContext, startPosition, endPosition)
RuntimeResult result, Context parentContext, Position startPosition, Position endPosition) : base(instanceType, parentContext, startPosition, endPosition)
{
Instance = instance;
InstanceTypeName = typeName;
Tag = $"{Tag}.{InstanceTypeName}.{Utils.GetNextUniqueId()}";
Tag = $"{Tag}.{SharpMemberName}.{Utils.GetNextUniqueId()}";

MethodInfo[] publicMethods = instanceType.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
MethodInfo[] publicMethods = instanceType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
Dictionary<string, int> duplicateNames = new(publicMethods.Length);
for (int i = 0; i < publicMethods.Length; i++)
{
MethodInfo method = publicMethods[i];
if (method.ContainsGenericParameters || method.IsGenericMethod)
{
result.Failure(new EzrUnsupportedWrappingError($"Cannot wrap CSharp method \"{method.Name}\" of instance \"{instanceType.Name}\"! Reasons can include the method being generic or containing generic parameters.", Context, StartPosition, EndPosition));
return;
}

if (method.IsAbstract)
continue;

Expand All @@ -77,41 +68,33 @@ public EzrSharpCompatibilityObjectInstance(
duplicateNames.Add(method.Name, 1);

EzrSharpCompatibilityFunction methodObject = new(method, Instance, Context, StartPosition, EndPosition);
if (methodObject.Validate(result))
return;

Context.Set(null, methodObjectName, ReferencePool.Get(methodObject, AccessMod.Constant));
}

PropertyInfo[] publicProperties = instanceType.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
PropertyInfo[] publicProperties = instanceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < publicProperties.Length; i++)
{
EzrSharpCompatibilityProperty property = new(publicProperties[i], Instance, Context, StartPosition, EndPosition);
Context.Set(null, property.SharpPropertyName, ReferencePool.Get(property, AccessMod.Constant));
if (property.Validate(result))
return;

Context.Set(null, property.SharpMemberName, ReferencePool.Get(property, AccessMod.Constant));
}

FieldInfo[] publicFields = instanceType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
FieldInfo[] publicFields = instanceType.GetFields(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < publicFields.Length; i++)
{
EzrSharpCompatibilityField field = new(publicFields[i], Instance, Context, StartPosition, EndPosition);
Context.Set(null, field.SharpFieldName, ReferencePool.Get(field, AccessMod.Constant));
if (field.Validate(result))
return;

Context.Set(null, field.SharpMemberName, ReferencePool.Get(field, AccessMod.Constant));
}
}

/// <summary>
/// Creates a new <see cref="EzrSharpCompatibilityObjectInstance"/>. Infers the type's name by converting it to snake_case.
/// </summary>
/// <param name="instance">The object to wrap.</param>
/// <param name="instanceType">The type of the wrapped instance</param>
/// <param name="result">Runtime result for carrying any errors.</param>
/// <param name="parentContext">The context in which this object was created.</param>
/// <param name="startPosition">The starting position of the object.</param>
/// <param name="endPosition">The ending position of the object.</param>
public EzrSharpCompatibilityObjectInstance(object instance,

[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)]
Type instanceType,

RuntimeResult result, Context parentContext, Position startPosition, Position endPosition)
: this(Utils.PascalToSnakeCase(instanceType.Name), instance, instanceType, result, parentContext, startPosition, endPosition) { }

/// <inheritdoc/>
public override int ComputeHashCode(RuntimeResult result)
{
Expand All @@ -127,6 +110,6 @@ public override bool StrictEquals(IEzrObject other, RuntimeResult result)
/// <inheritdoc/>
public override string ToString(RuntimeResult result)
{
return $"<{TypeName} of type \"{InstanceTypeName}\">";
return $"<{TypeName} of type \"{SharpMemberName}\">";
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using EzrSquared.Runtime.Types.Core.Errors;
using EzrSquared.Runtime.Types.CSharpWrappers.CompatWrappers.ObjectMembers;
using EzrSquared.Runtime.Types.CSharpWrappers.CompatWrappers.ObjectMembers.Executables;
using EzrSquared.Runtime.WrapperAttributes;
using EzrSquared.Util;
using System;
using System.Collections.Generic;
Expand All @@ -23,57 +24,54 @@ public class EzrSharpCompatibilityType : EzrSharpCompatibilityWrapper
/// <summary>
/// The type to wrap.
/// </summary>
[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields
| DynamicallyAccessedMemberTypes.NonPublicFields
| DynamicallyAccessedMemberTypes.PublicMethods
| DynamicallyAccessedMemberTypes.NonPublicMethods
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.NonPublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.NonPublicConstructors)]
public readonly Type SharpType;

/// <summary>
/// The name of the type to wrap, in ezr² format (snake_case).
/// </summary>
public readonly string SharpTypeName;

/// <summary>
/// Creates a new <see cref="EzrSharpCompatibilityType"/>.
/// </summary>
/// <param name="name">The name of the type to wrap, in ezr² format (snake_case).</param>
/// <param name="type">The type to wrap.</param>
/// <param name="result">Runtime result for carrying any errors.</param>
/// <param name="parentContext">The context in which this object was created.</param>
/// <param name="startPosition">The starting position of the object.</param>
/// <param name="endPosition">The ending position of the object.</param>
public EzrSharpCompatibilityType(
string name,

[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields
| DynamicallyAccessedMemberTypes.NonPublicFields
| DynamicallyAccessedMemberTypes.PublicMethods
| DynamicallyAccessedMemberTypes.NonPublicMethods
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.NonPublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.NonPublicConstructors
)] Type type,
| DynamicallyAccessedMemberTypes.NonPublicConstructors)]
Type type,

RuntimeResult result, Context parentContext, Position startPosition, Position endPosition) : base(parentContext, startPosition, endPosition)
RuntimeResult result, Context parentContext, Position startPosition, Position endPosition) : base(type, parentContext, startPosition, endPosition)
{
SharpType = type;
SharpTypeName = name;
Tag = $"{Tag}.{SharpTypeName}.{Utils.GetNextUniqueId()}";
Tag = $"{Tag}.{SharpMemberName}.{Utils.GetNextUniqueId()}";

if (SharpType.IsGenericType)
{
result.Failure(new EzrUnsupportedWrappingError($"Cannot wrap generic CSharp type \"{SharpType.Name}\"!", Context, StartPosition, EndPosition));
return;
}

MethodInfo[] publicStaticMethods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
Dictionary<string, int> duplicateNames = new(publicStaticMethods.Length);
for (int i = 0; i < publicStaticMethods.Length; i++)
MethodInfo[] allStaticMethods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
Dictionary<string, int> duplicateNames = new(allStaticMethods.Length);
for (int i = 0; i < allStaticMethods.Length; i++)
{
MethodInfo method = publicStaticMethods[i];
if (method.ContainsGenericParameters || method.IsGenericMethod)
{
result.Failure(new EzrUnsupportedWrappingError($"Cannot wrap CSharp static method \"{method.Name}\" of type \"{SharpType.Name}\"! Reasons can include the method being generic or containing generic parameters.", Context, StartPosition, EndPosition));
return;
}

if (method.IsAbstract)
MethodInfo method = allStaticMethods[i];
if (method.IsAbstract || (!method.IsPublic && method.GetCustomAttribute<SharpAutoWrapperAttribute>() is null))
continue;

string methodObjectName = Utils.PascalToSnakeCase(method.Name);
Expand All @@ -86,21 +84,38 @@ public EzrSharpCompatibilityType(
duplicateNames.Add(method.Name, 1);

EzrSharpCompatibilityFunction methodObject = new(method, null, Context, StartPosition, EndPosition);
if (!methodObject.Validate(result))
return;

Context.Set(null, methodObjectName, ReferencePool.Get(methodObject, AccessMod.Constant));
}

PropertyInfo[] publicStaticProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
for (int i = 0; i < publicStaticProperties.Length; i++)
PropertyInfo[] allStaticProperties = type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < allStaticProperties.Length; i++)
{
EzrSharpCompatibilityProperty property = new(publicStaticProperties[i], null, Context, StartPosition, EndPosition);
Context.Set(null, property.SharpPropertyName, ReferencePool.Get(property, AccessMod.Constant));
PropertyInfo property = allStaticProperties[i];
if (property.GetMethod?.IsPublic != true && property.SetMethod?.IsPublic != true && property.GetCustomAttribute<SharpAutoWrapperAttribute>() is null)
continue;

EzrSharpCompatibilityProperty propertyObject = new(property, null, Context, StartPosition, EndPosition);
if (!propertyObject.Validate(result))
return;

Context.Set(null, propertyObject.SharpMemberName, ReferencePool.Get(propertyObject, AccessMod.Constant));
}

FieldInfo[] publicStaticFields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
for (int i = 0; i < publicStaticFields.Length; i++)
FieldInfo[] allStaticFields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
for (int i = 0; i < allStaticFields.Length; i++)
{
EzrSharpCompatibilityField field = new(publicStaticFields[i], null, Context, StartPosition, EndPosition);
Context.Set(null, field.SharpFieldName, ReferencePool.Get(field, AccessMod.Constant));
FieldInfo field = allStaticFields[i];
if (!field.IsPublic && field.GetCustomAttribute<SharpAutoWrapperAttribute>() is null)
continue;

EzrSharpCompatibilityField fieldObject = new(field, null, Context, StartPosition, EndPosition);
if (!fieldObject.Validate(result))
return;

Context.Set(null, fieldObject.SharpMemberName, ReferencePool.Get(fieldObject, AccessMod.Constant));
}

ConstructorInfo[] publicConstructors = type.GetConstructors();
Expand All @@ -110,32 +125,14 @@ public EzrSharpCompatibilityType(
if (!constructor.IsPublic)
continue;

IEzrObject constructorObject = new EzrSharpCompatibilityConstructor(SharpTypeName, constructor, type, Context, StartPosition, EndPosition);
EzrSharpCompatibilityConstructor constructorObject = new(this, constructor, Context, StartPosition, EndPosition);
if (constructorObject.Validate(result))
return;

Context.Set(null, $"make_{i}", ReferencePool.Get(constructorObject, AccessMod.Constant));
}
}

/// <summary>
/// Creates a new <see cref="EzrSharpCompatibilityType"/>. Infers the name by converting the member's name to snake_case.
/// </summary>
/// <param name="type">The type to wrap.</param>
/// <param name="result">Runtime result for carrying any errors.</param>
/// <param name="parentContext">The context in which this object was created.</param>
/// <param name="startPosition">The starting position of the object.</param>
/// <param name="endPosition">The ending position of the object.</param>
public EzrSharpCompatibilityType(

[DynamicallyAccessedMembers(
DynamicallyAccessedMemberTypes.PublicFields
| DynamicallyAccessedMemberTypes.PublicMethods
| DynamicallyAccessedMemberTypes.PublicProperties
| DynamicallyAccessedMemberTypes.PublicConstructors
| DynamicallyAccessedMemberTypes.NonPublicConstructors
)] Type type,

RuntimeResult result, Context parentContext, Position startPosition, Position endPosition)
: this(Utils.PascalToSnakeCase(type.Name), type, result, parentContext, startPosition, endPosition) { }

/// <inheritdoc/>
public override int ComputeHashCode(RuntimeResult result)
{
Expand All @@ -151,6 +148,6 @@ public override bool StrictEquals(IEzrObject other, RuntimeResult result)
/// <inheritdoc/>
public override string ToString(RuntimeResult result)
{
return $"<{TypeName} \"{SharpTypeName}\">";
return $"<{TypeName} \"{SharpMemberName}\">";
}
}
Loading

0 comments on commit 0394832

Please sign in to comment.