Merge pull request #94599 from juanjp600/node-array-export-diagnostic

C#: Fix GD0107 not applying to arrays and dictionaries containing nodes
This commit is contained in:
Rémi Verschelde 2024-08-16 23:45:26 +02:00
commit 0d0eb71694
No known key found for this signature in database
GPG Key ID: C3336907360768E1
3 changed files with 99 additions and 19 deletions

View File

@ -11,11 +11,27 @@ partial class ExportDiagnostics_GD0107_OK
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
internal new static global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant> GetGodotPropertyDefaultValues()
{
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(2);
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(10);
global::Godot.Node __NodeProperty_default_value = default;
values.Add(PropertyName.@NodeProperty, global::Godot.Variant.From<global::Godot.Node>(__NodeProperty_default_value));
global::Godot.Node[] __SystemArrayOfNodesProperty_default_value = default;
values.Add(PropertyName.@SystemArrayOfNodesProperty, global::Godot.Variant.CreateFrom(__SystemArrayOfNodesProperty_default_value));
global::Godot.Collections.Array<global::Godot.Node> __GodotArrayOfNodesProperty_default_value = default;
values.Add(PropertyName.@GodotArrayOfNodesProperty, global::Godot.Variant.CreateFrom(__GodotArrayOfNodesProperty_default_value));
global::Godot.Collections.Dictionary<global::Godot.Node, string> __GodotDictionaryWithNodeAsKeyProperty_default_value = default;
values.Add(PropertyName.@GodotDictionaryWithNodeAsKeyProperty, global::Godot.Variant.CreateFrom(__GodotDictionaryWithNodeAsKeyProperty_default_value));
global::Godot.Collections.Dictionary<string, global::Godot.Node> __GodotDictionaryWithNodeAsValueProperty_default_value = default;
values.Add(PropertyName.@GodotDictionaryWithNodeAsValueProperty, global::Godot.Variant.CreateFrom(__GodotDictionaryWithNodeAsValueProperty_default_value));
global::Godot.Node __NodeField_default_value = default;
values.Add(PropertyName.@NodeField, global::Godot.Variant.From<global::Godot.Node>(__NodeField_default_value));
global::Godot.Node[] __SystemArrayOfNodesField_default_value = default;
values.Add(PropertyName.@SystemArrayOfNodesField, global::Godot.Variant.CreateFrom(__SystemArrayOfNodesField_default_value));
global::Godot.Collections.Array<global::Godot.Node> __GodotArrayOfNodesField_default_value = default;
values.Add(PropertyName.@GodotArrayOfNodesField, global::Godot.Variant.CreateFrom(__GodotArrayOfNodesField_default_value));
global::Godot.Collections.Dictionary<global::Godot.Node, string> __GodotDictionaryWithNodeAsKeyField_default_value = default;
values.Add(PropertyName.@GodotDictionaryWithNodeAsKeyField, global::Godot.Variant.CreateFrom(__GodotDictionaryWithNodeAsKeyField_default_value));
global::Godot.Collections.Dictionary<string, global::Godot.Node> __GodotDictionaryWithNodeAsValueField_default_value = default;
values.Add(PropertyName.@GodotDictionaryWithNodeAsValueField, global::Godot.Variant.CreateFrom(__GodotDictionaryWithNodeAsValueField_default_value));
return values;
}
#endif // TOOLS

View File

@ -1,12 +1,37 @@
using Godot;
using Godot.Collections;
public partial class ExportDiagnostics_GD0107_OK : Node
{
[Export]
public Node NodeField;
[Export]
public Node[] SystemArrayOfNodesField;
[Export]
public Array<Node> GodotArrayOfNodesField;
[Export]
public Dictionary<Node, string> GodotDictionaryWithNodeAsKeyField;
[Export]
public Dictionary<string, Node> GodotDictionaryWithNodeAsValueField;
[Export]
public Node NodeProperty { get; set; }
[Export]
public Node[] SystemArrayOfNodesProperty { get; set; }
[Export]
public Array<Node> GodotArrayOfNodesProperty { get; set; }
[Export]
public Dictionary<Node, string> GodotDictionaryWithNodeAsKeyProperty { get; set; }
[Export]
public Dictionary<string, Node> GodotDictionaryWithNodeAsValueProperty { get; set; }
}
public partial class ExportDiagnostics_GD0107_KO : Resource
@ -14,6 +39,30 @@ public partial class ExportDiagnostics_GD0107_KO : Resource
[Export]
public Node {|GD0107:NodeField|};
[Export]
public Node[] {|GD0107:SystemArrayOfNodesField|};
[Export]
public Array<Node> {|GD0107:GodotArrayOfNodesField|};
[Export]
public Dictionary<Node, string> {|GD0107:GodotDictionaryWithNodeAsKeyField|};
[Export]
public Dictionary<string, Node> {|GD0107:GodotDictionaryWithNodeAsValueField|};
[Export]
public Node {|GD0107:NodeProperty|} { get; set; }
[Export]
public Node[] {|GD0107:SystemArrayOfNodesProperty|} { get; set; }
[Export]
public Array<Node> {|GD0107:GodotArrayOfNodesProperty|} { get; set; }
[Export]
public Dictionary<Node, string> {|GD0107:GodotDictionaryWithNodeAsKeyProperty|} { get; set; }
[Export]
public Dictionary<string, Node> {|GD0107:GodotDictionaryWithNodeAsValueProperty|} { get; set; }
}

View File

@ -196,9 +196,7 @@ namespace Godot.SourceGenerators
continue;
}
if (marshalType == MarshalType.GodotObjectOrDerived)
{
if (!isNode && propertyType.InheritsFrom("GodotSharp", GodotClasses.Node))
if (!isNode && MemberHasNodeType(propertyType, marshalType.Value))
{
context.ReportDiagnostic(Diagnostic.Create(
Common.OnlyNodesShouldExportNodesRule,
@ -206,7 +204,6 @@ namespace Godot.SourceGenerators
));
continue;
}
}
var propertyDeclarationSyntax = property.DeclaringSyntaxReferences
.Select(r => r.GetSyntax() as PropertyDeclarationSyntax).FirstOrDefault();
@ -315,9 +312,7 @@ namespace Godot.SourceGenerators
continue;
}
if (marshalType == MarshalType.GodotObjectOrDerived)
{
if (!isNode && fieldType.InheritsFrom("GodotSharp", GodotClasses.Node))
if (!isNode && MemberHasNodeType(fieldType, marshalType.Value))
{
context.ReportDiagnostic(Diagnostic.Create(
Common.OnlyNodesShouldExportNodesRule,
@ -325,7 +320,6 @@ namespace Godot.SourceGenerators
));
continue;
}
}
EqualsValueClauseSyntax? initializer = field.DeclaringSyntaxReferences
.Select(r => r.GetSyntax())
@ -424,6 +418,27 @@ namespace Godot.SourceGenerators
context.AddSource(uniqueHint, SourceText.From(source.ToString(), Encoding.UTF8));
}
private static bool MemberHasNodeType(ITypeSymbol memberType, MarshalType marshalType)
{
if (marshalType == MarshalType.GodotObjectOrDerived)
{
return memberType.InheritsFrom("GodotSharp", GodotClasses.Node);
}
if (marshalType == MarshalType.GodotObjectOrDerivedArray)
{
var elementType = ((IArrayTypeSymbol)memberType).ElementType;
return elementType.InheritsFrom("GodotSharp", GodotClasses.Node);
}
if (memberType is INamedTypeSymbol { IsGenericType: true } genericType)
{
return genericType.TypeArguments
.Any(static typeArgument
=> typeArgument.InheritsFrom("GodotSharp", GodotClasses.Node));
}
return false;
}
private struct ExportedPropertyMetadata
{
public ExportedPropertyMetadata(string name, MarshalType type, ITypeSymbol typeSymbol, string? value)