summaryrefslogtreecommitdiff
path: root/modules/mono/editor
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/editor')
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs5
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs89
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs19
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs66
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs48
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs8
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs26
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MethodInfo.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/PropertyInfo.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs26
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs10
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs24
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs86
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs8
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs33
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs2
-rw-r--r--modules/mono/editor/bindings_generator.cpp92
-rw-r--r--modules/mono/editor/code_completion.cpp2
22 files changed, 422 insertions, 136 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs
index ac8d6473a6..9a46b7d164 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedFields.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
#pragma warning disable CS0169
@@ -83,6 +84,10 @@ namespace Godot.SourceGenerators.Sample
[Export] private StringName[] field_StringNameArray = { "foo", "bar" };
[Export] private NodePath[] field_NodePathArray = { "foo", "bar" };
[Export] private RID[] field_RIDArray = { default, default, default };
+ // Note we use Array and not System.Array. This tests the generated namespace qualification.
+ [Export] private Int32[] field_empty_Int32Array = Array.Empty<Int32>();
+ // Note we use List and not System.Collections.Generic.
+ [Export] private int[] field_array_from_list = new List<int>(Array.Empty<int>()).ToArray();
// Variant
[Export] private Variant field_Variant = "foo";
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs
index 3020cfbc50..eb83833b40 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/ExportedProperties.cs
@@ -12,6 +12,95 @@ namespace Godot.SourceGenerators.Sample
[SuppressMessage("ReSharper", "InconsistentNaming")]
public partial class ExportedProperties : Godot.Object
{
+ // Do not generate default value
+ private String _notGenerate_Property_String = new string("not generate");
+ [Export]
+ public String NotGenerate_Complex_Lamda_Property
+ {
+ get => _notGenerate_Property_String + Convert.ToInt32("1");
+ set => _notGenerate_Property_String = value;
+ }
+
+ [Export]
+ public String NotGenerate_Lamda_NoField_Property
+ {
+ get => new string("not generate");
+ set => _notGenerate_Property_String = value;
+ }
+
+ [Export]
+ public String NotGenerate_Complex_Return_Property
+ {
+ get
+ {
+ return _notGenerate_Property_String + Convert.ToInt32("1");
+ }
+ set
+ {
+ _notGenerate_Property_String = value;
+ }
+ }
+
+ private int _notGenerate_Property_Int = 1;
+ [Export]
+ public string NotGenerate_Returns_Property
+ {
+ get
+ {
+ if (_notGenerate_Property_Int == 1)
+ {
+ return "a";
+ }
+ else
+ {
+ return "b";
+ }
+ }
+ set
+ {
+ _notGenerate_Property_Int = value == "a" ? 1 : 2;
+ }
+ }
+
+ // Full Property
+ private String _fullProperty_String = "FullProperty_String";
+ [Export]
+ public String FullProperty_String
+ {
+ get
+ {
+ return _fullProperty_String;
+ }
+ set
+ {
+ _fullProperty_String = value;
+ }
+ }
+
+ private String _fullProperty_String_Complex = new string("FullProperty_String_Complex") + Convert.ToInt32("1");
+ [Export]
+ public String FullProperty_String_Complex
+ {
+ get
+ {
+ return _fullProperty_String_Complex;
+ }
+ set
+ {
+ _fullProperty_String_Complex = value;
+ }
+ }
+
+ // Lamda Property
+ private String _lamdaProperty_String = "LamdaProperty_String";
+ [Export]
+ public String LamdaProperty_String
+ {
+ get => _lamdaProperty_String;
+ set => _lamdaProperty_String = value;
+ }
+
+ // Auto Property
[Export] private Boolean property_Boolean { get; set; } = true;
[Export] private Char property_Char { get; set; } = 'f';
[Export] private SByte property_SByte { get; set; } = 10;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs
new file mode 100644
index 0000000000..a6c8e52667
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MoreExportedFields.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+#pragma warning disable CS0169
+#pragma warning disable CS0414
+
+namespace Godot.SourceGenerators.Sample
+{
+ [SuppressMessage("ReSharper", "BuiltInTypeReferenceStyle")]
+ [SuppressMessage("ReSharper", "RedundantNameQualifier")]
+ [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")]
+ [SuppressMessage("ReSharper", "InconsistentNaming")]
+ // We split the definition of ExportedFields to verify properties work across multiple files.
+ public partial class ExportedFields : Godot.Object
+ {
+ // Note we use Array and not System.Array. This tests the generated namespace qualification.
+ [Export] private Int64[] field_empty_Int64Array = Array.Empty<Int64>();
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
index e28788ec0b..4eed2d7b7b 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
@@ -14,7 +14,7 @@ namespace Godot.SourceGenerators
{
string message =
"Missing partial modifier on declaration of type '" +
- $"{symbol.FullQualifiedName()}' which is a subclass of '{GodotClasses.Object}'";
+ $"{symbol.FullQualifiedNameOmitGlobal()}' which is a subclass of '{GodotClasses.Object}'";
string description = $"{message}. Subclasses of '{GodotClasses.Object}' " +
"must be declared with the partial modifier.";
@@ -41,7 +41,7 @@ namespace Godot.SourceGenerators
.GetDeclaredSymbol(outerTypeDeclSyntax);
string fullQualifiedName = outerSymbol is INamedTypeSymbol namedTypeSymbol ?
- namedTypeSymbol.FullQualifiedName() :
+ namedTypeSymbol.FullQualifiedNameOmitGlobal() :
"type not found";
string message =
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 8de12de23b..7008fb638f 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
+using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -148,22 +149,73 @@ namespace Godot.SourceGenerators
};
}
+ public static string NameWithTypeParameters(this INamedTypeSymbol symbol)
+ {
+ return symbol.IsGenericType ?
+ string.Concat(symbol.Name, "<", string.Join(", ", symbol.TypeParameters), ">") :
+ symbol.Name;
+ }
+
private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } =
SymbolDisplayFormat.FullyQualifiedFormat
.WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted);
- public static string FullQualifiedName(this ITypeSymbol symbol)
+ private static SymbolDisplayFormat FullyQualifiedFormatIncludeGlobal { get; } =
+ SymbolDisplayFormat.FullyQualifiedFormat
+ .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Included);
+
+ public static string FullQualifiedNameOmitGlobal(this ITypeSymbol symbol)
=> symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal);
- public static string NameWithTypeParameters(this INamedTypeSymbol symbol)
+ public static string FullQualifiedNameOmitGlobal(this INamespaceSymbol namespaceSymbol)
+ => namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal);
+
+ public static string FullQualifiedNameIncludeGlobal(this ITypeSymbol symbol)
+ => symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatIncludeGlobal);
+
+ public static string FullQualifiedNameIncludeGlobal(this INamespaceSymbol namespaceSymbol)
+ => namespaceSymbol.ToDisplayString(FullyQualifiedFormatIncludeGlobal);
+
+ public static string FullQualifiedSyntax(this SyntaxNode node, SemanticModel sm)
{
- return symbol.IsGenericType ?
- string.Concat(symbol.Name, "<", string.Join(", ", symbol.TypeParameters), ">") :
- symbol.Name;
+ StringBuilder sb = new();
+ FullQualifiedSyntax(node, sm, sb, true);
+ return sb.ToString();
}
- public static string FullQualifiedName(this INamespaceSymbol namespaceSymbol)
- => namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal);
+ private static void FullQualifiedSyntax(SyntaxNode node, SemanticModel sm, StringBuilder sb, bool isFirstNode)
+ {
+ if (node is NameSyntax ns && isFirstNode)
+ {
+ SymbolInfo nameInfo = sm.GetSymbolInfo(ns);
+ sb.Append(nameInfo.Symbol?.ToDisplayString(FullyQualifiedFormatIncludeGlobal) ?? ns.ToString());
+ return;
+ }
+
+ bool innerIsFirstNode = true;
+ foreach (var child in node.ChildNodesAndTokens())
+ {
+ if (child.HasLeadingTrivia)
+ {
+ sb.Append(child.GetLeadingTrivia());
+ }
+
+ if (child.IsNode)
+ {
+ FullQualifiedSyntax(child.AsNode()!, sm, sb, isFirstNode: innerIsFirstNode);
+ innerIsFirstNode = false;
+ }
+ else
+ {
+ sb.Append(child);
+ }
+
+ if (child.HasTrailingTrivia)
+ {
+ sb.Append(child.GetTrailingTrivia());
+ }
+ }
+ }
public static string SanitizeQualifiedNameForUniqueHint(this string qualifiedName)
=> qualifiedName
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs
index 1a25d684a0..88c0e71155 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs
@@ -71,29 +71,29 @@ namespace Godot.SourceGenerators
Expression = 19,
PlaceholderText = 20,
ColorNoAlpha = 21,
- ImageCompressLossy = 22,
- ImageCompressLossless = 23,
- ObjectId = 24,
- TypeString = 25,
- NodePathToEditedNode = 26,
- MethodOfVariantType = 27,
- MethodOfBaseType = 28,
- MethodOfInstance = 29,
- MethodOfScript = 30,
- PropertyOfVariantType = 31,
- PropertyOfBaseType = 32,
- PropertyOfInstance = 33,
- PropertyOfScript = 34,
- ObjectTooBig = 35,
- NodePathValidTypes = 36,
- SaveFile = 37,
- GlobalSaveFile = 38,
- IntIsObjectid = 39,
- IntIsPointer = 41,
- ArrayType = 40,
- LocaleId = 42,
- LocalizableString = 43,
- NodeType = 44,
+ ObjectId = 22,
+ TypeString = 23,
+ NodePathToEditedNode = 24,
+ MethodOfVariantType = 25,
+ MethodOfBaseType = 26,
+ MethodOfInstance = 27,
+ MethodOfScript = 28,
+ PropertyOfVariantType = 29,
+ PropertyOfBaseType = 30,
+ PropertyOfInstance = 31,
+ PropertyOfScript = 32,
+ ObjectTooBig = 33,
+ NodePathValidTypes = 34,
+ SaveFile = 35,
+ GlobalSaveFile = 36,
+ IntIsObjectid = 37,
+ IntIsPointer = 38,
+ ArrayType = 39,
+ LocaleId = 40,
+ LocalizableString = 41,
+ NodeType = 42,
+ HideQuaternionEdit = 43,
+ Password = 44,
Max = 45
}
@@ -128,12 +128,14 @@ namespace Godot.SourceGenerators
DeferredSetResource = 33554432,
EditorInstantiateObject = 67108864,
EditorBasicSetting = 134217728,
+ ReadOnly = 268435456,
Array = 536870912,
Default = 6,
DefaultIntl = 38,
NoEditor = 2
}
+ [Flags]
public enum MethodFlags
{
Normal = 1,
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs
index db395e21cb..abd8079922 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs
@@ -3,7 +3,7 @@ using Microsoft.CodeAnalysis;
namespace Godot.SourceGenerators
{
- public struct GodotMethodData
+ public readonly struct GodotMethodData
{
public GodotMethodData(IMethodSymbol method, ImmutableArray<MarshalType> paramTypes,
ImmutableArray<ITypeSymbol> paramTypeSymbols, MarshalType? retType, ITypeSymbol? retSymbol)
@@ -22,7 +22,7 @@ namespace Godot.SourceGenerators
public ITypeSymbol? RetSymbol { get; }
}
- public struct GodotSignalDelegateData
+ public readonly struct GodotSignalDelegateData
{
public GodotSignalDelegateData(string name, INamedTypeSymbol delegateSymbol, GodotMethodData invokeMethodData)
{
@@ -36,7 +36,7 @@ namespace Godot.SourceGenerators
public GodotMethodData InvokeMethodData { get; }
}
- public struct GodotPropertyData
+ public readonly struct GodotPropertyData
{
public GodotPropertyData(IPropertySymbol propertySymbol, MarshalType type)
{
@@ -48,7 +48,7 @@ namespace Godot.SourceGenerators
public MarshalType Type { get; }
}
- public struct GodotFieldData
+ public readonly struct GodotFieldData
{
public GodotFieldData(IFieldSymbol fieldSymbol, MarshalType type)
{
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs
index 7ec3f88e5d..19fdd51dab 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs
@@ -56,7 +56,7 @@ namespace GodotPlugins.Game
}
";
- context.AddSource("GodotPlugins.Game_Generated",
+ context.AddSource("GodotPlugins.Game.generated",
SourceText.From(source, Encoding.UTF8));
}
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
index bd40675fd3..4fdd40f638 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
@@ -220,7 +220,7 @@ namespace Godot.SourceGenerators
_ => null
};
case "Collections"
- when type.ContainingNamespace?.FullQualifiedName() == "Godot.Collections":
+ when type.ContainingNamespace?.FullQualifiedNameOmitGlobal() == "Godot.Collections":
return type switch
{
{ Name: "Dictionary" } =>
@@ -367,7 +367,7 @@ namespace Godot.SourceGenerators
MarshalType.SignalInfo =>
source.Append(VariantUtils, ".ConvertToSignalInfo(", inputExpr, ")"),
MarshalType.Enum =>
- source.Append("(", typeSymbol.FullQualifiedName(),
+ source.Append("(", typeSymbol.FullQualifiedNameIncludeGlobal(),
")", VariantUtils, ".ConvertToInt32(", inputExpr, ")"),
MarshalType.ByteArray =>
source.Append(VariantUtils, ".ConvertAsPackedByteArrayToSystemArray(", inputExpr, ")"),
@@ -389,7 +389,7 @@ namespace Godot.SourceGenerators
source.Append(VariantUtils, ".ConvertAsPackedColorArrayToSystemArray(", inputExpr, ")"),
MarshalType.GodotObjectOrDerivedArray =>
source.Append(VariantUtils, ".ConvertToSystemArrayOfGodotObject<",
- ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">(", inputExpr, ")"),
+ ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">(", inputExpr, ")"),
MarshalType.SystemArrayOfStringName =>
source.Append(VariantUtils, ".ConvertToSystemArrayOfStringName(", inputExpr, ")"),
MarshalType.SystemArrayOfNodePath =>
@@ -399,7 +399,7 @@ namespace Godot.SourceGenerators
MarshalType.Variant =>
source.Append("global::Godot.Variant.CreateCopyingBorrowed(", inputExpr, ")"),
MarshalType.GodotObjectOrDerived =>
- source.Append("(", typeSymbol.FullQualifiedName(),
+ source.Append("(", typeSymbol.FullQualifiedNameIncludeGlobal(),
")", VariantUtils, ".ConvertToGodotObject(", inputExpr, ")"),
MarshalType.StringName =>
source.Append(VariantUtils, ".ConvertToStringNameObject(", inputExpr, ")"),
@@ -413,11 +413,11 @@ namespace Godot.SourceGenerators
source.Append(VariantUtils, ".ConvertToArrayObject(", inputExpr, ")"),
MarshalType.GodotGenericDictionary =>
source.Append(VariantUtils, ".ConvertToDictionaryObject<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ", ",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedName(), ">(", inputExpr, ")"),
+ ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ",
+ ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedNameIncludeGlobal(), ">(", inputExpr, ")"),
MarshalType.GodotGenericArray =>
source.Append(VariantUtils, ".ConvertToArrayObject<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">(", inputExpr, ")"),
+ ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ">(", inputExpr, ")"),
_ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType,
"Received unexpected marshal type")
};
@@ -578,7 +578,7 @@ namespace Godot.SourceGenerators
MarshalType.Callable => source.Append(inputExpr, ".AsCallable()"),
MarshalType.SignalInfo => source.Append(inputExpr, ".AsSignalInfo()"),
MarshalType.Enum =>
- source.Append("(", typeSymbol.FullQualifiedName(), ")", inputExpr, ".AsInt64()"),
+ source.Append("(", typeSymbol.FullQualifiedNameIncludeGlobal(), ")", inputExpr, ".AsInt64()"),
MarshalType.ByteArray => source.Append(inputExpr, ".AsByteArray()"),
MarshalType.Int32Array => source.Append(inputExpr, ".AsInt32Array()"),
MarshalType.Int64Array => source.Append(inputExpr, ".AsInt64Array()"),
@@ -589,23 +589,23 @@ namespace Godot.SourceGenerators
MarshalType.Vector3Array => source.Append(inputExpr, ".AsVector3Array()"),
MarshalType.ColorArray => source.Append(inputExpr, ".AsColorArray()"),
MarshalType.GodotObjectOrDerivedArray => source.Append(inputExpr, ".AsGodotObjectArray<",
- ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">()"),
+ ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">()"),
MarshalType.SystemArrayOfStringName => source.Append(inputExpr, ".AsSystemArrayOfStringName()"),
MarshalType.SystemArrayOfNodePath => source.Append(inputExpr, ".AsSystemArrayOfNodePath()"),
MarshalType.SystemArrayOfRID => source.Append(inputExpr, ".AsSystemArrayOfRID()"),
MarshalType.Variant => source.Append(inputExpr),
MarshalType.GodotObjectOrDerived => source.Append("(",
- typeSymbol.FullQualifiedName(), ")", inputExpr, ".AsGodotObject()"),
+ typeSymbol.FullQualifiedNameIncludeGlobal(), ")", inputExpr, ".AsGodotObject()"),
MarshalType.StringName => source.Append(inputExpr, ".AsStringName()"),
MarshalType.NodePath => source.Append(inputExpr, ".AsNodePath()"),
MarshalType.RID => source.Append(inputExpr, ".AsRID()"),
MarshalType.GodotDictionary => source.Append(inputExpr, ".AsGodotDictionary()"),
MarshalType.GodotArray => source.Append(inputExpr, ".AsGodotArray()"),
MarshalType.GodotGenericDictionary => source.Append(inputExpr, ".AsGodotDictionary<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ", ",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedName(), ">()"),
+ ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ",
+ ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedNameIncludeGlobal(), ">()"),
MarshalType.GodotGenericArray => source.Append(inputExpr, ".AsGodotArray<",
- ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">()"),
+ ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ">()"),
_ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType,
"Received unexpected marshal type")
};
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MethodInfo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MethodInfo.cs
index 81c6f2b7d5..bb9be862c4 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MethodInfo.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MethodInfo.cs
@@ -2,7 +2,7 @@ using System.Collections.Generic;
namespace Godot.SourceGenerators
{
- internal struct MethodInfo
+ internal readonly struct MethodInfo
{
public MethodInfo(string name, PropertyInfo returnVal, MethodFlags flags,
List<PropertyInfo>? arguments,
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/PropertyInfo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/PropertyInfo.cs
index b345f5f84d..2b89633ef6 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/PropertyInfo.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/PropertyInfo.cs
@@ -1,6 +1,6 @@
namespace Godot.SourceGenerators
{
- internal struct PropertyInfo
+ internal readonly struct PropertyInfo
{
public PropertyInfo(VariantType type, string name, PropertyHint hint,
string? hintString, PropertyUsageFlags usage, bool exported)
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 1ee31eb1a9..2f51018293 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
@@ -80,14 +80,14 @@ namespace Godot.SourceGenerators
{
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
- namespaceSymbol.FullQualifiedName() :
+ namespaceSymbol.FullQualifiedNameOmitGlobal() :
string.Empty;
bool hasNamespace = classNs.Length != 0;
bool isInnerClass = symbol.ContainingType != null;
- string uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()
- + "_ScriptMethods_Generated";
+ string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
+ + "_ScriptMethods.generated";
var source = new StringBuilder();
@@ -135,7 +135,7 @@ namespace Godot.SourceGenerators
source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
- source.Append($" public new class MethodName : {symbol.BaseType.FullQualifiedName()}.MethodName {{\n");
+ source.Append($" public new class MethodName : {symbol.BaseType.FullQualifiedNameIncludeGlobal()}.MethodName {{\n");
// Generate cached StringNames for methods and properties, for fast lookup
@@ -146,7 +146,7 @@ namespace Godot.SourceGenerators
foreach (string methodName in distinctMethodNames)
{
- source.Append(" public new static readonly StringName ");
+ source.Append(" public new static readonly global::Godot.StringName ");
source.Append(methodName);
source.Append(" = \"");
source.Append(methodName);
@@ -159,7 +159,7 @@ namespace Godot.SourceGenerators
if (godotClassMethods.Length > 0)
{
- const string listType = "System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>";
+ const string listType = "global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>";
source.Append(" internal new static ")
.Append(listType)
@@ -188,14 +188,14 @@ namespace Godot.SourceGenerators
if (godotClassMethods.Length > 0)
{
source.Append(" protected override bool InvokeGodotClassMethod(in godot_string_name method, ");
- source.Append("NativeVariantPtrArgs args, int argCount, out godot_variant ret)\n {\n");
+ source.Append("NativeVariantPtrArgs args, out godot_variant ret)\n {\n");
foreach (var method in godotClassMethods)
{
GenerateMethodInvoker(method, source);
}
- source.Append(" return base.InvokeGodotClassMethod(method, args, argCount, out ret);\n");
+ source.Append(" return base.InvokeGodotClassMethod(method, args, out ret);\n");
source.Append(" }\n");
}
@@ -248,7 +248,7 @@ namespace Godot.SourceGenerators
AppendPropertyInfo(source, methodInfo.ReturnVal);
- source.Append(", flags: (Godot.MethodFlags)")
+ source.Append(", flags: (global::Godot.MethodFlags)")
.Append((int)methodInfo.Flags)
.Append(", arguments: ");
@@ -276,15 +276,15 @@ namespace Godot.SourceGenerators
private static void AppendPropertyInfo(StringBuilder source, PropertyInfo propertyInfo)
{
- source.Append("new(type: (Godot.Variant.Type)")
+ source.Append("new(type: (global::Godot.Variant.Type)")
.Append((int)propertyInfo.Type)
.Append(", name: \"")
.Append(propertyInfo.Name)
- .Append("\", hint: (Godot.PropertyHint)")
+ .Append("\", hint: (global::Godot.PropertyHint)")
.Append((int)propertyInfo.Hint)
.Append(", hintString: \"")
.Append(propertyInfo.HintString)
- .Append("\", usage: (Godot.PropertyUsageFlags)")
+ .Append("\", usage: (global::Godot.PropertyUsageFlags)")
.Append((int)propertyInfo.Usage)
.Append(", exported: ")
.Append(propertyInfo.Exported ? "true" : "false")
@@ -364,7 +364,7 @@ namespace Godot.SourceGenerators
source.Append(" if (method == MethodName.");
source.Append(methodName);
- source.Append(" && argCount == ");
+ source.Append(" && args.Count == ");
source.Append(method.ParamTypes.Length);
source.Append(") {\n");
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 e8a9e28d0c..fb32f6192f 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs
@@ -92,12 +92,12 @@ namespace Godot.SourceGenerators
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
- namespaceSymbol.FullQualifiedName() :
+ namespaceSymbol.FullQualifiedNameOmitGlobal() :
string.Empty;
bool hasNamespace = classNs.Length != 0;
- var uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()
- + "_ScriptPath_Generated";
+ string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
+ + "_ScriptPath.generated";
var source = new StringBuilder();
@@ -126,7 +126,7 @@ namespace Godot.SourceGenerators
source.Append("\n}\n");
}
- context.AddSource(uniqueHint.ToString(), SourceText.From(source.ToString(), Encoding.UTF8));
+ context.AddSource(uniqueHint, SourceText.From(source.ToString(), Encoding.UTF8));
}
private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context,
@@ -157,7 +157,7 @@ namespace Godot.SourceGenerators
sourceBuilder.Append("})]\n");
- context.AddSource("AssemblyScriptTypes_Generated",
+ context.AddSource("AssemblyScriptTypes.generated",
SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
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 b331e2e794..252f162b0c 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
@@ -66,14 +66,14 @@ namespace Godot.SourceGenerators
{
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
- namespaceSymbol.FullQualifiedName() :
+ namespaceSymbol.FullQualifiedNameOmitGlobal() :
string.Empty;
bool hasNamespace = classNs.Length != 0;
bool isInnerClass = symbol.ContainingType != null;
- string uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()
- + "_ScriptProperties_Generated";
+ string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
+ + "_ScriptProperties.generated";
var source = new StringBuilder();
@@ -124,14 +124,14 @@ namespace Godot.SourceGenerators
source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
- source.Append($" public new class PropertyName : {symbol.BaseType.FullQualifiedName()}.PropertyName {{\n");
+ source.Append($" public new class PropertyName : {symbol.BaseType.FullQualifiedNameIncludeGlobal()}.PropertyName {{\n");
// Generate cached StringNames for methods and properties, for fast lookup
foreach (var property in godotClassProperties)
{
string propertyName = property.PropertySymbol.Name;
- source.Append(" public new static readonly StringName ");
+ source.Append(" public new static readonly global::Godot.StringName ");
source.Append(propertyName);
source.Append(" = \"");
source.Append(propertyName);
@@ -141,7 +141,7 @@ namespace Godot.SourceGenerators
foreach (var field in godotClassFields)
{
string fieldName = field.FieldSymbol.Name;
- source.Append(" public new static readonly StringName ");
+ source.Append(" public new static readonly global::Godot.StringName ");
source.Append(fieldName);
source.Append(" = \"");
source.Append(fieldName);
@@ -216,7 +216,7 @@ namespace Godot.SourceGenerators
// Generate GetGodotPropertyList
- string dictionaryType = "System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>";
+ string dictionaryType = "global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>";
source.Append(" internal new static ")
.Append(dictionaryType)
@@ -292,7 +292,7 @@ namespace Godot.SourceGenerators
source.Append("if (name == PropertyName.")
.Append(propertyMemberName)
.Append(") {\n")
- .Append(" ")
+ .Append(" this.")
.Append(propertyMemberName)
.Append(" = ")
.AppendNativeVariantToManagedExpr("value", propertyTypeSymbol, propertyMarshalType)
@@ -317,7 +317,7 @@ namespace Godot.SourceGenerators
.Append(propertyMemberName)
.Append(") {\n")
.Append(" value = ")
- .AppendManagedToNativeVariantExpr(propertyMemberName, propertyMarshalType)
+ .AppendManagedToNativeVariantExpr("this." + propertyMemberName, propertyMarshalType)
.Append(";\n")
.Append(" return true;\n")
.Append(" }\n");
@@ -340,15 +340,15 @@ namespace Godot.SourceGenerators
private static void AppendPropertyInfo(StringBuilder source, PropertyInfo propertyInfo)
{
- source.Append(" properties.Add(new(type: (Godot.Variant.Type)")
+ source.Append(" properties.Add(new(type: (global::Godot.Variant.Type)")
.Append((int)propertyInfo.Type)
.Append(", name: PropertyName.")
.Append(propertyInfo.Name)
- .Append(", hint: (Godot.PropertyHint)")
+ .Append(", hint: (global::Godot.PropertyHint)")
.Append((int)propertyInfo.Hint)
.Append(", hintString: \"")
.Append(propertyInfo.HintString)
- .Append("\", usage: (Godot.PropertyUsageFlags)")
+ .Append("\", usage: (global::Godot.PropertyUsageFlags)")
.Append((int)propertyInfo.Usage)
.Append(", exported: ")
.Append(propertyInfo.Exported ? "true" : "false")
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 65dadcb801..3f588a4c90 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
@@ -66,14 +67,14 @@ namespace Godot.SourceGenerators
{
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
- namespaceSymbol.FullQualifiedName() :
+ namespaceSymbol.FullQualifiedNameOmitGlobal() :
string.Empty;
bool hasNamespace = classNs.Length != 0;
bool isInnerClass = symbol.ContainingType != null;
- string uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()
- + "_ScriptPropertyDefVal_Generated";
+ string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
+ + "_ScriptPropertyDefVal.generated";
var source = new StringBuilder();
@@ -163,14 +164,69 @@ namespace Godot.SourceGenerators
continue;
}
- // TODO: Detect default value from simple property getters (currently we only detect from initializers)
+ var propertyDeclarationSyntax = property.DeclaringSyntaxReferences
+ .Select(r => r.GetSyntax() as PropertyDeclarationSyntax).FirstOrDefault();
- EqualsValueClauseSyntax? initializer = property.DeclaringSyntaxReferences
- .Select(r => r.GetSyntax() as PropertyDeclarationSyntax)
- .Select(s => s?.Initializer ?? null)
- .FirstOrDefault();
-
- string? value = initializer?.Value.ToString();
+ // Fully qualify the value to avoid issues with namespaces.
+ string? value = null;
+ if (propertyDeclarationSyntax != null)
+ {
+ if (propertyDeclarationSyntax.Initializer != null)
+ {
+ var sm = context.Compilation.GetSemanticModel(propertyDeclarationSyntax.Initializer.SyntaxTree);
+ value = propertyDeclarationSyntax.Initializer.Value.FullQualifiedSyntax(sm);
+ }
+ else
+ {
+ var propertyGet = propertyDeclarationSyntax.AccessorList?.Accessors.Where(a => a.Keyword.IsKind(SyntaxKind.GetKeyword)).FirstOrDefault();
+ if (propertyGet != null)
+ {
+ if (propertyGet.ExpressionBody != null)
+ {
+ if (propertyGet.ExpressionBody.Expression is IdentifierNameSyntax identifierNameSyntax)
+ {
+ var sm = context.Compilation.GetSemanticModel(identifierNameSyntax.SyntaxTree);
+ var fieldSymbol = sm.GetSymbolInfo(identifierNameSyntax).Symbol as IFieldSymbol;
+ EqualsValueClauseSyntax? initializer = fieldSymbol?.DeclaringSyntaxReferences
+ .Select(r => r.GetSyntax())
+ .OfType<VariableDeclaratorSyntax>()
+ .Select(s => s.Initializer)
+ .FirstOrDefault(i => i != null);
+
+ if (initializer != null)
+ {
+ sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
+ value = initializer.Value.FullQualifiedSyntax(sm);
+ }
+ }
+ }
+ else
+ {
+ var returns = propertyGet.DescendantNodes().OfType<ReturnStatementSyntax>();
+ if (returns.Count() == 1)
+ {// Generate only single return
+ var returnStatementSyntax = returns.Single();
+ if (returnStatementSyntax.Expression is IdentifierNameSyntax identifierNameSyntax)
+ {
+ var sm = context.Compilation.GetSemanticModel(identifierNameSyntax.SyntaxTree);
+ var fieldSymbol = sm.GetSymbolInfo(identifierNameSyntax).Symbol as IFieldSymbol;
+ EqualsValueClauseSyntax? initializer = fieldSymbol?.DeclaringSyntaxReferences
+ .Select(r => r.GetSyntax())
+ .OfType<VariableDeclaratorSyntax>()
+ .Select(s => s.Initializer)
+ .FirstOrDefault(i => i != null);
+
+ if (initializer != null)
+ {
+ sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
+ value = initializer.Value.FullQualifiedSyntax(sm);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
exportedMembers.Add(new ExportedPropertyMetadata(
property.Name, marshalType.Value, propertyType, value));
@@ -207,7 +263,13 @@ namespace Godot.SourceGenerators
.Select(s => s.Initializer)
.FirstOrDefault(i => i != null);
- string? value = initializer?.Value.ToString();
+ // This needs to be fully qualified to avoid issues with namespaces.
+ string? value = null;
+ if (initializer != null)
+ {
+ var sm = context.Compilation.GetSemanticModel(initializer.SyntaxTree);
+ value = initializer.Value.FullQualifiedSyntax(sm);
+ }
exportedMembers.Add(new ExportedPropertyMetadata(
field.Name, marshalType.Value, fieldType, value));
@@ -237,7 +299,7 @@ namespace Godot.SourceGenerators
string defaultValueLocalName = string.Concat("__", exportedMember.Name, "_default_value");
source.Append(" ");
- source.Append(exportedMember.TypeSymbol.FullQualifiedName());
+ source.Append(exportedMember.TypeSymbol.FullQualifiedNameIncludeGlobal());
source.Append(" ");
source.Append(defaultValueLocalName);
source.Append(" = ");
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 a40220565f..ed877cbd17 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
@@ -66,14 +66,14 @@ namespace Godot.SourceGenerators
{
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
- namespaceSymbol.FullQualifiedName() :
+ namespaceSymbol.FullQualifiedNameOmitGlobal() :
string.Empty;
bool hasNamespace = classNs.Length != 0;
bool isInnerClass = symbol.ContainingType != null;
- string uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()
- + "_ScriptSerialization_Generated";
+ string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
+ + "_ScriptSerialization.generated";
var source = new StringBuilder();
@@ -241,7 +241,7 @@ namespace Godot.SourceGenerators
foreach (var signalDelegate in godotSignalDelegates)
{
string signalName = signalDelegate.Name;
- string signalDelegateQualifiedName = signalDelegate.DelegateSymbol.FullQualifiedName();
+ string signalDelegateQualifiedName = signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal();
source.Append(" if (info.TryGetSignalEventDelegate<")
.Append(signalDelegateQualifiedName)
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 ea7cc3fe38..119cc9d4f0 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
@@ -75,14 +75,14 @@ namespace Godot.SourceGenerators
{
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
- namespaceSymbol.FullQualifiedName() :
+ namespaceSymbol.FullQualifiedNameOmitGlobal() :
string.Empty;
bool hasNamespace = classNs.Length != 0;
bool isInnerClass = symbol.ContainingType != null;
- string uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint()
- + "_ScriptSignals_Generated";
+ string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint()
+ + "_ScriptSignals.generated";
var source = new StringBuilder();
@@ -167,6 +167,7 @@ namespace Godot.SourceGenerators
Common.ReportSignalDelegateSignatureMustReturnVoid(context, signalDelegateSymbol);
}
}
+
continue;
}
@@ -175,14 +176,14 @@ namespace Godot.SourceGenerators
source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n");
- source.Append($" public new class SignalName : {symbol.BaseType.FullQualifiedName()}.SignalName {{\n");
+ source.Append($" public new class SignalName : {symbol.BaseType.FullQualifiedNameIncludeGlobal()}.SignalName {{\n");
// Generate cached StringNames for methods and properties, for fast lookup
foreach (var signalDelegate in godotSignalDelegates)
{
string signalName = signalDelegate.Name;
- source.Append(" public new static readonly StringName ");
+ source.Append(" public new static readonly global::Godot.StringName ");
source.Append(signalName);
source.Append(" = \"");
source.Append(signalName);
@@ -195,7 +196,7 @@ namespace Godot.SourceGenerators
if (godotSignalDelegates.Count > 0)
{
- const string listType = "System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>";
+ const string listType = "global::System.Collections.Generic.List<global::Godot.Bridge.MethodInfo>";
source.Append(" internal new static ")
.Append(listType)
@@ -230,15 +231,15 @@ namespace Godot.SourceGenerators
// as it doesn't emit the signal, only the event delegates. This can confuse users.
// Maybe we should directly connect the delegates, as we do with native signals?
source.Append(" private ")
- .Append(signalDelegate.DelegateSymbol.FullQualifiedName())
+ .Append(signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal())
.Append(" backing_")
.Append(signalName)
.Append(";\n");
- source.Append($" /// <inheritdoc cref=\"{signalDelegate.DelegateSymbol.FullQualifiedName()}\"/>\n");
+ source.Append($" /// <inheritdoc cref=\"{signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal()}\"/>\n");
source.Append(" public event ")
- .Append(signalDelegate.DelegateSymbol.FullQualifiedName())
+ .Append(signalDelegate.DelegateSymbol.FullQualifiedNameIncludeGlobal())
.Append(" ")
.Append(signalName)
.Append(" {\n")
@@ -257,14 +258,14 @@ namespace Godot.SourceGenerators
{
source.Append(
" protected override void RaiseGodotClassSignalCallbacks(in godot_string_name signal, ");
- source.Append("NativeVariantPtrArgs args, int argCount)\n {\n");
+ source.Append("NativeVariantPtrArgs args)\n {\n");
foreach (var signal in godotSignalDelegates)
{
GenerateSignalEventInvoker(signal, source);
}
- source.Append(" base.RaiseGodotClassSignalCallbacks(signal, args, argCount);\n");
+ source.Append(" base.RaiseGodotClassSignalCallbacks(signal, args);\n");
source.Append(" }\n");
}
@@ -299,7 +300,7 @@ namespace Godot.SourceGenerators
AppendPropertyInfo(source, methodInfo.ReturnVal);
- source.Append(", flags: (Godot.MethodFlags)")
+ source.Append(", flags: (global::Godot.MethodFlags)")
.Append((int)methodInfo.Flags)
.Append(", arguments: ");
@@ -327,15 +328,15 @@ namespace Godot.SourceGenerators
private static void AppendPropertyInfo(StringBuilder source, PropertyInfo propertyInfo)
{
- source.Append("new(type: (Godot.Variant.Type)")
+ source.Append("new(type: (global::Godot.Variant.Type)")
.Append((int)propertyInfo.Type)
.Append(", name: \"")
.Append(propertyInfo.Name)
- .Append("\", hint: (Godot.PropertyHint)")
+ .Append("\", hint: (global::Godot.PropertyHint)")
.Append((int)propertyInfo.Hint)
.Append(", hintString: \"")
.Append(propertyInfo.HintString)
- .Append("\", usage: (Godot.PropertyUsageFlags)")
+ .Append("\", usage: (global::Godot.PropertyUsageFlags)")
.Append((int)propertyInfo.Usage)
.Append(", exported: ")
.Append(propertyInfo.Exported ? "true" : "false")
@@ -404,7 +405,7 @@ namespace Godot.SourceGenerators
source.Append(" if (signal == SignalName.");
source.Append(signalName);
- source.Append(" && argCount == ");
+ source.Append(" && args.Count == ");
source.Append(invokeMethodData.ParamTypes.Length);
source.Append(") {\n");
source.Append(" backing_");
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs
index 9d593fbf8a..ab21527344 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs
@@ -13,7 +13,7 @@ namespace GodotTools.IdeMessaging.Utils
return waitAsyncTask.ContinueWith<IDisposable>(t => wrapper, cancellationToken).ConfigureAwait(false);
}
- private struct SemaphoreSlimWaitReleaseWrapper : IDisposable
+ private readonly struct SemaphoreSlimWaitReleaseWrapper : IDisposable
{
private readonly SemaphoreSlim semaphoreSlim;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 2184cae6d6..94efcba3f1 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -22,7 +22,7 @@ namespace GodotTools.Export
public bool FullAot;
private bool _useInterpreter;
- public bool UseInterpreter { get => _useInterpreter && !LLVMOnly; set => _useInterpreter = value; }
+ public bool UseInterpreter { readonly get => _useInterpreter && !LLVMOnly; set => _useInterpreter = value; }
public string[] ExtraAotOptions;
public string[] ExtraOptimizerOptions;
diff --git a/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs b/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs
index 820d0c0b83..9a8fdcc7c5 100644
--- a/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs
@@ -1,6 +1,6 @@
namespace GodotTools
{
- public struct PlaySettings
+ public readonly struct PlaySettings
{
public bool HasDebugger { get; }
public string DebuggerHost { get; }
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 3be8dd87c0..9185506776 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -1614,7 +1614,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual")
<< " bool " CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(in godot_string_name method, "
- << "NativeVariantPtrArgs args, int argCount, out godot_variant ret)\n"
+ << "NativeVariantPtrArgs args, out godot_variant ret)\n"
<< INDENT1 "{\n";
for (const MethodInterface &imethod : itype.methods) {
@@ -1630,7 +1630,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// We check both native names (snake_case) and proxy names (PascalCase)
output << INDENT2 "if ((method == " << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
<< " || method == MethodName." << imethod.proxy_name
- << ") && argCount == " << itos(imethod.arguments.size())
+ << ") && args.Count == " << itos(imethod.arguments.size())
<< " && " << CS_METHOD_HAS_GODOT_CLASS_METHOD << "((godot_string_name)"
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name << ".NativeValue))\n"
<< INDENT2 "{\n";
@@ -1682,7 +1682,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
if (is_derived_type) {
- output << INDENT2 "return base." CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(method, args, argCount, out ret);\n";
+ output << INDENT2 "return base." CS_METHOD_INVOKE_GODOT_CLASS_METHOD "(method, args, out ret);\n";
} else {
output << INDENT2 "ret = default;\n"
<< INDENT2 "return false;\n";
@@ -2200,6 +2200,11 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::SignalInterface &p_isignal, StringBuilder &p_output) {
String arguments_sig;
+ String delegate_type_params;
+
+ if (!p_isignal.arguments.is_empty()) {
+ delegate_type_params += "<";
+ }
// Retrieve information from the arguments
const ArgumentInterface &first = p_isignal.arguments.front()->get();
@@ -2220,11 +2225,18 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
if (&iarg != &first) {
arguments_sig += ", ";
+ delegate_type_params += ", ";
}
arguments_sig += arg_type->cs_type;
arguments_sig += " ";
arguments_sig += iarg.name;
+
+ delegate_type_params += arg_type->cs_type;
+ }
+
+ if (!p_isignal.arguments.is_empty()) {
+ delegate_type_params += ">";
}
// Generate signal
@@ -2248,15 +2260,45 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append("\")]");
}
- String delegate_name = p_isignal.proxy_name;
- delegate_name += "EventHandler"; // Delegate name is [SignalName]EventHandler
+ bool is_parameterless = p_isignal.arguments.size() == 0;
- // Generate delegate
- p_output.append(MEMBER_BEGIN "public delegate void ");
- p_output.append(delegate_name);
- p_output.append("(");
- p_output.append(arguments_sig);
- p_output.append(");\n");
+ // Delegate name is [SignalName]EventHandler
+ String delegate_name = is_parameterless ? "Action" : p_isignal.proxy_name + "EventHandler";
+
+ if (!is_parameterless) {
+ // Generate delegate
+ p_output.append(MEMBER_BEGIN "public delegate void ");
+ p_output.append(delegate_name);
+ p_output.append("(");
+ p_output.append(arguments_sig);
+ p_output.append(");\n");
+
+ // Generate Callable trampoline for the delegate
+ p_output << MEMBER_BEGIN "private static void " << p_isignal.proxy_name << "Trampoline"
+ << "(object delegateObj, NativeVariantPtrArgs args, out godot_variant ret)\n"
+ << INDENT1 "{\n"
+ << INDENT2 "Callable.ThrowIfArgCountMismatch(args, " << itos(p_isignal.arguments.size()) << ");\n"
+ << INDENT2 "((" << delegate_name << ")delegateObj)(";
+
+ int idx = 0;
+ for (const ArgumentInterface &iarg : p_isignal.arguments) {
+ const TypeInterface *arg_type = _get_type_or_null(iarg.type);
+ ERR_FAIL_NULL_V(arg_type, ERR_BUG); // Argument type not found
+
+ if (idx != 0) {
+ p_output << ",";
+ }
+
+ p_output << sformat(arg_type->cs_variant_to_managed,
+ "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name);
+
+ idx++;
+ }
+
+ p_output << ");\n"
+ << INDENT2 "ret = default;\n"
+ << INDENT1 "}\n";
+ }
if (p_isignal.method_doc && p_isignal.method_doc->description.size()) {
String xml_summary = bbcode_to_xml(fix_doc_description(p_isignal.method_doc->description), &p_itype);
@@ -2292,6 +2334,11 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append("static ");
}
+ if (!is_parameterless) {
+ // `unsafe` is needed for taking the trampoline's function pointer
+ p_output << "unsafe ";
+ }
+
p_output.append("event ");
p_output.append(delegate_name);
p_output.append(" ");
@@ -2304,8 +2351,13 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append("add => Connect(SignalName.");
}
- p_output.append(p_isignal.proxy_name);
- p_output.append(", new Callable(value));\n");
+ if (is_parameterless) {
+ // Delegate type is Action. No need for custom trampoline.
+ p_output << p_isignal.proxy_name << ", Callable.From(value));\n";
+ } else {
+ p_output << p_isignal.proxy_name
+ << ", Callable.CreateWithUnsafeTrampoline(value, &" << p_isignal.proxy_name << "Trampoline));\n";
+ }
if (p_itype.is_singleton) {
p_output.append(INDENT2 "remove => " CS_PROPERTY_SINGLETON ".Disconnect(SignalName.");
@@ -2313,8 +2365,14 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append(INDENT2 "remove => Disconnect(SignalName.");
}
- p_output.append(p_isignal.proxy_name);
- p_output.append(", new Callable(value));\n");
+ if (is_parameterless) {
+ // Delegate type is Action. No need for custom trampoline.
+ p_output << p_isignal.proxy_name << ", Callable.From(value));\n";
+ } else {
+ p_output << p_isignal.proxy_name
+ << ", Callable.CreateWithUnsafeTrampoline(value, &" << p_isignal.proxy_name << "Trampoline));\n";
+ }
+
p_output.append(CLOSE_BLOCK_L1);
}
@@ -2484,15 +2542,13 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall,
<< INDENT2 "int total_length = " << real_argc_str << " + vararg_length;\n";
r_output << INDENT2 "Span<godot_variant.movable> varargs_span = vararg_length <= VarArgsSpanThreshold ?\n"
- << INDENT3 "stackalloc godot_variant.movable[VarArgsSpanThreshold].Cleared() :\n"
+ << INDENT3 "stackalloc godot_variant.movable[VarArgsSpanThreshold] :\n"
<< INDENT3 "new godot_variant.movable[vararg_length];\n";
r_output << INDENT2 "Span<IntPtr> " C_LOCAL_PTRCALL_ARGS "_span = total_length <= VarArgsSpanThreshold ?\n"
<< INDENT3 "stackalloc IntPtr[VarArgsSpanThreshold] :\n"
<< INDENT3 "new IntPtr[total_length];\n";
- r_output << INDENT2 "using var variantSpanDisposer = new VariantSpanDisposer(varargs_span);\n";
-
r_output << INDENT2 "fixed (godot_variant.movable* varargs = &MemoryMarshal.GetReference(varargs_span))\n"
<< INDENT2 "fixed (IntPtr* " C_LOCAL_PTRCALL_ARGS " = "
"&MemoryMarshal.GetReference(" C_LOCAL_PTRCALL_ARGS "_span))\n"
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
index 40296eef10..dc69567261 100644
--- a/modules/mono/editor/code_completion.cpp
+++ b/modules/mono/editor/code_completion.cpp
@@ -140,7 +140,7 @@ PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_scr
}
} break;
case CompletionKind::RESOURCE_PATHS: {
- if (bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) {
+ if (bool(EDITOR_GET("text_editor/completion/complete_file_paths"))) {
_get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), suggestions);
}
} break;