Browse Source

Merge pull request #82918 from raulsntos/dotnet/only-node-can-export-node

C#: Report diagnostic for Node exports in a type that doesn't derive from Node
Rémi Verschelde 1 year ago
parent
commit
bf41c6bd34

+ 25 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs

@@ -230,6 +230,31 @@ namespace Godot.SourceGenerators
                 location?.SourceTree?.FilePath));
                 location?.SourceTree?.FilePath));
         }
         }
 
 
+        public static void ReportOnlyNodesShouldExportNodes(
+            GeneratorExecutionContext context,
+            ISymbol exportedMemberSymbol
+        )
+        {
+            var locations = exportedMemberSymbol.Locations;
+            var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault();
+            bool isField = exportedMemberSymbol is IFieldSymbol;
+
+            string message = $"Types not derived from Node should not export Node {(isField ? "fields" : "properties")}";
+
+            string description = $"{message}. Node export is only supported in Node-derived classes.";
+
+            context.ReportDiagnostic(Diagnostic.Create(
+                new DiagnosticDescriptor(id: "GD0107",
+                    title: message,
+                    messageFormat: message,
+                    category: "Usage",
+                    DiagnosticSeverity.Error,
+                    isEnabledByDefault: true,
+                    description),
+                location,
+                location?.SourceTree?.FilePath));
+        }
+
         public static void ReportSignalDelegateMissingSuffix(
         public static void ReportSignalDelegateMissingSuffix(
             GeneratorExecutionContext context,
             GeneratorExecutionContext context,
             INamedTypeSymbol delegateSymbol)
             INamedTypeSymbol delegateSymbol)

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

@@ -32,7 +32,7 @@ namespace Godot.SourceGenerators
             disabledGenerators != null &&
             disabledGenerators != null &&
             disabledGenerators.Split(';').Contains(generatorName));
             disabledGenerators.Split(';').Contains(generatorName));
 
 
-        public static bool InheritsFrom(this INamedTypeSymbol? symbol, string assemblyName, string typeFullName)
+        public static bool InheritsFrom(this ITypeSymbol? symbol, string assemblyName, string typeFullName)
         {
         {
             while (symbol != null)
             while (symbol != null)
             {
             {

+ 18 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs

@@ -170,6 +170,15 @@ namespace Godot.SourceGenerators
                     continue;
                     continue;
                 }
                 }
 
 
+                if (marshalType == MarshalType.GodotObjectOrDerived)
+                {
+                    if (!symbol.InheritsFrom("GodotSharp", "Godot.Node") &&
+                        propertyType.InheritsFrom("GodotSharp", "Godot.Node"))
+                    {
+                        Common.ReportOnlyNodesShouldExportNodes(context, property);
+                    }
+                }
+
                 var propertyDeclarationSyntax = property.DeclaringSyntaxReferences
                 var propertyDeclarationSyntax = property.DeclaringSyntaxReferences
                     .Select(r => r.GetSyntax() as PropertyDeclarationSyntax).FirstOrDefault();
                     .Select(r => r.GetSyntax() as PropertyDeclarationSyntax).FirstOrDefault();
 
 
@@ -265,6 +274,15 @@ namespace Godot.SourceGenerators
                     continue;
                     continue;
                 }
                 }
 
 
+                if (marshalType == MarshalType.GodotObjectOrDerived)
+                {
+                    if (!symbol.InheritsFrom("GodotSharp", "Godot.Node") &&
+                        fieldType.InheritsFrom("GodotSharp", "Godot.Node"))
+                    {
+                        Common.ReportOnlyNodesShouldExportNodes(context, field);
+                    }
+                }
+
                 EqualsValueClauseSyntax? initializer = field.DeclaringSyntaxReferences
                 EqualsValueClauseSyntax? initializer = field.DeclaringSyntaxReferences
                     .Select(r => r.GetSyntax())
                     .Select(r => r.GetSyntax())
                     .OfType<VariableDeclaratorSyntax>()
                     .OfType<VariableDeclaratorSyntax>()