Skip to content

Commit 4eaafc8

Browse files
committed
Merge pull request #91375 from paulloz/dotnet/prevent-generator-crash-on-exported-unconstructed-generic-arrays
C#: Fix generator crash w/ generic arrays
2 parents 098a4e9 + aba7873 commit 4eaafc8

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ScriptPropertiesGeneratorTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,13 @@ await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
5757
"ScriptBoilerplate_ScriptProperties.generated.cs", "OuterClass.NestedClass_ScriptProperties.generated.cs"
5858
);
5959
}
60+
61+
[Fact]
62+
public async void AbstractGenericNode()
63+
{
64+
await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
65+
"AbstractGenericNode.cs",
66+
"AbstractGenericNode(Of T)_ScriptProperties.generated.cs"
67+
);
68+
}
6069
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Godot;
2+
using Godot.NativeInterop;
3+
4+
partial class AbstractGenericNode<T>
5+
{
6+
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
7+
/// <summary>
8+
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
9+
/// </summary>
10+
public new class PropertyName : global::Godot.Node.PropertyName {
11+
/// <summary>
12+
/// Cached name for the 'MyArray' property.
13+
/// </summary>
14+
public new static readonly global::Godot.StringName MyArray = "MyArray";
15+
}
16+
/// <inheritdoc/>
17+
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
18+
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
19+
{
20+
if (name == PropertyName.MyArray) {
21+
this.MyArray = global::Godot.NativeInterop.VariantUtils.ConvertToArray<T>(value);
22+
return true;
23+
}
24+
return base.SetGodotClassPropertyValue(name, value);
25+
}
26+
/// <inheritdoc/>
27+
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
28+
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
29+
{
30+
if (name == PropertyName.MyArray) {
31+
value = global::Godot.NativeInterop.VariantUtils.CreateFromArray(this.MyArray);
32+
return true;
33+
}
34+
return base.GetGodotClassPropertyValue(name, out value);
35+
}
36+
/// <summary>
37+
/// Get the property information for all the properties declared in this class.
38+
/// This method is used by Godot to register the available properties in the editor.
39+
/// Do not call this method.
40+
/// </summary>
41+
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
42+
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
43+
{
44+
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
45+
properties.Add(new(type: (global::Godot.Variant.Type)28, name: PropertyName.MyArray, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
46+
return properties;
47+
}
48+
#pragma warning restore CS0109
49+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using Godot;
2+
3+
public abstract partial class AbstractGenericNode<[MustBeVariant] T> : Node
4+
{
5+
[Export] // This should be included, but without type hints.
6+
public Godot.Collections.Array<T> MyArray { get; set; } = new();
7+
}

modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,10 @@ static bool GetStringArrayEnumHint(VariantType elementVariantType,
658658
var elementType = MarshalUtils.GetArrayElementType(type);
659659

660660
if (elementType == null)
661-
return false; // Non-generic Array, so there's no hint to add
661+
return false; // Non-generic Array, so there's no hint to add.
662+
663+
if (elementType.TypeKind == TypeKind.TypeParameter)
664+
return false; // The generic is not constructed, we can't really hint anything.
662665

663666
var elementMarshalType = MarshalUtils.ConvertManagedTypeToMarshalType(elementType, typeCache)!.Value;
664667
var elementVariantType = MarshalUtils.ConvertMarshalTypeToVariantType(elementMarshalType)!.Value;

0 commit comments

Comments
 (0)