소스 검색

Merge pull request #85908 from avilches/fix-must-be-variant-analyzer-fail-with-generic-typed-attributes

Allow using `[MustBeVariant]` in generic typed attributes
Rémi Verschelde 1 년 전
부모
커밋
849b69828b

+ 492 - 2
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Sample/MustBeVariantSamples.cs

@@ -131,8 +131,253 @@ public class ClassWithGenericVariant<[MustBeVariant] T>
 
 public class MustBeVariantAnnotatedMethods
 {
+    [GenericTypeAttribute<bool>()]
+    public void MethodWithAttributeBool()
+    {
+    }
+
+    [GenericTypeAttribute<char>()]
+    public void MethodWithAttributeChar()
+    {
+    }
+
+    [GenericTypeAttribute<sbyte>()]
+    public void MethodWithAttributeSByte()
+    {
+    }
+
+    [GenericTypeAttribute<byte>()]
+    public void MethodWithAttributeByte()
+    {
+    }
+
+    [GenericTypeAttribute<short>()]
+    public void MethodWithAttributeInt16()
+    {
+    }
+
+    [GenericTypeAttribute<ushort>()]
+    public void MethodWithAttributeUInt16()
+    {
+    }
+
+    [GenericTypeAttribute<int>()]
+    public void MethodWithAttributeInt32()
+    {
+    }
+
+    [GenericTypeAttribute<uint>()]
+    public void MethodWithAttributeUInt32()
+    {
+    }
+
+    [GenericTypeAttribute<long>()]
+    public void MethodWithAttributeInt64()
+    {
+    }
+
+    [GenericTypeAttribute<ulong>()]
+    public void MethodWithAttributeUInt64()
+    {
+    }
+
+    [GenericTypeAttribute<float>()]
+    public void MethodWithAttributeSingle()
+    {
+    }
+
+    [GenericTypeAttribute<double>()]
+    public void MethodWithAttributeDouble()
+    {
+    }
+
     [GenericTypeAttribute<string>()]
-    public void MethodWithAttributeOk()
+    public void MethodWithAttributeString()
+    {
+    }
+
+    [GenericTypeAttribute<Vector2>()]
+    public void MethodWithAttributeVector2()
+    {
+    }
+
+    [GenericTypeAttribute<Vector2I>()]
+    public void MethodWithAttributeVector2I()
+    {
+    }
+
+    [GenericTypeAttribute<Rect2>()]
+    public void MethodWithAttributeRect2()
+    {
+    }
+
+    [GenericTypeAttribute<Rect2I>()]
+    public void MethodWithAttributeRect2I()
+    {
+    }
+
+    [GenericTypeAttribute<Transform2D>()]
+    public void MethodWithAttributeTransform2D()
+    {
+    }
+
+    [GenericTypeAttribute<Vector3>()]
+    public void MethodWithAttributeVector3()
+    {
+    }
+
+    [GenericTypeAttribute<Vector3I>()]
+    public void MethodWithAttributeVector3I()
+    {
+    }
+
+    [GenericTypeAttribute<Vector4>()]
+    public void MethodWithAttributeVector4()
+    {
+    }
+
+    [GenericTypeAttribute<Vector4I>()]
+    public void MethodWithAttributeVector4I()
+    {
+    }
+
+    [GenericTypeAttribute<Basis>()]
+    public void MethodWithAttributeBasis()
+    {
+    }
+
+    [GenericTypeAttribute<Quaternion>()]
+    public void MethodWithAttributeQuaternion()
+    {
+    }
+
+    [GenericTypeAttribute<Transform3D>()]
+    public void MethodWithAttributeTransform3D()
+    {
+    }
+
+    [GenericTypeAttribute<Projection>()]
+    public void MethodWithAttributeProjection()
+    {
+    }
+
+    [GenericTypeAttribute<Aabb>()]
+    public void MethodWithAttributeAabb()
+    {
+    }
+
+    [GenericTypeAttribute<Color>()]
+    public void MethodWithAttributeColor()
+    {
+    }
+
+    [GenericTypeAttribute<Plane>()]
+    public void MethodWithAttributePlane()
+    {
+    }
+
+    [GenericTypeAttribute<Callable>()]
+    public void MethodWithAttributeCallable()
+    {
+    }
+
+    [GenericTypeAttribute<Signal>()]
+    public void MethodWithAttributeSignal()
+    {
+    }
+
+    [GenericTypeAttribute<GodotObject>()]
+    public void MethodWithAttributeGodotObject()
+    {
+    }
+
+    [GenericTypeAttribute<StringName>()]
+    public void MethodWithAttributeStringName()
+    {
+    }
+
+    [GenericTypeAttribute<NodePath>()]
+    public void MethodWithAttributeNodePath()
+    {
+    }
+
+    [GenericTypeAttribute<Rid>()]
+    public void MethodWithAttributeRid()
+    {
+    }
+
+    [GenericTypeAttribute<Dictionary>()]
+    public void MethodWithAttributeDictionary()
+    {
+    }
+
+    [GenericTypeAttribute<Array>()]
+    public void MethodWithAttributeArray()
+    {
+    }
+
+    [GenericTypeAttribute<byte[]>()]
+    public void MethodWithAttributeByteArray()
+    {
+    }
+
+    [GenericTypeAttribute<int[]>()]
+    public void MethodWithAttributeInt32Array()
+    {
+    }
+
+    [GenericTypeAttribute<long[]>()]
+    public void MethodWithAttributeInt64Array()
+    {
+    }
+
+    [GenericTypeAttribute<float[]>()]
+    public void MethodWithAttributeSingleArray()
+    {
+    }
+
+    [GenericTypeAttribute<double[]>()]
+    public void MethodWithAttributeDoubleArray()
+    {
+    }
+
+    [GenericTypeAttribute<string[]>()]
+    public void MethodWithAttributeStringArray()
+    {
+    }
+
+    [GenericTypeAttribute<Vector2[]>()]
+    public void MethodWithAttributeVector2Array()
+    {
+    }
+
+    [GenericTypeAttribute<Vector3[]>()]
+    public void MethodWithAttributeVector3Array()
+    {
+    }
+
+    [GenericTypeAttribute<Color[]>()]
+    public void MethodWithAttributeColorArray()
+    {
+    }
+
+    [GenericTypeAttribute<GodotObject[]>()]
+    public void MethodWithAttributeGodotObjectArray()
+    {
+    }
+
+    [GenericTypeAttribute<StringName[]>()]
+    public void MethodWithAttributeStringNameArray()
+    {
+    }
+
+    [GenericTypeAttribute<NodePath[]>()]
+    public void MethodWithAttributeNodePathArray()
+    {
+    }
+
+    [GenericTypeAttribute<Rid[]>()]
+    public void MethodWithAttributeRidArray()
     {
     }
 
@@ -145,8 +390,253 @@ public class MustBeVariantAnnotatedMethods
     */
 }
 
+[GenericTypeAttribute<bool>()]
+public class ClassVariantAnnotatedBool
+{
+}
+
+[GenericTypeAttribute<char>()]
+public class ClassVariantAnnotatedChar
+{
+}
+
+[GenericTypeAttribute<sbyte>()]
+public class ClassVariantAnnotatedSByte
+{
+}
+
+[GenericTypeAttribute<byte>()]
+public class ClassVariantAnnotatedByte
+{
+}
+
+[GenericTypeAttribute<short>()]
+public class ClassVariantAnnotatedInt16
+{
+}
+
+[GenericTypeAttribute<ushort>()]
+public class ClassVariantAnnotatedUInt16
+{
+}
+
+[GenericTypeAttribute<int>()]
+public class ClassVariantAnnotatedInt32
+{
+}
+
+[GenericTypeAttribute<uint>()]
+public class ClassVariantAnnotatedUInt32
+{
+}
+
+[GenericTypeAttribute<long>()]
+public class ClassVariantAnnotatedInt64
+{
+}
+
+[GenericTypeAttribute<ulong>()]
+public class ClassVariantAnnotatedUInt64
+{
+}
+
+[GenericTypeAttribute<float>()]
+public class ClassVariantAnnotatedSingle
+{
+}
+
+[GenericTypeAttribute<double>()]
+public class ClassVariantAnnotatedDouble
+{
+}
+
 [GenericTypeAttribute<string>()]
-public class ClassVariantAnnotated
+public class ClassVariantAnnotatedString
+{
+}
+
+[GenericTypeAttribute<Vector2>()]
+public class ClassVariantAnnotatedVector2
+{
+}
+
+[GenericTypeAttribute<Vector2I>()]
+public class ClassVariantAnnotatedVector2I
+{
+}
+
+[GenericTypeAttribute<Rect2>()]
+public class ClassVariantAnnotatedRect2
+{
+}
+
+[GenericTypeAttribute<Rect2I>()]
+public class ClassVariantAnnotatedRect2I
+{
+}
+
+[GenericTypeAttribute<Transform2D>()]
+public class ClassVariantAnnotatedTransform2D
+{
+}
+
+[GenericTypeAttribute<Vector3>()]
+public class ClassVariantAnnotatedVector3
+{
+}
+
+[GenericTypeAttribute<Vector3I>()]
+public class ClassVariantAnnotatedVector3I
+{
+}
+
+[GenericTypeAttribute<Vector4>()]
+public class ClassVariantAnnotatedVector4
+{
+}
+
+[GenericTypeAttribute<Vector4I>()]
+public class ClassVariantAnnotatedVector4I
+{
+}
+
+[GenericTypeAttribute<Basis>()]
+public class ClassVariantAnnotatedBasis
+{
+}
+
+[GenericTypeAttribute<Quaternion>()]
+public class ClassVariantAnnotatedQuaternion
+{
+}
+
+[GenericTypeAttribute<Transform3D>()]
+public class ClassVariantAnnotatedTransform3D
+{
+}
+
+[GenericTypeAttribute<Projection>()]
+public class ClassVariantAnnotatedProjection
+{
+}
+
+[GenericTypeAttribute<Aabb>()]
+public class ClassVariantAnnotatedAabb
+{
+}
+
+[GenericTypeAttribute<Color>()]
+public class ClassVariantAnnotatedColor
+{
+}
+
+[GenericTypeAttribute<Plane>()]
+public class ClassVariantAnnotatedPlane
+{
+}
+
+[GenericTypeAttribute<Callable>()]
+public class ClassVariantAnnotatedCallable
+{
+}
+
+[GenericTypeAttribute<Signal>()]
+public class ClassVariantAnnotatedSignal
+{
+}
+
+[GenericTypeAttribute<GodotObject>()]
+public class ClassVariantAnnotatedGodotObject
+{
+}
+
+[GenericTypeAttribute<StringName>()]
+public class ClassVariantAnnotatedStringName
+{
+}
+
+[GenericTypeAttribute<NodePath>()]
+public class ClassVariantAnnotatedNodePath
+{
+}
+
+[GenericTypeAttribute<Rid>()]
+public class ClassVariantAnnotatedRid
+{
+}
+
+[GenericTypeAttribute<Dictionary>()]
+public class ClassVariantAnnotatedDictionary
+{
+}
+
+[GenericTypeAttribute<Array>()]
+public class ClassVariantAnnotatedArray
+{
+}
+
+[GenericTypeAttribute<byte[]>()]
+public class ClassVariantAnnotatedByteArray
+{
+}
+
+[GenericTypeAttribute<int[]>()]
+public class ClassVariantAnnotatedInt32Array
+{
+}
+
+[GenericTypeAttribute<long[]>()]
+public class ClassVariantAnnotatedInt64Array
+{
+}
+
+[GenericTypeAttribute<float[]>()]
+public class ClassVariantAnnotatedSingleArray
+{
+}
+
+[GenericTypeAttribute<double[]>()]
+public class ClassVariantAnnotatedDoubleArray
+{
+}
+
+[GenericTypeAttribute<string[]>()]
+public class ClassVariantAnnotatedStringArray
+{
+}
+
+[GenericTypeAttribute<Vector2[]>()]
+public class ClassVariantAnnotatedVector2Array
+{
+}
+
+[GenericTypeAttribute<Vector3[]>()]
+public class ClassVariantAnnotatedVector3Array
+{
+}
+
+[GenericTypeAttribute<Color[]>()]
+public class ClassVariantAnnotatedColorArray
+{
+}
+
+[GenericTypeAttribute<GodotObject[]>()]
+public class ClassVariantAnnotatedGodotObjectArray
+{
+}
+
+[GenericTypeAttribute<StringName[]>()]
+public class ClassVariantAnnotatedStringNameArray
+{
+}
+
+[GenericTypeAttribute<NodePath[]>()]
+public class ClassVariantAnnotatedNodePathArray
+{
+}
+
+[GenericTypeAttribute<Rid[]>()]
+public class ClassVariantAnnotatedRidArray
 {
 }
 

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

@@ -3,6 +3,7 @@ using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.CSharp.Testing;
 using Microsoft.CodeAnalysis.Diagnostics;
 using Microsoft.CodeAnalysis.Testing;
@@ -12,8 +13,10 @@ using Microsoft.CodeAnalysis.Text;
 namespace Godot.SourceGenerators.Tests;
 
 public static class CSharpAnalyzerVerifier<TAnalyzer>
-where TAnalyzer : DiagnosticAnalyzer, new()
+    where TAnalyzer : DiagnosticAnalyzer, new()
 {
+    public const LanguageVersion LangVersion = LanguageVersion.CSharp11;
+
     public class Test : CSharpAnalyzerTest<TAnalyzer, XUnitVerifier>
     {
         public Test()
@@ -24,7 +27,7 @@ where TAnalyzer : DiagnosticAnalyzer, new()
             {
                 Project project =
                     solution.GetProject(projectId)!.AddMetadataReference(Constants.GodotSharpAssembly
-                        .CreateMetadataReference());
+                        .CreateMetadataReference()).WithParseOptions(new CSharpParseOptions(LangVersion));
 
                 return project.Solution;
             });

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

@@ -15,6 +15,7 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.0" />
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit" Version="1.1.1" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
     <PackageReference Include="Microsoft.CodeAnalysis.Testing.Verifiers.XUnit" Version="1.1.1" />

+ 582 - 0
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/MustBeVariant.GD0301.cs

@@ -10,6 +10,7 @@ public class MustBeVariantGD0301
         // This raises a GD0301 diagnostic error: object is not Variant (and Method<T> requires a variant generic type).
         Method<{|GD0301:object|}>();
     }
+    
     public void MethodCallsOk()
     {
         // All these calls are valid because they are Variant types.
@@ -68,4 +69,585 @@ public class MustBeVariantGD0301
     public void Method<[MustBeVariant] T>()
     {
     }
+    
+    public void MustBeVariantClasses()
+    {
+        new ClassWithGenericVariant<bool>();
+        new ClassWithGenericVariant<char>();
+        new ClassWithGenericVariant<sbyte>();
+        new ClassWithGenericVariant<byte>();
+        new ClassWithGenericVariant<short>();
+        new ClassWithGenericVariant<ushort>();
+        new ClassWithGenericVariant<int>();
+        new ClassWithGenericVariant<uint>();
+        new ClassWithGenericVariant<long>();
+        new ClassWithGenericVariant<ulong>();
+        new ClassWithGenericVariant<float>();
+        new ClassWithGenericVariant<double>();
+        new ClassWithGenericVariant<string>();
+        new ClassWithGenericVariant<Vector2>();
+        new ClassWithGenericVariant<Vector2I>();
+        new ClassWithGenericVariant<Rect2>();
+        new ClassWithGenericVariant<Rect2I>();
+        new ClassWithGenericVariant<Transform2D>();
+        new ClassWithGenericVariant<Vector3>();
+        new ClassWithGenericVariant<Vector3I>();
+        new ClassWithGenericVariant<Vector4>();
+        new ClassWithGenericVariant<Vector4I>();
+        new ClassWithGenericVariant<Basis>();
+        new ClassWithGenericVariant<Quaternion>();
+        new ClassWithGenericVariant<Transform3D>();
+        new ClassWithGenericVariant<Projection>();
+        new ClassWithGenericVariant<Aabb>();
+        new ClassWithGenericVariant<Color>();
+        new ClassWithGenericVariant<Plane>();
+        new ClassWithGenericVariant<Callable>();
+        new ClassWithGenericVariant<Signal>();
+        new ClassWithGenericVariant<GodotObject>();
+        new ClassWithGenericVariant<StringName>();
+        new ClassWithGenericVariant<NodePath>();
+        new ClassWithGenericVariant<Rid>();
+        new ClassWithGenericVariant<Dictionary>();
+        new ClassWithGenericVariant<Array>();
+        new ClassWithGenericVariant<byte[]>();
+        new ClassWithGenericVariant<int[]>();
+        new ClassWithGenericVariant<long[]>();
+        new ClassWithGenericVariant<float[]>();
+        new ClassWithGenericVariant<double[]>();
+        new ClassWithGenericVariant<string[]>();
+        new ClassWithGenericVariant<Vector2[]>();
+        new ClassWithGenericVariant<Vector3[]>();
+        new ClassWithGenericVariant<Color[]>();
+        new ClassWithGenericVariant<GodotObject[]>();
+        new ClassWithGenericVariant<StringName[]>();
+        new ClassWithGenericVariant<NodePath[]>();
+        new ClassWithGenericVariant<Rid[]>();
+
+        // This class fails because generic type is not Variant-compatible.
+        new ClassWithGenericVariant<{|GD0301:object|}>();
+    }
+}
+
+public class ClassWithGenericVariant<[MustBeVariant] T>
+{
+}
+
+public class MustBeVariantAnnotatedMethods
+{
+    [GenericTypeAttribute<bool>()]
+    public void MethodWithAttributeBool()
+    {
+    }
+
+    [GenericTypeAttribute<char>()]
+    public void MethodWithAttributeChar()
+    {
+    }
+
+    [GenericTypeAttribute<sbyte>()]
+    public void MethodWithAttributeSByte()
+    {
+    }
+
+    [GenericTypeAttribute<byte>()]
+    public void MethodWithAttributeByte()
+    {
+    }
+
+    [GenericTypeAttribute<short>()]
+    public void MethodWithAttributeInt16()
+    {
+    }
+
+    [GenericTypeAttribute<ushort>()]
+    public void MethodWithAttributeUInt16()
+    {
+    }
+
+    [GenericTypeAttribute<int>()]
+    public void MethodWithAttributeInt32()
+    {
+    }
+
+    [GenericTypeAttribute<uint>()]
+    public void MethodWithAttributeUInt32()
+    {
+    }
+
+    [GenericTypeAttribute<long>()]
+    public void MethodWithAttributeInt64()
+    {
+    }
+
+    [GenericTypeAttribute<ulong>()]
+    public void MethodWithAttributeUInt64()
+    {
+    }
+
+    [GenericTypeAttribute<float>()]
+    public void MethodWithAttributeSingle()
+    {
+    }
+
+    [GenericTypeAttribute<double>()]
+    public void MethodWithAttributeDouble()
+    {
+    }
+
+    [GenericTypeAttribute<string>()]
+    public void MethodWithAttributeString()
+    {
+    }
+
+    [GenericTypeAttribute<Vector2>()]
+    public void MethodWithAttributeVector2()
+    {
+    }
+
+    [GenericTypeAttribute<Vector2I>()]
+    public void MethodWithAttributeVector2I()
+    {
+    }
+
+    [GenericTypeAttribute<Rect2>()]
+    public void MethodWithAttributeRect2()
+    {
+    }
+
+    [GenericTypeAttribute<Rect2I>()]
+    public void MethodWithAttributeRect2I()
+    {
+    }
+
+    [GenericTypeAttribute<Transform2D>()]
+    public void MethodWithAttributeTransform2D()
+    {
+    }
+
+    [GenericTypeAttribute<Vector3>()]
+    public void MethodWithAttributeVector3()
+    {
+    }
+
+    [GenericTypeAttribute<Vector3I>()]
+    public void MethodWithAttributeVector3I()
+    {
+    }
+
+    [GenericTypeAttribute<Vector4>()]
+    public void MethodWithAttributeVector4()
+    {
+    }
+
+    [GenericTypeAttribute<Vector4I>()]
+    public void MethodWithAttributeVector4I()
+    {
+    }
+
+    [GenericTypeAttribute<Basis>()]
+    public void MethodWithAttributeBasis()
+    {
+    }
+
+    [GenericTypeAttribute<Quaternion>()]
+    public void MethodWithAttributeQuaternion()
+    {
+    }
+
+    [GenericTypeAttribute<Transform3D>()]
+    public void MethodWithAttributeTransform3D()
+    {
+    }
+
+    [GenericTypeAttribute<Projection>()]
+    public void MethodWithAttributeProjection()
+    {
+    }
+
+    [GenericTypeAttribute<Aabb>()]
+    public void MethodWithAttributeAabb()
+    {
+    }
+
+    [GenericTypeAttribute<Color>()]
+    public void MethodWithAttributeColor()
+    {
+    }
+
+    [GenericTypeAttribute<Plane>()]
+    public void MethodWithAttributePlane()
+    {
+    }
+
+    [GenericTypeAttribute<Callable>()]
+    public void MethodWithAttributeCallable()
+    {
+    }
+
+    [GenericTypeAttribute<Signal>()]
+    public void MethodWithAttributeSignal()
+    {
+    }
+
+    [GenericTypeAttribute<GodotObject>()]
+    public void MethodWithAttributeGodotObject()
+    {
+    }
+
+    [GenericTypeAttribute<StringName>()]
+    public void MethodWithAttributeStringName()
+    {
+    }
+
+    [GenericTypeAttribute<NodePath>()]
+    public void MethodWithAttributeNodePath()
+    {
+    }
+
+    [GenericTypeAttribute<Rid>()]
+    public void MethodWithAttributeRid()
+    {
+    }
+
+    [GenericTypeAttribute<Dictionary>()]
+    public void MethodWithAttributeDictionary()
+    {
+    }
+
+    [GenericTypeAttribute<Array>()]
+    public void MethodWithAttributeArray()
+    {
+    }
+
+    [GenericTypeAttribute<byte[]>()]
+    public void MethodWithAttributeByteArray()
+    {
+    }
+
+    [GenericTypeAttribute<int[]>()]
+    public void MethodWithAttributeInt32Array()
+    {
+    }
+
+    [GenericTypeAttribute<long[]>()]
+    public void MethodWithAttributeInt64Array()
+    {
+    }
+
+    [GenericTypeAttribute<float[]>()]
+    public void MethodWithAttributeSingleArray()
+    {
+    }
+
+    [GenericTypeAttribute<double[]>()]
+    public void MethodWithAttributeDoubleArray()
+    {
+    }
+
+    [GenericTypeAttribute<string[]>()]
+    public void MethodWithAttributeStringArray()
+    {
+    }
+
+    [GenericTypeAttribute<Vector2[]>()]
+    public void MethodWithAttributeVector2Array()
+    {
+    }
+
+    [GenericTypeAttribute<Vector3[]>()]
+    public void MethodWithAttributeVector3Array()
+    {
+    }
+
+    [GenericTypeAttribute<Color[]>()]
+    public void MethodWithAttributeColorArray()
+    {
+    }
+
+    [GenericTypeAttribute<GodotObject[]>()]
+    public void MethodWithAttributeGodotObjectArray()
+    {
+    }
+
+    [GenericTypeAttribute<StringName[]>()]
+    public void MethodWithAttributeStringNameArray()
+    {
+    }
+
+    [GenericTypeAttribute<NodePath[]>()]
+    public void MethodWithAttributeNodePathArray()
+    {
+    }
+
+    [GenericTypeAttribute<Rid[]>()]
+    public void MethodWithAttributeRidArray()
+    {
+    }
+
+    // This method definition fails because generic type is not Variant-compatible.
+    [GenericTypeAttribute<{|GD0301:object|}>()]
+    public void MethodWithWrongAttribute()
+    {
+    }
+}
+
+[GenericTypeAttribute<bool>()]
+public class ClassVariantAnnotatedBool
+{
+}
+
+[GenericTypeAttribute<char>()]
+public class ClassVariantAnnotatedChar
+{
+}
+
+[GenericTypeAttribute<sbyte>()]
+public class ClassVariantAnnotatedSByte
+{
+}
+
+[GenericTypeAttribute<byte>()]
+public class ClassVariantAnnotatedByte
+{
+}
+
+[GenericTypeAttribute<short>()]
+public class ClassVariantAnnotatedInt16
+{
+}
+
+[GenericTypeAttribute<ushort>()]
+public class ClassVariantAnnotatedUInt16
+{
+}
+
+[GenericTypeAttribute<int>()]
+public class ClassVariantAnnotatedInt32
+{
+}
+
+[GenericTypeAttribute<uint>()]
+public class ClassVariantAnnotatedUInt32
+{
+}
+
+[GenericTypeAttribute<long>()]
+public class ClassVariantAnnotatedInt64
+{
+}
+
+[GenericTypeAttribute<ulong>()]
+public class ClassVariantAnnotatedUInt64
+{
+}
+
+[GenericTypeAttribute<float>()]
+public class ClassVariantAnnotatedSingle
+{
+}
+
+[GenericTypeAttribute<double>()]
+public class ClassVariantAnnotatedDouble
+{
+}
+
+[GenericTypeAttribute<string>()]
+public class ClassVariantAnnotatedString
+{
+}
+
+[GenericTypeAttribute<Vector2>()]
+public class ClassVariantAnnotatedVector2
+{
+}
+
+[GenericTypeAttribute<Vector2I>()]
+public class ClassVariantAnnotatedVector2I
+{
+}
+
+[GenericTypeAttribute<Rect2>()]
+public class ClassVariantAnnotatedRect2
+{
+}
+
+[GenericTypeAttribute<Rect2I>()]
+public class ClassVariantAnnotatedRect2I
+{
+}
+
+[GenericTypeAttribute<Transform2D>()]
+public class ClassVariantAnnotatedTransform2D
+{
+}
+
+[GenericTypeAttribute<Vector3>()]
+public class ClassVariantAnnotatedVector3
+{
+}
+
+[GenericTypeAttribute<Vector3I>()]
+public class ClassVariantAnnotatedVector3I
+{
+}
+
+[GenericTypeAttribute<Vector4>()]
+public class ClassVariantAnnotatedVector4
+{
+}
+
+[GenericTypeAttribute<Vector4I>()]
+public class ClassVariantAnnotatedVector4I
+{
+}
+
+[GenericTypeAttribute<Basis>()]
+public class ClassVariantAnnotatedBasis
+{
+}
+
+[GenericTypeAttribute<Quaternion>()]
+public class ClassVariantAnnotatedQuaternion
+{
+}
+
+[GenericTypeAttribute<Transform3D>()]
+public class ClassVariantAnnotatedTransform3D
+{
+}
+
+[GenericTypeAttribute<Projection>()]
+public class ClassVariantAnnotatedProjection
+{
+}
+
+[GenericTypeAttribute<Aabb>()]
+public class ClassVariantAnnotatedAabb
+{
+}
+
+[GenericTypeAttribute<Color>()]
+public class ClassVariantAnnotatedColor
+{
+}
+
+[GenericTypeAttribute<Plane>()]
+public class ClassVariantAnnotatedPlane
+{
+}
+
+[GenericTypeAttribute<Callable>()]
+public class ClassVariantAnnotatedCallable
+{
+}
+
+[GenericTypeAttribute<Signal>()]
+public class ClassVariantAnnotatedSignal
+{
+}
+
+[GenericTypeAttribute<GodotObject>()]
+public class ClassVariantAnnotatedGodotObject
+{
+}
+
+[GenericTypeAttribute<StringName>()]
+public class ClassVariantAnnotatedStringName
+{
+}
+
+[GenericTypeAttribute<NodePath>()]
+public class ClassVariantAnnotatedNodePath
+{
+}
+
+[GenericTypeAttribute<Rid>()]
+public class ClassVariantAnnotatedRid
+{
+}
+
+[GenericTypeAttribute<Dictionary>()]
+public class ClassVariantAnnotatedDictionary
+{
+}
+
+[GenericTypeAttribute<Array>()]
+public class ClassVariantAnnotatedArray
+{
+}
+
+[GenericTypeAttribute<byte[]>()]
+public class ClassVariantAnnotatedByteArray
+{
+}
+
+[GenericTypeAttribute<int[]>()]
+public class ClassVariantAnnotatedInt32Array
+{
+}
+
+[GenericTypeAttribute<long[]>()]
+public class ClassVariantAnnotatedInt64Array
+{
+}
+
+[GenericTypeAttribute<float[]>()]
+public class ClassVariantAnnotatedSingleArray
+{
+}
+
+[GenericTypeAttribute<double[]>()]
+public class ClassVariantAnnotatedDoubleArray
+{
+}
+
+[GenericTypeAttribute<string[]>()]
+public class ClassVariantAnnotatedStringArray
+{
+}
+
+[GenericTypeAttribute<Vector2[]>()]
+public class ClassVariantAnnotatedVector2Array
+{
+}
+
+[GenericTypeAttribute<Vector3[]>()]
+public class ClassVariantAnnotatedVector3Array
+{
+}
+
+[GenericTypeAttribute<Color[]>()]
+public class ClassVariantAnnotatedColorArray
+{
+}
+
+[GenericTypeAttribute<GodotObject[]>()]
+public class ClassVariantAnnotatedGodotObjectArray
+{
+}
+
+[GenericTypeAttribute<StringName[]>()]
+public class ClassVariantAnnotatedStringNameArray
+{
+}
+
+[GenericTypeAttribute<NodePath[]>()]
+public class ClassVariantAnnotatedNodePathArray
+{
+}
+
+[GenericTypeAttribute<Rid[]>()]
+public class ClassVariantAnnotatedRidArray
+{
+}
+
+// This class definition fails because generic type is not Variant-compatible.
+[GenericTypeAttribute<{|GD0301:object|}>()]
+public class ClassNonVariantAnnotated
+{
+}
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
+public class GenericTypeAttribute<[MustBeVariant] T> : Attribute
+{
 }

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

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <LangVersion>9.0</LangVersion>
+    <LangVersion>10</LangVersion>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   <PropertyGroup>

+ 12 - 4
modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs

@@ -109,11 +109,19 @@ namespace Godot.SourceGenerators
         /// <returns><see langword="true"/> if the type must be variant and must be analyzed.</returns>
         private bool ShouldCheckTypeArgument(SyntaxNodeAnalysisContext context, SyntaxNode parentSyntax, ISymbol parentSymbol, TypeSyntax typeArgumentSyntax, ITypeSymbol typeArgumentSymbol, int typeArgumentIndex)
         {
-            var typeParamSymbol = parentSymbol switch
+            ITypeParameterSymbol? typeParamSymbol = parentSymbol switch
             {
-                IMethodSymbol methodSymbol => methodSymbol.TypeParameters[typeArgumentIndex],
-                INamedTypeSymbol typeSymbol => typeSymbol.TypeParameters[typeArgumentIndex],
-                _ => null,
+                IMethodSymbol methodSymbol when parentSyntax.Parent is AttributeSyntax &&
+                                                methodSymbol.ContainingType.TypeParameters.Length > 0
+                    => methodSymbol.ContainingType.TypeParameters[typeArgumentIndex],
+
+                IMethodSymbol { TypeParameters.Length: > 0 } methodSymbol
+                    => methodSymbol.TypeParameters[typeArgumentIndex],
+
+                INamedTypeSymbol { TypeParameters.Length: > 0 } typeSymbol
+                    => typeSymbol.TypeParameters[typeArgumentIndex],
+                _
+                    => null
             };
 
             if (typeParamSymbol == null)