瀏覽代碼

Merge pull request #64743 from raulsntos/dotnet6-signal-analyzer

Improve C# signal analyzer errors
Ignacio Roldán Etcheverry 3 年之前
父節點
當前提交
e172b1aa91

+ 28 - 4
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs

@@ -192,7 +192,31 @@ namespace Godot.SourceGenerators
                 location?.SourceTree?.FilePath));
         }
 
-        public static void ReportSignalDelegateSignatureNotSupported(
+        public static void ReportSignalParameterTypeNotSupported(
+            GeneratorExecutionContext context,
+            IParameterSymbol parameterSymbol)
+        {
+            var locations = parameterSymbol.Locations;
+            var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault();
+
+            string message = "The parameter of the delegate signature of the signal " +
+                             $"is not supported: '{parameterSymbol.ToDisplayString()}'";
+
+            string description = $"{message}. Use supported types only or remove the '[Signal]' attribute.";
+
+            context.ReportDiagnostic(Diagnostic.Create(
+                new DiagnosticDescriptor(id: "GODOT-G0202",
+                    title: message,
+                    messageFormat: message,
+                    category: "Usage",
+                    DiagnosticSeverity.Error,
+                    isEnabledByDefault: true,
+                    description),
+                location,
+                location?.SourceTree?.FilePath));
+        }
+
+        public static void ReportSignalDelegateSignatureMustReturnVoid(
             GeneratorExecutionContext context,
             INamedTypeSymbol delegateSymbol)
         {
@@ -200,12 +224,12 @@ namespace Godot.SourceGenerators
             var location = locations.FirstOrDefault(l => l.SourceTree != null) ?? locations.FirstOrDefault();
 
             string message = "The delegate signature of the signal " +
-                             $"is not supported: '{delegateSymbol.ToDisplayString()}'";
+                             $"must return void: '{delegateSymbol.ToDisplayString()}'";
 
-            string description = $"{message}. Use supported types only or remove the '[Signal]' attribute.";
+            string description = $"{message}. Return void or remove the '[Signal]' attribute.";
 
             context.ReportDiagnostic(Diagnostic.Create(
-                new DiagnosticDescriptor(id: "GODOT-G0202",
+                new DiagnosticDescriptor(id: "GODOT-G0203",
                     title: message,
                     messageFormat: message,
                     category: "Usage",

+ 23 - 2
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs

@@ -148,8 +148,29 @@ namespace Godot.SourceGenerators
 
                 if (invokeMethodData == null)
                 {
-                    // TODO: Better error for incompatible signature. We should indicate incompatible argument types, as we do with exported properties.
-                    Common.ReportSignalDelegateSignatureNotSupported(context, signalDelegateSymbol);
+                    if (signalDelegateSymbol.DelegateInvokeMethod is IMethodSymbol methodSymbol)
+                    {
+                        foreach (var parameter in methodSymbol.Parameters)
+                        {
+                            if (parameter.RefKind != RefKind.None)
+                            {
+                                Common.ReportSignalParameterTypeNotSupported(context, parameter);
+                                continue;
+                            }
+
+                            var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(parameter.Type, typeCache);
+
+                            if (marshalType == null)
+                            {
+                                Common.ReportSignalParameterTypeNotSupported(context, parameter);
+                            }
+                        }
+
+                        if (!methodSymbol.ReturnsVoid)
+                        {
+                            Common.ReportSignalDelegateSignatureMustReturnVoid(context, signalDelegateSymbol);
+                        }
+                    }
                     continue;
                 }