@@ -491,12 +491,10 @@ public static function generate(int $layer, string $inputSchema, string $outputF
491491 $ stack [$ pos ][2 ] = $ oldFlag | Path::FLAG_UNPACK_ARRAY ;
492492 }
493493 if ($ isMethod ) {
494- $ stack [$ pos ][3 ] = true ;
495494 if (!$ incoming ) {
496495 $ onStackEnd ($ stack );
497496 }
498497 } else {
499- $ stack [$ pos ][3 ] = false ;
500498 $ recurse ($ onStackEnd , $ t , $ stack , $ stackTypes , $ incoming );
501499 }
502500 unset($ stack [$ pos ]);
@@ -508,11 +506,11 @@ public static function generate(int $layer, string $inputSchema, string $outputF
508506
509507 if ($ incoming ) {
510508 foreach ($ TL ->getMethodsOfType ($ type , true ) as $ method => $ data ) {
511- $ stack [$ pos ] = [$ method , '' , 0 , true ];
509+ $ stack [$ pos ] = [$ method , '' , 0 ];
512510 $ onStackEnd ($ stack );
513511 }
514512 foreach ($ TL ->getMethodsOfType ("Vector< $ type> " , true ) as $ method => $ data ) {
515- $ stack [$ pos ] = [$ method , '' , Path::FLAG_UNPACK_ARRAY , true ];
513+ $ stack [$ pos ] = [$ method , '' , Path::FLAG_UNPACK_ARRAY ];
516514 $ onStackEnd ($ stack );
517515 }
518516 }
@@ -591,7 +589,7 @@ public static function generate(int $layer, string $inputSchema, string $outputF
591589 continue ;
592590 }
593591 $ type = $ TL ->tl ->getConstructors ()->findByPredicate ($ constructor )['type ' ];
594- $ stack = [[$ constructor , 'file_reference ' , 0 , false ]];
592+ $ stack = [[$ constructor , 'file_reference ' , 0 ]];
595593 $ stackTypes = [$ type => 1 ];
596594
597595 $ outgoingTraversalPairs = [];
@@ -601,20 +599,14 @@ static function (array $stack) use (&$outgoingTraversalPairs): void {
601599 if ($ pair [1 ] === 'file_reference ' ) {
602600 continue ;
603601 }
604- $ pairTraverse = Path::arrayPathToTraversePath ($ pair );
605- $ encoded = json_encode ($ pairTraverse );
606- if (!isset ($ outgoingTraversalPairs [$ encoded ])) {
607- $ outgoingTraversalPairs [$ encoded ] = $ pairTraverse ;
608- }
602+ $ outgoingTraversalPairs [$ pair [0 ]][$ pair [1 ]] = $ pair ;
609603 }
610604 },
611605 $ type ,
612606 $ stack ,
613607 $ stackTypes ,
614608 false ,
615609 );
616- ksort ($ outgoingTraversalPairs );
617- $ outgoingTraversalPairs = array_values ($ outgoingTraversalPairs );
618610 $ outgoingTraversalPairsByCons [$ constructor ] = $ outgoingTraversalPairs ;
619611 }
620612 unset($ outgoingTraversalPairs );
@@ -623,7 +615,7 @@ static function (array $stack) use (&$outgoingTraversalPairs): void {
623615 $ tmp = new Ast (blacklistedPredicates: $ blacklistedPredicates , allowUnpacking: true , outputSchema: $ pre );
624616 foreach ($ incomingCons as $ constructor => $ _ ) {
625617 $ type = ucfirst ($ constructor );
626- $ stack = [[$ constructor , 'file_reference ' , 0 , false ]];
618+ $ stack = [[$ constructor , 'file_reference ' , 0 ]];
627619 $ stackTypes = [$ type => 1 ];
628620
629621 $ incomingTraversalPairs = [];
@@ -640,11 +632,7 @@ static function (array $stack) use ($locations, $TL, $tmp, &$incomingTraversalPa
640632 $ pair = $ stack [$ x ];
641633
642634 if ($ pair [1 ] !== 'file_reference ' ) {
643- $ pairTraverse = Path::arrayPathToTraversePath ($ pair );
644- $ encoded = json_encode ($ pairTraverse );
645- if (!isset ($ tmpPairs [$ encoded ])) {
646- $ tmpPairs [$ encoded ] = $ pairTraverse ;
647- }
635+ $ tmpPairs [$ pair [0 ]][$ pair [1 ]] = $ pair ;
648636 }
649637
650638 foreach ($ locations [$ pair [0 ]] ?? [] as $ op ) {
@@ -669,7 +657,10 @@ static function (array $stack) use ($locations, $TL, $tmp, &$incomingTraversalPa
669657 $ slice [] = $ pair ;
670658 }
671659 if ($ hadAnyNotNoop ) {
672- $ incomingTraversalPairs += $ tmpPairs ;
660+ foreach ($ tmpPairs as $ cons => $ fields ) {
661+ $ incomingTraversalPairs [$ pair [0 ]] ??= [];
662+ $ incomingTraversalPairs [$ pair [0 ]] += $ fields ;
663+ }
673664 }
674665 if (!$ hadAny ) {
675666 throw new AssertionError ("Uncovered path: " . json_encode ($ stack ));
@@ -718,9 +709,6 @@ static function (array $stack) use ($locations, $TL, $tmp, &$incomingTraversalPa
718709 $ stackTypes ,
719710 true ,
720711 );
721-
722- ksort ($ incomingTraversalPairs );
723- $ incomingTraversalPairs = array_values ($ incomingTraversalPairs );
724712 $ incomingTraversalPairsByCons [$ constructor ] = $ incomingTraversalPairs ;
725713 }
726714 unset($ incomingTraversalPairs );
@@ -752,12 +740,54 @@ static function (array $stack) use ($locations, $TL, $tmp, &$incomingTraversalPa
752740 $ layer ,
753741 array_filter ($ outgoingCons ),
754742 $ incomingCons ,
755- $ incomingTraversalPairsByCons ,
756- $ outgoingTraversalPairsByCons ,
743+ self :: fixupTraversalPairs ( $ TL , $ incomingTraversalPairsByCons) ,
744+ self :: fixupTraversalPairs ( $ TL , $ outgoingTraversalPairsByCons) ,
757745 $ outputFile ,
758746 $ outputFileJson
759747 );
760748
761749 echo ("OK $ layer! \n" .PHP_EOL );
762750 }
751+
752+ public static function fixupTraversalPairs (TLWrapper $ TL , array $ pairsByCons ): array
753+ {
754+ $ fixed = [];
755+ foreach ($ pairsByCons as $ parentCons => $ pairs ) {
756+ foreach ($ pairs as $ cons => $ fields ) {
757+ $ newFields = [];
758+ foreach ($ fields as $ field => $ part ) {
759+ $ newPart = [
760+ '_ ' => 'traverseParam ' ,
761+ 'name ' => $ field ,
762+ 'is_vector ' => false ,
763+ 'is_flag ' => false ,
764+ ];
765+ if (isset ($ part [2 ])) {
766+ if ($ part [2 ] instanceof TypedOp) {
767+ throw new \InvalidArgumentException ('Cannot use TypedOp in traverse path ' );
768+ } elseif (\is_int ($ part [2 ])) {
769+ if ($ part [2 ] & Path::FLAG_UNPACK_ARRAY ) {
770+ $ newPart ['is_vector ' ] = true ;
771+ }
772+ if ($ part [2 ] & Path::FLAG_IF_ABSENT_ABORT ) {
773+ $ newPart ['is_flag ' ] = true ;
774+ }
775+ if ($ part [2 ] & Path::FLAG_PASSTHROUGH ) {
776+ $ newPart ['is_flag ' ] = true ;
777+ }
778+ }
779+ }
780+ $ newFields [] = $ newPart ;
781+ }
782+ Assert::notEmpty ($ newFields );
783+
784+ $ fixed [$ parentCons ][] = [
785+ '_ ' => $ TL ->isConstructor ($ cons ) ? 'traverseConstructor ' : 'traverseMethod ' ,
786+ 'predicate ' => $ cons ,
787+ 'params ' => $ newFields ,
788+ ];
789+ }
790+ }
791+ return $ fixed ;
792+ }
763793}
0 commit comments