Skip to content

Handle file-scoped namespaces in Logging Source Generator #57894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,13 @@ public IReadOnlyList<LoggerClass> GetLogClasses(IEnumerable<ClassDeclarationSynt
{
// 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 &&
potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax)
{
potentialNamespaceParent = potentialNamespaceParent.Parent;
}
if (potentialNamespaceParent is NamespaceDeclarationSyntax namespaceParent)
if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent)
{
nspace = namespaceParent.Name.ToString();
while (true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ internal class Class2 { }
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,24 @@ public partial class Nested
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")]
Expand Down