[release/6.0] Fix Logging Source Generator to handle file-scoped namespaces (#57894...
authorMaryam Ariyan <maryam.ariyan@microsoft.com>
Fri, 17 Sep 2021 22:40:07 +0000 (15:40 -0700)
committerGitHub <noreply@github.com>
Fri, 17 Sep 2021 22:40:07 +0000 (15:40 -0700)
* Handle file-scoped namespaces (#57894)

Handle namespace not being emitted when file-scoped
namespaces are used for a log class.
Relates to #57880.

* Fix build issue

Co-authored-by: Martin Costello <martin@martincostello.com>
src/libraries/Microsoft.Extensions.Logging.Abstractions/gen/LoggerMessageGenerator.Parser.cs
src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorEmitterTests.cs
src/libraries/Microsoft.Extensions.Logging.Abstractions/tests/Microsoft.Extensions.Logging.Generators.Tests/LoggerMessageGeneratorParserTests.cs

index b448bc7..93d7590 100644 (file)
@@ -438,11 +438,21 @@ namespace Microsoft.Extensions.Logging.Generators
                                         {
                                             // determine the namespace the class is declared in, if any
                                             SyntaxNode? potentialNamespaceParent = classDec.Parent;
-                                            while (potentialNamespaceParent != null && potentialNamespaceParent is not NamespaceDeclarationSyntax)
+                                            while (potentialNamespaceParent != null &&
+                                                   potentialNamespaceParent is not NamespaceDeclarationSyntax
+#if ROSLYN4_0_OR_GREATER
+                                                   && potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax
+#endif
+                                                   )
                                             {
                                                 potentialNamespaceParent = potentialNamespaceParent.Parent;
                                             }
+
+#if ROSLYN4_0_OR_GREATER
+                                            if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent)
+#else
                                             if (potentialNamespaceParent is NamespaceDeclarationSyntax namespaceParent)
+#endif
                                             {
                                                 nspace = namespaceParent.Name.ToString();
                                                 while (true)
index c9b2092..097dcc7 100644 (file)
@@ -147,6 +147,20 @@ namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses
             await VerifyAgainstBaselineUsingFile("TestWithNestedClass.generated.txt", testSourceCode);
         }
 
+        [Fact]
+        public async Task TestBaseline_TestWithFileScopedNamespace_Success()
+        {
+            string testSourceCode = @"
+namespace Microsoft.Extensions.Logging.Generators.Tests.TestClasses;
+
+internal static partial class TestWithDefaultValues
+{
+    [LoggerMessage]
+    public static partial void M0(ILogger logger, LogLevel level);
+}";
+            await VerifyAgainstBaselineUsingFile("TestWithDefaultValues.generated.txt", testSourceCode);
+        }
+
         private async Task VerifyAgainstBaselineUsingFile(string filename, string testSourceCode)
         {
             string baseline = await File.ReadAllTextAsync(Path.Combine("Baselines", filename)).ConfigureAwait(false);
index a1ec425..4ccb289 100644 (file)
@@ -350,6 +350,24 @@ namespace Microsoft.Extensions.Logging.Generators.Tests
             Assert.Empty(diagnostics);
         }
 
+        [Fact]
+        public async Task FileScopedNamespaceOK()
+        {
+            IReadOnlyList<Diagnostic> diagnostics = await RunGenerator(@"
+                using Microsoft.Extensions.Logging;
+
+                namespace MyLibrary;
+
+                internal partial class Logger
+                {
+                    [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = ""Hello {Name}!"")]
+                    public static partial void Greeting(ILogger logger, string name);
+                }
+            ");
+
+            Assert.Empty(diagnostics);
+        }
+
         [Theory]
         [InlineData("false")]
         [InlineData("true")]