88using Microsoft . CodeAnalysis . CSharp . Syntax ;
99using PlantUmlClassDiagramGenerator . Attributes ;
1010
11- namespace PlantUmlClassDiagramGenerator . Library ;
11+ namespace PlantUmlClassDiagramGenerator . Library . ClassDiagramGenerator ;
1212
1313public class ClassDiagramGenerator (
1414 TextWriter writer ,
1515 string indent ,
1616 Accessibilities ignoreMemberAccessibilities = Accessibilities . None ,
1717 bool createAssociation = true ,
1818 bool attributeRequired = false ,
19- bool excludeUmlBeginEndTags = false ) : CSharpSyntaxWalker
19+ bool excludeUmlBeginEndTags = false ,
20+ bool addPackageTags = false ) : CSharpSyntaxWalker
2021{
2122 private readonly HashSet < string > types = [ ] ;
2223 private readonly List < SyntaxNode > additionalTypeDeclarationNodes = [ ] ;
2324 private readonly Accessibilities ignoreMemberAccessibilities = ignoreMemberAccessibilities ;
24- private readonly RelationshipCollection relationships = new ( ) ;
25+ public readonly RelationshipCollection relationships = new ( ) ;
2526 private readonly TextWriter writer = writer ;
2627 private readonly string indent = indent ;
2728 private int nestingDepth = 0 ;
2829 private readonly bool createAssociation = createAssociation ;
2930 private readonly bool attributeRequired = attributeRequired ;
3031 private readonly bool excludeUmlBeginEndTags = excludeUmlBeginEndTags ;
32+ private readonly bool addPackageTags = addPackageTags ;
3133 private readonly Dictionary < string , string > escapeDictionary = new ( )
3234 {
3335 { @"(?<before>[^{]){(?<after>{[^{])" , "${before}{${after}" } ,
@@ -45,7 +47,24 @@ public void GenerateInternal(SyntaxNode root)
4547 {
4648 Visit ( root ) ;
4749 GenerateAdditionalTypeDeclarations ( ) ;
48- GenerateRelationships ( ) ;
50+ if ( ! this . addPackageTags )
51+ GenerateRelationships ( ) ;
52+ }
53+
54+ public override void VisitFileScopedNamespaceDeclaration ( FileScopedNamespaceDeclarationSyntax node )
55+ {
56+ if ( this . addPackageTags )
57+ VisitFileScopedNamespaceDeclaration ( node , ( ) => base . VisitFileScopedNamespaceDeclaration ( node ) ) ;
58+ else
59+ base . VisitFileScopedNamespaceDeclaration ( node ) ;
60+ }
61+
62+ public override void VisitNamespaceDeclaration ( NamespaceDeclarationSyntax node )
63+ {
64+ if ( this . addPackageTags )
65+ VisitNamespaceDeclaration ( node , ( ) => base . VisitNamespaceDeclaration ( node ) ) ;
66+ else
67+ base . VisitNamespaceDeclaration ( node ) ;
4968 }
5069
5170 public override void VisitInterfaceDeclaration ( InterfaceDeclarationSyntax node )
@@ -371,7 +390,7 @@ private void WriteLine(string line)
371390 private bool SkipInnerTypeDeclaration ( SyntaxNode node )
372391 {
373392 if ( nestingDepth <= 0 ) return false ;
374-
393+ if ( nestingDepth == 1 && addPackageTags ) return false ;
375394 additionalTypeDeclarationNodes . Add ( node ) ;
376395 return true ;
377396 }
@@ -411,6 +430,47 @@ private void GenerateRelationships()
411430 WriteLine ( relationship . ToString ( ) ) ;
412431 }
413432 }
433+
434+ public static string [ ] GenerateRelationships ( RelationshipCollection relationshipCollection )
435+ {
436+ List < string > strings = new List < string > ( ) ;
437+ foreach ( var relationship in relationshipCollection )
438+ {
439+ strings . AddRange ( relationshipCollection . Select ( r => r . ToString ( ) ) ) ;
440+ }
441+
442+ return strings . ToArray ( ) ;
443+ }
444+
445+ private void VisitFileScopedNamespaceDeclaration ( FileScopedNamespaceDeclarationSyntax node , Action visitBase )
446+ {
447+ if ( attributeRequired && ! node . AttributeLists . HasDiagramAttribute ( ) ) { return ; }
448+ if ( node . AttributeLists . HasIgnoreAttribute ( ) ) { return ; }
449+ if ( SkipInnerTypeDeclaration ( node ) ) { return ; }
450+
451+ var typeName = NamespaceNameText . From ( node ) ;
452+
453+ WriteLine ( $ "package \" { typeName . Identifier } \" {{") ;
454+ nestingDepth ++ ;
455+ visitBase ( ) ;
456+ nestingDepth -- ;
457+ WriteLine ( "}" ) ;
458+ }
459+
460+ private void VisitNamespaceDeclaration ( NamespaceDeclarationSyntax node , Action visitBase )
461+ {
462+ if ( attributeRequired && ! node . AttributeLists . HasDiagramAttribute ( ) ) { return ; }
463+ if ( node . AttributeLists . HasIgnoreAttribute ( ) ) { return ; }
464+ if ( SkipInnerTypeDeclaration ( node ) ) { return ; }
465+
466+ var typeName = NamespaceNameText . From ( node ) ;
467+
468+ WriteLine ( $ "package \" { typeName . Identifier } \" {{") ;
469+ nestingDepth ++ ;
470+ visitBase ( ) ;
471+ nestingDepth -- ;
472+ WriteLine ( "}" ) ;
473+ }
414474
415475 private void VisitTypeDeclaration ( TypeDeclarationSyntax node , Action visitBase )
416476 {
0 commit comments