diff options
Diffstat (limited to 'modules/mono/editor')
56 files changed, 1337 insertions, 1222 deletions
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props index 0459257106..0d0889c491 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props @@ -12,8 +12,7 @@ <Configurations>Debug;ExportDebug;ExportRelease</Configurations> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <GodotProjectDir Condition=" '$(SolutionDir)' != '' ">$(SolutionDir)</GodotProjectDir> - <GodotProjectDir Condition=" '$(SolutionDir)' == '' ">$(MSBuildProjectDirectory)</GodotProjectDir> + <GodotProjectDir Condition=" '$(GodotProjectDir)' == '' ">$(MSBuildProjectDirectory)</GodotProjectDir> <GodotProjectDir>$([MSBuild]::EnsureTrailingSlash('$(GodotProjectDir)'))</GodotProjectDir> <!-- Custom output paths for Godot projects. In brief, 'bin\' and 'obj\' are moved to '$(GodotProjectDir)\.godot\mono\temp\'. --> diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs index 5eaebc4474..2d797e2f46 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Bar.cs @@ -1,6 +1,6 @@ namespace Godot.SourceGenerators.Sample { - partial class Bar : Godot.Object + partial class Bar : GodotObject { } @@ -9,7 +9,7 @@ namespace Godot.SourceGenerators.Sample { } - partial class NotSameNameAsFile : Godot.Object + partial class NotSameNameAsFile : GodotObject { } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs index 764ba8f121..ee6aa857fc 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/EventSignals.cs @@ -1,6 +1,6 @@ namespace Godot.SourceGenerators.Sample; -public partial class EventSignals : Godot.Object +public partial class EventSignals : GodotObject { [Signal] public delegate void MySignalEventHandler(string str, int num); 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..31e66ac306 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 @@ -10,7 +11,7 @@ namespace Godot.SourceGenerators.Sample [SuppressMessage("ReSharper", "RedundantNameQualifier")] [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")] [SuppressMessage("ReSharper", "InconsistentNaming")] - public partial class ExportedFields : Godot.Object + public partial class ExportedFields : GodotObject { [Export] private Boolean field_Boolean = true; [Export] private Char field_Char = 'f'; @@ -28,23 +29,23 @@ namespace Godot.SourceGenerators.Sample // Godot structs [Export] private Vector2 field_Vector2 = new(10f, 10f); - [Export] private Vector2i field_Vector2i = Vector2i.Up; + [Export] private Vector2I field_Vector2I = Vector2I.Up; [Export] private Rect2 field_Rect2 = new(new Vector2(10f, 10f), new Vector2(10f, 10f)); - [Export] private Rect2i field_Rect2i = new(new Vector2i(10, 10), new Vector2i(10, 10)); + [Export] private Rect2I field_Rect2I = new(new Vector2I(10, 10), new Vector2I(10, 10)); [Export] private Transform2D field_Transform2D = Transform2D.Identity; [Export] private Vector3 field_Vector3 = new(10f, 10f, 10f); - [Export] private Vector3i field_Vector3i = Vector3i.Back; + [Export] private Vector3I field_Vector3I = Vector3I.Back; [Export] private Basis field_Basis = new Basis(Quaternion.Identity); [Export] private Quaternion field_Quaternion = new Quaternion(Basis.Identity); [Export] private Transform3D field_Transform3D = Transform3D.Identity; [Export] private Vector4 field_Vector4 = new(10f, 10f, 10f, 10f); - [Export] private Vector4i field_Vector4i = Vector4i.One; + [Export] private Vector4I field_Vector4I = Vector4I.One; [Export] private Projection field_Projection = Projection.Identity; - [Export] private AABB field_AABB = new AABB(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); + [Export] private Aabb field_Aabb = new Aabb(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); [Export] private Color field_Color = Colors.Aquamarine; [Export] private Plane field_Plane = Plane.PlaneXZ; [Export] private Callable field_Callable = new Callable(Engine.GetMainLoop(), "_process"); - [Export] private SignalInfo field_SignalInfo = new SignalInfo(Engine.GetMainLoop(), "property_list_changed"); + [Export] private Signal field_Signal = new Signal(Engine.GetMainLoop(), "property_list_changed"); // Enums [SuppressMessage("ReSharper", "UnusedMember.Local")] @@ -79,20 +80,24 @@ namespace Godot.SourceGenerators.Sample [Export] private Vector2[] field_Vector2Array = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; [Export] private Vector3[] field_Vector3Array = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; [Export] private Color[] field_ColorArray = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige }; - [Export] private Godot.Object[] field_GodotObjectOrDerivedArray = { null }; + [Export] private GodotObject[] field_GodotObjectOrDerivedArray = { null }; [Export] private StringName[] field_StringNameArray = { "foo", "bar" }; [Export] private NodePath[] field_NodePathArray = { "foo", "bar" }; - [Export] private RID[] field_RIDArray = { default, default, default }; + [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"; // Classes - [Export] private Godot.Object field_GodotObjectOrDerived; + [Export] private GodotObject field_GodotObjectOrDerived; [Export] private Godot.Texture field_GodotResourceTexture; [Export] private StringName field_StringName = new StringName("foo"); [Export] private NodePath field_NodePath = new NodePath("foo"); - [Export] private RID field_RID; + [Export] private Rid field_Rid; [Export] private Godot.Collections.Dictionary field_GodotDictionary = 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..aef2a8824e 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 @@ -10,8 +10,97 @@ namespace Godot.SourceGenerators.Sample [SuppressMessage("ReSharper", "RedundantNameQualifier")] [SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeEvident")] [SuppressMessage("ReSharper", "InconsistentNaming")] - public partial class ExportedProperties : Godot.Object + public partial class ExportedProperties : GodotObject { + // 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; + } + } + + // Lambda 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; @@ -28,23 +117,23 @@ namespace Godot.SourceGenerators.Sample // Godot structs [Export] private Vector2 property_Vector2 { get; set; } = new(10f, 10f); - [Export] private Vector2i property_Vector2i { get; set; } = Vector2i.Up; + [Export] private Vector2I property_Vector2I { get; set; } = Vector2I.Up; [Export] private Rect2 property_Rect2 { get; set; } = new(new Vector2(10f, 10f), new Vector2(10f, 10f)); - [Export] private Rect2i property_Rect2i { get; set; } = new(new Vector2i(10, 10), new Vector2i(10, 10)); + [Export] private Rect2I property_Rect2I { get; set; } = new(new Vector2I(10, 10), new Vector2I(10, 10)); [Export] private Transform2D property_Transform2D { get; set; } = Transform2D.Identity; [Export] private Vector3 property_Vector3 { get; set; } = new(10f, 10f, 10f); - [Export] private Vector3i property_Vector3i { get; set; } = Vector3i.Back; + [Export] private Vector3I property_Vector3I { get; set; } = Vector3I.Back; [Export] private Basis property_Basis { get; set; } = new Basis(Quaternion.Identity); [Export] private Quaternion property_Quaternion { get; set; } = new Quaternion(Basis.Identity); [Export] private Transform3D property_Transform3D { get; set; } = Transform3D.Identity; [Export] private Vector4 property_Vector4 { get; set; } = new(10f, 10f, 10f, 10f); - [Export] private Vector4i property_Vector4i { get; set; } = Vector4i.One; + [Export] private Vector4I property_Vector4I { get; set; } = Vector4I.One; [Export] private Projection property_Projection { get; set; } = Projection.Identity; - [Export] private AABB property_AABB { get; set; } = new AABB(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); + [Export] private Aabb property_Aabb { get; set; } = new Aabb(10f, 10f, 10f, new Vector3(1f, 1f, 1f)); [Export] private Color property_Color { get; set; } = Colors.Aquamarine; [Export] private Plane property_Plane { get; set; } = Plane.PlaneXZ; [Export] private Callable property_Callable { get; set; } = new Callable(Engine.GetMainLoop(), "_process"); - [Export] private SignalInfo property_SignalInfo { get; set; } = new SignalInfo(Engine.GetMainLoop(), "property_list_changed"); + [Export] private Signal property_Signal { get; set; } = new Signal(Engine.GetMainLoop(), "property_list_changed"); // Enums [SuppressMessage("ReSharper", "UnusedMember.Local")] @@ -79,20 +168,20 @@ namespace Godot.SourceGenerators.Sample [Export] private Vector2[] property_Vector2Array { get; set; } = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right }; [Export] private Vector3[] property_Vector3Array { get; set; } = { Vector3.Up, Vector3.Down, Vector3.Left, Vector3.Right }; [Export] private Color[] property_ColorArray { get; set; } = { Colors.Aqua, Colors.Aquamarine, Colors.Azure, Colors.Beige }; - [Export] private Godot.Object[] property_GodotObjectOrDerivedArray { get; set; } = { null }; + [Export] private GodotObject[] property_GodotObjectOrDerivedArray { get; set; } = { null }; [Export] private StringName[] field_StringNameArray { get; set; } = { "foo", "bar" }; [Export] private NodePath[] field_NodePathArray { get; set; } = { "foo", "bar" }; - [Export] private RID[] field_RIDArray { get; set; } = { default, default, default }; + [Export] private Rid[] field_RidArray { get; set; } = { default, default, default }; // Variant [Export] private Variant property_Variant { get; set; } = "foo"; // Classes - [Export] private Godot.Object property_GodotObjectOrDerived { get; set; } + [Export] private GodotObject property_GodotObjectOrDerived { get; set; } [Export] private Godot.Texture property_GodotResourceTexture { get; set; } [Export] private StringName property_StringName { get; set; } = new StringName("foo"); [Export] private NodePath property_NodePath { get; set; } = new NodePath("foo"); - [Export] private RID property_RID { get; set; } + [Export] private Rid property_Rid { get; set; } [Export] private Godot.Collections.Dictionary property_GodotDictionary { get; set; } = diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs index 21a5bfe560..9ef72d9e02 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Foo.cs @@ -1,6 +1,6 @@ namespace Godot.SourceGenerators.Sample { - partial class Foo : Godot.Object + partial class Foo : GodotObject { } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs index b21b035b4d..2cd1a08c0e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Generic.cs @@ -2,19 +2,19 @@ namespace Godot.SourceGenerators.Sample { - partial class Generic<T> : Godot.Object + partial class Generic<T> : GodotObject { private int _field; } // Generic again but different generic parameters - partial class Generic<T, R> : Godot.Object + partial class Generic<T, R> : GodotObject { private int _field; } // Generic again but without generic parameters - partial class Generic : Godot.Object + partial class Generic : GodotObject { private int _field; } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs index 618ba24abc..9aa6be3972 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Methods.cs @@ -3,7 +3,7 @@ using System.Diagnostics.CodeAnalysis; namespace Godot.SourceGenerators.Sample; [SuppressMessage("ReSharper", "RedundantNameQualifier")] -public partial class Methods : Godot.Object +public partial class Methods : GodotObject { private void MethodWithOverload() { 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..64088215e9 --- /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 : GodotObject + { + // 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..41bf89e6d8 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs @@ -14,9 +14,9 @@ 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.GodotObject}'"; - string description = $"{message}. Subclasses of '{GodotClasses.Object}' " + + string description = $"{message}. Subclasses of '{GodotClasses.GodotObject}' " + "must be declared with the partial modifier."; context.ReportDiagnostic(Diagnostic.Create( @@ -41,14 +41,14 @@ namespace Godot.SourceGenerators .GetDeclaredSymbol(outerTypeDeclSyntax); string fullQualifiedName = outerSymbol is INamedTypeSymbol namedTypeSymbol ? - namedTypeSymbol.FullQualifiedName() : + namedTypeSymbol.FullQualifiedNameOmitGlobal() : "type not found"; string message = $"Missing partial modifier on declaration of type '{fullQualifiedName}', " + - $"which contains one or more subclasses of '{GodotClasses.Object}'"; + $"which contains one or more subclasses of '{GodotClasses.GodotObject}'"; - string description = $"{message}. Subclasses of '{GodotClasses.Object}' and their " + + string description = $"{message}. Subclasses of '{GodotClasses.GodotObject}' and their " + "containing types must be declared with the partial modifier."; context.ReportDiagnostic(Diagnostic.Create( 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..f0c9043fd5 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; @@ -84,7 +85,7 @@ namespace Godot.SourceGenerators var classTypeSymbol = sm.GetDeclaredSymbol(cds); if (classTypeSymbol?.BaseType == null - || !classTypeSymbol.BaseType.InheritsFrom("GodotSharp", GodotClasses.Object)) + || !classTypeSymbol.BaseType.InheritsFrom("GodotSharp", GodotClasses.GodotObject)) { symbol = null; return false; @@ -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 @@ -216,8 +268,9 @@ namespace Godot.SourceGenerators if (parameters.Length > paramTypes.Length) return null; // Ignore incompatible method - return new GodotMethodData(method, paramTypes, parameters - .Select(p => p.Type).ToImmutableArray(), retType, retSymbol); + return new GodotMethodData(method, paramTypes, + parameters.Select(p => p.Type).ToImmutableArray(), + retType != null ? (retType.Value, retSymbol) : null); } public static IEnumerable<GodotMethodData> WhereHasGodotCompatibleSignature( @@ -242,8 +295,8 @@ namespace Godot.SourceGenerators foreach (var property in properties) { // TODO: We should still restore read-only properties after reloading assembly. Two possible ways: reflection or turn RestoreGodotObjectData into a constructor overload. - // Ignore properties without a getter or without a setter. Godot properties must be both readable and writable. - if (property.IsWriteOnly || property.IsReadOnly) + // Ignore properties without a getter, without a setter or with an init-only setter. Godot properties must be both readable and writable. + if (property.IsWriteOnly || property.IsReadOnly || property.SetMethod!.IsInitOnly) continue; var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(property.Type, typeCache); @@ -278,10 +331,10 @@ namespace Godot.SourceGenerators public static string Path(this Location location) => location.SourceTree?.GetLineSpan(location.SourceSpan).Path - ?? location.GetLineSpan().Path; + ?? location.GetLineSpan().Path; public static int StartLine(this Location location) => location.SourceTree?.GetLineSpan(location.SourceSpan).StartLinePosition.Line - ?? location.GetLineSpan().StartLinePosition.Line; + ?? location.GetLineSpan().StartLinePosition.Line; } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs index 1d8ddbabf2..b60148b34f 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs @@ -2,7 +2,7 @@ namespace Godot.SourceGenerators { public static class GodotClasses { - public const string Object = "Godot.Object"; + public const string GodotObject = "Godot.GodotObject"; public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute"; public const string ExportAttr = "Godot.ExportAttribute"; public const string ExportCategoryAttr = "Godot.ExportCategoryAttribute"; @@ -10,7 +10,7 @@ namespace Godot.SourceGenerators public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute"; public const string SignalAttr = "Godot.SignalAttribute"; public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute"; - public const string GodotClassNameAttr = "Godot.GodotClassName"; + public const string GodotClassNameAttr = "Godot.GodotClassNameAttribute"; public const string SystemFlagsAttr = "System.FlagsAttribute"; } } 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..b30c8c240e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotEnums.cs @@ -12,19 +12,19 @@ namespace Godot.SourceGenerators Float = 3, String = 4, Vector2 = 5, - Vector2i = 6, + Vector2I = 6, Rect2 = 7, - Rect2i = 8, + Rect2I = 8, Vector3 = 9, - Vector3i = 10, - Transform2d = 11, + Vector3I = 10, + Transform2D = 11, Vector4 = 12, - Vector4i = 13, + Vector4I = 13, Plane = 14, Quaternion = 15, Aabb = 16, Basis = 17, - Transform3d = 18, + Transform3D = 18, Projection = 19, Color = 20, StringName = 21, @@ -56,12 +56,12 @@ namespace Godot.SourceGenerators ExpEasing = 4, Link = 5, Flags = 6, - Layers2dRender = 7, - Layers2dPhysics = 8, - Layers2dNavigation = 9, - Layers3dRender = 10, - Layers3dPhysics = 11, - Layers3dNavigation = 12, + Layers2DRender = 7, + Layers2DPhysics = 8, + Layers2DNavigation = 9, + Layers3DRender = 10, + Layers3DPhysics = 11, + Layers3DNavigation = 12, File = 13, Dir = 14, GlobalFile = 15, @@ -71,30 +71,22 @@ 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, - Max = 45 + ObjectId = 22, + TypeString = 23, + NodePathToEditedNode = 24, + ObjectTooBig = 25, + NodePathValidTypes = 26, + SaveFile = 27, + GlobalSaveFile = 28, + IntIsObjectid = 29, + IntIsPointer = 30, + ArrayType = 31, + LocaleId = 32, + LocalizableString = 33, + NodeType = 34, + HideQuaternionEdit = 35, + Password = 36, + Max = 37 } [Flags] @@ -103,9 +95,9 @@ namespace Godot.SourceGenerators None = 0, Storage = 2, Editor = 4, - Checkable = 8, - Checked = 16, - Internationalized = 32, + Internal = 8, + Checkable = 16, + Checked = 32, Group = 64, Category = 128, Subgroup = 256, @@ -114,13 +106,13 @@ namespace Godot.SourceGenerators RestartIfChanged = 2048, ScriptVariable = 4096, StoreIfNull = 8192, - AnimateAsTrigger = 16384, - UpdateAllIfModified = 32768, - ScriptDefaultValue = 65536, - ClassIsEnum = 131072, - NilIsVariant = 262144, - Internal = 524288, - DoNotShareOnDuplicate = 1048576, + UpdateAllIfModified = 16384, + ScriptDefaultValue = 32768, + ClassIsEnum = 65536, + NilIsVariant = 131072, + Array = 262144, + AlwaysDuplicate = 524288, + NeverDuplicate = 1048576, HighEndGfx = 2097152, NodePathFromSceneRoot = 4194304, ResourceNotPersistent = 8388608, @@ -128,12 +120,12 @@ namespace Godot.SourceGenerators DeferredSetResource = 33554432, EditorInstantiateObject = 67108864, EditorBasicSetting = 134217728, - Array = 536870912, + ReadOnly = 268435456, 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..0760ea11bb 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs @@ -3,26 +3,24 @@ 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) + ImmutableArray<ITypeSymbol> paramTypeSymbols, (MarshalType MarshalType, ITypeSymbol TypeSymbol)? retType) { Method = method; ParamTypes = paramTypes; ParamTypeSymbols = paramTypeSymbols; RetType = retType; - RetSymbol = retSymbol; } public IMethodSymbol Method { get; } public ImmutableArray<MarshalType> ParamTypes { get; } public ImmutableArray<ITypeSymbol> ParamTypeSymbols { get; } - public MarshalType? RetType { get; } - public ITypeSymbol? RetSymbol { get; } + public (MarshalType MarshalType, ITypeSymbol TypeSymbol)? RetType { get; } } - public struct GodotSignalDelegateData + public readonly struct GodotSignalDelegateData { public GodotSignalDelegateData(string name, INamedTypeSymbol delegateSymbol, GodotMethodData invokeMethodData) { @@ -36,7 +34,7 @@ namespace Godot.SourceGenerators public GodotMethodData InvokeMethodData { get; } } - public struct GodotPropertyData + public readonly struct GodotPropertyData { public GodotPropertyData(IPropertySymbol propertySymbol, MarshalType type) { @@ -48,7 +46,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 19fdd51dab..47a4516948 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotPluginsInitializerGenerator.cs @@ -34,7 +34,7 @@ namespace GodotPlugins.Game { DllImportResolver dllImportResolver = new GodotDllImportResolver(godotDllHandle).OnResolveDllImport; - var coreApiAssembly = typeof(Godot.Object).Assembly; + var coreApiAssembly = typeof(global::Godot.GodotObject).Assembly; NativeLibrary.SetDllImportResolver(coreApiAssembly, dllImportResolver); @@ -42,13 +42,13 @@ namespace GodotPlugins.Game ManagedCallbacks.Create(outManagedCallbacks); - ScriptManagerBridge.LookupScriptsInAssembly(typeof(GodotPlugins.Game.Main).Assembly); + ScriptManagerBridge.LookupScriptsInAssembly(typeof(global::GodotPlugins.Game.Main).Assembly); return godot_bool.True; } catch (Exception e) { - Console.Error.WriteLine(e); + global::System.Console.Error.WriteLine(e); return false.ToGodotBool(); } } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs index 15f5803bf0..be6af117eb 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalType.cs @@ -21,23 +21,23 @@ namespace Godot.SourceGenerators // Godot structs Vector2, - Vector2i, + Vector2I, Rect2, - Rect2i, + Rect2I, Transform2D, Vector3, - Vector3i, + Vector3I, Basis, Quaternion, Transform3D, Vector4, - Vector4i, + Vector4I, Projection, - AABB, + Aabb, Color, Plane, Callable, - SignalInfo, + Signal, // Enums Enum, @@ -55,7 +55,7 @@ namespace Godot.SourceGenerators GodotObjectOrDerivedArray, SystemArrayOfStringName, SystemArrayOfNodePath, - SystemArrayOfRID, + SystemArrayOfRid, // Variant Variant, @@ -64,7 +64,7 @@ namespace Godot.SourceGenerators GodotObjectOrDerived, StringName, NodePath, - RID, + Rid, GodotDictionary, GodotArray, GodotGenericDictionary, 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..0258f53062 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs @@ -19,7 +19,7 @@ namespace Godot.SourceGenerators throw new InvalidOperationException($"Type not found: '{fullyQualifiedMetadataName}'."); } - GodotObjectType = GetTypeByMetadataNameOrThrow("Godot.Object"); + GodotObjectType = GetTypeByMetadataNameOrThrow(GodotClasses.GodotObject); } } @@ -40,23 +40,23 @@ namespace Godot.SourceGenerators MarshalType.Double => VariantType.Float, MarshalType.String => VariantType.String, MarshalType.Vector2 => VariantType.Vector2, - MarshalType.Vector2i => VariantType.Vector2i, + MarshalType.Vector2I => VariantType.Vector2I, MarshalType.Rect2 => VariantType.Rect2, - MarshalType.Rect2i => VariantType.Rect2i, - MarshalType.Transform2D => VariantType.Transform2d, + MarshalType.Rect2I => VariantType.Rect2I, + MarshalType.Transform2D => VariantType.Transform2D, MarshalType.Vector3 => VariantType.Vector3, - MarshalType.Vector3i => VariantType.Vector3i, + MarshalType.Vector3I => VariantType.Vector3I, MarshalType.Basis => VariantType.Basis, MarshalType.Quaternion => VariantType.Quaternion, - MarshalType.Transform3D => VariantType.Transform3d, + MarshalType.Transform3D => VariantType.Transform3D, MarshalType.Vector4 => VariantType.Vector4, - MarshalType.Vector4i => VariantType.Vector4i, + MarshalType.Vector4I => VariantType.Vector4I, MarshalType.Projection => VariantType.Projection, - MarshalType.AABB => VariantType.Aabb, + MarshalType.Aabb => VariantType.Aabb, MarshalType.Color => VariantType.Color, MarshalType.Plane => VariantType.Plane, MarshalType.Callable => VariantType.Callable, - MarshalType.SignalInfo => VariantType.Signal, + MarshalType.Signal => VariantType.Signal, MarshalType.Enum => VariantType.Int, MarshalType.ByteArray => VariantType.PackedByteArray, MarshalType.Int32Array => VariantType.PackedInt32Array, @@ -70,12 +70,12 @@ namespace Godot.SourceGenerators MarshalType.GodotObjectOrDerivedArray => VariantType.Array, MarshalType.SystemArrayOfStringName => VariantType.Array, MarshalType.SystemArrayOfNodePath => VariantType.Array, - MarshalType.SystemArrayOfRID => VariantType.Array, + MarshalType.SystemArrayOfRid => VariantType.Array, MarshalType.Variant => VariantType.Nil, MarshalType.GodotObjectOrDerived => VariantType.Object, MarshalType.StringName => VariantType.StringName, MarshalType.NodePath => VariantType.NodePath, - MarshalType.RID => VariantType.Rid, + MarshalType.Rid => VariantType.Rid, MarshalType.GodotDictionary => VariantType.Dictionary, MarshalType.GodotArray => VariantType.Array, MarshalType.GodotGenericDictionary => VariantType.Dictionary, @@ -130,24 +130,24 @@ namespace Godot.SourceGenerators return type switch { { Name: "Vector2" } => MarshalType.Vector2, - { Name: "Vector2i" } => MarshalType.Vector2i, + { Name: "Vector2I" } => MarshalType.Vector2I, { Name: "Rect2" } => MarshalType.Rect2, - { Name: "Rect2i" } => MarshalType.Rect2i, + { Name: "Rect2I" } => MarshalType.Rect2I, { Name: "Transform2D" } => MarshalType.Transform2D, { Name: "Vector3" } => MarshalType.Vector3, - { Name: "Vector3i" } => MarshalType.Vector3i, + { Name: "Vector3I" } => MarshalType.Vector3I, { Name: "Basis" } => MarshalType.Basis, { Name: "Quaternion" } => MarshalType.Quaternion, { Name: "Transform3D" } => MarshalType.Transform3D, { Name: "Vector4" } => MarshalType.Vector4, - { Name: "Vector4i" } => MarshalType.Vector4i, + { Name: "Vector4I" } => MarshalType.Vector4I, { Name: "Projection" } => MarshalType.Projection, - { Name: "AABB" } => MarshalType.AABB, + { Name: "Aabb" } => MarshalType.Aabb, { Name: "Color" } => MarshalType.Color, { Name: "Plane" } => MarshalType.Plane, - { Name: "RID" } => MarshalType.RID, + { Name: "Rid" } => MarshalType.Rid, { Name: "Callable" } => MarshalType.Callable, - { Name: "SignalInfo" } => MarshalType.SignalInfo, + { Name: "Signal" } => MarshalType.Signal, { Name: "Variant" } => MarshalType.Variant, _ => null }; @@ -196,8 +196,8 @@ namespace Godot.SourceGenerators return MarshalType.SystemArrayOfStringName; case { Name: "NodePath" }: return MarshalType.SystemArrayOfNodePath; - case { Name: "RID" }: - return MarshalType.SystemArrayOfRID; + case { Name: "Rid" }: + return MarshalType.SystemArrayOfRid; } } @@ -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" } => @@ -304,240 +304,41 @@ namespace Godot.SourceGenerators { return marshalType switch { - MarshalType.Boolean => - source.Append(VariantUtils, ".ConvertToBool(", inputExpr, ")"), - MarshalType.Char => - source.Append("(char)", VariantUtils, ".ConvertToUInt16(", inputExpr, ")"), - MarshalType.SByte => - source.Append(VariantUtils, ".ConvertToInt8(", inputExpr, ")"), - MarshalType.Int16 => - source.Append(VariantUtils, ".ConvertToInt16(", inputExpr, ")"), - MarshalType.Int32 => - source.Append(VariantUtils, ".ConvertToInt32(", inputExpr, ")"), - MarshalType.Int64 => - source.Append(VariantUtils, ".ConvertToInt64(", inputExpr, ")"), - MarshalType.Byte => - source.Append(VariantUtils, ".ConvertToUInt8(", inputExpr, ")"), - MarshalType.UInt16 => - source.Append(VariantUtils, ".ConvertToUInt16(", inputExpr, ")"), - MarshalType.UInt32 => - source.Append(VariantUtils, ".ConvertToUInt32(", inputExpr, ")"), - MarshalType.UInt64 => - source.Append(VariantUtils, ".ConvertToUInt64(", inputExpr, ")"), - MarshalType.Single => - source.Append(VariantUtils, ".ConvertToFloat32(", inputExpr, ")"), - MarshalType.Double => - source.Append(VariantUtils, ".ConvertToFloat64(", inputExpr, ")"), - MarshalType.String => - source.Append(VariantUtils, ".ConvertToStringObject(", inputExpr, ")"), - MarshalType.Vector2 => - source.Append(VariantUtils, ".ConvertToVector2(", inputExpr, ")"), - MarshalType.Vector2i => - source.Append(VariantUtils, ".ConvertToVector2i(", inputExpr, ")"), - MarshalType.Rect2 => - source.Append(VariantUtils, ".ConvertToRect2(", inputExpr, ")"), - MarshalType.Rect2i => - source.Append(VariantUtils, ".ConvertToRect2i(", inputExpr, ")"), - MarshalType.Transform2D => - source.Append(VariantUtils, ".ConvertToTransform2D(", inputExpr, ")"), - MarshalType.Vector3 => - source.Append(VariantUtils, ".ConvertToVector3(", inputExpr, ")"), - MarshalType.Vector3i => - source.Append(VariantUtils, ".ConvertToVector3i(", inputExpr, ")"), - MarshalType.Basis => - source.Append(VariantUtils, ".ConvertToBasis(", inputExpr, ")"), - MarshalType.Quaternion => - source.Append(VariantUtils, ".ConvertToQuaternion(", inputExpr, ")"), - MarshalType.Transform3D => - source.Append(VariantUtils, ".ConvertToTransform3D(", inputExpr, ")"), - MarshalType.Vector4 => - source.Append(VariantUtils, ".ConvertToVector4(", inputExpr, ")"), - MarshalType.Vector4i => - source.Append(VariantUtils, ".ConvertToVector4i(", inputExpr, ")"), - MarshalType.Projection => - source.Append(VariantUtils, ".ConvertToProjection(", inputExpr, ")"), - MarshalType.AABB => - source.Append(VariantUtils, ".ConvertToAABB(", inputExpr, ")"), - MarshalType.Color => - source.Append(VariantUtils, ".ConvertToColor(", inputExpr, ")"), - MarshalType.Plane => - source.Append(VariantUtils, ".ConvertToPlane(", inputExpr, ")"), - MarshalType.Callable => - source.Append(VariantUtils, ".ConvertToCallableManaged(", inputExpr, ")"), - MarshalType.SignalInfo => - source.Append(VariantUtils, ".ConvertToSignalInfo(", inputExpr, ")"), - MarshalType.Enum => - source.Append("(", typeSymbol.FullQualifiedName(), - ")", VariantUtils, ".ConvertToInt32(", inputExpr, ")"), - MarshalType.ByteArray => - source.Append(VariantUtils, ".ConvertAsPackedByteArrayToSystemArray(", inputExpr, ")"), - MarshalType.Int32Array => - source.Append(VariantUtils, ".ConvertAsPackedInt32ArrayToSystemArray(", inputExpr, ")"), - MarshalType.Int64Array => - source.Append(VariantUtils, ".ConvertAsPackedInt64ArrayToSystemArray(", inputExpr, ")"), - MarshalType.Float32Array => - source.Append(VariantUtils, ".ConvertAsPackedFloat32ArrayToSystemArray(", inputExpr, ")"), - MarshalType.Float64Array => - source.Append(VariantUtils, ".ConvertAsPackedFloat64ArrayToSystemArray(", inputExpr, ")"), - MarshalType.StringArray => - source.Append(VariantUtils, ".ConvertAsPackedStringArrayToSystemArray(", inputExpr, ")"), - MarshalType.Vector2Array => - source.Append(VariantUtils, ".ConvertAsPackedVector2ArrayToSystemArray(", inputExpr, ")"), - MarshalType.Vector3Array => - source.Append(VariantUtils, ".ConvertAsPackedVector3ArrayToSystemArray(", inputExpr, ")"), - MarshalType.ColorArray => - source.Append(VariantUtils, ".ConvertAsPackedColorArrayToSystemArray(", inputExpr, ")"), + // We need a special case for GodotObjectOrDerived[], because it's not supported by VariantUtils.ConvertTo<T> MarshalType.GodotObjectOrDerivedArray => source.Append(VariantUtils, ".ConvertToSystemArrayOfGodotObject<", - ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">(", inputExpr, ")"), - MarshalType.SystemArrayOfStringName => - source.Append(VariantUtils, ".ConvertToSystemArrayOfStringName(", inputExpr, ")"), - MarshalType.SystemArrayOfNodePath => - source.Append(VariantUtils, ".ConvertToSystemArrayOfNodePath(", inputExpr, ")"), - MarshalType.SystemArrayOfRID => - source.Append(VariantUtils, ".ConvertToSystemArrayOfRID(", inputExpr, ")"), - MarshalType.Variant => - source.Append("global::Godot.Variant.CreateCopyingBorrowed(", inputExpr, ")"), - MarshalType.GodotObjectOrDerived => - source.Append("(", typeSymbol.FullQualifiedName(), - ")", VariantUtils, ".ConvertToGodotObject(", inputExpr, ")"), - MarshalType.StringName => - source.Append(VariantUtils, ".ConvertToStringNameObject(", inputExpr, ")"), - MarshalType.NodePath => - source.Append(VariantUtils, ".ConvertToNodePathObject(", inputExpr, ")"), - MarshalType.RID => - source.Append(VariantUtils, ".ConvertToRID(", inputExpr, ")"), - MarshalType.GodotDictionary => - source.Append(VariantUtils, ".ConvertToDictionaryObject(", inputExpr, ")"), - MarshalType.GodotArray => - source.Append(VariantUtils, ".ConvertToArrayObject(", inputExpr, ")"), + ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">(", + inputExpr, ")"), + // We need a special case for generic Godot collections and GodotObjectOrDerived[], because VariantUtils.ConvertTo<T> is slower MarshalType.GodotGenericDictionary => - source.Append(VariantUtils, ".ConvertToDictionaryObject<", - ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ", ", - ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedName(), ">(", inputExpr, ")"), + source.Append(VariantUtils, ".ConvertToDictionary<", + ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ", + ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedNameIncludeGlobal(), ">(", + inputExpr, ")"), MarshalType.GodotGenericArray => - source.Append(VariantUtils, ".ConvertToArrayObject<", - ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">(", inputExpr, ")"), - _ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType, - "Received unexpected marshal type") + source.Append(VariantUtils, ".ConvertToArray<", + ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ">(", + inputExpr, ")"), + _ => source.Append(VariantUtils, ".ConvertTo<", + typeSymbol.FullQualifiedNameIncludeGlobal(), ">(", inputExpr, ")"), }; } - public static StringBuilder AppendManagedToNativeVariantExpr( - this StringBuilder source, string inputExpr, MarshalType marshalType) + public static StringBuilder AppendManagedToNativeVariantExpr(this StringBuilder source, + string inputExpr, ITypeSymbol typeSymbol, MarshalType marshalType) { return marshalType switch { - MarshalType.Boolean => - source.Append(VariantUtils, ".CreateFromBool(", inputExpr, ")"), - MarshalType.Char => - source.Append(VariantUtils, ".CreateFromInt((ushort)", inputExpr, ")"), - MarshalType.SByte => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.Int16 => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.Int32 => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.Int64 => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.Byte => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.UInt16 => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.UInt32 => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.UInt64 => - source.Append(VariantUtils, ".CreateFromInt(", inputExpr, ")"), - MarshalType.Single => - source.Append(VariantUtils, ".CreateFromFloat(", inputExpr, ")"), - MarshalType.Double => - source.Append(VariantUtils, ".CreateFromFloat(", inputExpr, ")"), - MarshalType.String => - source.Append(VariantUtils, ".CreateFromString(", inputExpr, ")"), - MarshalType.Vector2 => - source.Append(VariantUtils, ".CreateFromVector2(", inputExpr, ")"), - MarshalType.Vector2i => - source.Append(VariantUtils, ".CreateFromVector2i(", inputExpr, ")"), - MarshalType.Rect2 => - source.Append(VariantUtils, ".CreateFromRect2(", inputExpr, ")"), - MarshalType.Rect2i => - source.Append(VariantUtils, ".CreateFromRect2i(", inputExpr, ")"), - MarshalType.Transform2D => - source.Append(VariantUtils, ".CreateFromTransform2D(", inputExpr, ")"), - MarshalType.Vector3 => - source.Append(VariantUtils, ".CreateFromVector3(", inputExpr, ")"), - MarshalType.Vector3i => - source.Append(VariantUtils, ".CreateFromVector3i(", inputExpr, ")"), - MarshalType.Basis => - source.Append(VariantUtils, ".CreateFromBasis(", inputExpr, ")"), - MarshalType.Quaternion => - source.Append(VariantUtils, ".CreateFromQuaternion(", inputExpr, ")"), - MarshalType.Transform3D => - source.Append(VariantUtils, ".CreateFromTransform3D(", inputExpr, ")"), - MarshalType.Vector4 => - source.Append(VariantUtils, ".CreateFromVector4(", inputExpr, ")"), - MarshalType.Vector4i => - source.Append(VariantUtils, ".CreateFromVector4i(", inputExpr, ")"), - MarshalType.Projection => - source.Append(VariantUtils, ".CreateFromProjection(", inputExpr, ")"), - MarshalType.AABB => - source.Append(VariantUtils, ".CreateFromAABB(", inputExpr, ")"), - MarshalType.Color => - source.Append(VariantUtils, ".CreateFromColor(", inputExpr, ")"), - MarshalType.Plane => - source.Append(VariantUtils, ".CreateFromPlane(", inputExpr, ")"), - MarshalType.Callable => - source.Append(VariantUtils, ".CreateFromCallable(", inputExpr, ")"), - MarshalType.SignalInfo => - source.Append(VariantUtils, ".CreateFromSignalInfo(", inputExpr, ")"), - MarshalType.Enum => - source.Append(VariantUtils, ".CreateFromInt((int)", inputExpr, ")"), - MarshalType.ByteArray => - source.Append(VariantUtils, ".CreateFromPackedByteArray(", inputExpr, ")"), - MarshalType.Int32Array => - source.Append(VariantUtils, ".CreateFromPackedInt32Array(", inputExpr, ")"), - MarshalType.Int64Array => - source.Append(VariantUtils, ".CreateFromPackedInt64Array(", inputExpr, ")"), - MarshalType.Float32Array => - source.Append(VariantUtils, ".CreateFromPackedFloat32Array(", inputExpr, ")"), - MarshalType.Float64Array => - source.Append(VariantUtils, ".CreateFromPackedFloat64Array(", inputExpr, ")"), - MarshalType.StringArray => - source.Append(VariantUtils, ".CreateFromPackedStringArray(", inputExpr, ")"), - MarshalType.Vector2Array => - source.Append(VariantUtils, ".CreateFromPackedVector2Array(", inputExpr, ")"), - MarshalType.Vector3Array => - source.Append(VariantUtils, ".CreateFromPackedVector3Array(", inputExpr, ")"), - MarshalType.ColorArray => - source.Append(VariantUtils, ".CreateFromPackedColorArray(", inputExpr, ")"), + // We need a special case for GodotObjectOrDerived[], because it's not supported by VariantUtils.CreateFrom<T> MarshalType.GodotObjectOrDerivedArray => source.Append(VariantUtils, ".CreateFromSystemArrayOfGodotObject(", inputExpr, ")"), - MarshalType.SystemArrayOfStringName => - source.Append(VariantUtils, ".CreateFromSystemArrayOfStringName(", inputExpr, ")"), - MarshalType.SystemArrayOfNodePath => - source.Append(VariantUtils, ".CreateFromSystemArrayOfNodePath(", inputExpr, ")"), - MarshalType.SystemArrayOfRID => - source.Append(VariantUtils, ".CreateFromSystemArrayOfRID(", inputExpr, ")"), - MarshalType.Variant => - source.Append(inputExpr, ".CopyNativeVariant()"), - MarshalType.GodotObjectOrDerived => - source.Append(VariantUtils, ".CreateFromGodotObject(", inputExpr, ")"), - MarshalType.StringName => - source.Append(VariantUtils, ".CreateFromStringName(", inputExpr, ")"), - MarshalType.NodePath => - source.Append(VariantUtils, ".CreateFromNodePath(", inputExpr, ")"), - MarshalType.RID => - source.Append(VariantUtils, ".CreateFromRID(", inputExpr, ")"), - MarshalType.GodotDictionary => - source.Append(VariantUtils, ".CreateFromDictionary(", inputExpr, ")"), - MarshalType.GodotArray => - source.Append(VariantUtils, ".CreateFromArray(", inputExpr, ")"), + // We need a special case for generic Godot collections and GodotObjectOrDerived[], because VariantUtils.CreateFrom<T> is slower MarshalType.GodotGenericDictionary => source.Append(VariantUtils, ".CreateFromDictionary(", inputExpr, ")"), MarshalType.GodotGenericArray => source.Append(VariantUtils, ".CreateFromArray(", inputExpr, ")"), - _ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType, - "Received unexpected marshal type") + _ => source.Append(VariantUtils, ".CreateFrom<", + typeSymbol.FullQualifiedNameIncludeGlobal(), ">(", inputExpr, ")"), }; } @@ -546,137 +347,37 @@ namespace Godot.SourceGenerators { return marshalType switch { - MarshalType.Boolean => source.Append(inputExpr, ".AsBool()"), - MarshalType.Char => source.Append(inputExpr, ".AsChar()"), - MarshalType.SByte => source.Append(inputExpr, ".AsSByte()"), - MarshalType.Int16 => source.Append(inputExpr, ".AsInt16()"), - MarshalType.Int32 => source.Append(inputExpr, ".AsInt32()"), - MarshalType.Int64 => source.Append(inputExpr, ".AsInt64()"), - MarshalType.Byte => source.Append(inputExpr, ".AsByte()"), - MarshalType.UInt16 => source.Append(inputExpr, ".AsUInt16()"), - MarshalType.UInt32 => source.Append(inputExpr, ".AsUInt32()"), - MarshalType.UInt64 => source.Append(inputExpr, ".AsUInt64()"), - MarshalType.Single => source.Append(inputExpr, ".AsSingle()"), - MarshalType.Double => source.Append(inputExpr, ".AsDouble()"), - MarshalType.String => source.Append(inputExpr, ".AsString()"), - MarshalType.Vector2 => source.Append(inputExpr, ".AsVector2()"), - MarshalType.Vector2i => source.Append(inputExpr, ".AsVector2i()"), - MarshalType.Rect2 => source.Append(inputExpr, ".AsRect2()"), - MarshalType.Rect2i => source.Append(inputExpr, ".AsRect2i()"), - MarshalType.Transform2D => source.Append(inputExpr, ".AsTransform2D()"), - MarshalType.Vector3 => source.Append(inputExpr, ".AsVector3()"), - MarshalType.Vector3i => source.Append(inputExpr, ".AsVector3i()"), - MarshalType.Basis => source.Append(inputExpr, ".AsBasis()"), - MarshalType.Quaternion => source.Append(inputExpr, ".AsQuaternion()"), - MarshalType.Transform3D => source.Append(inputExpr, ".AsTransform3D()"), - MarshalType.Vector4 => source.Append(inputExpr, ".AsVector4()"), - MarshalType.Vector4i => source.Append(inputExpr, ".AsVector4i()"), - MarshalType.Projection => source.Append(inputExpr, ".AsProjection()"), - MarshalType.AABB => source.Append(inputExpr, ".AsAABB()"), - MarshalType.Color => source.Append(inputExpr, ".AsColor()"), - MarshalType.Plane => source.Append(inputExpr, ".AsPlane()"), - MarshalType.Callable => source.Append(inputExpr, ".AsCallable()"), - MarshalType.SignalInfo => source.Append(inputExpr, ".AsSignalInfo()"), - MarshalType.Enum => - source.Append("(", typeSymbol.FullQualifiedName(), ")", inputExpr, ".AsInt64()"), - MarshalType.ByteArray => source.Append(inputExpr, ".AsByteArray()"), - MarshalType.Int32Array => source.Append(inputExpr, ".AsInt32Array()"), - MarshalType.Int64Array => source.Append(inputExpr, ".AsInt64Array()"), - MarshalType.Float32Array => source.Append(inputExpr, ".AsFloat32Array()"), - MarshalType.Float64Array => source.Append(inputExpr, ".AsFloat64Array()"), - MarshalType.StringArray => source.Append(inputExpr, ".AsStringArray()"), - MarshalType.Vector2Array => source.Append(inputExpr, ".AsVector2Array()"), - MarshalType.Vector3Array => source.Append(inputExpr, ".AsVector3Array()"), - MarshalType.ColorArray => source.Append(inputExpr, ".AsColorArray()"), - MarshalType.GodotObjectOrDerivedArray => source.Append(inputExpr, ".AsGodotObjectArray<", - ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedName(), ">()"), - 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()"), - 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(), ">()"), - MarshalType.GodotGenericArray => source.Append(inputExpr, ".AsGodotArray<", - ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedName(), ">()"), - _ => throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType, - "Received unexpected marshal type") + // We need a special case for GodotObjectOrDerived[], because it's not supported by Variant.As<T> + MarshalType.GodotObjectOrDerivedArray => + source.Append(inputExpr, ".AsGodotObjectArray<", + ((IArrayTypeSymbol)typeSymbol).ElementType.FullQualifiedNameIncludeGlobal(), ">()"), + // We need a special case for generic Godot collections and GodotObjectOrDerived[], because Variant.As<T> is slower + MarshalType.GodotGenericDictionary => + source.Append(inputExpr, ".AsGodotDictionary<", + ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ", ", + ((INamedTypeSymbol)typeSymbol).TypeArguments[1].FullQualifiedNameIncludeGlobal(), ">()"), + MarshalType.GodotGenericArray => + source.Append(inputExpr, ".AsGodotArray<", + ((INamedTypeSymbol)typeSymbol).TypeArguments[0].FullQualifiedNameIncludeGlobal(), ">()"), + _ => source.Append(inputExpr, ".As<", + typeSymbol.FullQualifiedNameIncludeGlobal(), ">()") }; } public static StringBuilder AppendManagedToVariantExpr(this StringBuilder source, - string inputExpr, MarshalType marshalType) + string inputExpr, ITypeSymbol typeSymbol, MarshalType marshalType) { - switch (marshalType) + return marshalType switch { - case MarshalType.Boolean: - case MarshalType.Char: - case MarshalType.SByte: - case MarshalType.Int16: - case MarshalType.Int32: - case MarshalType.Int64: - case MarshalType.Byte: - case MarshalType.UInt16: - case MarshalType.UInt32: - case MarshalType.UInt64: - case MarshalType.Single: - case MarshalType.Double: - case MarshalType.String: - case MarshalType.Vector2: - case MarshalType.Vector2i: - case MarshalType.Rect2: - case MarshalType.Rect2i: - case MarshalType.Transform2D: - case MarshalType.Vector3: - case MarshalType.Vector3i: - case MarshalType.Basis: - case MarshalType.Quaternion: - case MarshalType.Transform3D: - case MarshalType.Vector4: - case MarshalType.Vector4i: - case MarshalType.Projection: - case MarshalType.AABB: - case MarshalType.Color: - case MarshalType.Plane: - case MarshalType.Callable: - case MarshalType.SignalInfo: - case MarshalType.ByteArray: - case MarshalType.Int32Array: - case MarshalType.Int64Array: - case MarshalType.Float32Array: - case MarshalType.Float64Array: - case MarshalType.StringArray: - case MarshalType.Vector2Array: - case MarshalType.Vector3Array: - case MarshalType.ColorArray: - case MarshalType.GodotObjectOrDerivedArray: - case MarshalType.SystemArrayOfStringName: - case MarshalType.SystemArrayOfNodePath: - case MarshalType.SystemArrayOfRID: - case MarshalType.GodotObjectOrDerived: - case MarshalType.StringName: - case MarshalType.NodePath: - case MarshalType.RID: - case MarshalType.GodotDictionary: - case MarshalType.GodotArray: - case MarshalType.GodotGenericDictionary: - case MarshalType.GodotGenericArray: - return source.Append("Variant.CreateFrom(", inputExpr, ")"); - case MarshalType.Enum: - return source.Append("Variant.CreateFrom((long)", inputExpr, ")"); - case MarshalType.Variant: - return source.Append(inputExpr); - default: - throw new ArgumentOutOfRangeException(nameof(marshalType), marshalType, - "Received unexpected marshal type"); - } + // We need a special case for GodotObjectOrDerived[], because it's not supported by Variant.From<T> + MarshalType.GodotObjectOrDerivedArray => + source.Append("global::Godot.Variant.CreateFrom(", inputExpr, ")"), + // We need a special case for generic Godot collections, because Variant.From<T> is slower + MarshalType.GodotGenericDictionary or MarshalType.GodotGenericArray => + source.Append("global::Godot.Variant.CreateFrom(", inputExpr, ")"), + _ => source.Append("global::Godot.Variant.From<", + typeSymbol.FullQualifiedNameIncludeGlobal(), ">(", inputExpr, ")") + }; } } } 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/MustBeVariantAnalyzer.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs index 98ca534c66..2a9758516c 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs @@ -26,6 +26,10 @@ namespace Godot.SourceGenerators private void AnalyzeNode(SyntaxNodeAnalysisContext context) { + // Ignore syntax inside comments + if (IsInsideDocumentation(context.Node)) + return; + var typeArgListSyntax = (TypeArgumentListSyntax)context.Node; // Method invocation or variable declaration that contained the type arguments @@ -74,6 +78,26 @@ namespace Godot.SourceGenerators } /// <summary> + /// Check if the syntax node is inside a documentation syntax. + /// </summary> + /// <param name="syntax">Syntax node to check.</param> + /// <returns><see langword="true"/> if the syntax node is inside a documentation syntax.</returns> + private bool IsInsideDocumentation(SyntaxNode? syntax) + { + while (syntax != null) + { + if (syntax is DocumentationCommentTriviaSyntax) + { + return true; + } + + syntax = syntax.Parent; + } + + return false; + } + + /// <summary> /// Check if the given type argument is being used in a type parameter that contains /// the <c>MustBeVariantAttribute</c>; otherwise, we ignore the attribute. /// </summary> 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 d5d80df643..f79909589e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs @@ -80,13 +80,13 @@ 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() + string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint() + "_ScriptMethods.generated"; var source = new StringBuilder(); @@ -135,7 +135,8 @@ 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 +147,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 +160,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) @@ -248,7 +249,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 +277,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") @@ -297,7 +298,7 @@ namespace Godot.SourceGenerators if (method.RetType != null) { - returnVal = DeterminePropertyInfo(method.RetType.Value, name: string.Empty); + returnVal = DeterminePropertyInfo(method.RetType.Value.MarshalType, name: string.Empty); } else { @@ -391,7 +392,8 @@ namespace Godot.SourceGenerators { source.Append(" ret = "); - source.AppendManagedToNativeVariantExpr("callRet", method.RetType.Value); + source.AppendManagedToNativeVariantExpr("callRet", + method.RetType.Value.TypeSymbol, method.RetType.Value.MarshalType); source.Append(";\n"); source.Append(" return true;\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 ccfb405d26..eae7e41da8 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs @@ -45,8 +45,11 @@ namespace Godot.SourceGenerators return false; }) ) - // Ignore classes whose name is not the same as the file name - .Where(x => Path.GetFileNameWithoutExtension(x.cds.SyntaxTree.FilePath) == x.symbol.Name) + .Where(x => + // Ignore classes whose name is not the same as the file name + Path.GetFileNameWithoutExtension(x.cds.SyntaxTree.FilePath) == x.symbol.Name && + // Ignore generic classes + !x.symbol.IsGenericType) .GroupBy(x => x.symbol) .ToDictionary(g => g.Key, g => g.Select(x => x.cds)); @@ -92,11 +95,11 @@ namespace Godot.SourceGenerators INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace; string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ? - namespaceSymbol.FullQualifiedName() : + namespaceSymbol.FullQualifiedNameOmitGlobal() : string.Empty; bool hasNamespace = classNs.Length != 0; - string uniqueHint = symbol.FullQualifiedName().SanitizeQualifiedNameForUniqueHint() + string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint() + "_ScriptPath.generated"; var source = new StringBuilder(); @@ -150,8 +153,6 @@ namespace Godot.SourceGenerators first = false; sourceBuilder.Append("typeof("); sourceBuilder.Append(qualifiedName); - if (godotClass.Key.IsGenericType) - sourceBuilder.Append($"<{new string(',', godotClass.Key.TypeParameters.Count() - 1)}>"); sourceBuilder.Append(")"); } 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 1198c633d9..b720fb93a3 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs @@ -66,13 +66,13 @@ 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() + string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint() + "_ScriptProperties.generated"; var source = new StringBuilder(); @@ -124,14 +124,15 @@ 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 +142,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); @@ -157,7 +158,7 @@ namespace Godot.SourceGenerators // Generate SetGodotClassPropertyValue bool allPropertiesAreReadOnly = godotClassFields.All(fi => fi.FieldSymbol.IsReadOnly) && - godotClassProperties.All(pi => pi.PropertySymbol.IsReadOnly); + godotClassProperties.All(pi => pi.PropertySymbol.IsReadOnly || pi.PropertySymbol.SetMethod!.IsInitOnly); if (!allPropertiesAreReadOnly) { @@ -167,7 +168,7 @@ namespace Godot.SourceGenerators isFirstEntry = true; foreach (var property in godotClassProperties) { - if (property.PropertySymbol.IsReadOnly) + if (property.PropertySymbol.IsReadOnly || property.PropertySymbol.SetMethod!.IsInitOnly) continue; GeneratePropertySetter(property.PropertySymbol.Name, @@ -199,14 +200,14 @@ namespace Godot.SourceGenerators foreach (var property in godotClassProperties) { GeneratePropertyGetter(property.PropertySymbol.Name, - property.Type, source, isFirstEntry); + property.PropertySymbol.Type, property.Type, source, isFirstEntry); isFirstEntry = false; } foreach (var field in godotClassFields) { GeneratePropertyGetter(field.FieldSymbol.Name, - field.Type, source, isFirstEntry); + field.FieldSymbol.Type, field.Type, source, isFirstEntry); isFirstEntry = false; } @@ -216,7 +217,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 +293,7 @@ namespace Godot.SourceGenerators source.Append("if (name == PropertyName.") .Append(propertyMemberName) .Append(") {\n") - .Append(" ") + .Append(" this.") .Append(propertyMemberName) .Append(" = ") .AppendNativeVariantToManagedExpr("value", propertyTypeSymbol, propertyMarshalType) @@ -303,6 +304,7 @@ namespace Godot.SourceGenerators private static void GeneratePropertyGetter( string propertyMemberName, + ITypeSymbol propertyTypeSymbol, MarshalType propertyMarshalType, StringBuilder source, bool isFirstEntry @@ -317,7 +319,8 @@ namespace Godot.SourceGenerators .Append(propertyMemberName) .Append(") {\n") .Append(" value = ") - .AppendManagedToNativeVariantExpr(propertyMemberName, propertyMarshalType) + .AppendManagedToNativeVariantExpr("this." + propertyMemberName, + propertyTypeSymbol, propertyMarshalType) .Append(";\n") .Append(" return true;\n") .Append(" }\n"); @@ -325,30 +328,30 @@ namespace Godot.SourceGenerators private static void AppendGroupingPropertyInfo(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)VariantType.Nil) .Append(", name: \"") .Append(propertyInfo.Name) - .Append("\", hint: (Godot.PropertyHint)") + .Append("\", hint: (global::Godot.PropertyHint)") .Append((int)PropertyHint.None) .Append(", hintString: \"") .Append(propertyInfo.HintString) - .Append("\", usage: (Godot.PropertyUsageFlags)") + .Append("\", usage: (global::Godot.PropertyUsageFlags)") .Append((int)propertyInfo.Usage) .Append(", exported: true));\n"); } 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") @@ -376,7 +379,8 @@ namespace Godot.SourceGenerators if (propertyUsage != PropertyUsageFlags.Category && attr.ConstructorArguments.Length > 1) hintString = attr.ConstructorArguments[1].Value?.ToString(); - yield return new PropertyInfo(VariantType.Nil, name, PropertyHint.None, hintString, propertyUsage.Value, true); + yield return new PropertyInfo(VariantType.Nil, name, PropertyHint.None, hintString, + propertyUsage.Value, true); } } } @@ -403,7 +407,7 @@ namespace Godot.SourceGenerators return null; } - if (propertySymbol.SetMethod == null) + if (propertySymbol.SetMethod == null || propertySymbol.SetMethod.IsInitOnly) { // This should never happen, as we filtered ReadOnly properties, but just in case. Common.ReportExportedMemberIsReadOnly(context, propertySymbol); 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 98b9745c16..99a4c95e73 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,21 +67,17 @@ 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() + string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint() + "_ScriptPropertyDefVal.generated"; var source = new StringBuilder(); - source.Append("using Godot;\n"); - source.Append("using Godot.NativeInterop;\n"); - source.Append("\n"); - if (hasNamespace) { source.Append("namespace "); @@ -141,14 +138,14 @@ namespace Godot.SourceGenerators } // TODO: We should still restore read-only properties after reloading assembly. Two possible ways: reflection or turn RestoreGodotObjectData into a constructor overload. - // Ignore properties without a getter or without a setter. Godot properties must be both readable and writable. + // Ignore properties without a getter, without a setter or with an init-only setter. Godot properties must be both readable and writable. if (property.IsWriteOnly) { Common.ReportExportedMemberIsWriteOnly(context, property); continue; } - if (property.IsReadOnly) + if (property.IsReadOnly || property.SetMethod!.IsInitOnly) { Common.ReportExportedMemberIsReadOnly(context, property); continue; @@ -163,14 +160,71 @@ namespace Godot.SourceGenerators continue; } - // TODO: Detect default value from simple property getters (currently we only detect from initializers) - - EqualsValueClauseSyntax? initializer = property.DeclaringSyntaxReferences - .Select(r => r.GetSyntax() as PropertyDeclarationSyntax) - .Select(s => s?.Initializer ?? null) - .FirstOrDefault(); + var propertyDeclarationSyntax = property.DeclaringSyntaxReferences + .Select(r => r.GetSyntax() as PropertyDeclarationSyntax).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 +261,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)); @@ -219,7 +279,8 @@ namespace Godot.SourceGenerators { source.Append("#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword\n"); - string dictionaryType = "System.Collections.Generic.Dictionary<StringName, object>"; + string dictionaryType = + "global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>"; source.Append("#if TOOLS\n"); source.Append(" internal new static "); @@ -237,7 +298,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(" = "); @@ -246,7 +307,8 @@ namespace Godot.SourceGenerators source.Append(" values.Add(PropertyName."); source.Append(exportedMember.Name); source.Append(", "); - source.Append(defaultValueLocalName); + source.AppendManagedToVariantExpr(defaultValueLocalName, + exportedMember.TypeSymbol, exportedMember.Type); source.Append(");\n"); } 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 11e0a6fa21..821f3af75f 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs @@ -66,13 +66,13 @@ 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() + string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint() + "_ScriptSerialization.generated"; var source = new StringBuilder(); @@ -162,7 +162,8 @@ namespace Godot.SourceGenerators source.Append(" info.AddProperty(PropertyName.") .Append(propertyName) .Append(", ") - .AppendManagedToVariantExpr(string.Concat("this.", propertyName), property.Type) + .AppendManagedToVariantExpr(string.Concat("this.", propertyName), + property.PropertySymbol.Type, property.Type) .Append(");\n"); } @@ -175,7 +176,8 @@ namespace Godot.SourceGenerators source.Append(" info.AddProperty(PropertyName.") .Append(fieldName) .Append(", ") - .AppendManagedToVariantExpr(string.Concat("this.", fieldName), field.Type) + .AppendManagedToVariantExpr(string.Concat("this.", fieldName), + field.FieldSymbol.Type, field.Type) .Append(");\n"); } @@ -241,7 +243,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 50196b84f0..d67cb5349d 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -75,13 +75,13 @@ 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() + string uniqueHint = symbol.FullQualifiedNameOmitGlobal().SanitizeQualifiedNameForUniqueHint() + "_ScriptSignals.generated"; var source = new StringBuilder(); @@ -176,14 +176,15 @@ 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); @@ -196,7 +197,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) @@ -231,15 +232,16 @@ 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") @@ -270,6 +272,25 @@ namespace Godot.SourceGenerators source.Append(" }\n"); } + // Generate HasGodotClassSignal + + if (godotSignalDelegates.Count > 0) + { + source.Append( + " protected override bool HasGodotClassSignal(in godot_string_name signal)\n {\n"); + + bool isFirstEntry = true; + foreach (var signal in godotSignalDelegates) + { + GenerateHasSignalEntry(signal.Name, source, isFirstEntry); + isFirstEntry = false; + } + + source.Append(" return base.HasGodotClassSignal(signal);\n"); + + source.Append(" }\n"); + } + source.Append("}\n"); // partial class if (isInnerClass) @@ -300,7 +321,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: "); @@ -328,15 +349,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") @@ -351,7 +372,7 @@ namespace Godot.SourceGenerators if (invokeMethodData.RetType != null) { - returnVal = DeterminePropertyInfo(invokeMethodData.RetType.Value, name: string.Empty); + returnVal = DeterminePropertyInfo(invokeMethodData.RetType.Value.MarshalType, name: string.Empty); } else { @@ -395,6 +416,20 @@ namespace Godot.SourceGenerators PropertyHint.None, string.Empty, propUsage, exported: false); } + private static void GenerateHasSignalEntry( + string signalName, + StringBuilder source, + bool isFirstEntry + ) + { + source.Append(" "); + if (!isFirstEntry) + source.Append("else "); + source.Append("if (signal == SignalName."); + source.Append(signalName); + source.Append(") {\n return true;\n }\n"); + } + private static void GenerateSignalEventInvoker( GodotSignalDelegateData signal, StringBuilder source 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/Build/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs index edbf53a389..7c02f29606 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs @@ -12,6 +12,7 @@ namespace GodotTools.Build public sealed partial class BuildInfo : RefCounted // TODO Remove RefCounted once we have proper serialization { public string Solution { get; private set; } + public string Project { get; private set; } public string Configuration { get; private set; } public string? RuntimeIdentifier { get; private set; } public string? PublishOutputDir { get; private set; } @@ -22,13 +23,13 @@ namespace GodotTools.Build // TODO Use List once we have proper serialization public Godot.Collections.Array CustomProperties { get; private set; } = new(); - public string LogsDirPath => - Path.Combine(GodotSharpDirs.BuildLogsDirs, $"{Solution.MD5Text()}_{Configuration}"); + public string LogsDirPath => GodotSharpDirs.LogsDirPathFor(Solution, Configuration); public override bool Equals(object? obj) { return obj is BuildInfo other && other.Solution == Solution && + other.Project == Project && other.Configuration == Configuration && other.RuntimeIdentifier == RuntimeIdentifier && other.PublishOutputDir == PublishOutputDir && other.Restore == Restore && other.Rebuild == Rebuild && other.OnlyClean == OnlyClean && @@ -42,6 +43,7 @@ namespace GodotTools.Build { int hash = 17; hash = (hash * 29) + Solution.GetHashCode(); + hash = (hash * 29) + Project.GetHashCode(); hash = (hash * 29) + Configuration.GetHashCode(); hash = (hash * 29) + (RuntimeIdentifier?.GetHashCode() ?? 0); hash = (hash * 29) + (PublishOutputDir?.GetHashCode() ?? 0); @@ -58,22 +60,25 @@ namespace GodotTools.Build private BuildInfo() { Solution = string.Empty; + Project = string.Empty; Configuration = string.Empty; } - public BuildInfo(string solution, string configuration, bool restore, bool rebuild, bool onlyClean) + public BuildInfo(string solution, string project, string configuration, bool restore, bool rebuild, bool onlyClean) { Solution = solution; + Project = project; Configuration = configuration; Restore = restore; Rebuild = rebuild; OnlyClean = onlyClean; } - public BuildInfo(string solution, string configuration, string runtimeIdentifier, + public BuildInfo(string solution, string project, string configuration, string runtimeIdentifier, string publishOutputDir, bool restore, bool rebuild, bool onlyClean) { Solution = solution; + Project = project; Configuration = configuration; RuntimeIdentifier = runtimeIdentifier; PublishOutputDir = publishOutputDir; diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs index 993c6d9217..ed3a4c6e26 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs @@ -55,7 +55,7 @@ namespace GodotTools.Build private static void PrintVerbose(string text) { - if (OS.IsStdoutVerbose()) + if (OS.IsStdOutVerbose()) GD.Print(text); } @@ -262,7 +262,7 @@ namespace GodotTools.Build bool onlyClean = false ) { - var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, configuration, + var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, GodotSharpDirs.ProjectCsProjPath, configuration, restore: true, rebuild, onlyClean); // If a platform was not specified, try determining the current one. If that fails, let MSBuild auto-detect it. @@ -282,7 +282,7 @@ namespace GodotTools.Build [DisallowNull] string publishOutputDir ) { - var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, configuration, + var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, GodotSharpDirs.ProjectCsProjPath, configuration, runtimeIdentifier, publishOutputDir, restore: true, rebuild: false, onlyClean: false); buildInfo.CustomProperties.Add($"GodotTargetPlatform={platform}"); diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs index 4d40724a83..c083b9cc60 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs @@ -336,7 +336,7 @@ namespace GodotTools.Build _ = index; // Unused _issuesListContextMenu.Clear(); - _issuesListContextMenu.Size = new Vector2i(1, 1); + _issuesListContextMenu.Size = new Vector2I(1, 1); if (_issuesList.IsAnythingSelected()) { @@ -347,7 +347,7 @@ namespace GodotTools.Build if (_issuesListContextMenu.ItemCount > 0) { - _issuesListContextMenu.Position = (Vector2i)(_issuesList.GlobalPosition + atPosition); + _issuesListContextMenu.Position = (Vector2I)(_issuesList.GlobalPosition + atPosition); _issuesListContextMenu.Popup(); } } @@ -356,19 +356,19 @@ namespace GodotTools.Build { base._Ready(); - SizeFlagsVertical = (int)SizeFlags.ExpandFill; + SizeFlagsVertical = SizeFlags.ExpandFill; var hsc = new HSplitContainer { - SizeFlagsHorizontal = (int)SizeFlags.ExpandFill, - SizeFlagsVertical = (int)SizeFlags.ExpandFill + SizeFlagsHorizontal = SizeFlags.ExpandFill, + SizeFlagsVertical = SizeFlags.ExpandFill }; AddChild(hsc); _issuesList = new ItemList { - SizeFlagsVertical = (int)SizeFlags.ExpandFill, - SizeFlagsHorizontal = (int)SizeFlags.ExpandFill // Avoid being squashed by the build log + SizeFlagsVertical = SizeFlags.ExpandFill, + SizeFlagsHorizontal = SizeFlags.ExpandFill // Avoid being squashed by the build log }; _issuesList.ItemActivated += IssueActivated; _issuesList.AllowRmbSelect = true; @@ -382,8 +382,8 @@ namespace GodotTools.Build _buildLog = new TextEdit { Editable = false, - SizeFlagsVertical = (int)SizeFlags.ExpandFill, - SizeFlagsHorizontal = (int)SizeFlags.ExpandFill // Avoid being squashed by the issues list + SizeFlagsVertical = SizeFlags.ExpandFill, + SizeFlagsHorizontal = SizeFlags.ExpandFill // Avoid being squashed by the issues list }; hsc.AddChild(_buildLog); diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs index d0cd529d1f..d550c36b82 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Godot; using GodotTools.BuildLogger; using GodotTools.Utils; @@ -22,19 +23,23 @@ namespace GodotTools.Build if (dotnetPath == null) throw new FileNotFoundException("Cannot find the dotnet executable."); + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var startInfo = new ProcessStartInfo(dotnetPath); - BuildArguments(buildInfo, startInfo.ArgumentList); + BuildArguments(buildInfo, startInfo.ArgumentList, editorSettings); string launchMessage = startInfo.GetCommandLineDisplay(new StringBuilder("Running: ")).ToString(); stdOutHandler?.Invoke(launchMessage); - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine(launchMessage); startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; + startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] + = ((string)editorSettings.GetSetting("interface/editor/editor_language")).Replace('_', '-'); // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); @@ -83,18 +88,22 @@ namespace GodotTools.Build if (dotnetPath == null) throw new FileNotFoundException("Cannot find the dotnet executable."); + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var startInfo = new ProcessStartInfo(dotnetPath); - BuildPublishArguments(buildInfo, startInfo.ArgumentList); + BuildPublishArguments(buildInfo, startInfo.ArgumentList, editorSettings); string launchMessage = startInfo.GetCommandLineDisplay(new StringBuilder("Running: ")).ToString(); stdOutHandler?.Invoke(launchMessage); - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine(launchMessage); startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; + startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] + = ((string)editorSettings.GetSetting("interface/editor/editor_language")).Replace('_', '-'); // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); @@ -124,13 +133,14 @@ namespace GodotTools.Build } } - private static void BuildArguments(BuildInfo buildInfo, Collection<string> arguments) + private static void BuildArguments(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) { // `dotnet clean` / `dotnet build` commands arguments.Add(buildInfo.OnlyClean ? "clean" : "build"); - // Solution - arguments.Add(buildInfo.Solution); + // C# Project + arguments.Add(buildInfo.Project); // `dotnet clean` doesn't recognize these options if (!buildInfo.OnlyClean) @@ -150,12 +160,14 @@ namespace GodotTools.Build arguments.Add(buildInfo.Configuration); // Verbosity - arguments.Add("-v"); - arguments.Add("normal"); + AddVerbosityArguments(buildInfo, arguments, editorSettings); // Logger AddLoggerArgument(buildInfo, arguments); + // Binary log + AddBinaryLogArgument(buildInfo, arguments, editorSettings); + // Custom properties foreach (var customProperty in buildInfo.CustomProperties) { @@ -163,12 +175,13 @@ namespace GodotTools.Build } } - private static void BuildPublishArguments(BuildInfo buildInfo, Collection<string> arguments) + private static void BuildPublishArguments(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) { arguments.Add("publish"); // `dotnet publish` command - // Solution - arguments.Add(buildInfo.Solution); + // C# Project + arguments.Add(buildInfo.Project); // Restore // `dotnet publish` restores by default, unless requested not to @@ -193,12 +206,14 @@ namespace GodotTools.Build arguments.Add("true"); // Verbosity - arguments.Add("-v"); - arguments.Add("normal"); + AddVerbosityArguments(buildInfo, arguments, editorSettings); // Logger AddLoggerArgument(buildInfo, arguments); + // Binary log + AddBinaryLogArgument(buildInfo, arguments, editorSettings); + // Custom properties foreach (var customProperty in buildInfo.CustomProperties) { @@ -213,6 +228,25 @@ namespace GodotTools.Build } } + private static void AddVerbosityArguments(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) + { + var verbosityLevel = + editorSettings.GetSetting(GodotSharpEditor.Settings.VerbosityLevel).As<VerbosityLevelId>(); + arguments.Add("-v"); + arguments.Add(verbosityLevel switch + { + VerbosityLevelId.Quiet => "quiet", + VerbosityLevelId.Minimal => "minimal", + VerbosityLevelId.Detailed => "detailed", + VerbosityLevelId.Diagnostic => "diagnostic", + _ => "normal", + }); + + if ((bool)editorSettings.GetSetting(GodotSharpEditor.Settings.NoConsoleLogging)) + arguments.Add("-noconlog"); + } + private static void AddLoggerArgument(BuildInfo buildInfo, Collection<string> arguments) { string buildLoggerPath = Path.Combine(Internals.GodotSharpDirs.DataEditorToolsDir, @@ -222,6 +256,16 @@ namespace GodotTools.Build $"-l:{typeof(GodotBuildLogger).FullName},{buildLoggerPath};{buildInfo.LogsDirPath}"); } + private static void AddBinaryLogArgument(BuildInfo buildInfo, Collection<string> arguments, + EditorSettings editorSettings) + { + if (!(bool)editorSettings.GetSetting(GodotSharpEditor.Settings.CreateBinaryLog)) + return; + + arguments.Add($"-bl:{Path.Combine(buildInfo.LogsDirPath, "msbuild.binlog")}"); + arguments.Add("-ds:False"); // Honestly never understood why -bl also switches -ds on. + } + private static void RemovePlatformVariable(StringDictionary environmentVariables) { // EnvironmentVariables is case sensitive? Seriously? diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs index 237ac85267..cf1b84e37f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MSBuildPanel.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Godot; using GodotTools.Internals; using static GodotTools.Internals.Globals; @@ -14,6 +15,7 @@ namespace GodotTools.Build private Button _errorsBtn; private Button _warningsBtn; private Button _viewLogBtn; + private Button _openLogsFolderBtn; private void WarningsToggled(bool pressed) { @@ -93,6 +95,10 @@ namespace GodotTools.Build private void ViewLogToggled(bool pressed) => BuildOutputView.LogVisible = pressed; + private void OpenLogsFolderPressed() => OS.ShellOpen( + $"file://{GodotSharpDirs.LogsDirPathFor("Debug")}" + ); + private void BuildMenuOptionPressed(long id) { switch ((BuildMenuOptions)id) @@ -122,10 +128,10 @@ namespace GodotTools.Build { base._Ready(); - CustomMinimumSize = new Vector2i(0, (int)(228 * EditorScale)); - SizeFlagsVertical = (int)SizeFlags.ExpandFill; + CustomMinimumSize = new Vector2(0, 228 * EditorScale); + SizeFlagsVertical = SizeFlags.ExpandFill; - var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = (int)SizeFlags.ExpandFill }; + var toolBarHBox = new HBoxContainer { SizeFlagsHorizontal = SizeFlags.ExpandFill }; AddChild(toolBarHBox); _buildMenuBtn = new MenuButton { Text = "Build", Icon = GetThemeIcon("Play", "EditorIcons") }; @@ -171,11 +177,27 @@ namespace GodotTools.Build _viewLogBtn.Toggled += ViewLogToggled; toolBarHBox.AddChild(_viewLogBtn); + // Horizontal spacer, push everything to the right. + toolBarHBox.AddChild(new Control + { + SizeFlagsHorizontal = SizeFlags.ExpandFill, + }); + + _openLogsFolderBtn = new Button + { + Text = "Show Logs in File Manager".TTR(), + Icon = GetThemeIcon("Filesystem", "EditorIcons"), + ExpandIcon = false, + FocusMode = FocusModeEnum.None, + }; + _openLogsFolderBtn.Pressed += OpenLogsFolderPressed; + toolBarHBox.AddChild(_openLogsFolderBtn); + BuildOutputView = new BuildOutputView(); AddChild(BuildOutputView); } - public override void _Notification(long what) + public override void _Notification(int what) { base._Notification(what); 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/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 745a8b73f8..a284451a35 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -17,24 +17,14 @@ namespace GodotTools.Export { public partial class ExportPlugin : EditorExportPlugin { + public override string _GetName() => "C#"; + private List<string> _tempFolders = new List<string>(); public void RegisterExportSettings() { // TODO: These would be better as export preset options, but that doesn't seem to be supported yet - - GlobalDef("mono/export/include_scripts_content", false); - - GlobalDef("mono/export/aot/enabled", false); - GlobalDef("mono/export/aot/full_aot", false); - GlobalDef("mono/export/aot/use_interpreter", true); - - // --aot or --aot=opt1,opt2 (use 'mono --aot=help AuxAssembly.dll' to list AOT options) - GlobalDef("mono/export/aot/extra_aot_options", Array.Empty<string>()); - // --optimize/-O=opt1,opt2 (use 'mono --list-opt'' to list optimize options) - GlobalDef("mono/export/aot/extra_optimizer_options", Array.Empty<string>()); - - GlobalDef("mono/export/aot/android_toolchain_path", ""); + GlobalDef("dotnet/export/include_scripts_content", false); } private string _maybeLastExportError; @@ -54,7 +44,7 @@ namespace GodotTools.Export // TODO What if the source file is not part of the game's C# project - bool includeScriptsContent = (bool)ProjectSettings.GetSetting("mono/export/include_scripts_content"); + bool includeScriptsContent = (bool)ProjectSettings.GetSetting("dotnet/export/include_scripts_content"); if (!includeScriptsContent) { @@ -69,7 +59,7 @@ namespace GodotTools.Export } } - public override void _ExportBegin(string[] features, bool isDebug, string path, long flags) + public override void _ExportBegin(string[] features, bool isDebug, string path, uint flags) { base._ExportBegin(features, isDebug, path, flags); @@ -183,7 +173,9 @@ namespace GodotTools.Export foreach (string file in Directory.GetFiles(publishOutputTempDir, "*", SearchOption.AllDirectories)) { - AddSharedObject(file, tags: null, projectDataDirName); + AddSharedObject(file, tags: null, + Path.Join(projectDataDirName, + Path.GetRelativePath(publishOutputTempDir, Path.GetDirectoryName(file)))); } } } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 89364d1c02..43ead4af69 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -22,6 +22,14 @@ namespace GodotTools { public partial class GodotSharpEditor : EditorPlugin, ISerializationListener { + public static class Settings + { + public const string ExternalEditor = "dotnet/editor/external_editor"; + public const string VerbosityLevel = "dotnet/build/verbosity_level"; + public const string NoConsoleLogging = "dotnet/build/no_console_logging"; + public const string CreateBinaryLog = "dotnet/build/create_binary_log"; + } + private EditorSettings _editorSettings; private PopupMenu _menuPopup; @@ -57,24 +65,22 @@ namespace GodotTools { pr.Step("Generating C# project...".TTR()); - string resourceDir = ProjectSettings.GlobalizePath("res://"); - - string path = resourceDir; + string csprojDir = Path.GetDirectoryName(GodotSharpDirs.ProjectCsProjPath); + string slnDir = Path.GetDirectoryName(GodotSharpDirs.ProjectSlnPath); string name = GodotSharpDirs.ProjectAssemblyName; - - string guid = CsProjOperations.GenerateGameProject(path, name); + string guid = CsProjOperations.GenerateGameProject(csprojDir, name); if (guid.Length > 0) { var solution = new DotNetSolution(name) { - DirectoryPath = path + DirectoryPath = slnDir }; var projectInfo = new DotNetSolution.ProjectInfo { Guid = guid, - PathRelativeToSolution = name + ".csproj", + PathRelativeToSolution = Path.GetRelativePath(slnDir, GodotSharpDirs.ProjectCsProjPath), Configs = new List<string> { "Debug", "ExportDebug", "ExportRelease" } }; @@ -173,7 +179,7 @@ namespace GodotTools [UsedImplicitly] public Error OpenInExternalEditor(Script script, int line, int col) { - var editorId = (ExternalEditorId)(int)_editorSettings.GetSetting("mono/editor/external_editor"); + var editorId = _editorSettings.GetSetting(Settings.ExternalEditor).As<ExternalEditorId>(); switch (editorId) { @@ -194,7 +200,7 @@ namespace GodotTools try { - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine( $"Running: \"{command}\" {string.Join(" ", args.Select(a => $"\"{a}\""))}"); @@ -325,8 +331,7 @@ namespace GodotTools [UsedImplicitly] public bool OverridesExternalEditor() { - return (ExternalEditorId)(int)_editorSettings.GetSetting("mono/editor/external_editor") != - ExternalEditorId.None; + return _editorSettings.GetSetting(Settings.ExternalEditor).As<ExternalEditorId>() != ExternalEditorId.None; } public override bool _Build() @@ -375,6 +380,8 @@ namespace GodotTools { base._EnablePlugin(); + ProjectSettingsChanged += GodotSharpDirs.DetermineProjectLocation; + if (Instance != null) throw new InvalidOperationException(); Instance = this; @@ -385,7 +392,7 @@ namespace GodotTools // correct version first (`RegisterDefaults` always picks the latest). if (DotNetFinder.TryFindDotNetSdk(dotNetSdkSearchVersion, out var sdkVersion, out string sdkPath)) { - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine($"Found .NET Sdk version '{sdkVersion}': {sdkPath}"); ProjectUtils.MSBuildLocatorRegisterMSBuildPath(sdkPath); @@ -395,12 +402,12 @@ namespace GodotTools try { ProjectUtils.MSBuildLocatorRegisterDefaults(out sdkVersion, out sdkPath); - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) Console.WriteLine($"Found .NET Sdk version '{sdkVersion}': {sdkPath}"); } catch (InvalidOperationException e) { - if (Godot.OS.IsStdoutVerbose()) + if (Godot.OS.IsStdOutVerbose()) GD.PrintErr(e.ToString()); GD.PushError($".NET Sdk not found. The required version is '{dotNetSdkSearchVersion}'."); } @@ -411,8 +418,6 @@ namespace GodotTools _editorSettings = editorInterface.GetEditorSettings(); - GodotSharpDirs.RegisterProjectSettings(); - _errorDialog = new AcceptDialog(); editorBaseControl.AddChild(_errorDialog); @@ -455,7 +460,10 @@ namespace GodotTools _menuPopup.IdPressed += _MenuOptionPressed; // External editor settings - EditorDef("mono/editor/external_editor", ExternalEditorId.None); + EditorDef(Settings.ExternalEditor, Variant.From(ExternalEditorId.None)); + EditorDef(Settings.VerbosityLevel, Variant.From(VerbosityLevelId.Normal)); + EditorDef(Settings.NoConsoleLogging, false); + EditorDef(Settings.CreateBinaryLog, false); string settingsHintStr = "Disabled"; @@ -483,11 +491,23 @@ namespace GodotTools _editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary { ["type"] = (int)Variant.Type.Int, - ["name"] = "mono/editor/external_editor", + ["name"] = Settings.ExternalEditor, ["hint"] = (int)PropertyHint.Enum, ["hint_string"] = settingsHintStr }); + var verbosityLevels = Enum.GetValues<VerbosityLevelId>().Select(level => $"{Enum.GetName(level)}:{(int)level}"); + _editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary + { + ["type"] = (int)Variant.Type.Int, + ["name"] = Settings.VerbosityLevel, + ["hint"] = (int)PropertyHint.Enum, + ["hint_string"] = string.Join(",", verbosityLevels), + }); + + OnSettingsChanged(); + _editorSettings.SettingsChanged += OnSettingsChanged; + // Export plugin var exportPlugin = new ExportPlugin(); AddExportPlugin(exportPlugin); @@ -512,6 +532,24 @@ namespace GodotTools AddChild(GodotIdeManager); } + public override void _DisablePlugin() + { + base._DisablePlugin(); + + _editorSettings.SettingsChanged -= OnSettingsChanged; + } + + private void OnSettingsChanged() + { + // We want to force NoConsoleLogging to true when the VerbosityLevel is at Detailed or above. + // At that point, there's so much info logged that it doesn't make sense to display it in + // the tiny editor window, and it'd make the editor hang or crash anyway. + var verbosityLevel = _editorSettings.GetSetting(Settings.VerbosityLevel).As<VerbosityLevelId>(); + var hideConsoleLog = (bool)_editorSettings.GetSetting(Settings.NoConsoleLogging); + if (verbosityLevel >= VerbosityLevelId.Detailed && !hideConsoleLog) + _editorSettings.SetSetting(Settings.NoConsoleLogging, Variant.From(true)); + } + protected override void Dispose(bool disposing) { if (disposing) diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs index 89ac8058b9..eb42f01b3a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -9,9 +9,9 @@ namespace GodotTools { private Timer _watchTimer; - public override void _Notification(long what) + public override void _Notification(int what) { - if (what == Node.NotificationWmWindowFocusIn) + if (what == Node.NotificationWMWindowFocusIn) { RestartTimer(); diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs index 9df90ac608..83621ce5af 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs @@ -21,7 +21,8 @@ namespace GodotTools.Ides return _messagingServer; _messagingServer?.Dispose(); - _messagingServer = new MessagingServer(OS.GetExecutablePath(), ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger()); + _messagingServer = new MessagingServer(OS.GetExecutablePath(), + ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger()); _ = _messagingServer.Listen(); @@ -76,8 +77,8 @@ namespace GodotTools.Ides public async Task<EditorPick?> LaunchIdeAsync(int millisecondsTimeout = 10000) { - var editorId = (ExternalEditorId)(int)GodotSharpEditor.Instance.GetEditorInterface() - .GetEditorSettings().GetSetting("mono/editor/external_editor"); + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var editorId = editorSettings.GetSetting(GodotSharpEditor.Settings.ExternalEditor).As<ExternalEditorId>(); string editorIdentity = GetExternalEditorIdentity(editorId); var runningServer = GetRunningOrNewServer(); @@ -200,13 +201,13 @@ namespace GodotTools.Ides { public void LogDebug(string message) { - if (OS.IsStdoutVerbose()) + if (OS.IsStdOutVerbose()) Console.WriteLine(message); } public void LogInfo(string message) { - if (OS.IsStdoutVerbose()) + if (OS.IsStdOutVerbose()) Console.WriteLine(message); } diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs index 60602a5847..f55ca4c7d7 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs @@ -9,7 +9,7 @@ namespace GodotTools.Ides.Rider { public static class RiderPathManager { - public static readonly string EditorPathSettingName = "mono/editor/editor_path_optional"; + public static readonly string EditorPathSettingName = "dotnet/editor/editor_path_optional"; private static string GetRiderPathFromSettings() { @@ -22,7 +22,7 @@ namespace GodotTools.Ides.Rider public static void Initialize() { var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); - var editor = (ExternalEditorId)(int)editorSettings.GetSetting("mono/editor/external_editor"); + var editor = editorSettings.GetSetting(GodotSharpEditor.Settings.ExternalEditor).As<ExternalEditorId>(); if (editor == ExternalEditorId.Rider) { if (!editorSettings.HasSetting(EditorPathSettingName)) diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs index acb7cc3ab0..45ae7eb86b 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs @@ -1,3 +1,4 @@ +using Godot; using Godot.NativeInterop; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; @@ -8,30 +9,31 @@ namespace GodotTools.Internals { public static float EditorScale => Internal.godot_icall_Globals_EditorScale(); - public static unsafe object GlobalDef(string setting, object defaultValue, bool restartIfChanged = false) + // ReSharper disable once UnusedMethodReturnValue.Global + public static Variant GlobalDef(string setting, Variant defaultValue, bool restartIfChanged = false) { using godot_string settingIn = Marshaling.ConvertStringToNative(setting); - using godot_variant defaultValueIn = Marshaling.ConvertManagedObjectToVariant(defaultValue); - Internal.godot_icall_Globals_GlobalDef(settingIn, defaultValueIn, restartIfChanged, out godot_variant result); - using (result) - return Marshaling.ConvertVariantToManagedObject(result); + using godot_variant defaultValueIn = defaultValue.CopyNativeVariant(); + Internal.godot_icall_Globals_GlobalDef(settingIn, defaultValueIn, restartIfChanged, + out godot_variant result); + return Variant.CreateTakingOwnershipOfDisposableValue(result); } - public static unsafe object EditorDef(string setting, object defaultValue, bool restartIfChanged = false) + // ReSharper disable once UnusedMethodReturnValue.Global + public static Variant EditorDef(string setting, Variant defaultValue, bool restartIfChanged = false) { using godot_string settingIn = Marshaling.ConvertStringToNative(setting); - using godot_variant defaultValueIn = Marshaling.ConvertManagedObjectToVariant(defaultValue); - Internal.godot_icall_Globals_EditorDef(settingIn, defaultValueIn, restartIfChanged, out godot_variant result); - using (result) - return Marshaling.ConvertVariantToManagedObject(result); + using godot_variant defaultValueIn = defaultValue.CopyNativeVariant(); + Internal.godot_icall_Globals_EditorDef(settingIn, defaultValueIn, restartIfChanged, + out godot_variant result); + return Variant.CreateTakingOwnershipOfDisposableValue(result); } - public static object EditorShortcut(string setting) + public static Variant EditorShortcut(string setting) { using godot_string settingIn = Marshaling.ConvertStringToNative(setting); Internal.godot_icall_Globals_EditorShortcut(settingIn, out godot_variant result); - using (result) - return Marshaling.ConvertVariantToManagedObject(result); + return Variant.CreateTakingOwnershipOfDisposableValue(result); } [SuppressMessage("ReSharper", "InconsistentNaming")] diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs index 14285cc0f1..fb68fcbae6 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs @@ -48,14 +48,7 @@ namespace GodotTools.Internals } } - public static void RegisterProjectSettings() - { - GlobalDef("dotnet/project/assembly_name", ""); - GlobalDef("dotnet/project/solution_directory", ""); - GlobalDef("dotnet/project/c#_project_directory", ""); - } - - private static void DetermineProjectLocation() + public static void DetermineProjectLocation() { static string DetermineProjectName() { @@ -76,10 +69,11 @@ namespace GodotTools.Internals string slnParentDir = (string)ProjectSettings.GetSetting("dotnet/project/solution_directory"); if (string.IsNullOrEmpty(slnParentDir)) slnParentDir = "res://"; + else if (!slnParentDir.StartsWith("res://")) + slnParentDir = "res://" + slnParentDir; - string csprojParentDir = (string)ProjectSettings.GetSetting("dotnet/project/c#_project_directory"); - if (string.IsNullOrEmpty(csprojParentDir)) - csprojParentDir = "res://"; + // The csproj should be in the same folder as project.godot. + string csprojParentDir = "res://"; _projectSlnPath = Path.Combine(ProjectSettings.GlobalizePath(slnParentDir), string.Concat(_projectAssemblyName, ".sln")); @@ -121,5 +115,11 @@ namespace GodotTools.Internals return _projectCsProjPath; } } + + public static string LogsDirPathFor(string solution, string configuration) + => Path.Combine(BuildLogsDirs, $"{solution.Md5Text()}_{configuration}"); + + public static string LogsDirPathFor(string configuration) + => LogsDirPathFor(ProjectSlnPath, configuration); } } 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/GodotTools/GodotTools/VerbosityLevelId.cs b/modules/mono/editor/GodotTools/GodotTools/VerbosityLevelId.cs new file mode 100644 index 0000000000..0e1afe6bbf --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/VerbosityLevelId.cs @@ -0,0 +1,11 @@ +namespace GodotTools +{ + public enum VerbosityLevelId : long + { + Quiet, + Minimal, + Normal, + Detailed, + Diagnostic, + } +} diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index b90321b586..ad6306bb41 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* bindings_generator.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* bindings_generator.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "bindings_generator.h" @@ -38,10 +38,10 @@ #include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/os/os.h" -#include "core/string/ucaps.h" #include "main/main.h" #include "../godotsharp_defs.h" +#include "../utils/naming_utils.h" #include "../utils/path_utils.h" #include "../utils/string_utils.h" @@ -84,10 +84,12 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) { #define CS_PROPERTY_SINGLETON "Singleton" #define CS_METHOD_INVOKE_GODOT_CLASS_METHOD "InvokeGodotClassMethod" #define CS_METHOD_HAS_GODOT_CLASS_METHOD "HasGodotClassMethod" +#define CS_METHOD_HAS_GODOT_CLASS_SIGNAL "HasGodotClassSignal" #define CS_STATIC_FIELD_NATIVE_CTOR "NativeCtor" #define CS_STATIC_FIELD_METHOD_BIND_PREFIX "MethodBind" #define CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX "MethodProxyName_" +#define CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX "SignalProxyName_" #define ICALL_PREFIX "godot_icall_" #define ICALL_CLASSDB_GET_METHOD "ClassDB_get_method" @@ -144,74 +146,6 @@ static String fix_doc_description(const String &p_bbcode) { .strip_edges(); } -static String snake_to_pascal_case(const String &p_identifier, bool p_input_is_upper = false) { - String ret; - Vector<String> parts = p_identifier.split("_", true); - - for (int i = 0; i < parts.size(); i++) { - String part = parts[i]; - - if (part.length()) { - part[0] = _find_upper(part[0]); - if (p_input_is_upper) { - for (int j = 1; j < part.length(); j++) { - part[j] = _find_lower(part[j]); - } - } - ret += part; - } else { - if (i == 0 || i == (parts.size() - 1)) { - // Preserve underscores at the beginning and end - ret += "_"; - } else { - // Preserve contiguous underscores - if (parts[i - 1].length()) { - ret += "__"; - } else { - ret += "_"; - } - } - } - } - - return ret; -} - -static String snake_to_camel_case(const String &p_identifier, bool p_input_is_upper = false) { - String ret; - Vector<String> parts = p_identifier.split("_", true); - - for (int i = 0; i < parts.size(); i++) { - String part = parts[i]; - - if (part.length()) { - if (i != 0) { - part[0] = _find_upper(part[0]); - } - if (p_input_is_upper) { - for (int j = i != 0 ? 1 : 0; j < part.length(); j++) { - part[j] = _find_lower(part[j]); - } - } - ret += part; - } else { - if (i == 0 || i == (parts.size() - 1)) { - // Preserve underscores at the beginning and end - ret += "_"; - } else { - // Preserve contiguous underscores - if (parts[i - 1].length()) { - ret += "__"; - } else { - ret += "_"; - } - } - } - } - - return ret; -} - String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype) { // Based on the version in EditorHelp @@ -229,6 +163,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf List<String> tag_stack; bool code_tag = false; + bool line_del = false; int pos = 0; while (pos < bbcode.length()) { @@ -239,20 +174,22 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf } if (brk_pos > pos) { - String text = bbcode.substr(pos, brk_pos - pos); - if (code_tag || tag_stack.size() > 0) { - xml_output.append(text.xml_escape()); - } else { - Vector<String> lines = text.split("\n"); - for (int i = 0; i < lines.size(); i++) { - if (i != 0) { - xml_output.append("<para>"); - } + if (!line_del) { + String text = bbcode.substr(pos, brk_pos - pos); + if (code_tag || tag_stack.size() > 0) { + xml_output.append(text.xml_escape()); + } else { + Vector<String> lines = text.split("\n"); + for (int i = 0; i < lines.size(); i++) { + if (i != 0) { + xml_output.append("<para>"); + } - xml_output.append(lines[i].xml_escape()); + xml_output.append(lines[i].xml_escape()); - if (i != lines.size() - 1) { - xml_output.append("</para>\n"); + if (i != lines.size() - 1) { + xml_output.append("</para>\n"); + } } } } @@ -265,20 +202,22 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf int brk_end = bbcode.find("]", brk_pos + 1); if (brk_end == -1) { - String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos); - if (code_tag || tag_stack.size() > 0) { - xml_output.append(text.xml_escape()); - } else { - Vector<String> lines = text.split("\n"); - for (int i = 0; i < lines.size(); i++) { - if (i != 0) { - xml_output.append("<para>"); - } + if (!line_del) { + String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos); + if (code_tag || tag_stack.size() > 0) { + xml_output.append(text.xml_escape()); + } else { + Vector<String> lines = text.split("\n"); + for (int i = 0; i < lines.size(); i++) { + if (i != 0) { + xml_output.append("<para>"); + } - xml_output.append(lines[i].xml_escape()); + xml_output.append(lines[i].xml_escape()); - if (i != lines.size() - 1) { - xml_output.append("</para>\n"); + if (i != lines.size() - 1) { + xml_output.append("</para>\n"); + } } } } @@ -292,7 +231,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length()); if (!tag_ok) { - xml_output.append("["); + if (!line_del) { + xml_output.append("["); + } pos = brk_pos + 1; continue; } @@ -307,11 +248,20 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append("</c>"); } else if (tag == "/codeblock") { xml_output.append("</code>"); + } else if (tag == "/b") { + xml_output.append("</b>"); + } else if (tag == "/i") { + xml_output.append("</i>"); + } else if (tag == "/csharp") { + xml_output.append("</code>"); + line_del = true; + } else if (tag == "/codeblocks") { + line_del = false; } } else if (code_tag) { xml_output.append("["); pos = brk_pos + 1; - } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ")) { + } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ") || tag.begins_with("theme_item ") || tag.begins_with("param ")) { const int tag_end = tag.find(" "); const String link_tag = tag.substr(0, tag_end); const String link_target = tag.substr(tag_end + 1, tag.length()).lstrip(" "); @@ -356,6 +306,8 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf } else if (link_tag == "theme_item") { // We do not declare theme_items in any way in C#, so there is nothing to reference _append_xml_undeclared(xml_output, link_target); + } else if (link_tag == "param") { + _append_xml_undeclared(xml_output, snake_to_camel_case(link_target, false)); } pos = brk_end + 1; @@ -377,8 +329,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf #endif "\"/>"); } else if (tag == "Variant") { - // We use System.Object for Variant, so there is no Variant type in C# - xml_output.append("<c>Variant</c>"); + xml_output.append("<see cref=\"Godot.Variant\"/>"); } else if (tag == "String") { xml_output.append("<see cref=\"string\"/>"); } else if (tag == "Nil") { @@ -428,11 +379,13 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf pos = brk_end + 1; } else if (tag == "b") { - // bold is not supported in xml comments + xml_output.append("<b>"); + pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "i") { - // italics is not supported in xml comments + xml_output.append("<i>"); + pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "code") { @@ -447,6 +400,17 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf code_tag = true; pos = brk_end + 1; tag_stack.push_front(tag); + } else if (tag == "codeblocks") { + line_del = true; + pos = brk_end + 1; + tag_stack.push_front(tag); + } else if (tag == "csharp") { + xml_output.append("<code>"); + + line_del = false; + code_tag = true; + pos = brk_end + 1; + tag_stack.push_front(tag); } else if (tag == "kbd") { // keyboard combinations are not supported in xml comments pos = brk_end + 1; @@ -459,7 +423,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append("\n"); // FIXME: Should use <para> instead. Luckily this tag isn't used for now. pos = brk_end + 1; } else if (tag == "u") { - // underline is not supported in xml comments + // underline is not supported in Rider xml comments pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "s") { @@ -510,7 +474,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf pos = brk_end + 1; tag_stack.push_front("font"); } else { - xml_output.append("["); // ignore + if (!line_del) { + xml_output.append("["); // ignore + } pos = brk_pos + 1; } } @@ -531,7 +497,7 @@ void BindingsGenerator::_append_xml_method(StringBuilder &p_xml_output, const Ty } else if (!p_target_itype || !p_target_itype->is_object_type) { if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve method reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve method reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from method reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -571,7 +537,7 @@ void BindingsGenerator::_append_xml_member(StringBuilder &p_xml_output, const Ty } else if (!p_target_itype || !p_target_itype->is_object_type) { if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve member reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve member reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from member reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -607,7 +573,7 @@ void BindingsGenerator::_append_xml_signal(StringBuilder &p_xml_output, const Ty if (!p_target_itype || !p_target_itype->is_object_type) { if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve signal reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve signal reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from signal reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -664,7 +630,7 @@ void BindingsGenerator::_append_xml_constant(StringBuilder &p_xml_output, const if (OS::get_singleton()->is_stdout_verbose()) { if (p_target_itype) { - OS::get_singleton()->print("Cannot resolve constant reference for non-Godot.Object type in documentation: %s\n", p_link_target.utf8().get_data()); + OS::get_singleton()->print("Cannot resolve constant reference for non-GodotObject type in documentation: %s\n", p_link_target.utf8().get_data()); } else { OS::get_singleton()->print("Cannot resolve type from constant reference in documentation: %s\n", p_link_target.utf8().get_data()); } @@ -933,11 +899,11 @@ void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { ARRAY_ALL(string); ARRAY_ALL(Color); ARRAY_ALL(Vector2); - ARRAY_ALL(Vector2i); + ARRAY_ALL(Vector2I); ARRAY_ALL(Vector3); - ARRAY_ALL(Vector3i); + ARRAY_ALL(Vector3I); ARRAY_ALL(Vector4); - ARRAY_ALL(Vector4i); + ARRAY_ALL(Vector4I); #undef ARRAY_ALL #undef ARRAY_IS_EMPTY @@ -1007,7 +973,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { _log("Declaring global enum '%s' inside struct '%s'\n", enum_proxy_name.utf8().get_data(), enum_class_name.utf8().get_data()); p_output.append("\npublic partial struct "); - p_output.append(enum_class_name); + p_output.append(pascal_to_pascal_case(enum_class_name)); p_output.append("\n" OPEN_BLOCK); } @@ -1016,7 +982,7 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { } p_output.append("\npublic enum "); - p_output.append(enum_proxy_name); + p_output.append(pascal_to_pascal_case(enum_proxy_name)); p_output.append(" : long"); p_output.append("\n" OPEN_BLOCK); @@ -1351,7 +1317,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str bool is_derived_type = itype.base_name != StringName(); if (!is_derived_type) { - // Some Godot.Object assertions + // Some GodotObject assertions CRASH_COND(itype.cname != name_cache.type_Object); CRASH_COND(!itype.is_instantiable); CRASH_COND(itype.api_type != ClassDB::API_CORE); @@ -1468,7 +1434,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output.append(MEMBER_BEGIN "public enum "); - output.append(ienum.cname.operator String()); + output.append(pascal_to_pascal_case(ienum.cname.operator String())); output.append(" : long"); output.append(MEMBER_BEGIN OPEN_BLOCK); @@ -1513,9 +1479,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str if (itype.is_singleton) { // Add the type name and the singleton pointer as static fields - output.append(MEMBER_BEGIN "private static Godot.Object singleton;\n"); + output.append(MEMBER_BEGIN "private static GodotObject singleton;\n"); - output << MEMBER_BEGIN "public static Godot.Object " CS_PROPERTY_SINGLETON "\n" INDENT1 "{\n" + output << MEMBER_BEGIN "public static GodotObject " CS_PROPERTY_SINGLETON "\n" INDENT1 "{\n" << INDENT2 "get\n" INDENT2 "{\n" INDENT3 "if (singleton == null)\n" << INDENT4 "singleton = " C_METHOD_ENGINE_GET_SINGLETON "(typeof(" << itype.proxy_name @@ -1525,8 +1491,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(itype.name); output.append("\";\n"); } else { - // IMPORTANT: We also generate the static fields for Godot.Object instead of declaring - // them manually in the `Object.base.cs` partial class declaration, because they're + // IMPORTANT: We also generate the static fields for GodotObject instead of declaring + // them manually in the `GodotObject.base.cs` partial class declaration, because they're // required by other static fields in this generated partial class declaration. // Static fields are initialized in order of declaration, but when they're in different // partial class declarations then it becomes harder to tell (Rider warns about this). @@ -1608,6 +1574,16 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str << " = \"" << imethod.proxy_name << "\";\n"; } + // Generate signal names cache fields + + for (const SignalInterface &isignal : itype.signals_) { + output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n" + << INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" + << INDENT1 "private static readonly StringName " + << CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX << isignal.name + << " = \"" << isignal.proxy_name << "\";\n"; + } + // TODO: Only generate HasGodotClassMethod and InvokeGodotClassMethod if there's any method // Generate InvokeGodotClassMethod @@ -1721,6 +1697,34 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str } output << INDENT1 "}\n"; + + // Generate HasGodotClassSignal + + output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual") + << " bool " CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(in godot_string_name signal)\n" + << INDENT1 "{\n"; + + for (const SignalInterface &isignal : itype.signals_) { + // We check for native names (snake_case). If we detect one, we call HasGodotClassSignal + // again, but this time with the respective proxy name (PascalCase). It's the job of + // user derived classes to override the method and check for those. Our C# source + // generators take care of generating those override methods. + output << INDENT2 "if (signal == SignalName." << isignal.proxy_name + << ")\n" INDENT2 "{\n" + << INDENT3 "if (" CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(" + << CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX << isignal.name + << ".NativeValue.DangerousSelfRef))\n" INDENT3 "{\n" + << INDENT4 "return true;\n" + << INDENT3 "}\n" INDENT2 "}\n"; + } + + if (is_derived_type) { + output << INDENT2 "return base." CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(signal);\n"; + } else { + output << INDENT2 "return false;\n"; + } + + output << INDENT1 "}\n"; } //Generate StringName for all class members @@ -1864,12 +1868,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.append("\n" OPEN_BLOCK_L1); if (getter) { - p_output.append(INDENT2 "get\n" - - // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) - "#pragma warning disable CS0618 // Disable warning about obsolete method\n" - - OPEN_BLOCK_L2 INDENT3); + p_output.append(INDENT2 "get\n" OPEN_BLOCK_L2 INDENT3); p_output.append("return "); p_output.append(getter->proxy_name + "("); @@ -1884,21 +1883,11 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.append(itos(p_iprop.index)); } } - p_output.append(");\n" - - CLOSE_BLOCK_L2 - - // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) - "#pragma warning restore CS0618\n"); + p_output.append(");\n" CLOSE_BLOCK_L2); } if (setter) { - p_output.append(INDENT2 "set\n" - - // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) - "#pragma warning disable CS0618 // Disable warning about obsolete method\n" - - OPEN_BLOCK_L2 INDENT3); + p_output.append(INDENT2 "set\n" OPEN_BLOCK_L2 INDENT3); p_output.append(setter->proxy_name + "("); if (p_iprop.index != -1) { @@ -1912,12 +1901,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.append(itos(p_iprop.index) + ", "); } } - p_output.append("value);\n" - - CLOSE_BLOCK_L2 - - // TODO Remove this once we make accessor methods private/internal (they will no longer be marked as obsolete after that) - "#pragma warning restore CS0618\n"); + p_output.append("value);\n" CLOSE_BLOCK_L2); } p_output.append(CLOSE_BLOCK_L1); @@ -2078,9 +2062,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf << INDENT1 "private static readonly IntPtr " << method_bind_field << " = "; if (p_itype.is_singleton) { - // Singletons are static classes. They don't derive Godot.Object, + // Singletons are static classes. They don't derive GodotObject, // so we need to specify the type to call the static method. - p_output << "Object."; + p_output << "GodotObject."; } p_output << ICALL_CLASSDB_GET_METHOD "(" BINDINGS_NATIVE_NAME_FIELD ", MethodName." @@ -2274,7 +2258,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf p_output.append(");\n"); // Generate Callable trampoline for the delegate - p_output << MEMBER_BEGIN "private static unsafe void " << p_isignal.proxy_name << "Trampoline" + 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" @@ -2289,9 +2273,8 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf p_output << ","; } - // TODO: We don't need to use VariantConversionCallbacks. We have the type information so we can use [cs_variant_to_managed] and [cs_managed_to_variant]. - p_output << "\n" INDENT3 "VariantConversionCallbacks.GetToManagedCallback<" - << arg_type->cs_type << ">()(args[" << itos(idx) << "])"; + p_output << sformat(arg_type->cs_variant_to_managed, + "args[" + itos(idx) + "]", arg_type->cs_type, arg_type->name); idx++; } @@ -2490,9 +2473,12 @@ Error BindingsGenerator::_generate_cs_native_calls(const InternalCall &p_icall, if (!ret_void) { if (return_type->cname != name_cache.type_Variant) { + // Usually the return value takes ownership, but in this case the variant is only used + // for conversion to another return type. As such, the local variable takes ownership. r_output << "using godot_variant " << C_LOCAL_VARARG_RET " = "; } else { - r_output << "using godot_variant " << C_LOCAL_RET " = "; + // Variant's [c_out] takes ownership of the variant value + r_output << "godot_variant " << C_LOCAL_RET " = "; } } @@ -2543,15 +2529,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" @@ -2795,6 +2779,18 @@ bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant & return false; } +bool method_has_ptr_parameter(MethodInfo p_method_info) { + if (p_method_info.return_val.type == Variant::INT && p_method_info.return_val.hint == PROPERTY_HINT_INT_IS_POINTER) { + return true; + } + for (PropertyInfo arg : p_method_info.arguments) { + if (arg.type == Variant::INT && arg.hint == PROPERTY_HINT_INT_IS_POINTER) { + return true; + } + } + return false; +} + bool BindingsGenerator::_populate_object_type_interfaces() { obj_types.clear(); @@ -2832,7 +2828,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(type_cname); - TypeInterface itype = TypeInterface::create_object_type(type_cname, api_type); + TypeInterface itype = TypeInterface::create_object_type(type_cname, pascal_to_pascal_case(type_cname), api_type); itype.base_name = ClassDB::get_parent_class(type_cname); itype.is_singleton = Engine::get_singleton()->has_singleton(itype.proxy_name); @@ -2840,9 +2836,6 @@ bool BindingsGenerator::_populate_object_type_interfaces() { itype.is_ref_counted = ClassDB::is_parent_class(type_cname, name_cache.type_RefCounted); itype.memory_own = itype.is_ref_counted; - itype.cs_variant_to_managed = "(%1)VariantUtils.ConvertToGodotObject(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromGodotObject(%0)"; - itype.c_out = "%5return "; itype.c_out += C_METHOD_UNMANAGED_GET_MANAGED; itype.c_out += itype.is_ref_counted ? "(%1.Reference);\n" : "(%1);\n"; @@ -2850,9 +2843,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() { itype.cs_type = itype.proxy_name; if (itype.is_singleton) { - itype.cs_in_expr = "Object." CS_STATIC_METHOD_GETINSTANCE "(" CS_PROPERTY_SINGLETON ")"; + itype.cs_in_expr = "GodotObject." CS_STATIC_METHOD_GETINSTANCE "(" CS_PROPERTY_SINGLETON ")"; } else { - itype.cs_in_expr = "Object." CS_STATIC_METHOD_GETINSTANCE "(%0)"; + itype.cs_in_expr = "GodotObject." CS_STATIC_METHOD_GETINSTANCE "(%0)"; } itype.cs_out = "%5return (%2)%0(%1);"; @@ -2860,7 +2853,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { itype.c_arg_in = "(void*)%s"; itype.c_type = "IntPtr"; itype.c_type_in = itype.c_type; - itype.c_type_out = "Object"; + itype.c_type_out = "GodotObject"; // Populate properties @@ -2941,6 +2934,11 @@ bool BindingsGenerator::_populate_object_type_interfaces() { continue; } + if (method_has_ptr_parameter(method_info)) { + // Pointers are not supported. + continue; + } + MethodInterface imethod; imethod.name = method_info.name; imethod.cname = cname; @@ -3002,7 +3000,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (return_info.type == Variant::NIL) { imethod.return_type.cname = name_cache.type_void; } else { - imethod.return_type.cname = _get_type_name_from_meta(return_info.type, m ? m->get_argument_meta(-1) : GodotTypeInfo::METADATA_NONE); + imethod.return_type.cname = _get_type_name_from_meta(return_info.type, m ? m->get_argument_meta(-1) : (GodotTypeInfo::Metadata)method_info.return_val_metadata); } for (int i = 0; i < argc; i++) { @@ -3026,7 +3024,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (arginfo.type == Variant::NIL) { iarg.type.cname = name_cache.type_Variant; } else { - iarg.type.cname = _get_type_name_from_meta(arginfo.type, m ? m->get_argument_meta(i) : GodotTypeInfo::METADATA_NONE); + iarg.type.cname = _get_type_name_from_meta(arginfo.type, m ? m->get_argument_meta(i) : (GodotTypeInfo::Metadata)method_info.get_argument_meta(i)); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); @@ -3059,12 +3057,10 @@ bool BindingsGenerator::_populate_object_type_interfaces() { HashMap<StringName, StringName>::Iterator accessor = accessor_methods.find(imethod.cname); if (accessor) { - const PropertyInterface *accessor_property = itype.find_property_by_name(accessor->value); - - // We only deprecate an accessor method if it's in the same class as the property. It's easier this way, but also - // we don't know if an accessor method in a different class could have other purposes, so better leave those untouched. - imethod.is_deprecated = true; - imethod.deprecation_message = imethod.proxy_name + " is deprecated. Use the " + accessor_property->proxy_name + " property instead."; + // We only make internal an accessor method if it's in the same class as the property. + // It's easier this way, but also we don't know if an accessor method in a different class + // could have other purposes, so better leave those untouched. + imethod.is_internal = true; } if (itype.class_doc) { @@ -3128,7 +3124,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { } else if (arginfo.type == Variant::NIL) { iarg.type.cname = name_cache.type_Variant; } else { - iarg.type.cname = _get_type_name_from_meta(arginfo.type, GodotTypeInfo::METADATA_NONE); + iarg.type.cname = _get_type_name_from_meta(arginfo.type, (GodotTypeInfo::Metadata)method_info.get_argument_meta(i)); } iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name)); @@ -3177,7 +3173,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &E : enum_map) { StringName enum_proxy_cname = E.key; - String enum_proxy_name = enum_proxy_cname.operator String(); + String enum_proxy_name = pascal_to_pascal_case(enum_proxy_cname.operator String()); if (itype.find_property_by_proxy_name(enum_proxy_name) || itype.find_method_by_proxy_name(enum_proxy_name) || itype.find_signal_by_proxy_name(enum_proxy_name)) { // In case the enum name conflicts with other PascalCase members, // we append 'Enum' to the enum name in those cases. @@ -3221,8 +3217,6 @@ bool BindingsGenerator::_populate_object_type_interfaces() { enum_itype.cname = StringName(enum_itype.name); enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name; TypeInterface::postsetup_enum_type(enum_itype); - enum_itype.cs_variant_to_managed = "(%1)VariantUtils.ConvertToInt32(%0)"; - enum_itype.cs_managed_to_variant = "VariantUtils.CreateFromInt((int)%0)"; enum_types.insert(enum_itype.cname, enum_itype); } @@ -3307,7 +3301,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } break; case Variant::AABB: { AABB aabb = p_val.operator ::AABB(); - r_iarg.default_argument = "new AABB(new Vector3" + aabb.position.operator String() + ", new Vector3" + aabb.size.operator String() + ")"; + r_iarg.default_argument = "new Aabb(new Vector3" + aabb.position.operator String() + ", new Vector3" + aabb.size.operator String() + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::RECT2: { @@ -3317,7 +3311,7 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } break; case Variant::RECT2I: { Rect2i rect = p_val.operator Rect2i(); - r_iarg.default_argument = "new Rect2i(new Vector2i" + rect.position.operator String() + ", new Vector2i" + rect.size.operator String() + ")"; + r_iarg.default_argument = "new Rect2I(new Vector2I" + rect.position.operator String() + ", new Vector2I" + rect.size.operator String() + ")"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; case Variant::COLOR: @@ -3451,34 +3445,30 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { TypeInterface itype; -#define INSERT_STRUCT_TYPE(m_type) \ - { \ - itype = TypeInterface::create_value_type(String(#m_type)); \ - itype.c_type_in = #m_type "*"; \ - itype.c_type_out = itype.cs_type; \ - itype.cs_in_expr = "&%0"; \ - itype.cs_in_expr_is_unsafe = true; \ - itype.cs_variant_to_managed = "VariantUtils.ConvertTo%2(%0)"; \ - itype.cs_managed_to_variant = "VariantUtils.CreateFrom%2(%0)"; \ - builtin_types.insert(itype.cname, itype); \ - } - - INSERT_STRUCT_TYPE(Vector2) - INSERT_STRUCT_TYPE(Vector2i) - INSERT_STRUCT_TYPE(Rect2) - INSERT_STRUCT_TYPE(Rect2i) - INSERT_STRUCT_TYPE(Transform2D) - INSERT_STRUCT_TYPE(Vector3) - INSERT_STRUCT_TYPE(Vector3i) - INSERT_STRUCT_TYPE(Basis) - INSERT_STRUCT_TYPE(Quaternion) - INSERT_STRUCT_TYPE(Transform3D) - INSERT_STRUCT_TYPE(AABB) - INSERT_STRUCT_TYPE(Color) - INSERT_STRUCT_TYPE(Plane) - INSERT_STRUCT_TYPE(Vector4) - INSERT_STRUCT_TYPE(Vector4i) - INSERT_STRUCT_TYPE(Projection) +#define INSERT_STRUCT_TYPE(m_type, m_proxy_name) \ + { \ + itype = TypeInterface::create_value_type(String(#m_type), String(#m_proxy_name)); \ + itype.cs_in_expr = "&%0"; \ + itype.cs_in_expr_is_unsafe = true; \ + builtin_types.insert(itype.cname, itype); \ + } + + INSERT_STRUCT_TYPE(Vector2, Vector2) + INSERT_STRUCT_TYPE(Vector2i, Vector2I) + INSERT_STRUCT_TYPE(Rect2, Rect2) + INSERT_STRUCT_TYPE(Rect2i, Rect2I) + INSERT_STRUCT_TYPE(Transform2D, Transform2D) + INSERT_STRUCT_TYPE(Vector3, Vector3) + INSERT_STRUCT_TYPE(Vector3i, Vector3I) + INSERT_STRUCT_TYPE(Basis, Basis) + INSERT_STRUCT_TYPE(Quaternion, Quaternion) + INSERT_STRUCT_TYPE(Transform3D, Transform3D) + INSERT_STRUCT_TYPE(AABB, Aabb) + INSERT_STRUCT_TYPE(Color, Color) + INSERT_STRUCT_TYPE(Plane, Plane) + INSERT_STRUCT_TYPE(Vector4, Vector4) + INSERT_STRUCT_TYPE(Vector4i, Vector4I) + INSERT_STRUCT_TYPE(Projection, Projection) #undef INSERT_STRUCT_TYPE @@ -3491,8 +3481,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.c_type; itype.c_arg_in = "&%s"; itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromBool(%1);\n"; - itype.cs_variant_to_managed = "VariantUtils.ConvertToBool(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromBool(%0)"; builtin_types.insert(itype.cname, itype); // Integer types @@ -3513,8 +3501,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_in = itype.name; \ itype.c_type_out = itype.name; \ itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromInt(%1);\n"; \ - itype.cs_variant_to_managed = "VariantUtils.ConvertTo" m_int_struct_name "(%0)"; \ - itype.cs_managed_to_variant = "VariantUtils.CreateFromInt(%0)"; \ builtin_types.insert(itype.cname, itype); \ } @@ -3550,8 +3536,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_in = itype.proxy_name; itype.c_type_out = itype.proxy_name; itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromFloat(%1);\n"; - itype.cs_variant_to_managed = "VariantUtils.ConvertToFloat32(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromFloat(%0)"; builtin_types.insert(itype.cname, itype); // double @@ -3565,8 +3549,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_in = itype.proxy_name; itype.c_type_out = itype.proxy_name; itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromFloat(%1);\n"; - itype.cs_variant_to_managed = "VariantUtils.ConvertToFloat64(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromFloat(%0)"; builtin_types.insert(itype.cname, itype); } @@ -3584,8 +3566,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = true; itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromString(%1);\n"; - itype.cs_variant_to_managed = "VariantUtils.ConvertToStringObject(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromString(%0)"; builtin_types.insert(itype.cname, itype); // StringName @@ -3604,8 +3584,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_in_vararg = "%5using godot_variant %1_in = VariantUtils.CreateFromStringName(%1);\n"; itype.c_type_is_disposable_struct = false; // [c_out] takes ownership itype.c_ret_needs_default_initialization = true; - itype.cs_variant_to_managed = "VariantUtils.ConvertToStringNameObject(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromStringName(%0)"; builtin_types.insert(itype.cname, itype); // NodePath @@ -3623,22 +3601,18 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = false; // [c_out] takes ownership itype.c_ret_needs_default_initialization = true; - itype.cs_variant_to_managed = "VariantUtils.ConvertToNodePathObject(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromNodePath(%0)"; builtin_types.insert(itype.cname, itype); // RID itype = TypeInterface(); itype.name = "RID"; itype.cname = itype.name; - itype.proxy_name = "RID"; + itype.proxy_name = "Rid"; itype.cs_type = itype.proxy_name; itype.c_arg_in = "&%s"; itype.c_type = itype.cs_type; itype.c_type_in = itype.c_type; itype.c_type_out = itype.c_type; - itype.cs_variant_to_managed = "VariantUtils.ConvertToRID(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromRID(%0)"; builtin_types.insert(itype.cname, itype); // Variant @@ -3655,8 +3629,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = false; // [c_out] takes ownership itype.c_ret_needs_default_initialization = true; - itype.cs_variant_to_managed = "Variant.CreateCopyingBorrowed(%0)"; - itype.cs_managed_to_variant = "%0.CopyNativeVariant()"; builtin_types.insert(itype.cname, itype); // Callable @@ -3669,26 +3641,22 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_in = "in " + itype.cs_type; itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = true; - itype.cs_variant_to_managed = "VariantUtils.ConvertToCallableManaged(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromCallable(%0)"; builtin_types.insert(itype.cname, itype); // Signal itype = TypeInterface(); itype.name = "Signal"; itype.cname = itype.name; - itype.proxy_name = "SignalInfo"; + itype.proxy_name = "Signal"; itype.cs_type = itype.proxy_name; itype.cs_in_expr = "%0"; itype.c_in = "%5using %0 %1_in = " C_METHOD_MANAGED_TO_SIGNAL "(in %1);\n"; - itype.c_out = "%5return " C_METHOD_MANAGED_FROM_SIGNAL "(&%1);\n"; + itype.c_out = "%5return " C_METHOD_MANAGED_FROM_SIGNAL "(in %1);\n"; itype.c_arg_in = "&%s_in"; itype.c_type = "godot_signal"; itype.c_type_in = "in " + itype.cs_type; itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = true; - itype.cs_variant_to_managed = "VariantUtils.ConvertToSignalInfo(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromSignalInfo(%0)"; builtin_types.insert(itype.cname, itype); // VarArg (fictitious type to represent variable arguments) @@ -3718,8 +3686,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_in = itype.proxy_name; \ itype.c_type_out = itype.proxy_name; \ itype.c_type_is_disposable_struct = true; \ - itype.cs_variant_to_managed = "VariantUtils.ConvertAs%2ToSystemArray(%0)"; \ - itype.cs_managed_to_variant = "VariantUtils.CreateFrom%2(%0)"; \ builtin_types.insert(itype.name, itype); \ } @@ -3755,8 +3721,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = false; // [c_out] takes ownership itype.c_ret_needs_default_initialization = true; - itype.cs_variant_to_managed = "VariantUtils.ConvertToArrayObject(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromArray(%0)"; builtin_types.insert(itype.cname, itype); // Array_@generic @@ -3764,6 +3728,9 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.name = "Array_@generic"; itype.cname = itype.name; itype.cs_out = "%5return new %2(%0(%1));"; + // For generic Godot collections, Variant.From<T>/As<T> is slower, so we need this special case + itype.cs_variant_to_managed = "VariantUtils.ConvertToArray(%0)"; + itype.cs_managed_to_variant = "VariantUtils.CreateFromArray(%0)"; builtin_types.insert(itype.cname, itype); // Dictionary @@ -3781,8 +3748,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.c_type_out = itype.cs_type; itype.c_type_is_disposable_struct = false; // [c_out] takes ownership itype.c_ret_needs_default_initialization = true; - itype.cs_variant_to_managed = "VariantUtils.ConvertToDictionaryObject(%0)"; - itype.cs_managed_to_variant = "VariantUtils.CreateFromDictionary(%0)"; builtin_types.insert(itype.cname, itype); // Dictionary_@generic @@ -3790,6 +3755,9 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { itype.name = "Dictionary_@generic"; itype.cname = itype.name; itype.cs_out = "%5return new %2(%0(%1));"; + // For generic Godot collections, Variant.From<T>/As<T> is slower, so we need this special case + itype.cs_variant_to_managed = "VariantUtils.ConvertToDictionary(%0)"; + itype.cs_managed_to_variant = "VariantUtils.CreateFromDictionary(%0)"; builtin_types.insert(itype.cname, itype); // void (fictitious type to represent the return type of methods that do not return anything) @@ -3835,7 +3803,7 @@ void BindingsGenerator::_populate_global_constants() { if (enum_name != StringName()) { EnumInterface ienum(enum_name); - // TODO: ienum.is_flags is always false for core constants since they don't seem to support bitfield enums + ienum.is_flags = CoreConstants::is_global_constant_bitfield(i); List<EnumInterface>::Element *enum_match = global_enums.find(ienum); if (enum_match) { enum_match->get().constants.push_back(iconstant); @@ -3853,10 +3821,8 @@ void BindingsGenerator::_populate_global_constants() { enum_itype.is_enum = true; enum_itype.name = ienum.cname.operator String(); enum_itype.cname = ienum.cname; - enum_itype.proxy_name = enum_itype.name; + enum_itype.proxy_name = pascal_to_pascal_case(enum_itype.name); TypeInterface::postsetup_enum_type(enum_itype); - enum_itype.cs_variant_to_managed = "(%1)VariantUtils.ConvertToInt32(%0)"; - enum_itype.cs_managed_to_variant = "VariantUtils.CreateFromInt((int)%0)"; enum_types.insert(enum_itype.cname, enum_itype); int prefix_length = _determine_enum_prefix(ienum); @@ -3877,9 +3843,9 @@ void BindingsGenerator::_populate_global_constants() { // HARDCODED List<StringName> hardcoded_enums; hardcoded_enums.push_back("Vector2.Axis"); - hardcoded_enums.push_back("Vector2i.Axis"); + hardcoded_enums.push_back("Vector2I.Axis"); hardcoded_enums.push_back("Vector3.Axis"); - hardcoded_enums.push_back("Vector3i.Axis"); + hardcoded_enums.push_back("Vector3I.Axis"); for (const StringName &enum_cname : hardcoded_enums) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) // Here, we assume core types do not begin with underscore @@ -3887,10 +3853,8 @@ void BindingsGenerator::_populate_global_constants() { enum_itype.is_enum = true; enum_itype.name = enum_cname.operator String(); enum_itype.cname = enum_cname; - enum_itype.proxy_name = enum_itype.name; + enum_itype.proxy_name = pascal_to_pascal_case(enum_itype.name); TypeInterface::postsetup_enum_type(enum_itype); - enum_itype.cs_variant_to_managed = "(%1)VariantUtils.ConvertToInt32(%0)"; - enum_itype.cs_managed_to_variant = "VariantUtils.CreateFromInt((int)%0)"; enum_types.insert(enum_itype.cname, enum_itype); } } diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index a479c44368..5c266ed31f 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* bindings_generator.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* bindings_generator.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef BINDINGS_GENERATOR_H #define BINDINGS_GENERATOR_H @@ -209,7 +209,7 @@ class BindingsGenerator { String name; StringName cname; - int type_parameter_count; + int type_parameter_count = 0; /** * Identifier name of the base class. @@ -472,49 +472,99 @@ class BindingsGenerator { } private: + static DocData::ClassDoc *_get_type_doc(TypeInterface &itype) { + String doc_name = itype.name.begins_with("_") ? itype.name.substr(1) : itype.name; + return &EditorHelp::get_doc_data()->class_list[doc_name]; + } + static void _init_value_type(TypeInterface &itype) { - itype.proxy_name = itype.name; + if (itype.proxy_name.is_empty()) { + itype.proxy_name = itype.name; + } - itype.c_type = itype.name; itype.cs_type = itype.proxy_name; - itype.c_type_in = itype.proxy_name + "*"; - itype.c_type_out = itype.proxy_name; - itype.class_doc = &EditorHelp::get_doc_data()->class_list[itype.proxy_name]; + itype.c_type = itype.cs_type; + itype.c_type_in = itype.cs_type + "*"; + itype.c_type_out = itype.cs_type; + + itype.class_doc = _get_type_doc(itype); + } + + static void _init_object_type(TypeInterface &itype, ClassDB::APIType p_api_type) { + if (itype.proxy_name.is_empty()) { + itype.proxy_name = itype.name; + } + + if (itype.proxy_name.begins_with("_")) { + itype.proxy_name = itype.proxy_name.substr(1); + } + + itype.api_type = p_api_type; + itype.is_object_type = true; + + itype.class_doc = _get_type_doc(itype); } public: - static TypeInterface create_value_type(const String &p_name) { + static TypeInterface create_value_type(const String &p_name, const String &p_proxy_name) { TypeInterface itype; itype.name = p_name; - itype.cname = StringName(p_name); + itype.cname = p_name; + itype.proxy_name = p_proxy_name; + _init_value_type(itype); + return itype; + } + + static TypeInterface create_value_type(const StringName &p_cname, const String &p_proxy_name) { + TypeInterface itype; + itype.name = p_cname; + itype.cname = p_cname; + itype.proxy_name = p_proxy_name; _init_value_type(itype); return itype; } - static TypeInterface create_value_type(const StringName &p_name) { + static TypeInterface create_value_type(const String &p_name) { TypeInterface itype; - itype.name = p_name.operator String(); + itype.name = p_name; itype.cname = p_name; _init_value_type(itype); return itype; } - static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) { + static TypeInterface create_value_type(const StringName &p_cname) { TypeInterface itype; + itype.name = p_cname; + itype.cname = p_cname; + _init_value_type(itype); + return itype; + } + static TypeInterface create_object_type(const StringName &p_cname, const String &p_proxy_name, ClassDB::APIType p_api_type) { + TypeInterface itype; itype.name = p_cname; itype.cname = p_cname; - itype.proxy_name = itype.name.begins_with("_") ? itype.name.substr(1, itype.name.length()) : itype.name; - itype.api_type = p_api_type; - itype.is_object_type = true; - itype.class_doc = &EditorHelp::get_doc_data()->class_list[itype.proxy_name]; + itype.proxy_name = p_proxy_name; + _init_object_type(itype, p_api_type); + return itype; + } + static TypeInterface create_object_type(const StringName &p_cname, ClassDB::APIType p_api_type) { + TypeInterface itype; + itype.name = p_cname; + itype.cname = p_cname; + _init_object_type(itype, p_api_type); return itype; } static void postsetup_enum_type(TypeInterface &r_enum_itype); - TypeInterface() {} + TypeInterface() { + static String default_cs_variant_to_managed = "VariantUtils.ConvertTo<%1>(%0)"; + static String default_cs_managed_to_variant = "VariantUtils.CreateFrom<%1>(%0)"; + cs_variant_to_managed = default_cs_variant_to_managed; + cs_managed_to_variant = default_cs_managed_to_variant; + } }; struct InternalCall { diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp index dc69567261..ae02e16256 100644 --- a/modules/mono/editor/code_completion.cpp +++ b/modules/mono/editor/code_completion.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* code_completion.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* code_completion.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "code_completion.h" diff --git a/modules/mono/editor/code_completion.h b/modules/mono/editor/code_completion.h index 82b592003b..89d19b10e0 100644 --- a/modules/mono/editor/code_completion.h +++ b/modules/mono/editor/code_completion.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* code_completion.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* code_completion.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef CODE_COMPLETION_H #define CODE_COMPLETION_H diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index 91392c8f79..ad9ab66cc9 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* editor_internal_calls.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* editor_internal_calls.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "editor_internal_calls.h" diff --git a/modules/mono/editor/editor_internal_calls.h b/modules/mono/editor/editor_internal_calls.h index 35391f1f04..48da02987a 100644 --- a/modules/mono/editor/editor_internal_calls.h +++ b/modules/mono/editor/editor_internal_calls.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* editor_internal_calls.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* editor_internal_calls.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef EDITOR_INTERNAL_CALLS_H #define EDITOR_INTERNAL_CALLS_H diff --git a/modules/mono/editor/hostfxr_resolver.cpp b/modules/mono/editor/hostfxr_resolver.cpp index ea5978b2cd..786272b28c 100644 --- a/modules/mono/editor/hostfxr_resolver.cpp +++ b/modules/mono/editor/hostfxr_resolver.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* hostfxr_resolver.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* hostfxr_resolver.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ /* Adapted to Godot from the nethost library: https://github.com/dotnet/runtime/tree/main/src/native/corehost diff --git a/modules/mono/editor/hostfxr_resolver.h b/modules/mono/editor/hostfxr_resolver.h index 0f029ab7ae..398a58c730 100644 --- a/modules/mono/editor/hostfxr_resolver.h +++ b/modules/mono/editor/hostfxr_resolver.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* hostfxr_resolver.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* hostfxr_resolver.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef HOSTFXR_RESOLVER_H #define HOSTFXR_RESOLVER_H diff --git a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs index fbad482cf6..87468fb433 100644 --- a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs @@ -17,22 +17,22 @@ public partial class _CLASS_ : _BASE_ // Add the gravity. if (!IsOnFloor()) - velocity.y += gravity * (float)delta; + velocity.Y += gravity * (float)delta; // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - velocity.y = JumpVelocity; + velocity.Y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 direction = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); if (direction != Vector2.Zero) { - velocity.x = direction.x * Speed; + velocity.X = direction.X * Speed; } else { - velocity.x = Mathf.MoveToward(Velocity.x, 0, Speed); + velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed); } Velocity = velocity; diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs index abed246a1e..ddeb9d7e00 100644 --- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs +++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs @@ -17,25 +17,25 @@ public partial class _CLASS_ : _BASE_ // Add the gravity. if (!IsOnFloor()) - velocity.y -= gravity * (float)delta; + velocity.Y -= gravity * (float)delta; // Handle Jump. if (Input.IsActionJustPressed("ui_accept") && IsOnFloor()) - velocity.y = JumpVelocity; + velocity.Y = JumpVelocity; // Get the input direction and handle the movement/deceleration. // As good practice, you should replace UI actions with custom gameplay actions. Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down"); - Vector3 direction = (Transform.basis * new Vector3(inputDir.x, 0, inputDir.y)).Normalized(); + Vector3 direction = (Transform.Basis * new Vector3(inputDir.X, 0, inputDir.Y)).Normalized(); if (direction != Vector3.Zero) { - velocity.x = direction.x * Speed; - velocity.z = direction.z * Speed; + velocity.X = direction.X * Speed; + velocity.Z = direction.Z * Speed; } else { - velocity.x = Mathf.MoveToward(Velocity.x, 0, Speed); - velocity.z = Mathf.MoveToward(Velocity.z, 0, Speed); + velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed); + velocity.Z = Mathf.MoveToward(Velocity.Z, 0, Speed); } Velocity = velocity; diff --git a/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs b/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs index 9e1b7ef580..fa2ff30a09 100644 --- a/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs +++ b/modules/mono/editor/script_templates/EditorScenePostImport/basic_import_script.cs @@ -7,7 +7,7 @@ using System; [Tool] public partial class _CLASS_ : _BASE_ { - public override Godot.Object _PostImport(Node scene) + public override GodotObject _PostImport(Node scene) { // Modify the contents of the scene upon import. return scene; // Return the modified root node when you're done. diff --git a/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs b/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs index bf2c9434e4..4365ba5a04 100644 --- a/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs +++ b/modules/mono/editor/script_templates/EditorScenePostImport/no_comments.cs @@ -7,7 +7,7 @@ using System; [Tool] public partial class _CLASS_ : _BASE_ { - public override Godot.Object _PostImport(Node scene) + public override GodotObject _PostImport(Node scene) { return scene; } diff --git a/modules/mono/editor/semver.cpp b/modules/mono/editor/semver.cpp index 1656d0932f..1ca3005420 100644 --- a/modules/mono/editor/semver.cpp +++ b/modules/mono/editor/semver.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* semver.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* semver.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "semver.h" diff --git a/modules/mono/editor/semver.h b/modules/mono/editor/semver.h index 48ea8b043e..2f65e99ef5 100644 --- a/modules/mono/editor/semver.h +++ b/modules/mono/editor/semver.h @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* semver.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* semver.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #ifndef SEMVER_H #define SEMVER_H |