From f192430921b288a3f72ffb0a4a8fc15329c3c14e Mon Sep 17 00:00:00 2001 From: 2750558108 Date: Fri, 8 Aug 2025 11:10:54 +0800 Subject: [PATCH] Fix source generator exceptions appearing when use "@+internal keyword" as type or namespace name in C# script --- .../KeywordClassNameAndNamespaceTest.cs | 15 +++++++++++++++ .../namespace.class_ScriptMethods.generated.cs | 17 +++++++++++++++++ .../Sources/KeywordClassNameAndNamespace.cs | 8 ++++++++ .../Godot.SourceGenerators/ExtensionMethods.cs | 9 ++------- .../ScriptMethodsGenerator.cs | 4 ++-- .../ScriptPathAttributeGenerator.cs | 2 +- .../ScriptPropertiesGenerator.cs | 4 ++-- .../ScriptPropertyDefValGenerator.cs | 4 ++-- .../ScriptSerializationGenerator.cs | 4 ++-- .../ScriptSignalsGenerator.cs | 4 ++-- .../ExtensionMethods.cs | 9 ++------- .../UnmanagedCallbacksGenerator.cs | 4 ++-- 12 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs create mode 100644 modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs create mode 100644 modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs new file mode 100644 index 00000000000..2cb24f03c30 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs @@ -0,0 +1,15 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class KeywordClassAndNamespaceTest +{ + [Fact] + public async void GenerateScriptMethodsTest() + { + await CSharpSourceGeneratorVerifier.Verify( + "KeywordClassNameAndNamespace.cs", + "namespace.class_ScriptMethods.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs new file mode 100644 index 00000000000..fd5ac594408 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs @@ -0,0 +1,17 @@ +using Godot; +using Godot.NativeInterop; + +namespace @namespace { + +partial class @class +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// + /// Cached StringNames for the methods contained in this class, for fast lookup. + /// + public new class MethodName : global::Godot.GodotObject.MethodName { + } +#pragma warning restore CS0109 +} + +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs new file mode 100644 index 00000000000..97ac64c237c --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs @@ -0,0 +1,8 @@ +using Godot; + +namespace @namespace +{ + partial class @class : GodotObject + { + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs index 12e25389431..bc6091562d7 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -181,13 +181,6 @@ namespace Godot.SourceGenerators }; } - public static string NameWithTypeParameters(this INamedTypeSymbol symbol) - { - return symbol.IsGenericType && symbol.TypeParameters.Length > 0 ? - string.Concat(symbol.Name, "<", string.Join(", ", symbol.TypeParameters), ">") : - symbol.Name; - } - private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } = SymbolDisplayFormat.FullyQualifiedFormat .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted); @@ -268,6 +261,8 @@ namespace Godot.SourceGenerators public static string SanitizeQualifiedNameForUniqueHint(this string qualifiedName) => qualifiedName + // AddSource() doesn't support @ prefix + .Replace("@", "") // AddSource() doesn't support angle brackets .Replace("<", "(Of ") .Replace(">", ")"); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs index e482d9ca79e..7cbab34c5b5 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs @@ -114,13 +114,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs index 59cf9946c97..ec6094637d3 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs @@ -138,7 +138,7 @@ namespace Godot.SourceGenerators source.Append(attributes); source.Append("\npartial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n}\n"); if (hasNamespace) diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs index 4d69611a70e..4dba18424cf 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs @@ -103,13 +103,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs index 6c3824711f8..e2422ae1ed5 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs @@ -100,13 +100,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var exportedMembers = new List(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs index 937da763351..57e24ec25e6 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs @@ -101,13 +101,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs index 2c1b48a8587..a860ce8f89e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -103,13 +103,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs index 3fc27a29d87..a7e3f57c3ca 100644 --- a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs +++ b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs @@ -94,13 +94,6 @@ internal static class ExtensionMethods }; } - public static string NameWithTypeParameters(this INamedTypeSymbol symbol) - { - return symbol.IsGenericType && symbol.TypeParameters.Length > 0 ? - string.Concat(symbol.Name, "<", string.Join(", ", symbol.TypeParameters), ">") : - symbol.Name; - } - private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } = SymbolDisplayFormat.FullyQualifiedFormat .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted); @@ -123,6 +116,8 @@ internal static class ExtensionMethods public static string SanitizeQualifiedNameForUniqueHint(this string qualifiedName) => qualifiedName + // AddSource() doesn't support @ prefix + .Replace("@", "") // AddSource() doesn't support angle brackets .Replace("<", "(Of ") .Replace(">", ")"); diff --git a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs index 80d6160f3d6..53197bf895d 100644 --- a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs +++ b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs @@ -140,7 +140,7 @@ using Godot.NativeInterop; source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } @@ -319,7 +319,7 @@ using Godot.NativeInterop; source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } }