From f192d29c32be0a878bf5fe624cf1b653227a180c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 13:33:27 +0000 Subject: [PATCH 1/4] Initial plan From 876e76c457f3570b7508b78abadd1a79fb1f967b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 13:40:17 +0000 Subject: [PATCH 2/4] Fix: Source generator now respects RootNamespace property, add sample project Co-authored-by: Soar360 <15421284+Soar360@users.noreply.github.com> --- .../build/LuYao.ResourcePacker.MSBuild.props | 1 + .../ResourcePackageGenerator.cs | 15 ++--- LuYao.ResourcePacker.slnx | 3 + samples/RootNamespaceTest/Program.cs | 49 ++++++++++++++++ .../RootNamespaceTest/Resources/config.json | 4 ++ .../RootNamespaceTest/Resources/sample.txt | 1 + .../RootNamespaceTest.csproj | 58 +++++++++++++++++++ 7 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 samples/RootNamespaceTest/Program.cs create mode 100644 samples/RootNamespaceTest/Resources/config.json create mode 100644 samples/RootNamespaceTest/Resources/sample.txt create mode 100644 samples/RootNamespaceTest/RootNamespaceTest.csproj diff --git a/LuYao.ResourcePacker.MSBuild/build/LuYao.ResourcePacker.MSBuild.props b/LuYao.ResourcePacker.MSBuild/build/LuYao.ResourcePacker.MSBuild.props index 7f30fee..de588e6 100644 --- a/LuYao.ResourcePacker.MSBuild/build/LuYao.ResourcePacker.MSBuild.props +++ b/LuYao.ResourcePacker.MSBuild/build/LuYao.ResourcePacker.MSBuild.props @@ -8,5 +8,6 @@ + \ No newline at end of file diff --git a/LuYao.ResourcePacker.SourceGenerator/ResourcePackageGenerator.cs b/LuYao.ResourcePacker.SourceGenerator/ResourcePackageGenerator.cs index 80e732f..767f489 100644 --- a/LuYao.ResourcePacker.SourceGenerator/ResourcePackageGenerator.cs +++ b/LuYao.ResourcePacker.SourceGenerator/ResourcePackageGenerator.cs @@ -59,7 +59,7 @@ private static void Execute(SourceProductionContext context, Compilation compila var className = "R"; // Get root namespace from compilation options or default to assembly name - var rootNamespace = GetRootNamespace(compilation); + var rootNamespace = GetRootNamespace(compilation, configOptions); // Visibility is always internal var visibility = "internal"; @@ -82,14 +82,15 @@ private static void Execute(SourceProductionContext context, Compilation compila context.AddSource($"{className}.g.cs", SourceText.From(source, Encoding.UTF8)); } - private static string GetRootNamespace(Compilation compilation) + private static string GetRootNamespace(Compilation compilation, AnalyzerConfigOptionsProvider configOptions) { - // Try to get RootNamespace from compilation options - // First, check if there's a global namespace option - if (compilation.Options is CSharpCompilationOptions csharpOptions) + // Try to get RootNamespace from analyzer config (MSBuild property) + if (configOptions.GlobalOptions.TryGetValue("build_property.RootNamespace", out var rootNamespace)) { - // Look for MSBuild properties that might contain the root namespace - // The RootNamespace is typically passed through analyzer config + if (!string.IsNullOrWhiteSpace(rootNamespace)) + { + return rootNamespace; + } } // Default to assembly name if no explicit root namespace is found diff --git a/LuYao.ResourcePacker.slnx b/LuYao.ResourcePacker.slnx index 36785bc..886483a 100644 --- a/LuYao.ResourcePacker.slnx +++ b/LuYao.ResourcePacker.slnx @@ -12,6 +12,9 @@ + + + diff --git a/samples/RootNamespaceTest/Program.cs b/samples/RootNamespaceTest/Program.cs new file mode 100644 index 0000000..3bc9069 --- /dev/null +++ b/samples/RootNamespaceTest/Program.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using LuYao.ResourcePacker; + +namespace Popcorn.Toolkit +{ + /// + /// Test program to verify that the generated R class respects the RootNamespace property. + /// When RootNamespace is set to "Popcorn.Toolkit", the R class should be in this namespace. + /// + public class Program + { + public static async Task Main(string[] args) + { + Console.WriteLine("RootNamespace Test - Verifying generated R class namespace"); + Console.WriteLine("============================================================="); + Console.WriteLine(); + + // This test verifies that R class is in Popcorn.Toolkit namespace + // If RootNamespace property is not respected, this won't compile + Console.WriteLine($"R class is accessible in namespace: {typeof(R).Namespace}"); + Console.WriteLine($"Expected namespace: Popcorn.Toolkit"); + Console.WriteLine(); + + // List available resource keys + Console.WriteLine("Available resource keys:"); + Console.WriteLine($" - R.Keys.sample: {R.Keys.sample}"); + Console.WriteLine($" - R.Keys.config: {R.Keys.config}"); + Console.WriteLine(); + + // Test reading resources + try + { + var sampleText = await R.ReadSampleAsyncAsString(); + Console.WriteLine($"Sample resource content: {sampleText}"); + + var configJson = await R.ReadConfigAsyncAsString(); + Console.WriteLine($"Config resource content: {configJson}"); + + Console.WriteLine(); + Console.WriteLine("✓ Test PASSED: R class is in the correct namespace (Popcorn.Toolkit)"); + } + catch (Exception ex) + { + Console.WriteLine($"✗ Error reading resources: {ex.Message}"); + } + } + } +} diff --git a/samples/RootNamespaceTest/Resources/config.json b/samples/RootNamespaceTest/Resources/config.json new file mode 100644 index 0000000..82b8657 --- /dev/null +++ b/samples/RootNamespaceTest/Resources/config.json @@ -0,0 +1,4 @@ +{ + "message": "Hello from RootNamespace test!", + "version": "1.0" +} \ No newline at end of file diff --git a/samples/RootNamespaceTest/Resources/sample.txt b/samples/RootNamespaceTest/Resources/sample.txt new file mode 100644 index 0000000..4c2c32e --- /dev/null +++ b/samples/RootNamespaceTest/Resources/sample.txt @@ -0,0 +1 @@ +This is a sample resource file for testing RootNamespace property. \ No newline at end of file diff --git a/samples/RootNamespaceTest/RootNamespaceTest.csproj b/samples/RootNamespaceTest/RootNamespaceTest.csproj new file mode 100644 index 0000000..c5412c5 --- /dev/null +++ b/samples/RootNamespaceTest/RootNamespaceTest.csproj @@ -0,0 +1,58 @@ + + + + Exe + net8.0 + enable + enable + false + Popcorn.Toolkit + true + Resources + + + + + + + + + + + + + + + + + + + + + + + + + + $(AssemblyName).dat + + + + + + + PreserveNewest + $(ResourcePackerOutputFileName) + + + + + From 17158c4168080930ca17674dff8ab2ebb9173b94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 13:42:56 +0000 Subject: [PATCH 3/4] Add README for RootNamespaceTest sample Co-authored-by: Soar360 <15421284+Soar360@users.noreply.github.com> --- samples/RootNamespaceTest/README.md | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 samples/RootNamespaceTest/README.md diff --git a/samples/RootNamespaceTest/README.md b/samples/RootNamespaceTest/README.md new file mode 100644 index 0000000..7214b8b --- /dev/null +++ b/samples/RootNamespaceTest/README.md @@ -0,0 +1,55 @@ +# RootNamespace Test Sample + +This sample project demonstrates and validates that the source generator correctly respects the `RootNamespace` property in the .csproj file. + +## Purpose + +When a project sets `Popcorn.Toolkit` in its .csproj file, the generated `R` class should be placed in the `Popcorn.Toolkit` namespace rather than defaulting to the assembly name. + +## Project Configuration + +The project is configured with: +- **AssemblyName**: RootNamespaceTest +- **RootNamespace**: Popcorn.Toolkit +- **Resources**: Contains sample.txt and config.json + +## Expected Behavior + +The source generator should: +1. Read the `RootNamespace` property from MSBuild +2. Generate the `R` class in the `Popcorn.Toolkit` namespace +3. The Program.cs can access `R` class directly since it's in the same namespace + +## Running the Test + +```bash +dotnet run --project samples/RootNamespaceTest/RootNamespaceTest.csproj +``` + +Expected output: +``` +RootNamespace Test - Verifying generated R class namespace +============================================================= + +R class is accessible in namespace: Popcorn.Toolkit +Expected namespace: Popcorn.Toolkit + +Available resource keys: + - R.Keys.sample: sample + - R.Keys.config: config + +Sample resource content: This is a sample resource file for testing RootNamespace property. +Config resource content: { + "message": "Hello from RootNamespace test!", + "version": "1.0" +} + +✓ Test PASSED: R class is in the correct namespace (Popcorn.Toolkit) +``` + +## Verification + +The test program: +1. Accesses the `R` class without qualification (proving it's in `Popcorn.Toolkit`) +2. Verifies the namespace using reflection +3. Reads resources to ensure functionality works correctly From f686e6be50ec5e19796b2b51c443b73cde0c929c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 13:44:24 +0000 Subject: [PATCH 4/4] Address code review comments in README Co-authored-by: Soar360 <15421284+Soar360@users.noreply.github.com> --- samples/RootNamespaceTest/README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/samples/RootNamespaceTest/README.md b/samples/RootNamespaceTest/README.md index 7214b8b..3b5bb6b 100644 --- a/samples/RootNamespaceTest/README.md +++ b/samples/RootNamespaceTest/README.md @@ -22,10 +22,16 @@ The source generator should: ## Running the Test +From the repository root: ```bash dotnet run --project samples/RootNamespaceTest/RootNamespaceTest.csproj ``` +Or from this directory: +```bash +dotnet run +``` + Expected output: ``` RootNamespace Test - Verifying generated R class namespace @@ -49,7 +55,7 @@ Config resource content: { ## Verification -The test program: -1. Accesses the `R` class without qualification (proving it's in `Popcorn.Toolkit`) -2. Verifies the namespace using reflection -3. Reads resources to ensure functionality works correctly +The test program verifies the fix by: +1. Accessing the `R` class without namespace qualification (proving it's in the same `Popcorn.Toolkit` namespace as Program.cs) +2. Using reflection to verify the namespace is exactly `Popcorn.Toolkit` +3. Reading resources to ensure the generated code functions correctly