summaryrefslogtreecommitdiff
path: root/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-02-27 21:57:30 +0100
committerIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-08-22 03:36:51 +0200
commit92503ae8dbdf8f0f543dd785b79d3ec13b19092f (patch)
tree18e276bd75919eb701b625338b58af653821687e /modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
parent88e367a4066773a6fbfe2ea25dc2e81d2035d791 (diff)
C#: Add source generator for properties and exports default values
The editor no longer needs to create temporary instances to get the default values. The initializer values of the exported properties are still evaluated at runtime. For example, in the following example, `GetInitialValue()` will be called when first looks for default values: ``` [Export] int MyValue = GetInitialValue(); ``` Exporting fields with a non-supported type now results in a compiler error rather than a runtime error when the script is used.
Diffstat (limited to 'modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs')
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs176
1 files changed, 136 insertions, 40 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
index a77e1800fb..5a4badd66e 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
@@ -1,9 +1,10 @@
using System;
+using System.Linq;
using Microsoft.CodeAnalysis;
namespace Godot.SourceGenerators
{
- public static class MarshalUtils
+ internal static class MarshalUtils
{
public class TypeCache
{
@@ -35,7 +36,73 @@ namespace Godot.SourceGenerators
}
}
- public static MarshalType? ConvertManagedTypeToVariantType(ITypeSymbol type, TypeCache typeCache)
+ public static VariantType? ConvertMarshalTypeToVariantType(MarshalType marshalType)
+ => marshalType switch
+ {
+ MarshalType.Boolean => VariantType.Bool,
+ MarshalType.Char => VariantType.Int,
+ MarshalType.SByte => VariantType.Int,
+ MarshalType.Int16 => VariantType.Int,
+ MarshalType.Int32 => VariantType.Int,
+ MarshalType.Int64 => VariantType.Int,
+ MarshalType.Byte => VariantType.Int,
+ MarshalType.UInt16 => VariantType.Int,
+ MarshalType.UInt32 => VariantType.Int,
+ MarshalType.UInt64 => VariantType.Int,
+ MarshalType.Single => VariantType.Float,
+ MarshalType.Double => VariantType.Float,
+ MarshalType.String => VariantType.String,
+ MarshalType.Vector2 => VariantType.Vector2,
+ MarshalType.Vector2i => VariantType.Vector2i,
+ MarshalType.Rect2 => VariantType.Rect2,
+ MarshalType.Rect2i => VariantType.Rect2i,
+ MarshalType.Transform2D => VariantType.Transform2d,
+ MarshalType.Vector3 => VariantType.Vector3,
+ MarshalType.Vector3i => VariantType.Vector3i,
+ MarshalType.Basis => VariantType.Basis,
+ MarshalType.Quaternion => VariantType.Quaternion,
+ MarshalType.Transform3D => VariantType.Transform3d,
+ MarshalType.Vector4 => VariantType.Vector4,
+ MarshalType.Vector4i => VariantType.Vector4i,
+ MarshalType.Projection => VariantType.Projection,
+ MarshalType.AABB => VariantType.Aabb,
+ MarshalType.Color => VariantType.Color,
+ MarshalType.Plane => VariantType.Plane,
+ MarshalType.Callable => VariantType.Callable,
+ MarshalType.SignalInfo => VariantType.Signal,
+ MarshalType.Enum => VariantType.Int,
+ MarshalType.ByteArray => VariantType.PackedByteArray,
+ MarshalType.Int32Array => VariantType.PackedInt32Array,
+ MarshalType.Int64Array => VariantType.PackedInt64Array,
+ MarshalType.SingleArray => VariantType.PackedFloat32Array,
+ MarshalType.DoubleArray => VariantType.PackedFloat64Array,
+ MarshalType.StringArray => VariantType.PackedStringArray,
+ MarshalType.Vector2Array => VariantType.PackedVector2Array,
+ MarshalType.Vector3Array => VariantType.PackedVector3Array,
+ MarshalType.ColorArray => VariantType.PackedColorArray,
+ MarshalType.GodotObjectOrDerivedArray => VariantType.Array,
+ MarshalType.SystemObjectArray => VariantType.Array,
+ MarshalType.GodotGenericDictionary => VariantType.Dictionary,
+ MarshalType.GodotGenericArray => VariantType.Array,
+ MarshalType.SystemGenericDictionary => VariantType.Dictionary,
+ MarshalType.SystemGenericList => VariantType.Array,
+ MarshalType.GenericIDictionary => VariantType.Dictionary,
+ MarshalType.GenericICollection => VariantType.Array,
+ MarshalType.GenericIEnumerable => VariantType.Array,
+ MarshalType.SystemObject => VariantType.Nil,
+ MarshalType.GodotObjectOrDerived => VariantType.Object,
+ MarshalType.StringName => VariantType.StringName,
+ MarshalType.NodePath => VariantType.NodePath,
+ MarshalType.RID => VariantType.Rid,
+ MarshalType.GodotDictionary => VariantType.Dictionary,
+ MarshalType.GodotArray => VariantType.Array,
+ MarshalType.IDictionary => VariantType.Dictionary,
+ MarshalType.ICollection => VariantType.Array,
+ MarshalType.IEnumerable => VariantType.Array,
+ _ => null
+ };
+
+ public static MarshalType? ConvertManagedTypeToMarshalType(ITypeSymbol type, TypeCache typeCache)
{
var specialType = type.SpecialType;
@@ -69,39 +136,44 @@ namespace Godot.SourceGenerators
return MarshalType.String;
case SpecialType.System_Object:
return MarshalType.SystemObject;
- case SpecialType.System_ValueType:
+ default:
{
- if (type.ContainingAssembly.Name == "GodotSharp" &&
- type.ContainingNamespace.Name == "Godot")
+ var typeKind = type.TypeKind;
+
+ if (typeKind == TypeKind.Enum)
+ return MarshalType.Enum;
+
+ if (typeKind == TypeKind.Struct)
{
- return type switch
+ if (type.ContainingAssembly.Name == "GodotSharp" &&
+ type.ContainingNamespace.Name == "Godot")
{
- { Name: "Vector2" } => MarshalType.Vector2,
- { Name: "Vector2i" } => MarshalType.Vector2i,
- { Name: "Rect2" } => MarshalType.Rect2,
- { Name: "Rect2i" } => MarshalType.Rect2i,
- { Name: "Transform2D" } => MarshalType.Transform2D,
- { Name: "Vector3" } => MarshalType.Vector3,
- { Name: "Vector3i" } => MarshalType.Vector3i,
- { Name: "Basis" } => MarshalType.Basis,
- { Name: "Quaternion" } => MarshalType.Quaternion,
- { Name: "Transform3D" } => MarshalType.Transform3D,
- { Name: "AABB" } => MarshalType.AABB,
- { Name: "Color" } => MarshalType.Color,
- { Name: "Plane" } => MarshalType.Plane,
- { Name: "RID" } => MarshalType.RID,
- { Name: "Callable" } => MarshalType.Callable,
- { Name: "SignalInfo" } => MarshalType.SignalInfo,
- { TypeKind: TypeKind.Enum } => MarshalType.Enum,
- _ => null
- };
+ return type switch
+ {
+ { Name: "Vector2" } => MarshalType.Vector2,
+ { Name: "Vector2i" } => MarshalType.Vector2i,
+ { Name: "Rect2" } => MarshalType.Rect2,
+ { Name: "Rect2i" } => MarshalType.Rect2i,
+ { Name: "Transform2D" } => MarshalType.Transform2D,
+ { Name: "Vector3" } => MarshalType.Vector3,
+ { Name: "Vector3i" } => MarshalType.Vector3i,
+ { Name: "Basis" } => MarshalType.Basis,
+ { Name: "Quaternion" } => MarshalType.Quaternion,
+ { Name: "Transform3D" } => MarshalType.Transform3D,
+ { Name: "Vector4" } => MarshalType.Vector4,
+ { Name: "Vector4i" } => MarshalType.Vector4i,
+ { Name: "Projection" } => MarshalType.Projection,
+ { Name: "AABB" } => MarshalType.AABB,
+ { Name: "Color" } => MarshalType.Color,
+ { Name: "Plane" } => MarshalType.Plane,
+ { Name: "RID" } => MarshalType.RID,
+ { Name: "Callable" } => MarshalType.Callable,
+ { Name: "SignalInfo" } => MarshalType.SignalInfo,
+ _ => null
+ };
+ }
}
-
- return null;
- }
- default:
- {
- if (type.TypeKind == TypeKind.Array)
+ else if (typeKind == TypeKind.Array)
{
var arrayType = (IArrayTypeSymbol)type;
var elementType = arrayType.ElementType;
@@ -127,17 +199,24 @@ namespace Godot.SourceGenerators
if (elementType.SimpleDerivesFrom(typeCache.GodotObjectType))
return MarshalType.GodotObjectOrDerivedArray;
- if (type.ContainingAssembly.Name == "GodotSharp" &&
- type.ContainingNamespace.Name == "Godot")
+ if (elementType.ContainingAssembly.Name == "GodotSharp" &&
+ elementType.ContainingNamespace.Name == "Godot")
{
- return elementType switch
+ switch (elementType)
{
- { Name: "Vector2" } => MarshalType.Vector2Array,
- { Name: "Vector3" } => MarshalType.Vector3Array,
- { Name: "Color" } => MarshalType.ColorArray,
- _ => null
- };
+ case { Name: "Vector2" }:
+ return MarshalType.Vector2Array;
+ case { Name: "Vector3" }:
+ return MarshalType.Vector3Array;
+ case { Name: "Color" }:
+ return MarshalType.ColorArray;
+ }
}
+
+ if (ConvertManagedTypeToMarshalType(elementType, typeCache) != null)
+ return MarshalType.GodotArray;
+
+ return null;
}
else if (type is INamedTypeSymbol { IsGenericType: true } genericType)
{
@@ -190,7 +269,10 @@ namespace Godot.SourceGenerators
{ Name: "NodePath" } => MarshalType.NodePath,
_ => null
};
- case "Godot.Collections" when !(type is INamedTypeSymbol { IsGenericType: true }):
+ case "Collections"
+ when !(type is INamedTypeSymbol { IsGenericType: true }) &&
+ type.ContainingNamespace.FullQualifiedName() ==
+ "Godot.Collections":
return type switch
{
{ Name: "Dictionary" } => MarshalType.GodotDictionary,
@@ -220,5 +302,19 @@ namespace Godot.SourceGenerators
return false;
}
+
+ public static ITypeSymbol? GetArrayElementType(ITypeSymbol typeSymbol)
+ {
+ if (typeSymbol.TypeKind == TypeKind.Array)
+ {
+ var arrayType = (IArrayTypeSymbol)typeSymbol;
+ return arrayType.ElementType;
+ }
+
+ if (typeSymbol is INamedTypeSymbol { IsGenericType: true } genericType)
+ return genericType.TypeArguments.FirstOrDefault();
+
+ return null;
+ }
}
}