C#: Fix ScriptPathAttribute generator with none or nested namespaces
The following two bugs were fixed: - For classes without namespace we were still generating `namespace {` without a namespace identifier, causing a syntax error. - For classes with nested namespaces we were generating only the innermost part of the namespace was being generated, e.g.: for `Foo.Bar` we were generating `namespace Bar {` instead of `namespace Foo.Bar {`. This wasn't causing any build error, but because of the wrong namespace Godot wasn't able to find the class associated with the script.
This commit is contained in:
parent
bf309b8a13
commit
ee8e5146a4
4 changed files with 54 additions and 24 deletions
|
@ -1,6 +1,6 @@
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageVersion_Godot_NET_Sdk>4.0.0-dev4</PackageVersion_Godot_NET_Sdk>
|
<PackageVersion_Godot_NET_Sdk>4.0.0-dev5</PackageVersion_Godot_NET_Sdk>
|
||||||
<PackageVersion_Godot_SourceGenerators>4.0.0-dev1</PackageVersion_Godot_SourceGenerators>
|
<PackageVersion_Godot_SourceGenerators>4.0.0-dev2</PackageVersion_Godot_SourceGenerators>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -23,11 +23,12 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- Package Sdk\Sdk.props and Sdk\Sdk.targets file -->
|
<!-- Package Sdk\Sdk.props and Sdk\Sdk.targets file -->
|
||||||
<None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" Visible="false" />
|
<None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" />
|
||||||
<None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" Visible="false" />
|
<None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" />
|
||||||
<!-- SdkPackageVersions.props -->
|
<!-- SdkPackageVersions.props -->
|
||||||
|
<None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk">
|
||||||
<None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk" Visible="false" />
|
<Link>Sdk\SdkPackageVersions.props</Link>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
|
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
|
||||||
|
|
|
@ -82,5 +82,8 @@ namespace Godot.SourceGenerators
|
||||||
|
|
||||||
public static string FullQualifiedName(this INamedTypeSymbol symbol)
|
public static string FullQualifiedName(this INamedTypeSymbol symbol)
|
||||||
=> symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal);
|
=> symbol.ToDisplayString(NullableFlowState.NotNull, FullyQualifiedFormatOmitGlobal);
|
||||||
|
|
||||||
|
public static string FullQualifiedName(this INamespaceSymbol namespaceSymbol)
|
||||||
|
=> namespaceSymbol.ToDisplayString(FullyQualifiedFormatOmitGlobal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace Godot.SourceGenerators
|
||||||
IEnumerable<ClassDeclarationSyntax> classDeclarations
|
IEnumerable<ClassDeclarationSyntax> classDeclarations
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var attributesBuilder = new StringBuilder();
|
var attributes = new StringBuilder();
|
||||||
|
|
||||||
// Remember syntax trees for which we already added an attribute, to prevent unnecessary duplicates.
|
// Remember syntax trees for which we already added an attribute, to prevent unnecessary duplicates.
|
||||||
var attributedTrees = new List<SyntaxTree>();
|
var attributedTrees = new List<SyntaxTree>();
|
||||||
|
@ -81,28 +81,54 @@ namespace Godot.SourceGenerators
|
||||||
|
|
||||||
attributedTrees.Add(cds.SyntaxTree);
|
attributedTrees.Add(cds.SyntaxTree);
|
||||||
|
|
||||||
if (attributesBuilder.Length != 0)
|
if (attributes.Length != 0)
|
||||||
attributesBuilder.Append("\n ");
|
attributes.Append("\n");
|
||||||
|
|
||||||
attributesBuilder.Append(@"[ScriptPathAttribute(""res://");
|
attributes.Append(@"[ScriptPathAttribute(""res://");
|
||||||
attributesBuilder.Append(RelativeToDir(cds.SyntaxTree.FilePath, godotProjectDir));
|
attributes.Append(RelativeToDir(cds.SyntaxTree.FilePath, godotProjectDir));
|
||||||
attributesBuilder.Append(@""")]");
|
attributes.Append(@""")]");
|
||||||
}
|
}
|
||||||
|
|
||||||
string classNs = symbol.ContainingNamespace.Name;
|
|
||||||
string className = symbol.Name;
|
string className = symbol.Name;
|
||||||
|
|
||||||
var source = $@"using Godot;
|
INamespaceSymbol namespaceSymbol = symbol.ContainingNamespace;
|
||||||
namespace {classNs}
|
string classNs = namespaceSymbol != null && !namespaceSymbol.IsGlobalNamespace ?
|
||||||
{{
|
namespaceSymbol.FullQualifiedName() :
|
||||||
{attributesBuilder}
|
string.Empty;
|
||||||
partial class {className}
|
bool hasNamespace = classNs.Length != 0;
|
||||||
{{
|
|
||||||
}}
|
string uniqueName = hasNamespace ?
|
||||||
}}
|
classNs + "." + className + "_ScriptPath_Generated" :
|
||||||
";
|
className + "_ScriptPath_Generated";
|
||||||
context.AddSource(classNs + "." + className + "_ScriptPath_Generated",
|
|
||||||
SourceText.From(source, Encoding.UTF8));
|
var source = new StringBuilder();
|
||||||
|
|
||||||
|
// using Godot;
|
||||||
|
// namespace {classNs} {
|
||||||
|
// {attributesBuilder}
|
||||||
|
// partial class {className} { }
|
||||||
|
// }
|
||||||
|
|
||||||
|
source.Append("using Godot;\n");
|
||||||
|
|
||||||
|
if (hasNamespace)
|
||||||
|
{
|
||||||
|
source.Append("namespace ");
|
||||||
|
source.Append(classNs);
|
||||||
|
source.Append(" {\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
source.Append(attributes);
|
||||||
|
source.Append("\n partial class ");
|
||||||
|
source.Append(className);
|
||||||
|
source.Append("\n{\n}\n");
|
||||||
|
|
||||||
|
if (hasNamespace)
|
||||||
|
{
|
||||||
|
source.Append("\n}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
context.AddSource(uniqueName, SourceText.From(source.ToString(), Encoding.UTF8));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context,
|
private static void AddScriptTypesAssemblyAttr(GeneratorExecutionContext context,
|
||||||
|
|
Loading…
Reference in a new issue