99use Kauffinger \Codemap \Dto \CodemapMethodDto ;
1010use Kauffinger \Codemap \Dto \CodemapParameterDto ;
1111use Kauffinger \Codemap \Dto \CodemapPropertyDto ;
12+ use Kauffinger \Codemap \Dto \CodemapTraitDto ;
1213use Override ;
1314use PhpParser \Node ;
1415use PhpParser \Node \ComplexType ;
1718use PhpParser \Node \Stmt \Enum_ ;
1819use PhpParser \Node \Stmt \EnumCase ;
1920use PhpParser \Node \Stmt \Property ;
21+ use PhpParser \Node \Stmt \Trait_ ;
2022use PhpParser \NodeVisitorAbstract ;
2123
2224/**
23- * A node visitor that collects both classes and enums into DTOs.
25+ * A node visitor that collects classes, enums, and traits into DTOs.
2426 */
2527final class SymbolCollectionVisitor extends NodeVisitorAbstract
2628{
@@ -34,10 +36,17 @@ final class SymbolCollectionVisitor extends NodeVisitorAbstract
3436 */
3537 public array $ collectedEnums = [];
3638
39+ /**
40+ * @var array<string, CodemapTraitDto>
41+ */
42+ public array $ collectedTraits = [];
43+
3744 private ?string $ currentClassName = null ;
3845
3946 private ?string $ currentEnumName = null ;
4047
48+ private ?string $ currentTraitName = null ;
49+
4150 #[Override]
4251 public function enterNode (Node $ node ): null |int |Node |array
4352 {
@@ -47,7 +56,24 @@ public function enterNode(Node $node): null|int|Node|array
4756 ? $ node ->namespacedName ->toString ()
4857 : (string ) $ node ->name ;
4958
50- $ this ->collectedClasses [$ this ->currentClassName ] = new CodemapClassDto ;
59+ // Extract inheritance, implementation, and trait usage
60+ $ extends = $ node ->extends ? $ node ->extends ->toString () : null ;
61+ $ implements = array_map (fn (Node \Name $ name ) => $ name ->toString (), $ node ->implements );
62+ $ uses = [];
63+ foreach ($ node ->getTraitUses () as $ traitUse ) {
64+ foreach ($ traitUse ->traits as $ traitName ) {
65+ $ uses [] = $ traitName ->toString ();
66+ }
67+ }
68+
69+ // Initialize DTO with structural info; methods/props added later
70+ $ this ->collectedClasses [$ this ->currentClassName ] = new CodemapClassDto (
71+ [], // Methods added later
72+ [], // Properties added later
73+ $ uses ,
74+ $ extends ,
75+ $ implements
76+ );
5177 }
5278 // Handle enum
5379 elseif ($ node instanceof Enum_) {
@@ -66,6 +92,14 @@ public function enterNode(Node $node): null|int|Node|array
6692 $ backingType
6793 );
6894 }
95+ // Handle trait
96+ elseif ($ node instanceof Trait_) {
97+ $ this ->currentTraitName = $ node ->namespacedName
98+ ? $ node ->namespacedName ->toString ()
99+ : (string ) $ node ->name ; // Fallback, though namespacedName should exist after NameResolver
100+
101+ $ this ->collectedTraits [$ this ->currentTraitName ] = new CodemapTraitDto ($ this ->currentTraitName );
102+ }
69103
70104 return null ;
71105 }
@@ -81,8 +115,12 @@ public function leaveNode(Node $node): null|int|Node|array
81115 elseif ($ node instanceof Enum_ && $ this ->currentEnumName !== null ) {
82116 $ this ->currentEnumName = null ;
83117 }
84- // Inside a class
85- elseif ($ this ->currentClassName !== null ) {
118+ // End of a trait
119+ elseif ($ node instanceof Trait_ && $ this ->currentTraitName !== null ) {
120+ $ this ->currentTraitName = null ;
121+ }
122+ // Inside a class or trait
123+ elseif ($ this ->currentClassName !== null || $ this ->currentTraitName !== null ) {
86124 if ($ node instanceof ClassMethod) {
87125 $ this ->handleClassMethod ($ node );
88126 } elseif ($ node instanceof Property) {
@@ -130,7 +168,7 @@ private function renderComplexType(ComplexType $node): string
130168 }
131169
132170 /**
133- * Processes a ClassMethod node, building and adding its DTO to the current class.
171+ * Processes a ClassMethod node, building and adding its DTO to the current class or trait .
134172 */
135173 private function handleClassMethod (ClassMethod $ node ): void
136174 {
@@ -156,16 +194,29 @@ private function handleClassMethod(ClassMethod $node): void
156194 $ methodParameters
157195 );
158196
159- $ oldClassDto = $ this ->collectedClasses [$ this ->currentClassName ];
160- $ updatedMethods = [...$ oldClassDto ->classMethods , $ newMethod ];
161- $ this ->collectedClasses [$ this ->currentClassName ] = new CodemapClassDto (
162- $ updatedMethods ,
163- $ oldClassDto ->classProperties
164- );
197+ if ($ this ->currentClassName !== null ) {
198+ $ oldClassDto = $ this ->collectedClasses [$ this ->currentClassName ];
199+ $ updatedMethods = [...$ oldClassDto ->classMethods , $ newMethod ];
200+ $ this ->collectedClasses [$ this ->currentClassName ] = new CodemapClassDto (
201+ $ updatedMethods ,
202+ $ oldClassDto ->classProperties ,
203+ $ oldClassDto ->usesTraits ,
204+ $ oldClassDto ->extendsClass ,
205+ $ oldClassDto ->implementsInterfaces
206+ );
207+ } elseif ($ this ->currentTraitName !== null ) {
208+ $ oldTraitDto = $ this ->collectedTraits [$ this ->currentTraitName ];
209+ $ updatedMethods = [...$ oldTraitDto ->traitMethods , $ newMethod ];
210+ $ this ->collectedTraits [$ this ->currentTraitName ] = new CodemapTraitDto (
211+ $ oldTraitDto ->traitName ,
212+ $ updatedMethods ,
213+ $ oldTraitDto ->traitProperties
214+ );
215+ }
165216 }
166217
167218 /**
168- * Processes a Property node, building and adding its DTO(s) to the current class.
219+ * Processes a Property node, building and adding its DTO(s) to the current class or trait .
169220 */
170221 private function handleProperty (Property $ node ): void
171222 {
@@ -182,12 +233,25 @@ private function handleProperty(Property $node): void
182233 $ determinedPropertyType
183234 );
184235
185- $ oldClassDto = $ this ->collectedClasses [$ this ->currentClassName ];
186- $ updatedProperties = [...$ oldClassDto ->classProperties , $ newProperty ];
187- $ this ->collectedClasses [$ this ->currentClassName ] = new CodemapClassDto (
188- $ oldClassDto ->classMethods ,
189- $ updatedProperties
190- );
236+ if ($ this ->currentClassName !== null ) {
237+ $ oldClassDto = $ this ->collectedClasses [$ this ->currentClassName ];
238+ $ updatedProperties = [...$ oldClassDto ->classProperties , $ newProperty ];
239+ $ this ->collectedClasses [$ this ->currentClassName ] = new CodemapClassDto (
240+ $ oldClassDto ->classMethods ,
241+ $ updatedProperties ,
242+ $ oldClassDto ->usesTraits ,
243+ $ oldClassDto ->extendsClass ,
244+ $ oldClassDto ->implementsInterfaces
245+ );
246+ } elseif ($ this ->currentTraitName !== null ) {
247+ $ oldTraitDto = $ this ->collectedTraits [$ this ->currentTraitName ];
248+ $ updatedProperties = [...$ oldTraitDto ->traitProperties , $ newProperty ];
249+ $ this ->collectedTraits [$ this ->currentTraitName ] = new CodemapTraitDto (
250+ $ oldTraitDto ->traitName ,
251+ $ oldTraitDto ->traitMethods ,
252+ $ updatedProperties
253+ );
254+ }
191255 }
192256 }
193257
0 commit comments