Explorar o código

Merge pull request #88495 from paulloz/dotnet/test-and-fix-exports-diagnostics

[.NET] Test and fix exports diagnostics
Rémi Verschelde hai 1 ano
pai
achega
aeaec000fc
Modificáronse 19 ficheiros con 242 adicións e 9 borrados
  1. 77 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ExportDiagnosticsTests.cs
  2. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0101_ScriptPropertyDefVal.generated.cs
  3. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0102_ScriptPropertyDefVal.generated.cs
  4. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0103_ScriptPropertyDefVal.generated.cs
  5. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0104_ScriptPropertyDefVal.generated.cs
  6. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0105_ScriptPropertyDefVal.generated.cs
  7. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0106_KO_ScriptPropertyDefVal.generated.cs
  8. 21 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0106_OK_ScriptPropertyDefVal.generated.cs
  9. 3 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0107_KO_ScriptPropertyDefVal.generated.cs
  10. 23 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0107_OK_ScriptPropertyDefVal.generated.cs
  11. 10 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0101.cs
  12. 12 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0102.cs
  13. 10 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0103.cs
  14. 7 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0104.cs
  15. 12 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0105.cs
  16. 18 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0106.cs
  17. 19 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0107.cs
  18. 1 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
  19. 11 9
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs

+ 77 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/ExportDiagnosticsTests.cs

@@ -0,0 +1,77 @@
+using Xunit;
+
+namespace Godot.SourceGenerators.Tests;
+
+public class ExportDiagnosticsTests
+{
+    [Fact]
+    public async void StaticMembers()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            "ExportDiagnostics_GD0101.cs",
+            "ExportDiagnostics_GD0101_ScriptPropertyDefVal.generated.cs"
+        );
+    }
+
+    [Fact]
+    public async void TypeIsNotSupported()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            "ExportDiagnostics_GD0102.cs",
+            "ExportDiagnostics_GD0102_ScriptPropertyDefVal.generated.cs"
+        );
+    }
+
+    [Fact]
+    public async void ReadOnly()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            "ExportDiagnostics_GD0103.cs",
+            "ExportDiagnostics_GD0103_ScriptPropertyDefVal.generated.cs"
+        );
+    }
+
+    [Fact]
+    public async void WriteOnly()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            "ExportDiagnostics_GD0104.cs",
+            "ExportDiagnostics_GD0104_ScriptPropertyDefVal.generated.cs"
+        );
+    }
+
+    [Fact]
+    public async void Indexer()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            "ExportDiagnostics_GD0105.cs",
+            "ExportDiagnostics_GD0105_ScriptPropertyDefVal.generated.cs"
+        );
+    }
+
+    [Fact]
+    public async void ExplicitInterfaceImplementation()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            new string[] { "ExportDiagnostics_GD0106.cs" },
+            new string[]
+            {
+                "ExportDiagnostics_GD0106_OK_ScriptPropertyDefVal.generated.cs",
+                "ExportDiagnostics_GD0106_KO_ScriptPropertyDefVal.generated.cs",
+            }
+        );
+    }
+
+    [Fact]
+    public async void NodeExports()
+    {
+        await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
+            new string[] { "ExportDiagnostics_GD0107.cs" },
+            new string[]
+            {
+                "ExportDiagnostics_GD0107_OK_ScriptPropertyDefVal.generated.cs",
+                "ExportDiagnostics_GD0107_KO_ScriptPropertyDefVal.generated.cs",
+            }
+        );
+    }
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0101_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0101
+{
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0102_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0102
+{
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0103_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0103
+{
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0104_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0104
+{
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0105_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0105
+{
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0106_KO_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0106_KO
+{
+}

+ 21 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0106_OK_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,21 @@
+partial class ExportDiagnostics_GD0106_OK
+{
+#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
+#if TOOLS
+    /// <summary>
+    /// Get the default values for all properties declared in this class.
+    /// This method is used by Godot to determine the value that will be
+    /// used by the inspector when resetting properties.
+    /// Do not call this method.
+    /// </summary>
+    [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>(1);
+        int __MyProperty_default_value = default;
+        values.Add(PropertyName.MyProperty, global::Godot.Variant.From<int>(__MyProperty_default_value));
+        return values;
+    }
+#endif // TOOLS
+#pragma warning restore CS0109
+}

+ 3 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0107_KO_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,3 @@
+partial class ExportDiagnostics_GD0107_KO
+{
+}

+ 23 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/ExportDiagnostics_GD0107_OK_ScriptPropertyDefVal.generated.cs

@@ -0,0 +1,23 @@
+partial class ExportDiagnostics_GD0107_OK
+{
+#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
+#if TOOLS
+    /// <summary>
+    /// Get the default values for all properties declared in this class.
+    /// This method is used by Godot to determine the value that will be
+    /// used by the inspector when resetting properties.
+    /// Do not call this method.
+    /// </summary>
+    [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);
+        global::Godot.Node __NodeProperty_default_value = default;
+        values.Add(PropertyName.NodeProperty, global::Godot.Variant.From<global::Godot.Node>(__NodeProperty_default_value));
+        global::Godot.Node __NodeField_default_value = default;
+        values.Add(PropertyName.NodeField, global::Godot.Variant.From<global::Godot.Node>(__NodeField_default_value));
+        return values;
+    }
+#endif // TOOLS
+#pragma warning restore CS0109
+}

+ 10 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0101.cs

@@ -0,0 +1,10 @@
+using Godot;
+
+public partial class ExportDiagnostics_GD0101 : Node
+{
+    [Export]
+    public static string {|GD0101:StaticField|};
+
+    [Export]
+    public static int {|GD0101:StaticProperty|} { get; set; }
+}

+ 12 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0102.cs

@@ -0,0 +1,12 @@
+using Godot;
+
+public partial class ExportDiagnostics_GD0102 : Node
+{
+    public struct MyStruct { }
+
+    [Export]
+    public MyStruct {|GD0102:StructField|};
+
+    [Export]
+    public MyStruct {|GD0102:StructProperty|} { get; set; }
+}

+ 10 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0103.cs

@@ -0,0 +1,10 @@
+using Godot;
+
+public partial class ExportDiagnostics_GD0103 : Node
+{
+    [Export]
+    public readonly string {|GD0103:ReadOnlyField|};
+
+    [Export]
+    public string {|GD0103:ReadOnlyProperty|} { get; }
+}

+ 7 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0104.cs

@@ -0,0 +1,7 @@
+using Godot;
+
+public partial class ExportDiagnostics_GD0104 : Node
+{
+    [Export]
+    public string {|GD0104:WriteOnlyProperty|} { set { } }
+}

+ 12 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0105.cs

@@ -0,0 +1,12 @@
+using System;
+using Godot;
+
+public partial class ExportDiagnostics_GD0105 : Node
+{
+    [Export]
+    public int {|GD0105:this|}[int index]
+    {
+        get { return index; }
+        set { }
+    }
+}

+ 18 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0106.cs

@@ -0,0 +1,18 @@
+using Godot;
+
+public interface MyInterface
+{
+    public int MyProperty { get; set; }
+}
+
+public partial class ExportDiagnostics_GD0106_OK : Node, MyInterface
+{
+    [Export]
+    public int MyProperty { get; set; }
+}
+
+public partial class ExportDiagnostics_GD0106_KO : Node, MyInterface
+{
+    [Export]
+    int MyInterface.{|GD0106:MyProperty|} { get; set; }
+}

+ 19 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/ExportDiagnostics_GD0107.cs

@@ -0,0 +1,19 @@
+using Godot;
+
+public partial class ExportDiagnostics_GD0107_OK : Node
+{
+    [Export]
+    public Node NodeField;
+
+    [Export]
+    public Node NodeProperty { get; set; }
+}
+
+public partial class ExportDiagnostics_GD0107_KO : Resource
+{
+    [Export]
+    public Node {|GD0107:NodeField|};
+
+    [Export]
+    public Node {|GD0107:NodeProperty|} { get; set; }
+}

+ 1 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs

@@ -3,6 +3,7 @@ namespace Godot.SourceGenerators
     public static class GodotClasses
     {
         public const string GodotObject = "Godot.GodotObject";
+        public const string Node = "Godot.Node";
         public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute";
         public const string ExportAttr = "Godot.ExportAttribute";
         public const string ExportCategoryAttr = "Godot.ExportCategoryAttribute";

+ 11 - 9
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs

@@ -66,11 +66,13 @@ namespace Godot.SourceGenerators
         )
         {
             INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
-            string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
-                namespaceSymbol.FullQualifiedNameOmitGlobal() :
-                string.Empty;
+            string classNs = namespaceSymbol is { IsGlobalNamespace: false }
+                ? namespaceSymbol.FullQualifiedNameOmitGlobal()
+                : string.Empty;
             bool hasNamespace = classNs.Length != 0;
 
+            bool isNode = symbol.InheritsFrom("GodotSharp", GodotClasses.Node);
+
             bool isInnerClass = symbol.ContainingType != null;
 
             string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
@@ -114,14 +116,14 @@ namespace Godot.SourceGenerators
             var members = symbol.GetMembers();
 
             var exportedProperties = members
-                .Where(s => !s.IsStatic && s.Kind == SymbolKind.Property)
+                .Where(s => s.Kind == SymbolKind.Property)
                 .Cast<IPropertySymbol>()
                 .Where(s => s.GetAttributes()
                     .Any(a => a.AttributeClass?.IsGodotExportAttribute() ?? false))
                 .ToArray();
 
             var exportedFields = members
-                .Where(s => !s.IsStatic && s.Kind == SymbolKind.Field && !s.IsImplicitlyDeclared)
+                .Where(s => s.Kind == SymbolKind.Field && !s.IsImplicitlyDeclared)
                 .Cast<IFieldSymbol>()
                 .Where(s => s.GetAttributes()
                     .Any(a => a.AttributeClass?.IsGodotExportAttribute() ?? false))
@@ -198,13 +200,13 @@ namespace Godot.SourceGenerators
 
                 if (marshalType == MarshalType.GodotObjectOrDerived)
                 {
-                    if (!symbol.InheritsFrom("GodotSharp", "Godot.Node") &&
-                        propertyType.InheritsFrom("GodotSharp", "Godot.Node"))
+                    if (!isNode && propertyType.InheritsFrom("GodotSharp", GodotClasses.Node))
                     {
                         context.ReportDiagnostic(Diagnostic.Create(
                             Common.OnlyNodesShouldExportNodesRule,
                             property.Locations.FirstLocationWithSourceTreeOrDefault()
                         ));
+                        continue;
                     }
                 }
 
@@ -317,13 +319,13 @@ namespace Godot.SourceGenerators
 
                 if (marshalType == MarshalType.GodotObjectOrDerived)
                 {
-                    if (!symbol.InheritsFrom("GodotSharp", "Godot.Node") &&
-                        fieldType.InheritsFrom("GodotSharp", "Godot.Node"))
+                    if (!isNode && fieldType.InheritsFrom("GodotSharp", GodotClasses.Node))
                     {
                         context.ReportDiagnostic(Diagnostic.Create(
                             Common.OnlyNodesShouldExportNodesRule,
                             field.Locations.FirstLocationWithSourceTreeOrDefault()
                         ));
+                        continue;
                     }
                 }