diff --git a/ModInteropImportGenerator.Sample/CommunalHelperImports.cs b/ModInteropImportGenerator.Sample/CommunalHelperImports.cs index 822b262..8281f0b 100644 --- a/ModInteropImportGenerator.Sample/CommunalHelperImports.cs +++ b/ModInteropImportGenerator.Sample/CommunalHelperImports.cs @@ -2,16 +2,18 @@ using ModInteropImportGenerator.Sample.Stubs; namespace ModInteropImportGenerator.Sample; - -[GenerateImports("CommunalHelper.DashStates")] -public static partial class DashStates +partial class Sample { - public static partial int GetDreamTunnelDashState(); - public static partial bool HasDreamTunnelDash(); - public static partial int GetDreamTunnelDashCount(); - public static partial ComponentStub DreamTunnelInteraction( - Action onPlayerEnter, - Action onPlayerExit); - public static partial bool HasSeekerDash(); - public static partial bool IsSeekerDashAttacking(); + [GenerateImports("CommunalHelper.DashStates")] + public static partial class DashStates + { + public static partial int GetDreamTunnelDashState(); + public static partial bool HasDreamTunnelDash(); + public static partial int GetDreamTunnelDashCount(); + public static partial ComponentStub DreamTunnelInteraction( + Action onPlayerEnter, + Action onPlayerExit); + public static partial bool HasSeekerDash(); + public static partial bool IsSeekerDashAttacking(); + } } diff --git a/ModInteropImportGenerator/ModInteropImportSourceGenerator.cs b/ModInteropImportGenerator/ModInteropImportSourceGenerator.cs index 2673d9b..7a1da5c 100644 --- a/ModInteropImportGenerator/ModInteropImportSourceGenerator.cs +++ b/ModInteropImportGenerator/ModInteropImportSourceGenerator.cs @@ -258,9 +258,18 @@ private static void GenerateCode( sourceGen.AddUsings("System", "System.Diagnostics", "MonoMod.ModInterop", "ModInteropImportGenerator"); - sourceGen.WriteLine($"public static partial class {sourceGen.ClassName}"); - using (sourceGen.UseCodeBlock()) + var classes = classDeclaration.AncestorsAndSelf().OfType().ToArray(); + using (var indent = sourceGen.StartMultiIndent()) { + for (int i = classes.Length - 1; i >= 0; i--) + { + sourceGen.WriteLine(classes[i] switch + { + ClassDeclarationSyntax c => $"public static partial class {c.Identifier.Text}", + }); + indent.Indent(); + } + sourceGen.WriteLine( $"public static {ImportStateEnumTypeName} {SourceGenerators.ImportStateFieldName} " + $"{{ get; private set; }}"); diff --git a/ModInteropImportGenerator/SimpleSourceGenerator.cs b/ModInteropImportGenerator/SimpleSourceGenerator.cs index f69a09d..d11b846 100644 --- a/ModInteropImportGenerator/SimpleSourceGenerator.cs +++ b/ModInteropImportGenerator/SimpleSourceGenerator.cs @@ -26,7 +26,7 @@ public int IndentLevel public readonly ModImportMetadata ImportMeta; public readonly SemanticModel SemanticModel; - public readonly string Namespace; + public readonly INamespaceSymbol Namespace; public readonly string ClassName; public SimpleSourceGenerator(ClassDeclarationSyntax classDeclaration, @@ -42,7 +42,7 @@ public SimpleSourceGenerator(ClassDeclarationSyntax classDeclaration, $"Attempted to create a source generator for something that isn't an {nameof(INamedTypeSymbol)}."); ClassSymbol = typeSymbol; - Namespace = typeSymbol.ContainingNamespace.ToDisplayString(); + Namespace = typeSymbol.ContainingNamespace; ClassName = classDeclaration.Identifier.Text; } @@ -104,12 +104,15 @@ public SimpleSourceGenerator Write(char c) public string Generate() { + var ns = ""; + if (!Namespace.IsGlobalNamespace) + { + ns = $"\nnamespace {Namespace.ToDisplayString()};\n"; + } return $""" // {string.Join("\n", Usings.Select(usingNamespace => $"using {usingNamespace};"))} - - namespace {Namespace}; - + {ns} {SourceCode} """; } @@ -125,6 +128,8 @@ public SimpleSourceGenerator Dedent(int dedentCount = 1) IndentLevel -= dedentCount; return this; } + public MultipleIndentedCodeBlockContext StartMultiIndent(int indentCount = 1) + => new(this, indentCount); public IndentContext UseIndent(int indentCount = 1) => new(this, indentCount); @@ -139,8 +144,8 @@ private void WriteIndent() return; for (int i = 0; i < IndentLevel; i++) - for (int j = 0; j < 4; j++) - SourceCode.Append(' '); + for (int j = 0; j < 4; j++) + SourceCode.Append(' '); } public ref struct IndentContext : IDisposable @@ -199,4 +204,29 @@ public void Dispose() SourceGen.WriteLine(); } } + public ref struct MultipleIndentedCodeBlockContext(SimpleSourceGenerator sourceGen, int indentCount) : IDisposable + { + private bool Disposed; + private int IndentTimes; + + public void Indent() + { + IndentTimes++; + sourceGen.WriteLine('{'); + sourceGen.IndentLevel += indentCount; + } + + public void Dispose() + { + if (Disposed) + throw new ObjectDisposedException(nameof(IndentedCodeBlockContext)); + + Disposed = true; + for (int i = 0; i < IndentTimes; i++) + { + sourceGen.IndentLevel -= indentCount; + sourceGen.WriteLine('}'); + } + } + } }