Skip to content
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

Fix namespace generation issue #4455

Closed
rockfordlhotka opened this issue Jan 22, 2025 · 0 comments · Fixed by #4458
Closed

Fix namespace generation issue #4455

rockfordlhotka opened this issue Jan 22, 2025 · 0 comments · Fixed by #4458

Comments

@rockfordlhotka
Copy link
Member

I've tested and the PrivatAssets works. But omitting the namespace declaration dosn't work, because then the generated partial class is in the global namespace and this is not the same as the original namespace.

But I think I've found the solution 😀

During my tests I noticed that the problem only occurs, if I used file scoped namespaces. If I changed my code to use block-scoped namespaces all went fine. So I looked in TypeDefinitionExtractor.GetNamespace() and found the following line:

namespaceDeclaration = containingTypeDeclaration.Parent as NamespaceDeclarationSyntax;

NamespaceDeclarationSyntax only matches block-scoped namespaces. File scoped namespaces need FileScopedNamespaceDeclarationSyntax.

The final solution I got from Andrew Locks blog

// determine the namespace the class/enum/struct is declared in, if any
static string GetNamespace(BaseTypeDeclarationSyntax syntax)
{
    // If we don't have a namespace at all we'll return an empty string
    // This accounts for the "default namespace" case
    string nameSpace = string.Empty;

    // Get the containing syntax node for the type declaration
    // (could be a nested type, for example)
    SyntaxNode? potentialNamespaceParent = syntax.Parent;
    
    // Keep moving "out" of nested classes etc until we get to a namespace
    // or until we run out of parents
    while (potentialNamespaceParent != null &&
            potentialNamespaceParent is not NamespaceDeclarationSyntax
            && potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax)
    {
        potentialNamespaceParent = potentialNamespaceParent.Parent;
    }

    // Build up the final namespace by looping until we no longer have a namespace declaration
    if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent)
    {
        // We have a namespace. Use that as the type
        nameSpace = namespaceParent.Name.ToString();
        
        // Keep moving "out" of the namespace declarations until we 
        // run out of nested namespace declarations
        while (true)
        {
            if (namespaceParent.Parent is not NamespaceDeclarationSyntax parent)
            {
                break;
            }

            // Add the outer namespace as a prefix to the final namespace
            nameSpace = $"{namespaceParent.Name}.{nameSpace}";
            namespaceParent = parent;
        }
    }

    // return the final namespace
    return nameSpace;
}

This will fix it. Same method must be changed in TypeDefinitionExtractor in the project AutoSerialization.

Originally posted by @jensbrand in #4446

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.

1 participant