Ver Fonte

Move to .NET8

- Change TFM and LangVersion
- Better exception throwing (CA1510, CA1512, CA1513)
- Better exception utility method definition (CA1859)
- Prefer comparing `.Count` over calling `.Any()` (CA1860)
- Prefer `.AsSpan()` over `.Substring()` (CA1846)
- Add a few more `scoped`
- Use `RuntimeHelpers.GetUninitializedObject()` instead of `FormatterServices.GetUninitializedObject()`
- Use delegate instead of delegate pointer in variant generic conversions
- Enable EnforceExtendedAnalyzerRules in source generator projects
- Disable CS8981 on structs named movable in Godot.NativeInterop
Paul Joannon há 1 ano atrás
pai
commit
fb8553e4d7
28 ficheiros alterados com 167 adições e 110 exclusões
  1. 1 1
      modules/mono/build_scripts/build_assemblies.py
  2. 2 2
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj
  3. 1 1
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpAnalyzerVerifier.cs
  4. 1 2
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpCodeFixVerifier.cs
  5. 1 1
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpSourceGeneratorVerifier.cs
  6. 8 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Constants.cs
  7. 2 3
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Godot.SourceGenerators.Tests.csproj
  8. 1 0
      modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj
  9. 4 2
      modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
  10. 6 2
      modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
  11. 8 4
      modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj
  12. 10 2
      modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
  13. 6 2
      modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/Godot.SourceGenerators.Internal.csproj
  14. 16 8
      modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs
  15. 2 2
      modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj
  16. 8 13
      modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
  17. 2 3
      modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
  18. 2 2
      modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
  19. 5 7
      modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
  20. 1 2
      modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs
  21. 1 1
      modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs
  22. 12 1
      modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs
  23. 26 31
      modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
  24. 18 3
      modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs
  25. 9 10
      modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs
  26. 1 1
      modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
  27. 11 2
      modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
  28. 2 2
      modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj

+ 1 - 1
modules/mono/build_scripts/build_assemblies.py

@@ -229,7 +229,7 @@ def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local, pre
 
         core_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharp", "bin", build_config))
         editor_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotSharpEditor", "bin", build_config))
-        plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net7.0"))
+        plugins_src_dir = os.path.abspath(os.path.join(sln, os.pardir, "GodotPlugins", "bin", build_config, "net8.0"))
 
         if not os.path.isdir(editor_api_dir):
             assert not os.path.isfile(editor_api_dir)

+ 2 - 2
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/Godot.SourceGenerators.Sample.csproj

@@ -1,8 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net7.0</TargetFramework>
-    <LangVersion>11</LangVersion>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
   </PropertyGroup>
 
   <PropertyGroup>

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

@@ -21,7 +21,7 @@ public static class CSharpAnalyzerVerifier<TAnalyzer>
     {
         public Test()
         {
-            ReferenceAssemblies = ReferenceAssemblies.Net.Net60;
+            ReferenceAssemblies = Constants.Net80;
 
             SolutionTransforms.Add((Solution solution, ProjectId projectId) =>
             {

+ 1 - 2
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/CSharpCodeFixVerifier.cs

@@ -4,7 +4,6 @@ using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CodeFixes;
 using Microsoft.CodeAnalysis.CSharp.Testing;
 using Microsoft.CodeAnalysis.Diagnostics;
-using Microsoft.CodeAnalysis.Testing;
 using Microsoft.CodeAnalysis.Testing.Verifiers;
 
 namespace Godot.SourceGenerators.Tests;
@@ -17,7 +16,7 @@ public static class CSharpCodeFixVerifier<TCodeFix, TAnalyzer>
     {
         public Test()
         {
-            ReferenceAssemblies = ReferenceAssemblies.Net.Net60;
+            ReferenceAssemblies = Constants.Net80;
             SolutionTransforms.Add((Solution solution, ProjectId projectId) =>
             {
                 Project project = solution.GetProject(projectId)!

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

@@ -18,7 +18,7 @@ where TSourceGenerator : ISourceGenerator, new()
     {
         public Test()
         {
-            ReferenceAssemblies = ReferenceAssemblies.Net.Net60;
+            ReferenceAssemblies = Constants.Net80;
 
             SolutionTransforms.Add((Solution solution, ProjectId projectId) =>
             {

+ 8 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Constants.cs

@@ -1,5 +1,6 @@
 using System.IO;
 using System.Reflection;
+using Microsoft.CodeAnalysis.Testing;
 
 namespace Godot.SourceGenerators.Tests;
 
@@ -7,6 +8,13 @@ public static class Constants
 {
     public static Assembly GodotSharpAssembly => typeof(GodotObject).Assembly;
 
+    // Can't find what needs updating to be able to access ReferenceAssemblies.Net.Net80, so we're making our own one.
+    public static ReferenceAssemblies Net80 => new ReferenceAssemblies(
+        "net8.0",
+        new PackageIdentity("Microsoft.NETCore.App.Ref", "8.0.0"),
+        Path.Combine("ref", "net8.0")
+    );
+
     public static string ExecutingAssemblyPath { get; }
     public static string SourceFolderPath { get; }
     public static string GeneratedSourceFolderPath { get; }

+ 2 - 3
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/Godot.SourceGenerators.Tests.csproj

@@ -1,9 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net6.0</TargetFramework>
-
-    <LangVersion>11</LangVersion>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
 
     <Nullable>enable</Nullable>
     <IsPackable>false</IsPackable>

+ 1 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Godot.SourceGenerators.csproj

@@ -3,6 +3,7 @@
     <TargetFramework>netstandard2.0</TargetFramework>
     <LangVersion>10</LangVersion>
     <Nullable>enable</Nullable>
+    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
   </PropertyGroup>
   <PropertyGroup>
     <Description>Core C# source generator for Godot projects.</Description>

+ 4 - 2
modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj

@@ -1,8 +1,10 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
     <ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid>
-    <TargetFramework>net7.0</TargetFramework>
-    <LangVersion>10</LangVersion>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
     <Nullable>enable</Nullable>
   </PropertyGroup>
+
 </Project>

+ 6 - 2
modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj

@@ -1,17 +1,21 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
     <ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid>
-    <TargetFramework>net7.0</TargetFramework>
-    <LangVersion>10</LangVersion>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
     <Nullable>enable</Nullable>
   </PropertyGroup>
+
   <ItemGroup>
     <PackageReference Include="Microsoft.Build" Version="15.1.548" ExcludeAssets="runtime" />
     <PackageReference Include="Microsoft.Build.Locator" Version="1.2.6" />
     <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
   </ItemGroup>
+
   <ItemGroup>
     <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
     <ProjectReference Include="..\GodotTools.Shared\GodotTools.Shared.csproj" />
   </ItemGroup>
+
 </Project>

+ 8 - 4
modules/mono/editor/GodotTools/GodotTools.Shared/GodotTools.Shared.csproj

@@ -1,8 +1,12 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
+
     <PropertyGroup>
-        <TargetFramework>net8.0</TargetFramework>
-        <!-- Specify compile items manually to avoid including dangling generated items. -->
-        <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
+      <TargetFramework>net8.0</TargetFramework>
+      <LangVersion>12</LangVersion>
+      <!-- Specify compile items manually to avoid including dangling generated items. -->
+      <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
     </PropertyGroup>
+
     <Import Project="GenerateGodotNupkgsVersions.targets" />
+
 </Project>

+ 10 - 2
modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj

@@ -1,9 +1,10 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
     <ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid>
-    <TargetFramework>net7.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
     <EnableDynamicLoading>true</EnableDynamicLoading>
-    <LangVersion>10</LangVersion>
     <Nullable>enable</Nullable>
     <!-- The Godot editor uses the Debug Godot API assemblies -->
     <GodotApiConfiguration>Debug</GodotApiConfiguration>
@@ -13,13 +14,16 @@
     <ProduceReferenceAssembly>false</ProduceReferenceAssembly>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
+
   <!-- Needed for our source generators to work despite this not being a Godot game project -->
   <PropertyGroup>
     <IsGodotToolsProject>true</IsGodotToolsProject>
   </PropertyGroup>
+
   <ItemGroup>
     <CompilerVisibleProperty Include="IsGodotToolsProject" />
   </ItemGroup>
+
   <PropertyGroup Condition=" Exists('$(GodotApiAssembliesDir)/GodotSharp.dll') ">
     <!-- The project is part of the Godot source tree -->
     <!-- Use the Godot source tree output folder instead of '$(ProjectDir)/bin' -->
@@ -27,6 +31,7 @@
     <!-- Must not append '$(TargetFramework)' to the output path in this case -->
     <AppendTargetFrameworkToOutputPath>False</AppendTargetFrameworkToOutputPath>
   </PropertyGroup>
+
   <ItemGroup>
     <PackageReference Include="JetBrains.Annotations" Version="2019.1.3.0" ExcludeAssets="runtime" PrivateAssets="all" />
     <PackageReference Include="JetBrains.Rider.PathLocator" Version="1.0.9" />
@@ -41,14 +46,17 @@
       <Private>False</Private>
     </Reference>
   </ItemGroup>
+
   <ItemGroup>
     <ProjectReference Include="..\..\Godot.NET.Sdk\Godot.SourceGenerators\Godot.SourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
     <ProjectReference Include="..\..\..\glue\GodotSharp\Godot.SourceGenerators.Internal\Godot.SourceGenerators.Internal.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
   </ItemGroup>
+
   <ItemGroup>
     <ProjectReference Include="..\GodotTools.BuildLogger\GodotTools.BuildLogger.csproj" />
     <ProjectReference Include="..\GodotTools.IdeMessaging\GodotTools.IdeMessaging.csproj" />
     <ProjectReference Include="..\GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj" />
     <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
   </ItemGroup>
+
 </Project>

+ 6 - 2
modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/Godot.SourceGenerators.Internal.csproj

@@ -1,11 +1,15 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
     <LangVersion>10</LangVersion>
     <Nullable>enable</Nullable>
+    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
   </PropertyGroup>
+
   <ItemGroup>
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" />
+    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
+    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
   </ItemGroup>
+
 </Project>

+ 16 - 8
modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs

@@ -172,7 +172,11 @@ using Godot.NativeInterop;
             {
                 var parameter = callback.Parameters[i];
 
-                source.Append(parameter.DeclaringSyntaxReferences[0].GetSyntax().ToString());
+                AppendRefKind(source, parameter.RefKind, parameter.ScopedKind);
+                source.Append(' ');
+                source.Append(parameter.Type.FullQualifiedNameIncludeGlobal());
+                source.Append(' ');
+                source.Append(parameter.Name);
 
                 if (parameter.RefKind == RefKind.Out)
                 {
@@ -204,7 +208,7 @@ using Godot.NativeInterop;
                     {
                         // If it's a by-ref param and we can't get the pointer
                         // just pass it by-ref and let it be pinned.
-                        AppendRefKind(methodCallArguments, parameter.RefKind)
+                        AppendRefKind(methodCallArguments, parameter.RefKind, parameter.ScopedKind)
                             .Append(' ')
                             .Append(parameter.Name);
                     }
@@ -342,7 +346,7 @@ using Godot.NativeInterop;
                     {
                         // If it's a by-ref param and we can't get the pointer
                         // just pass it by-ref and let it be pinned.
-                        AppendRefKind(source, parameter.RefKind)
+                        AppendRefKind(source, parameter.RefKind, parameter.ScopedKind)
                             .Append(' ')
                             .Append(parameter.Type.FullQualifiedNameIncludeGlobal());
                     }
@@ -388,14 +392,18 @@ using Godot.NativeInterop;
     private static bool IsByRefParameter(IParameterSymbol parameter) =>
         parameter.RefKind is RefKind.In or RefKind.Out or RefKind.Ref;
 
-    private static StringBuilder AppendRefKind(StringBuilder source, RefKind refKind) =>
-        refKind switch
+    private static StringBuilder AppendRefKind(StringBuilder source, RefKind refKind, ScopedKind scopedKind)
+    {
+        return (refKind, scopedKind) switch
         {
-            RefKind.In => source.Append("in"),
-            RefKind.Out => source.Append("out"),
-            RefKind.Ref => source.Append("ref"),
+            (RefKind.Out, _) => source.Append("out"),
+            (RefKind.In, ScopedKind.ScopedRef) => source.Append("scoped in"),
+            (RefKind.In, _) => source.Append("in"),
+            (RefKind.Ref, ScopedKind.ScopedRef) => source.Append("scoped ref"),
+            (RefKind.Ref, _) => source.Append("ref"),
             _ => source,
         };
+    }
 
     private static void AppendPointerType(StringBuilder source, ITypeSymbol type)
     {

+ 2 - 2
modules/mono/glue/GodotSharp/GodotPlugins/GodotPlugins.csproj

@@ -1,8 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>net7.0</TargetFramework>
-    <LangVersion>10</LangVersion>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
     <Nullable>enable</Nullable>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 

+ 8 - 13
modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs

@@ -50,8 +50,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Array.</returns>
         public Array(IEnumerable<Variant> collection) : this()
         {
-            if (collection == null)
-                throw new ArgumentNullException(nameof(collection));
+            ArgumentNullException.ThrowIfNull(collection);
 
             foreach (Variant element in collection)
                 Add(element);
@@ -67,8 +66,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Array.</returns>
         public Array(Variant[] array)
         {
-            if (array == null)
-                throw new ArgumentNullException(nameof(array));
+            ArgumentNullException.ThrowIfNull(array);
 
             NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
             _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
@@ -1056,7 +1054,7 @@ namespace Godot.Collections
         IEnumerable<T>,
         IGenericGodotArray
     {
-        private static godot_variant ToVariantFunc(in Array<T> godotArray) =>
+        private static godot_variant ToVariantFunc(scoped in Array<T> godotArray) =>
             VariantUtils.CreateFromArray(godotArray);
 
         private static Array<T> FromVariantFunc(in godot_variant variant) =>
@@ -1080,8 +1078,8 @@ namespace Godot.Collections
 
         static unsafe Array()
         {
-            VariantUtils.GenericConversion<Array<T>>.ToVariantCb = &ToVariantFunc;
-            VariantUtils.GenericConversion<Array<T>>.FromVariantCb = &FromVariantFunc;
+            VariantUtils.GenericConversion<Array<T>>.ToVariantCb = ToVariantFunc;
+            VariantUtils.GenericConversion<Array<T>>.FromVariantCb = FromVariantFunc;
         }
 
         private readonly Array _underlyingArray;
@@ -1114,8 +1112,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Array.</returns>
         public Array(IEnumerable<T> collection)
         {
-            if (collection == null)
-                throw new ArgumentNullException(nameof(collection));
+            ArgumentNullException.ThrowIfNull(collection);
 
             _underlyingArray = new Array();
             SetTypedForUnderlyingArray();
@@ -1134,8 +1131,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Array.</returns>
         public Array(T[] array)
         {
-            if (array == null)
-                throw new ArgumentNullException(nameof(array));
+            ArgumentNullException.ThrowIfNull(array);
 
             _underlyingArray = new Array();
             SetTypedForUnderlyingArray();
@@ -1154,8 +1150,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Array.</returns>
         public Array(Array array)
         {
-            if (array == null)
-                throw new ArgumentNullException(nameof(array));
+            ArgumentNullException.ThrowIfNull(array);
 
             _underlyingArray = array;
         }

+ 2 - 3
modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs

@@ -90,8 +90,7 @@ namespace Godot.Bridge
         }
 
         [UnmanagedCallersOnly]
-        internal static unsafe IntPtr CreateManagedForGodotObjectBinding(godot_string_name* nativeTypeName,
-            IntPtr godotObject)
+        internal static unsafe IntPtr CreateManagedForGodotObjectBinding(godot_string_name* nativeTypeName, IntPtr godotObject)
         {
             try
             {
@@ -143,7 +142,7 @@ namespace Godot.Bridge
                     }
                 }
 
-                var obj = (GodotObject)FormatterServices.GetUninitializedObject(scriptType);
+                var obj = (GodotObject)RuntimeHelpers.GetUninitializedObject(scriptType);
 
                 var parameters = ctor.GetParameters();
                 int paramCount = parameters.Length;

+ 2 - 2
modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs

@@ -87,8 +87,8 @@ namespace Godot
 
             public void Resize(int size)
             {
-                if (size < 0)
-                    throw new ArgumentOutOfRangeException(nameof(size));
+                ArgumentOutOfRangeException.ThrowIfNegative(size);
+
                 var err = NativeFuncs.godotsharp_stack_info_vector_resize(ref this, size);
                 if (err != Error.Ok)
                     throw new InvalidOperationException("Failed to resize vector. Error code is: " + err.ToString());

+ 5 - 7
modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs

@@ -492,7 +492,7 @@ namespace Godot.Collections
         IReadOnlyDictionary<TKey, TValue>,
         IGenericGodotDictionary
     {
-        private static godot_variant ToVariantFunc(in Dictionary<TKey, TValue> godotDictionary) =>
+        private static godot_variant ToVariantFunc(scoped in Dictionary<TKey, TValue> godotDictionary) =>
             VariantUtils.CreateFromDictionary(godotDictionary);
 
         private static Dictionary<TKey, TValue> FromVariantFunc(in godot_variant variant) =>
@@ -521,8 +521,8 @@ namespace Godot.Collections
 
         static unsafe Dictionary()
         {
-            VariantUtils.GenericConversion<Dictionary<TKey, TValue>>.ToVariantCb = &ToVariantFunc;
-            VariantUtils.GenericConversion<Dictionary<TKey, TValue>>.FromVariantCb = &FromVariantFunc;
+            VariantUtils.GenericConversion<Dictionary<TKey, TValue>>.ToVariantCb = ToVariantFunc;
+            VariantUtils.GenericConversion<Dictionary<TKey, TValue>>.FromVariantCb = FromVariantFunc;
         }
 
         private readonly Dictionary _underlyingDict;
@@ -555,8 +555,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Dictionary.</returns>
         public Dictionary(IDictionary<TKey, TValue> dictionary)
         {
-            if (dictionary == null)
-                throw new ArgumentNullException(nameof(dictionary));
+            ArgumentNullException.ThrowIfNull(dictionary);
 
             _underlyingDict = new Dictionary();
             SetTypedForUnderlyingDictionary();
@@ -575,8 +574,7 @@ namespace Godot.Collections
         /// <returns>A new Godot Dictionary.</returns>
         public Dictionary(Dictionary dictionary)
         {
-            if (dictionary == null)
-                throw new ArgumentNullException(nameof(dictionary));
+            ArgumentNullException.ThrowIfNull(dictionary);
 
             _underlyingDict = dictionary;
         }

+ 1 - 2
modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.base.cs

@@ -90,8 +90,7 @@ namespace Godot
             // NativePtr is assigned, that would result in UB or crashes when calling
             // native functions that receive the pointer, which can happen because the
             // debugger calls ToString() and tries to get the value of properties.
-            if (instance._disposed || instance.NativePtr == IntPtr.Zero)
-                throw new ObjectDisposedException(instance.GetType().FullName);
+            ObjectDisposedException.ThrowIf(instance._disposed || instance.NativePtr == IntPtr.Zero, instance);
 
             return instance.NativePtr;
         }

+ 1 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/GodotTaskScheduler.cs

@@ -88,7 +88,7 @@ namespace Godot
 
                 lock (_tasks)
                 {
-                    if (_tasks.Any())
+                    if (_tasks.Count > 0)
                     {
                         task = _tasks.First.Value;
                         _tasks.RemoveFirst();

+ 12 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/InteropStructs.cs

@@ -173,7 +173,8 @@ namespace Godot.NativeInterop
         internal readonly unsafe godot_variant* GetUnsafeAddress()
             => (godot_variant*)Unsafe.AsPointer(ref Unsafe.AsRef(in _typeField));
 
-        // Variant.Type is generated as an enum of type long, so we can't use for the field as it must only take 32-bits. (the native enum actually has no fixed underlying type so it is only at least 6 bits long)
+        // Variant.Type is generated as an enum of type long, so we can't use for the field as it must only take 32-bits.
+        // The native enum actually has no fixed underlying type, so it is only at least 6 bits long.
         private int _typeField;
 
         // There's padding here
@@ -481,8 +482,10 @@ namespace Godot.NativeInterop
             Type = Variant.Type.Nil;
         }
 
+#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters
         [StructLayout(LayoutKind.Explicit)]
         internal struct movable
+#pragma warning restore CS8981
         {
             // Variant.Type is generated as an enum of type long, so we can't use for the field as it must only take 32-bits.
             [FieldOffset(0)] private int _typeField;
@@ -588,8 +591,10 @@ namespace Godot.NativeInterop
             return _data.GetHashCode();
         }
 
+#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters
         [StructLayout(LayoutKind.Sequential)]
         internal struct movable
+#pragma warning restore CS8981
         {
             private IntPtr _data;
 
@@ -634,8 +639,10 @@ namespace Godot.NativeInterop
             get => _data == IntPtr.Zero;
         }
 
+#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters
         [StructLayout(LayoutKind.Sequential)]
         internal struct movable
+#pragma warning restore CS8981
         {
             private IntPtr _data;
 
@@ -809,8 +816,10 @@ namespace Godot.NativeInterop
             _p = null;
         }
 
+#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters
         [StructLayout(LayoutKind.Sequential)]
         internal struct movable
+#pragma warning restore CS8981
         {
             private unsafe ArrayPrivate* _p;
 
@@ -876,8 +885,10 @@ namespace Godot.NativeInterop
             _p = null;
         }
 
+#pragma warning disable CS8981 // The type name only contains lower-cased ascii characters
         [StructLayout(LayoutKind.Sequential)]
         internal struct movable
+#pragma warning restore CS8981
         {
             private unsafe DictionaryPrivate* _p;
 

+ 26 - 31
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs

@@ -233,51 +233,51 @@ namespace Godot.NativeInterop
         public static partial void godotsharp_variant_new_packed_color_array(out godot_variant r_dest,
             scoped in godot_packed_color_array p_pca);
 
-        public static partial godot_bool godotsharp_variant_as_bool(in godot_variant p_self);
+        public static partial godot_bool godotsharp_variant_as_bool(scoped in godot_variant p_self);
 
-        public static partial Int64 godotsharp_variant_as_int(in godot_variant p_self);
+        public static partial Int64 godotsharp_variant_as_int(scoped in godot_variant p_self);
 
-        public static partial double godotsharp_variant_as_float(in godot_variant p_self);
+        public static partial double godotsharp_variant_as_float(scoped in godot_variant p_self);
 
         public static partial godot_string godotsharp_variant_as_string(scoped in godot_variant p_self);
 
-        public static partial Vector2 godotsharp_variant_as_vector2(in godot_variant p_self);
+        public static partial Vector2 godotsharp_variant_as_vector2(scoped in godot_variant p_self);
 
-        public static partial Vector2I godotsharp_variant_as_vector2i(in godot_variant p_self);
+        public static partial Vector2I godotsharp_variant_as_vector2i(scoped in godot_variant p_self);
 
-        public static partial Rect2 godotsharp_variant_as_rect2(in godot_variant p_self);
+        public static partial Rect2 godotsharp_variant_as_rect2(scoped in godot_variant p_self);
 
-        public static partial Rect2I godotsharp_variant_as_rect2i(in godot_variant p_self);
+        public static partial Rect2I godotsharp_variant_as_rect2i(scoped in godot_variant p_self);
 
-        public static partial Vector3 godotsharp_variant_as_vector3(in godot_variant p_self);
+        public static partial Vector3 godotsharp_variant_as_vector3(scoped in godot_variant p_self);
 
-        public static partial Vector3I godotsharp_variant_as_vector3i(in godot_variant p_self);
+        public static partial Vector3I godotsharp_variant_as_vector3i(scoped in godot_variant p_self);
 
-        public static partial Transform2D godotsharp_variant_as_transform2d(in godot_variant p_self);
+        public static partial Transform2D godotsharp_variant_as_transform2d(scoped in godot_variant p_self);
 
-        public static partial Vector4 godotsharp_variant_as_vector4(in godot_variant p_self);
+        public static partial Vector4 godotsharp_variant_as_vector4(scoped in godot_variant p_self);
 
-        public static partial Vector4I godotsharp_variant_as_vector4i(in godot_variant p_self);
+        public static partial Vector4I godotsharp_variant_as_vector4i(scoped in godot_variant p_self);
 
-        public static partial Plane godotsharp_variant_as_plane(in godot_variant p_self);
+        public static partial Plane godotsharp_variant_as_plane(scoped in godot_variant p_self);
 
-        public static partial Quaternion godotsharp_variant_as_quaternion(in godot_variant p_self);
+        public static partial Quaternion godotsharp_variant_as_quaternion(scoped in godot_variant p_self);
 
-        public static partial Aabb godotsharp_variant_as_aabb(in godot_variant p_self);
+        public static partial Aabb godotsharp_variant_as_aabb(scoped in godot_variant p_self);
 
-        public static partial Basis godotsharp_variant_as_basis(in godot_variant p_self);
+        public static partial Basis godotsharp_variant_as_basis(scoped in godot_variant p_self);
 
-        public static partial Transform3D godotsharp_variant_as_transform3d(in godot_variant p_self);
+        public static partial Transform3D godotsharp_variant_as_transform3d(scoped in godot_variant p_self);
 
-        public static partial Projection godotsharp_variant_as_projection(in godot_variant p_self);
+        public static partial Projection godotsharp_variant_as_projection(scoped in godot_variant p_self);
 
-        public static partial Color godotsharp_variant_as_color(in godot_variant p_self);
+        public static partial Color godotsharp_variant_as_color(scoped in godot_variant p_self);
 
         public static partial godot_string_name godotsharp_variant_as_string_name(scoped in godot_variant p_self);
 
         public static partial godot_node_path godotsharp_variant_as_node_path(scoped in godot_variant p_self);
 
-        public static partial Rid godotsharp_variant_as_rid(in godot_variant p_self);
+        public static partial Rid godotsharp_variant_as_rid(scoped in godot_variant p_self);
 
         public static partial godot_callable godotsharp_variant_as_callable(scoped in godot_variant p_self);
 
@@ -293,27 +293,22 @@ namespace Godot.NativeInterop
 
         public static partial godot_packed_int64_array godotsharp_variant_as_packed_int64_array(scoped in godot_variant p_self);
 
-        public static partial godot_packed_float32_array godotsharp_variant_as_packed_float32_array(
-            scoped in godot_variant p_self);
+        public static partial godot_packed_float32_array godotsharp_variant_as_packed_float32_array(scoped in godot_variant p_self);
 
-        public static partial godot_packed_float64_array godotsharp_variant_as_packed_float64_array(
-            scoped in godot_variant p_self);
+        public static partial godot_packed_float64_array godotsharp_variant_as_packed_float64_array(scoped in godot_variant p_self);
 
-        public static partial godot_packed_string_array godotsharp_variant_as_packed_string_array(
-            scoped in godot_variant p_self);
+        public static partial godot_packed_string_array godotsharp_variant_as_packed_string_array(scoped in godot_variant p_self);
 
-        public static partial godot_packed_vector2_array godotsharp_variant_as_packed_vector2_array(
-            scoped in godot_variant p_self);
+        public static partial godot_packed_vector2_array godotsharp_variant_as_packed_vector2_array(scoped in godot_variant p_self);
 
-        public static partial godot_packed_vector3_array godotsharp_variant_as_packed_vector3_array(
-            scoped in godot_variant p_self);
+        public static partial godot_packed_vector3_array godotsharp_variant_as_packed_vector3_array(scoped in godot_variant p_self);
 
         public static partial godot_packed_vector4_array godotsharp_variant_as_packed_vector4_array(
             in godot_variant p_self);
 
         public static partial godot_packed_color_array godotsharp_variant_as_packed_color_array(scoped in godot_variant p_self);
 
-        public static partial godot_bool godotsharp_variant_equals(in godot_variant p_a, in godot_variant p_b);
+        public static partial godot_bool godotsharp_variant_equals(scoped in godot_variant p_a, scoped in godot_variant p_b);
 
         // string.h
 

+ 18 - 3
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.cs

@@ -248,13 +248,28 @@ namespace Godot.NativeInterop
         }
 
         public static godot_variant CreateFromSystemArrayOfStringName(scoped Span<StringName> from)
-            => CreateFromArray(new Collections.Array(from));
+        {
+            if (from == null)
+                return default;
+            using var fromGodot = new Collections.Array(from);
+            return CreateFromArray((godot_array)fromGodot.NativeValue);
+        }
 
         public static godot_variant CreateFromSystemArrayOfNodePath(scoped Span<NodePath> from)
-            => CreateFromArray(new Collections.Array(from));
+        {
+            if (from == null)
+                return default;
+            using var fromGodot = new Collections.Array(from);
+            return CreateFromArray((godot_array)fromGodot.NativeValue);
+        }
 
         public static godot_variant CreateFromSystemArrayOfRid(scoped Span<Rid> from)
-            => CreateFromArray(new Collections.Array(from));
+        {
+            if (from == null)
+                return default;
+            using var fromGodot = new Collections.Array(from);
+            return CreateFromArray((godot_array)fromGodot.NativeValue);
+        }
 
         public static godot_variant CreateFromSystemArrayOfGodotObject(GodotObject[]? from)
         {

+ 9 - 10
modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/VariantUtils.generic.cs

@@ -7,24 +7,23 @@ namespace Godot.NativeInterop;
 
 public partial class VariantUtils
 {
-    private static Exception UnsupportedType<T>() => new InvalidOperationException(
+    private static InvalidOperationException UnsupportedType<T>() => new InvalidOperationException(
         $"The type is not supported for conversion to/from Variant: '{typeof(T).FullName}'");
 
     internal static class GenericConversion<T>
     {
+        internal delegate godot_variant ToVariantConverter(scoped in T from);
+        internal delegate T FromVariantConverter(in godot_variant from);
+
         public static unsafe godot_variant ToVariant(scoped in T from) =>
-#pragma warning disable CS9088 // the delegate pointer cannot be marked scoped, but it should be
-            ToVariantCb != null ? ToVariantCb(from) : throw UnsupportedType<T>();
-#pragma warning restore CS9088
+             ToVariantCb != null ? ToVariantCb(from) : throw UnsupportedType<T>();
 
         public static unsafe T FromVariant(in godot_variant variant) =>
             FromVariantCb != null ? FromVariantCb(variant) : throw UnsupportedType<T>();
 
-        // ReSharper disable once StaticMemberInGenericType
-        internal static unsafe delegate*<in T, godot_variant> ToVariantCb;
+        internal static ToVariantConverter? ToVariantCb;
 
-        // ReSharper disable once StaticMemberInGenericType
-        internal static unsafe delegate*<in godot_variant, T> FromVariantCb;
+        internal static FromVariantConverter? FromVariantCb;
 
         static GenericConversion()
         {
@@ -36,7 +35,7 @@ public partial class VariantUtils
     public static godot_variant CreateFrom<[MustBeVariant] T>(scoped in T from)
     {
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        static TTo UnsafeAs<TTo>(in T f) => Unsafe.As<T, TTo>(ref Unsafe.AsRef(f));
+        static TTo UnsafeAs<TTo>(in T f) => Unsafe.As<T, TTo>(ref Unsafe.AsRef(in f));
 
         // `typeof(T) == typeof(X)` is optimized away. We cannot cache `typeof(T)` in a local variable, as it's not optimized when done like that.
 
@@ -229,7 +228,7 @@ public partial class VariantUtils
     public static T ConvertTo<[MustBeVariant] T>(in godot_variant variant)
     {
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        static T UnsafeAsT<TFrom>(TFrom f) => Unsafe.As<TFrom, T>(ref Unsafe.AsRef(f));
+        static T UnsafeAsT<TFrom>(TFrom f) => Unsafe.As<TFrom, T>(ref Unsafe.AsRef(in f));
 
         if (typeof(T) == typeof(bool))
             return UnsafeAsT(ConvertToBool(variant));

+ 1 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs

@@ -1581,7 +1581,7 @@ namespace Godot
                 if (end < 0)
                     end = len;
                 if (allowEmpty || end > from)
-                    ret.Add(float.Parse(instance.Substring(from), CultureInfo.InvariantCulture));
+                    ret.Add(float.Parse(instance.AsSpan(from), CultureInfo.InvariantCulture));
                 if (end == len)
                     break;
 

+ 11 - 2
modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj

@@ -1,17 +1,19 @@
 <Project Sdk="Microsoft.NET.Sdk">
+
   <PropertyGroup>
     <ProjectGuid>{AEBF0036-DA76-4341-B651-A3F2856AB2FA}</ProjectGuid>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
     <OutputPath>bin/$(Configuration)</OutputPath>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
     <RootNamespace>Godot</RootNamespace>
-    <TargetFramework>net7.0</TargetFramework>
     <DocumentationFile>$(OutputPath)/$(AssemblyName).xml</DocumentationFile>
     <EnableDefaultItems>false</EnableDefaultItems>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <LangVersion>11</LangVersion>
 
     <AnalysisMode>Recommended</AnalysisMode>
   </PropertyGroup>
+
   <PropertyGroup>
     <Description>Godot C# Core API.</Description>
     <Authors>Godot Engine contributors</Authors>
@@ -28,23 +30,28 @@
     <IncludeSymbols>true</IncludeSymbols>
     <SymbolPackageFormat>snupkg</SymbolPackageFormat>
   </PropertyGroup>
+
   <ItemGroup>
     <!-- SdkPackageVersions.props for easy access -->
     <None Include="$(GodotSdkPackageVersionsFilePath)">
       <Link>SdkPackageVersions.props</Link>
     </None>
   </ItemGroup>
+
   <PropertyGroup>
     <DefineConstants>$(DefineConstants);GODOT</DefineConstants>
     <DefineConstants Condition=" '$(GodotFloat64)' == 'true' ">REAL_T_IS_DOUBLE;$(DefineConstants)</DefineConstants>
   </PropertyGroup>
+
   <ItemGroup>
     <PackageReference Include="ReflectionAnalyzers" Version="0.1.22-dev" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" />
     <!--PackageReference Include="IDisposableAnalyzers" Version="3.4.13" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" /-->
   </ItemGroup>
+
   <ItemGroup>
     <ProjectReference Include="..\Godot.SourceGenerators.Internal\Godot.SourceGenerators.Internal.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
   </ItemGroup>
+
   <!-- Sources -->
   <ItemGroup>
     <Compile Include="Core\Aabb.cs" />
@@ -135,10 +142,12 @@
     <Compile Include="GlobalUsings.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+
   <!-- Compat Sources -->
   <ItemGroup Condition=" '$(GodotNoDeprecated)' == '' ">
     <Compile Include="Compat.cs" />
   </ItemGroup>
+
   <!--
   We import a props file with auto-generated includes. This works well with Rider.
   However, Visual Studio and MonoDevelop won't list them in the solution explorer.

+ 2 - 2
modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj

@@ -1,14 +1,14 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <ProjectGuid>{8FBEC238-D944-4074-8548-B3B524305905}</ProjectGuid>
+    <TargetFramework>net8.0</TargetFramework>
+    <LangVersion>12</LangVersion>
     <OutputPath>bin/$(Configuration)</OutputPath>
     <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
     <RootNamespace>Godot</RootNamespace>
-    <TargetFramework>net7.0</TargetFramework>
     <DocumentationFile>$(OutputPath)/$(AssemblyName).xml</DocumentationFile>
     <EnableDefaultItems>false</EnableDefaultItems>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <LangVersion>10</LangVersion>
   </PropertyGroup>
   <PropertyGroup>
     <Description>Godot C# Editor API.</Description>