Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added array support in TypeBase and unit tests
  • Loading branch information
snakex64 committed Oct 9, 2024
commit bc031e252751ba448e550accab770c3eca097a2d
8 changes: 7 additions & 1 deletion src/NodeDev.Core/Types/ExecType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ public class ExecType : TypeBase

public override TypeBase[] Interfaces => throw new NotImplementedException();

public override IEnumerable<IMemberInfo> GetMembers() => throw new NotImplementedException();
public override bool IsArray => false;

public override TypeBase ArrayInnerType => throw new Exception("Can't call ArrayInnerType on ExecType");

public override TypeBase ArrayType => throw new Exception("Can't call ArrayType on ExecType");

public override IEnumerable<IMemberInfo> GetMembers() => throw new NotImplementedException();

public override IEnumerable<IMethodInfo> GetMethods() => [];

Expand Down
110 changes: 110 additions & 0 deletions src/NodeDev.Core/Types/NodeClassArrayType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NodeDev.Core.Types
{
public class NodeClassArrayType : TypeBase
{
public readonly NodeClassType InnerNodeClassType;

public readonly int NbArrayLevels;

public NodeClassArrayType(NodeClassType innerClassType, int nbArrayLevels)
{
if (nbArrayLevels == 0)
throw new ArgumentException("NodeClassArrayType cannot have 0 array level. That imples 'not array', in which case NodeClassType should be used instead", nameof(nbArrayLevels));

InnerNodeClassType = innerClassType;
NbArrayLevels = nbArrayLevels;
}

public override string Name => InnerNodeClassType.Name + GetArrayString();

public override string FullName => InnerNodeClassType.FullName + GetArrayString();

public override TypeBase[] Generics => InnerNodeClassType.Generics;

public override TypeBase? BaseType => InnerNodeClassType.NodeClass.TypeFactory.Get<Array>();

public override TypeBase[] Interfaces => [InnerNodeClassType.NodeClass.TypeFactory.Get(typeof(IReadOnlyList<>), [ArrayInnerType])];

public override bool IsArray => true;

public override string FriendlyName => InnerNodeClassType.FriendlyName + GetArrayString();

public override TypeBase ArrayInnerType => NbArrayLevels == 1 ? InnerNodeClassType : new NodeClassArrayType(InnerNodeClassType, NbArrayLevels - 1);

public override TypeBase ArrayType => new NodeClassArrayType(InnerNodeClassType, NbArrayLevels + 1);

public override TypeBase CloneWithGenerics(TypeBase[] newGenerics)
{
return new NodeClassArrayType((NodeClassType)InnerNodeClassType.CloneWithGenerics(newGenerics), NbArrayLevels);
}

public override IEnumerable<IMemberInfo> GetMembers()
{
return [];
}

public override IEnumerable<IMethodInfo> GetMethods()
{
return [];
}

public override IEnumerable<IMethodInfo> GetMethods(string name)
{
return [];
}

public override bool IsSameBackend(TypeBase typeBase)
{
if(typeBase is not NodeClassArrayType nodeClassArrayType)
return false;

return NbArrayLevels == nodeClassArrayType.NbArrayLevels && InnerNodeClassType.IsSameBackend(nodeClassArrayType.InnerNodeClassType);
}

public override Type MakeRealType()
{
var realBaseType = InnerNodeClassType.MakeRealType();

for(int i = 0; i < NbArrayLevels; i++)
realBaseType = realBaseType.MakeArrayType();

return realBaseType;
}

private record class SerializedNodeClassArrayType(string InnerNodeClassType, int NbArrayLevels);
protected internal override string Serialize()
{
return System.Text.Json.JsonSerializer.Serialize(new SerializedNodeClassArrayType(InnerNodeClassType.Serialize(), NbArrayLevels));
}

public new static NodeClassArrayType Deserialize(TypeFactory typeFactory, string serializedString)
{
var deserialized = System.Text.Json.JsonSerializer.Deserialize<SerializedNodeClassArrayType>(serializedString);
if(deserialized == null)
throw new ArgumentException("Failed to deserialize NodeClassArrayType");

return new NodeClassArrayType(NodeClassType.Deserialize(typeFactory, deserialized.InnerNodeClassType), deserialized.NbArrayLevels);
}


private string GetArrayString()
{
var str = string.Create(NbArrayLevels * 2, NbArrayLevels, static (span, nbLevels) =>
{
for (int i = 0; i < span.Length; i += 2)
{
span[i] = '[';
span[i + 1] = ']';
}
});

return str;
}
}
}
110 changes: 62 additions & 48 deletions src/NodeDev.Core/Types/NodeClassType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,69 +7,83 @@

namespace NodeDev.Core.Types
{
public class NodeClassType : TypeBase
{
public readonly NodeClass NodeClass;
public class NodeClassType : TypeBase
{
public readonly NodeClass NodeClass;

public NodeClassType(NodeClass nodeClass, TypeBase[] generics)
{
if (generics.Length != 0)
throw new NotImplementedException("Generics are not supported yet for NodeClass");
public NodeClassType(NodeClass nodeClass, TypeBase[] generics)
{
if (generics.Length != 0)
throw new NotImplementedException("Generics are not supported yet for NodeClass");

NodeClass = nodeClass;
Generics = generics;
}
NodeClass = nodeClass;
Generics = generics;
}

public override string Name => NodeClass.Name;
public override string Name => NodeClass.Name;

public override string FullName => NodeClass.Namespace + "." + NodeClass.Name;
public override string FullName => NodeClass.Namespace + "." + NodeClass.Name;

public override TypeBase[] Generics { get; }
public override TypeBase[] Generics { get; }

override public TypeBase? BaseType => null;
override public TypeBase? BaseType => null;

public override string FriendlyName => Name;
public override string FriendlyName => Name;

public override TypeBase[] Interfaces => Array.Empty<TypeBase>();
public override bool IsArray => false;

public override IEnumerable<IMemberInfo> GetMembers() =>NodeClass.Properties;
public override TypeBase ArrayInnerType => throw new NotImplementedException();

internal protected override string Serialize()
{
return FullName;
}
public override TypeBase ArrayType => new NodeClassArrayType(this, 1);

public override TypeBase CloneWithGenerics(TypeBase[] newGenerics)
{
if (Generics.Length != newGenerics.Length)
throw new ArgumentException("Generics count mismatch");
public override TypeBase[] Interfaces => [];

return new NodeClassType(NodeClass, newGenerics);
}
public override IEnumerable<IMemberInfo> GetMembers() => NodeClass.Properties;

public new static NodeClassType Deserialize(TypeFactory typeFactory, string typeName)
{
return typeFactory.Project.GetNodeClassType(typeFactory.Project.Classes.First(x => x.Namespace + "." + x.Name == typeName));
}
public NodeClassType GetNonArray()
{
if(!IsArray)
return this;

public override IEnumerable<IMethodInfo> GetMethods()
{
return NodeClass.Methods;
}
return NodeClass.Project.GetNodeClassType(NodeClass, Generics);
}

public override IEnumerable<IMethodInfo> GetMethods(string name)
{
return NodeClass.Methods.Where(x => x.Name == name);
}
internal protected override string Serialize()
{
return FullName;
}

public override Type MakeRealType()
{
return NodeClass.Project.GetCreatedClassType(NodeClass);
}
public override TypeBase CloneWithGenerics(TypeBase[] newGenerics)
{
if (Generics.Length != newGenerics.Length)
throw new ArgumentException("Generics count mismatch");

public override bool IsSameBackend(TypeBase typeBase)
{
return typeBase is NodeClassType nodeClassType && nodeClassType.NodeClass == NodeClass;
}
}
return new NodeClassType(NodeClass, newGenerics);
}

public new static NodeClassType Deserialize(TypeFactory typeFactory, string typeName)
{
return typeFactory.Project.GetNodeClassType(typeFactory.Project.Classes.First(x => x.Namespace + "." + x.Name == typeName));
}

public override IEnumerable<IMethodInfo> GetMethods()
{
return NodeClass.Methods;
}

public override IEnumerable<IMethodInfo> GetMethods(string name)
{
return NodeClass.Methods.Where(x => x.Name == name);
}

public override Type MakeRealType()
{
return NodeClass.Project.GetCreatedClassType(NodeClass);
}

public override bool IsSameBackend(TypeBase typeBase)
{
return typeBase is NodeClassType nodeClassType && nodeClassType.NodeClass == NodeClass;
}
}
}
8 changes: 7 additions & 1 deletion src/NodeDev.Core/Types/RealType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ public class RealType : TypeBase
private TypeBase[]? _Interfaces;
public override TypeBase[] Interfaces => _Interfaces ?? InitializeInterfaces();

public override bool IsIn(int genericIndex) => BackendType.GetGenericArguments()[genericIndex].IsGenericParameter && (BackendType.GetGenericArguments()[genericIndex].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Contravariant) != System.Reflection.GenericParameterAttributes.None;
public override bool IsArray => BackendType.IsArray;

public override TypeBase ArrayType => TypeFactory.Get(BackendType.MakeArrayType(), Generics);

public override TypeBase ArrayInnerType => IsArray ? TypeFactory.Get(BackendType.GetElementType()!, Generics) : throw new Exception("Can't call ArrayInnerType on non-array type");

public override bool IsIn(int genericIndex) => BackendType.GetGenericArguments()[genericIndex].IsGenericParameter && (BackendType.GetGenericArguments()[genericIndex].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Contravariant) != System.Reflection.GenericParameterAttributes.None;

public override bool IsOut(int genericIndex) => BackendType.GetGenericArguments()[genericIndex].IsGenericParameter && (BackendType.GetGenericArguments()[genericIndex].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != System.Reflection.GenericParameterAttributes.None;

Expand Down
Loading