@@ -193,8 +193,9 @@ private function childHasInterestingData(Frame $child): bool
193193
194194 private function wrapInGIfNeeded (string $ name ): string
195195 {
196- if (str_contains ($ name , '$ ' ) || str_contains ($ name , '- ' )) {
197- return '_G[" ' . $ name . '"] ' ;
196+ if (!preg_match ('/^[A-z][A-z0-9]*$/ ' , $ name )) {
197+ // json_encode adds and properly escapes quotes
198+ return '_G[ ' . json_encode ($ name ) . '] ' ;
198199 }
199200
200201 return $ name ;
@@ -209,6 +210,7 @@ private function writeFrame(Frame $frame, ?string $linkPrefix, ?string $typeOver
209210
210211 $ data = '' ;
211212 $ globalChildrenWithParentKey = [];
213+ /** @var array<string, KeyValueDTO> $inheritedKeyValues */
212214 $ inheritedKeyValues = [];
213215 foreach ($ frame ->getChildren () as $ child ) {
214216 if ($ this ->childHasInterestingData ($ child )) {
@@ -268,12 +270,15 @@ private function writeFrame(Frame $frame, ?string $linkPrefix, ?string $typeOver
268270 return $ data . "\n" ;
269271 }
270272
273+ /**
274+ * @param array<string, KeyValueDTO> $inheritedKeyValues
275+ */
271276 private function handleInherits (Frame $ frame , array &$ inheritedKeyValues , ?string $ linkPrefix , string &$ data ): void
272277 {
273278 foreach ($ this ->iterateInherits ($ frame ) as $ template ) {
274279 $ template = $ template ->withParent ($ frame );
275280 foreach ($ template ->getKeyValues () as $ key => $ value ) {
276- $ inheritedKeyValues [$ key ] = $ value ;
281+ $ inheritedKeyValues [$ key ] ?? = $ value ;
277282 }
278283 foreach ($ template ->getChildren () as $ child ) {
279284 $ clone = $ child ->withParent ($ frame );
@@ -287,7 +292,11 @@ private function handleInherits(Frame $frame, array &$inheritedKeyValues, ?strin
287292 : $ child ->getType (),
288293 );
289294 if ($ clone ->getParentKey ()) {
290- $ inheritedKeyValues [$ clone ->getParentKey ()] = [$ clone ->getName ()];
295+ $ inheritedKeyValues [$ clone ->getParentKey ()] ??= new KeyValueDTO (
296+ $ clone ->getParentKey (),
297+ $ clone ->getName (),
298+ KeyValueTypeEnum::GLOBAL ,
299+ );
291300 }
292301 }
293302 }
@@ -308,7 +317,7 @@ private function writeClassAndFieldHints(Frame $frame): string
308317 }
309318 $ data .= "\n" ;
310319 foreach ($ frame ->getKeyValues () as $ key => $ value ) {
311- $ data .= '--- @field ' . $ key . ' ' . $ value[ 1 ] . ' # ' . $ value[ 0 ] . "\n" ;
320+ $ data .= '--- @field ' . $ key . ' ' . $ value-> type -> luaType () . ' # ' . $ value-> value . "\n" ;
312321 }
313322 $ allParentKeys = [];
314323 $ allParentArrays = [];
@@ -383,23 +392,46 @@ private function iterateInherits(Frame $frame): iterable
383392 }
384393 }
385394
395+ /**
396+ * @param array<string, KeyValueDTO> $inheritedKeyValues
397+ */
386398 private function writeExplicitGlobal (
387399 Frame $ frame ,
388400 array $ globalChildrenWithParentKey ,
389401 array $ inheritedKeyValues ,
390402 ): string {
391403 $ name = $ this ->wrapInGIfNeeded ($ frame ->getName ());
392404 $ data = $ name . " = {} \n" ;
405+ $ definedKeys = [];
393406 foreach ($ globalChildrenWithParentKey as $ key => $ value ) {
407+ $ definedKeys [$ key ] = true ;
394408 $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value ) . "\n" ;
395409 }
396410 foreach ($ frame ->getKeyValues () as $ key => $ value ) {
397- $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value [0 ]) . "\n" ;
411+ if (isset ($ definedKeys [$ key ])) {
412+ continue ;
413+ }
414+ $ definedKeys [$ key ] = true ;
415+ $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->formatKeyValue ($ value ) . "\n" ;
398416 }
399417 foreach ($ inheritedKeyValues as $ key => $ value ) {
400- $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->wrapInGIfNeeded ($ value [0 ]) . " -- inherited \n" ;
418+ if (isset ($ definedKeys [$ key ])) {
419+ continue ;
420+ }
421+ $ definedKeys [$ key ] = true ;
422+ $ data .= $ name . '[" ' . $ key . '"] = ' . $ this ->formatKeyValue ($ value ) . " -- inherited \n" ;
401423 }
402424
403425 return $ data ;
404426 }
427+
428+ private function formatKeyValue (KeyValueDTO $ keyValue ): string
429+ {
430+ return match ($ keyValue ->type ) {
431+ KeyValueTypeEnum::STRING => json_encode ($ keyValue ->value ), // json_encode adds and properly escapes quotes
432+ KeyValueTypeEnum::NUMBER , KeyValueTypeEnum::BOOLEAN => $ keyValue ->value ,
433+ KeyValueTypeEnum::GLOBAL => $ this ->wrapInGIfNeeded ($ keyValue ->value ),
434+ KeyValueTypeEnum::NIL => 'nil ' ,
435+ };
436+ }
405437}
0 commit comments