From f62a73389e3d00e745aa536e6aa81d88031693e0 Mon Sep 17 00:00:00 2001 From: Jens Brand Date: Thu, 23 Jan 2025 14:24:54 +0100 Subject: [PATCH] Fixed namespace generation issue #4455 --- .../Discovery/TypeDefinitionExtractor.cs | 46 ++++++++++++++----- .../Discovery/TypeDefinitionExtractor.cs | 46 ++++++++++++++----- 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/Source/Csla.Generators/cs/AutoImplementProperties/Csla.Generator.AutoImplementProperties.CSharp/AutoImplement/Discovery/TypeDefinitionExtractor.cs b/Source/Csla.Generators/cs/AutoImplementProperties/Csla.Generator.AutoImplementProperties.CSharp/AutoImplement/Discovery/TypeDefinitionExtractor.cs index 7d1443fd14..0dcc4d70b8 100644 --- a/Source/Csla.Generators/cs/AutoImplementProperties/Csla.Generator.AutoImplementProperties.CSharp/AutoImplement/Discovery/TypeDefinitionExtractor.cs +++ b/Source/Csla.Generators/cs/AutoImplementProperties/Csla.Generator.AutoImplementProperties.CSharp/AutoImplement/Discovery/TypeDefinitionExtractor.cs @@ -138,24 +138,46 @@ private static string GetBaseClassTypeName(DefinitionExtractionContext extractio /// The namespace of the type for which generation is being performed private static string GetNamespace(TypeDeclarationSyntax targetTypeDeclaration) { - string namespaceName = string.Empty; - NamespaceDeclarationSyntax namespaceDeclaration; - TypeDeclarationSyntax containingTypeDeclaration; - - // Iterate through the containing types should the target type be nested inside other types - containingTypeDeclaration = targetTypeDeclaration; - while (containingTypeDeclaration.Parent is TypeDeclarationSyntax 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 = targetTypeDeclaration.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) { - containingTypeDeclaration = syntax; + potentialNamespaceParent = potentialNamespaceParent.Parent; } - namespaceDeclaration = containingTypeDeclaration.Parent as NamespaceDeclarationSyntax; - if (namespaceDeclaration is not null) + // Build up the final namespace by looping until we no longer have a namespace declaration + if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent) { - namespaceName = namespaceDeclaration.Name.ToString(); + // 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 namespaceName; + // return the final namespace + return nameSpace; } /// diff --git a/Source/Csla.Generators/cs/AutoSerialization/Csla.Generator.AutoSerialization.CSharp/AutoSerializable/Discovery/TypeDefinitionExtractor.cs b/Source/Csla.Generators/cs/AutoSerialization/Csla.Generator.AutoSerialization.CSharp/AutoSerializable/Discovery/TypeDefinitionExtractor.cs index a4c4930aeb..40f4449a2d 100644 --- a/Source/Csla.Generators/cs/AutoSerialization/Csla.Generator.AutoSerialization.CSharp/AutoSerializable/Discovery/TypeDefinitionExtractor.cs +++ b/Source/Csla.Generators/cs/AutoSerialization/Csla.Generator.AutoSerialization.CSharp/AutoSerializable/Discovery/TypeDefinitionExtractor.cs @@ -68,24 +68,46 @@ public static ExtractedTypeDefinition ExtractTypeDefinition(DefinitionExtraction /// The namespace of the type for which generation is being performed private static string GetNamespace(DefinitionExtractionContext extractionContext, TypeDeclarationSyntax targetTypeDeclaration) { - string namespaceName = string.Empty; - NamespaceDeclarationSyntax namespaceDeclaration; - TypeDeclarationSyntax containingTypeDeclaration; - - // Iterate through the containing types should the target type be nested inside other types - containingTypeDeclaration = targetTypeDeclaration; - while (containingTypeDeclaration.Parent is TypeDeclarationSyntax 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 = targetTypeDeclaration.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) { - containingTypeDeclaration = syntax; + potentialNamespaceParent = potentialNamespaceParent.Parent; } - namespaceDeclaration = containingTypeDeclaration.Parent as NamespaceDeclarationSyntax; - if (namespaceDeclaration is not null) + // Build up the final namespace by looping until we no longer have a namespace declaration + if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent) { - namespaceName = namespaceDeclaration.Name.ToString(); + // 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 namespaceName; + // return the final namespace + return nameSpace; } ///