Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analyzer 'Godot.SourceGenerators.MustBeVariantAnalyzer' threw an exception of type 'System.IndexOutOfRangeException' #85553

Closed
tparviainen opened this issue Nov 30, 2023 · 6 comments · Fixed by #85908

Comments

@tparviainen
Copy link

tparviainen commented Nov 30, 2023

Godot version

v4.2.stable.mono.official [46dc277]

System information

Ubuntu Linux

Issue description

Source generator MustBeVariantAnalyzer throws exception System.IndexOutOfRangeException when generic attributes are declared in my own Godot project. I think that generic attributes worked fine with Godot version 4.1.3.

Steps to reproduce

  1. Create new .NET Godot project
  2. Add <LangVersion>latest</LangVersion> to csproj so that C# 'generic attributes' feature can be used
  3. Create 2D scene with Node2D as the root node and rename this to for example Level
  4. Attach script to Level node
  5. Add next code to Level.cs file
[global::System.AttributeUsageAttribute(global::System.AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
internal sealed class AutoloadAttribute<T> : global::System.Attribute
{
}
  1. Decorate the Level class with the attribute i.e.
[Autoload<Level>]
public partial class Level : Node2D
{
}
  1. Compile the project, output window has warning Analyzer 'Godot.SourceGenerators.MustBeVariantAnalyzer' threw an exception of type 'System.IndexOutOfRangeException' with message 'Index was outside the bounds of the array.'

If you compile the project from CLI using command dotnet build --no-incremental -v d you can see that the exception is thrown from method MustBeVariantAnalyzer.ShouldCheckTypeArgument.

Minimal reproduction project

GodotTest.zip

@AThousandShips
Copy link
Member

I think that generic attributes worked fine with Godot version 4.1.3.

What do you mean? Do you mean you recall that it maybe worked fine, or that your opinion is that it worked fine?

@tparviainen
Copy link
Author

I used version 4.1.3 before and I don't remember seeing that exception message in the compilation output.

@AThousandShips
Copy link
Member

Then please do test that it does work there 🙂

@tparviainen
Copy link
Author

v4.1.3.stable.mono.official [f06b6836a] throws an exception as well.

@lewiji
Copy link
Contributor

lewiji commented Dec 4, 2023

Encountered the same issue here, using Arch ECS with 4.2 stable.

[Query, All<MapGenContext, MapGenStepCorridors>] 
   void MapGenCorridors(in Entity entity)
{
  // ...
}   

Causes the warning:

  <Frongu>\src\Systems\Init\ApplyMapGenStepsSystem.cs:0 Analyzer 'Godot.SourceGenerators.MustBeVariantAnalyzer' threw an exception of type 'System.IndexOutOfRangeException' with message 'Index was outside the bounds of the array.'.
Exception occurred with following context:
Compilation: Frongu
SyntaxTree: /home/lewiji/dev/Frongu/Frongu/src/Systems/Init/ApplyMapGenStepsSystem.cs
SyntaxNode: <MapGenContext, MapGenStepCorridors ... [TypeArgumentListSyntax]@[1403..1439) (36,14)-(36,50)

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Godot.SourceGenerators.MustBeVariantAnalyzer.ShouldCheckTypeArgument(SyntaxNodeAnalysisContext context, SyntaxNode parentSyntax, ISymbol parentSymbol, TypeSyntax typeArgumentSyntax, ITypeSymbol typeArgumentSymbol, Int32 typeArgumentIndex)
   at Godot.SourceGenerators.MustBeVariantAnalyzer.AnalyzeNode(SyntaxNodeAnalysisContext context)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info, CancellationToken cancellationToken) in Z:\BuildAgent\work\3b7ce003563d6f8f\src\Compilers\Core\Portable\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 1182
-----

Suppress the following diagnostics to disable this analyzer: GD0301, GD0302, GD0303

Rolling back to 4.1.2, yes, the same warning crops up. At first, it appeared it didn't, as the warning didn't show up in the project initially, even after building, running, and manually re-running the analyzers, but as soon as I made a change to the file the analyzer warning appeared.

Should note it is simply a warning and doesn't seem to have any effect on the project otherwise, I can build and run fine and the annotations seem to behave as expected. So the analyzer failure doesn't seem to be indicating an actual problem with the annotation definition.

Edit: not entirely certain what this particular analyzer is supposed to be doing tbh but it seems the scope is just too wide?

var typeParamSymbol = parentSymbol switch {
    IMethodSymbol methodSymbol => methodSymbol.TypeParameters[typeArgumentIndex],
    INamedTypeSymbol typeSymbol => typeSymbol.TypeParameters[typeArgumentIndex],
    _ => null,
};

This is the failing code, MS docs say that TypeParameters may be an empty list if non-generic, so perhaps using ElementAtOrDefault instead of direct access would stop the exception, but it would still report GD0303: parent of a type argument that must be Variant compatible was not handled.

Thing is - none of the classes or methods in question are in the Godot context - the class isn't extending a godot type, and the attribute I'm defining is to do with my ECS library and not Godot. So it seems like the scope of what attributes should be analysed needs to be limited to just GodotSharp attributes?

@avilches
Copy link
Contributor

avilches commented Dec 8, 2023

Thing is - none of the classes or methods in question are in the Godot context - the class isn't extending a godot type, and the attribute I'm defining is to do with my ECS library and not Godot. So it seems like the scope of what attributes should be analysed needs to be limited to just GodotSharp attributes?

The error is happening when it tries to extract the generic type before checking if the type is (or it isn't) annotated with the [MustBeVariant] attribute. Generic types in attributes belongs to the "ctor" method and the types are located in ContainingType.TypeParameters instead of TypeParameters. I've already solved it #85908

@akien-mga akien-mga added this to the 4.3 milestone Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants