Improve handling of generic C# types

- Create CSharpScript for generic C# types.
  - `ScriptPathAttributeGenerator` registers the path for the generic type definition.
  - `ScriptManagerBridge` lookup uses the generic type definition that was registered by the generator.
  - Constructed generic types use a virtual `csharp://` path so they can be registered in the map and loaded as if there was a different file for each constructed type, even though they all share the same real path.
  - This allows getting the base type for a C# type that derives from a generic type.
- Shows base scripts in the _Add Node_ and _Create Resource_ dialogs even when they are generic types.
  - `get_global_class_name` implementation was moved to C# and now always returns the base type even if the script is not a global class (this behavior matches GDScript).
- Create `CSharpScript::TypeInfo` struct to hold all the type information about the C# type that corresponds to the `CSharpScript`, and use it as the parameter in `UpdateScriptClassInfo` to avoid adding more parameters.
This commit is contained in:
Raul Santos
2024-02-05 02:49:57 +01:00
parent 41564aaf77
commit 5815d1c8c8
10 changed files with 422 additions and 141 deletions

View File

@ -54,9 +54,7 @@ namespace Godot.SourceGenerators
)
.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)
Path.GetFileNameWithoutExtension(x.cds.SyntaxTree.FilePath) == x.symbol.Name)
.GroupBy(x => x.symbol)
.ToDictionary(g => g.Key, g => g.Select(x => x.cds));
@ -160,6 +158,8 @@ 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(")");
}