diff options
author | Ignacio Roldán Etcheverry <ignalfonsore@gmail.com> | 2022-02-27 21:57:30 +0100 |
---|---|---|
committer | Ignacio Roldán Etcheverry <ignalfonsore@gmail.com> | 2022-08-22 03:36:51 +0200 |
commit | 92503ae8dbdf8f0f543dd785b79d3ec13b19092f (patch) | |
tree | 18e276bd75919eb701b625338b58af653821687e /modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs | |
parent | 88e367a4066773a6fbfe2ea25dc2e81d2035d791 (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.cs | 176 |
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; + } } } |