From d2c6c9a94870f260ceb1d20a1f49a02a0559e645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Mon, 14 Sep 2026 22:05:10 +0200 Subject: [PATCH] Fixed TypeExtension.FindType for array types --- ScriptCore/Extensions/TypeExtension.cs | 116 +++++++++++++----- .../Serialization/DeserializationObject.cs | 1 + 2 files changed, 83 insertions(+), 34 deletions(-) diff --git a/ScriptCore/Extensions/TypeExtension.cs b/ScriptCore/Extensions/TypeExtension.cs index d9bab2b..9ffa0e0 100644 --- a/ScriptCore/Extensions/TypeExtension.cs +++ b/ScriptCore/Extensions/TypeExtension.cs @@ -94,53 +94,101 @@ public static class TypeExtension ReadOnlySpan typeName = ReadTypeName(fullName); rest = rest.Slice(typeName.Length); - - if (rest.IsEmpty || rest[0] != '`') + + Type? baseType = GetType(typeName); + + if (baseType == null) { - // Non generic type, easy! - return GetType(typeName); + return null; } - // Handle generic type - - int brackedIndex = fullName.IndexOf('['); - - typeName = fullName.Slice(0, brackedIndex); - rest = fullName.Slice(brackedIndex + 1).Trim(); - - Type? genericType = GetType(typeName); - - Console.WriteLine($"Generic Type: {genericType}"); - - List arguments = new List(); - - while (true) + if (rest.IsEmpty) { - Type? argument = FindType(rest, ref rest); - Console.WriteLine($"Argument: {argument}"); - - Debug.Assert(argument != null); - - arguments.Add(argument!); - - rest = rest.TrimStart(); - - if (rest.TrimStart()[0] == ',') + // Non generic type, easy! + return baseType; + } + + if (rest[0] == '[') + { + // Handle array type + int rank = 1; + bool forceMultiDimensional = false; + for (int i = 0; i < rest.Length; i++) { - rest = rest.Slice(1); + if (rest[i] == ',') + { + rank++; + } + else if (rest[i] == '*') + { + forceMultiDimensional = true; + } + else if (rest[i] == ']') + { + rest = rest.Slice(i + 1); + break; + } } - else if (rest.TrimStart()[0] == ']') + + Debug.Assert(rest.IsEmpty); + + // It is important to use MakeArrayType() for single-dimensional arrays, as a single-dimension array is distinct from a multi-dimension array of rank 1. The latter cannot be created using normal code, but can be created using reflection. + if (rank == 1 && !forceMultiDimensional) { - rest = rest.Slice(1); - break; + return baseType.MakeArrayType(); } else { - break; + return baseType.MakeArrayType(rank); } } - return genericType?.MakeGenericType(arguments.ToArray()); + if (rest[0] == '`') + { + // Handle generic type + + int brackedIndex = fullName.IndexOf('['); + + typeName = fullName.Slice(0, brackedIndex); + rest = fullName.Slice(brackedIndex + 1).Trim(); + + Type? genericType = GetType(typeName); + + Console.WriteLine($"Generic Type: {genericType}"); + + List arguments = new List(); + + while (true) + { + Type? argument = FindType(rest, ref rest); + Console.WriteLine($"Argument: {argument}"); + + Debug.Assert(argument != null); + + arguments.Add(argument!); + + rest = rest.TrimStart(); + + if (rest.TrimStart()[0] == ',') + { + rest = rest.Slice(1); + } + else if (rest.TrimStart()[0] == ']') + { + rest = rest.Slice(1); + break; + } + else + { + break; + } + } + + return genericType?.MakeGenericType(arguments.ToArray()); + } + + Log.Error($"Failed to find a type for {typeName}."); + return null; } private static Type? GetType(ReadOnlySpan fullName) diff --git a/ScriptCore/Serialization/DeserializationObject.cs b/ScriptCore/Serialization/DeserializationObject.cs index 7ae0809..e32ea08 100644 --- a/ScriptCore/Serialization/DeserializationObject.cs +++ b/ScriptCore/Serialization/DeserializationObject.cs @@ -56,6 +56,7 @@ public class DeserializationObject { ScriptGlue.Serialization_GetObjectTypeName(_internalContext, out string fullTypeName); + // TODO: Retrieving the entire type by name is not ideal, we should probably consider using a more efficient approach. return GetTypeFromName(fullTypeName); } }