@@ -182,6 +182,10 @@ private function wrapInGIfNeeded(string $name): string
182182 private function writeFrame (Frame $ frame , ?string $ linkPrefix , ?string $ typeOverride = null ): string
183183 {
184184 $ shouldWriteGlobal = $ frame ->getRootNode ()->getName () && $ frame ->getRootNode ()::class === Frame::class;
185+ $ shouldWriteExplicitGlobal = $ shouldWriteGlobal && $ frame ->getName ();
186+ $ shouldWriteType = $ typeOverride && $ shouldWriteExplicitGlobal ;
187+ $ shouldWriteClass = !$ typeOverride && $ frame ->getClassName ();
188+
185189 $ data = '' ;
186190 $ globalChildrenWithParentKey = [];
187191 $ inheritedKeyValues = [];
@@ -202,6 +206,10 @@ private function writeFrame(Frame $frame, ?string $linkPrefix, ?string $typeOver
202206 );
203207 }
204208
209+ if (!$ shouldWriteType && !$ shouldWriteClass && !$ shouldWriteExplicitGlobal ) {
210+ return $ data ;
211+ }
212+
205213 if ($ linkPrefix ) {
206214 $ data .= "--- [Source]( $ linkPrefix#L " . $ frame ->getLineNumber () . ") \n" ;
207215 }
@@ -217,57 +225,32 @@ private function writeFrame(Frame $frame, ?string $linkPrefix, ?string $typeOver
217225 } elseif ($ frame instanceof Template) {
218226 $ data .= "--- Template \n" ;
219227 }
220- if ($ typeOverride ) {
221- $ data .= '--- @type ' . $ typeOverride ;
222- } else {
223- $ data .= '--- @class ' . $ frame ->getClassName () . ' : ' . $ frame ->getType ();
224- foreach ($ frame ->getInherits () as $ inherit ) {
225- $ data .= ', ' . $ inherit ;
228+ if ($ frame instanceof Template) { // includes Intrinsics
229+ if ($ frame ->getParentArray ()) {
230+ $ data .= "--- Adds itself to the parent inside the array ` {$ frame ->getParentArray ()}` \n" ;
226231 }
227- foreach ($ frame ->getMixins () as $ mixin ) {
228- $ data .= ' , ' . $ mixin ;
232+ if ($ frame ->getParentKey () ) {
233+ $ data .= " --- Adds itself to the parent with key ` { $ frame -> getParentKey ()} ` \n" ;
229234 }
230235 }
231- $ data .= "\n" ;
232-
233- foreach ($ frame ->getKeyValues () as $ key => $ value ) {
234- $ data .= '--- @field ' . $ key . ' ' . $ value [1 ] . ' # ' . $ value [0 ] . "\n" ;
236+ if ($ shouldWriteType ) {
237+ $ data .= '--- @type ' . $ typeOverride . "\n" ;
235238 }
236- foreach ($ frame ->getChildren () as $ child ) {
237- if ($ child ->getParentKey ()) {
238- if ($ this ->childHasInterestingData ($ child )) {
239- $ data .= '--- @field ' . $ child ->getParentKey () . ' ' . $ child ->getClassName () . "\n" ;
240- } else {
241- $ data .= '--- @field ' . $ child ->getParentKey () . ' ' . $ child ->getType () . "\n" ;
242- }
243- }
239+ if ($ shouldWriteClass ) {
240+ $ data .= $ this ->writeClassAndFieldHints ($ frame );
244241 }
245- if ($ shouldWriteGlobal && $ frame ->getName ()) {
246- $ name = $ this ->wrapInGIfNeeded ($ frame ->getName ());
247- $ data .= $ name . " = {} \n" ;
248- foreach ($ globalChildrenWithParentKey as $ key => $ value ) {
249- $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value ) . "\n" ;
250- }
251- foreach ($ frame ->getKeyValues () as $ key => $ value ) {
252- $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value [0 ]) . "\n" ;
253- }
254- foreach ($ inheritedKeyValues as $ key => $ value ) {
255- $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value [0 ]) . " -- inherited \n" ;
256- }
242+
243+ if ($ shouldWriteExplicitGlobal ) {
244+ $ data .= $ this ->writeExplicitGlobal ($ frame , $ globalChildrenWithParentKey , $ inheritedKeyValues );
257245 }
258246
259247 return $ data . "\n" ;
260248 }
261249
262250 private function handleInherits (Frame $ frame , array &$ inheritedKeyValues , ?string $ linkPrefix , string &$ data ): void
263251 {
264- foreach ($ frame ->getInherits () as $ templateName ) {
265- $ template = $ this ->templateRegistry ->get ($ templateName );
266- if (!$ template ) {
267- continue ;
268- }
252+ foreach ($ this ->iterateInherits ($ frame ) as $ template ) {
269253 $ template = $ template ->withParent ($ frame );
270- $ this ->handleInherits ($ template , $ inheritedKeyValues , $ linkPrefix , $ data );
271254 foreach ($ template ->getKeyValues () as $ key => $ value ) {
272255 $ inheritedKeyValues [$ key ] = $ value ;
273256 }
@@ -283,10 +266,97 @@ private function handleInherits(Frame $frame, array &$inheritedKeyValues, ?strin
283266 : $ child ->getType (),
284267 );
285268 if ($ clone ->getParentKey ()) {
286- $ inheritedKeyValues [$ clone ->getParentKey ()] = [$ this -> wrapInGIfNeeded ( $ clone ->getName () )];
269+ $ inheritedKeyValues [$ clone ->getParentKey ()] = [$ clone ->getName ()];
287270 }
288271 }
289272 }
290273 }
291274 }
275+
276+ private function writeClassAndFieldHints (Frame $ frame ): string
277+ {
278+ if (!$ frame ->getClassName ()) {
279+ return '' ;
280+ }
281+ $ data = '--- @class ' . $ frame ->getClassName () . ' : ' . $ frame ->getType ();
282+ foreach ($ frame ->getInherits () as $ inherit ) {
283+ $ data .= ', ' . $ inherit ;
284+ }
285+ foreach ($ frame ->getMixins () as $ mixin ) {
286+ $ data .= ', ' . $ mixin ;
287+ }
288+ $ data .= "\n" ;
289+ foreach ($ frame ->getKeyValues () as $ key => $ value ) {
290+ $ data .= '--- @field ' . $ key . ' ' . $ value [1 ] . ' # ' . $ value [0 ] . "\n" ;
291+ }
292+ foreach ($ frame ->getChildren () as $ child ) {
293+ $ typehint = $ this ->childHasInterestingData ($ child ) ? $ child ->getClassName () : $ child ->getType ();
294+ $ parentKeys = [];
295+ if ($ child ->getParentKey ()) {
296+ $ parentKeys [$ child ->getParentKey ()] = $ typehint ;
297+ }
298+ foreach ($ this ->iterateInherits ($ child ) as $ inherit ) {
299+ if ($ inherit ->getParentKey ()) {
300+ $ inheritTypehint = $ typehint ?: $ inherit ->getClassName ();
301+ $ parentKeys [$ inherit ->getParentKey ()] = $ inheritTypehint ;
302+ }
303+ }
304+ foreach ($ parentKeys as $ parentKey => $ typehint ) {
305+ $ data .= '--- @field ' . $ parentKey . ' ' . $ typehint . "\n" ;
306+ }
307+
308+ $ parentArrays = [];
309+ if ($ child ->getParentArray ()) {
310+ $ parentArrays [$ child ->getParentArray ()] = $ typehint ;
311+ }
312+ foreach ($ this ->iterateInherits ($ child ) as $ inherit ) {
313+ if ($ inherit ->getParentArray ()) {
314+ $ inheritTypehint = $ typehint ?: $ inherit ->getClassName ();
315+ $ parentArrays [$ inherit ->getParentArray ()] ??= $ inheritTypehint ;
316+ }
317+ }
318+ foreach ($ parentArrays as $ parentArray => $ typehint ) {
319+ $ data .= '--- @field ' . $ parentArray . ' table<number, ' . $ typehint . "> \n" ;
320+ }
321+ }
322+
323+ return $ data ;
324+ }
325+
326+ /**
327+ * @param Frame $frame
328+ *
329+ * @return iterable<Template>
330+ */
331+ private function iterateInherits (Frame $ frame ): iterable
332+ {
333+ foreach ($ frame ->getInherits () as $ templateName ) {
334+ $ template = $ this ->templateRegistry ->get ($ templateName );
335+ if (!$ template ) {
336+ continue ;
337+ }
338+ yield $ template ;
339+ yield from $ this ->iterateInherits ($ template );
340+ }
341+ }
342+
343+ private function writeExplicitGlobal (
344+ Frame $ frame ,
345+ array $ globalChildrenWithParentKey ,
346+ array $ inheritedKeyValues ,
347+ ): string {
348+ $ name = $ this ->wrapInGIfNeeded ($ frame ->getName ());
349+ $ data = $ name . " = {} \n" ;
350+ foreach ($ globalChildrenWithParentKey as $ key => $ value ) {
351+ $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value ) . "\n" ;
352+ }
353+ foreach ($ frame ->getKeyValues () as $ key => $ value ) {
354+ $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value [0 ]) . "\n" ;
355+ }
356+ foreach ($ inheritedKeyValues as $ key => $ value ) {
357+ $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value [0 ]) . " -- inherited \n" ;
358+ }
359+
360+ return $ data ;
361+ }
292362}
0 commit comments