44
55use ReallifeKip \ImmutableBase \Attributes \Spec ;
66use ReallifeKip \ImmutableBase \CLI \Writer ;
7+ use ReallifeKip \ImmutableBase \ImmutableBase ;
78use ReallifeKip \ImmutableBase \Types ;
89use ReflectionProperty ;
910
2526abstract class Markdown
2627{
2728 public static array $ header = [];
29+ public static array $ enums = [];
2830 /**
2931 * Iterates all namespace groups and delegates each class to
3032 * Writer::buildClassBlock() for Markdown table generation.
@@ -42,6 +44,7 @@ public static function namespaceBlocksGenerate(array $namespaceGroups, array $cl
4244 $ content = array_merge ($ content ?? [], Writer::buildClassBlock ($ entry , $ classMap , $ shortNameCount ));
4345 }
4446 }
47+ $ content = array_merge ($ content ?? [], self ::enumBlocksGenerate ());
4548
4649 return $ content ;
4750 }
@@ -71,8 +74,8 @@ public static function contentBlocksGenerate(array $classMap, array $entry)
7174 $ content [] = $ spec ;
7275 }
7376 $ content [] = '' ;
74- $ content [] = '|name|required|type|description| ' ;
75- $ content [] = '|--|--|--|--| ' ;
77+ $ content [] = '|name|required|type|default| description| ' ;
78+ $ content [] = '|--|--|--|--|--| ' ;
7679 foreach ($ types as $ type ) {
7780 /** @var ReflectionProperty $propRef */
7881 $ propRef = $ type ['propertyRef ' ] ?? $ ref ->getProperty ($ type ['propertyName ' ]);
@@ -90,8 +93,26 @@ public static function contentBlocksGenerate(array $classMap, array $entry)
9093 $ shortname = end ($ shortname );
9194 $ typename = "[ $ shortname](# $ typename) " ;
9295 }
96+ if (enum_exists ($ type ['typename ' ]['string ' ])) {
97+ self ::$ enums [$ type ['typename ' ]['string ' ]] = true ;
98+ }
99+ }
100+ $ desc = $ propDocs ['desc ' ] ?: '- ' ;
101+ $ default = '- ' ;
102+ if (isset ($ type ['defaults ' ])) {
103+ $ default = $ type ['defaults ' ];
104+ $ default = match (true ) {
105+ $ default instanceof \BackedEnum => (string ) $ default ->value ,
106+ $ default instanceof \UnitEnum => $ default ->name ,
107+ $ default instanceof ImmutableBase => $ default ::class,
108+ is_callable ($ default ) => '(dynamic) ' ,
109+ \is_array ($ default ) => json_encode ($ default ),
110+ $ default === null => 'null ' ,
111+ $ default === false => 'false ' ,
112+ default => (string ) $ default
113+ };
93114 }
94- $ content [] = "| {$ type ['propertyName ' ]} | $ required | $ typename | " . ( $ propDocs [ ' desc ' ] ?: ' - ' ) . ' | ' ;
115+ $ content [] = "| {$ type ['propertyName ' ]} | $ required | $ typename | $ default | $ desc | " ;
95116 }
96117 $ content [] = '' ;
97118 $ content [] = '--- ' ;
@@ -136,9 +157,57 @@ final protected static function unionTypeNamesParser(array $type): string
136157 $ shortname = explode ('\\' , $ typename );
137158 $ shortname = end ($ shortname );
138159
160+ if (enum_exists ($ typename )) {
161+ self ::$ enums [$ typename ] = true ;
162+ }
163+
139164 return "[ $ shortname](# $ typename) " ;
140165 }
141166
142167 return $ typename ;
143168 }
169+ /**
170+ * Generates Markdown documentation blocks for all Enum classes
171+ * referenced by ImmutableBase property types. Only Enums actually
172+ * used as property types are included. BackedEnum cases display
173+ * both name and backing value; UnitEnum cases display name only.
174+ *
175+ * @return list<string>
176+ */
177+ public static function enumBlocksGenerate (): array
178+ {
179+ $ content = [];
180+
181+ foreach (self ::$ enums as $ enumClass => $ _ ) {
182+ $ ref = new \ReflectionEnum ($ enumClass );
183+ $ shortName = $ ref ->getShortName ();
184+ $ isBacked = $ ref ->isBacked ();
185+
186+ $ content [] = "# {$ shortName } {# {$ enumClass }} " ;
187+ $ content [] = '' ;
188+
189+ if ($ isBacked ) {
190+ $ backingType = $ ref ->getBackingType ()->getName ();
191+ $ content [] = "| case | value ( {$ backingType }) | " ;
192+ $ content [] = '|--|--| ' ;
193+ foreach ($ ref ->getCases () as $ case ) {
194+ /** @var \ReflectionEnumBackedCase $case */
195+ $ value = $ case ->getBackingValue ();
196+ $ content [] = "| {$ case ->getName ()} | {$ value } | " ;
197+ }
198+ } else {
199+ $ content [] = '| case | ' ;
200+ $ content [] = '|--| ' ;
201+ foreach ($ ref ->getCases () as $ case ) {
202+ $ content [] = "| {$ case ->getName ()} | " ;
203+ }
204+ }
205+
206+ $ content [] = '' ;
207+ $ content [] = '--- ' ;
208+ $ content [] = '' ;
209+ }
210+
211+ return $ content ;
212+ }
144213}
0 commit comments