@@ -87,46 +87,57 @@ public function normalize(array $stack, string $current, bool $ignoreFlag): ?sel
8787 );
8888 }
8989
90- public function buildPath ( TLContext $ tl , string $ extractor ): string
90+ public static function arrayPathToConstructorPath ( int $ k , array $ part , int $ finalK , ? TLContext $ tl = null ): array
9191 {
92- $ new = [];
93- foreach ($ this ->path as $ k => $ part ) {
94- $ newPart = [
95- '_ ' => 'pathPart ' ,
96- 'constructor ' => $ part [0 ],
97- 'param ' => $ part [1 ],
98- 'flag ' => ['_ ' => 'paramNotFlag ' ],
99- ];
100- if (isset ($ part [2 ])) {
101- if ($ part [2 ] instanceof TypedOp) {
102- $ fallback = $ part [2 ]->build ($ tl );
103- array_walk_recursive ($ fallback , static function ($ v ): void {
104- if (\is_array ($ v )
105- && isset ($ v ['_ ' ])
106- && \in_array ($ v ['_ ' ], ['copyOp ' , 'getInputChannelByIdOp ' , 'getInputUserByIdOp ' , 'getInputPeerByIdOp ' ], true )
107- ) {
108- throw new \InvalidArgumentException ("Cannot use {$ v ['_ ' ]} as fallback in TypedOp " );
109- }
110- });
111- $ newPart ['flag ' ] = ['_ ' => 'paramIsFlagFallback ' , 'fallback ' => $ fallback ];
112- } elseif (\is_int ($ part [2 ])) {
113- if ($ part [2 ] & self ::FLAG_UNPACK_ARRAY ) {
114- if ($ tl ->buildMode instanceof Ast && !$ tl ->buildMode ->allowUnpacking ) {
115- throw new AssertionError ('Cannot use unpack_array flag in Ast mode with backrefs enabled ' );
116- }
117- $ newPart ['unpack_vector ' ] = true ;
118- }
119- if ($ part [2 ] & self ::FLAG_IF_ABSENT_ABORT ) {
120- $ newPart ['flag ' ] = ['_ ' => 'paramIsFlagAbortIfEmpty ' ];
92+ $ newPart = [
93+ '_ ' => 'pathPart ' ,
94+ 'constructor ' => $ part [0 ],
95+ 'param ' => $ part [1 ],
96+ 'flag ' => ['_ ' => 'paramNotFlag ' ],
97+ ];
98+ if (isset ($ part [2 ])) {
99+ if ($ part [2 ] instanceof TypedOp) {
100+ if ($ tl === null ) {
101+ throw new \InvalidArgumentException ('Cannot use TypedOp as fallback in this context ' );
102+ }
103+ $ fallback = $ part [2 ]->build ($ tl );
104+ array_walk_recursive ($ fallback , static function ($ v ): void {
105+ if (\is_array ($ v )
106+ && isset ($ v ['_ ' ])
107+ && \in_array ($ v ['_ ' ], ['copyOp ' , 'getInputChannelByIdOp ' , 'getInputUserByIdOp ' , 'getInputPeerByIdOp ' ], true )
108+ ) {
109+ throw new \InvalidArgumentException ("Cannot use {$ v ['_ ' ]} as fallback in TypedOp " );
121110 }
122- if ($ part [2 ] & self ::FLAG_PASSTHROUGH ) {
123- Assert::eq ($ k , \count ($ this ->path ) - 1 , 'Can only use passthrough flag on last element ' );
124- $ newPart ['flag ' ] = ['_ ' => 'paramIsFlagPassthrough ' ];
111+ });
112+ $ newPart ['flag ' ] = ['_ ' => 'paramIsFlagFallback ' , 'fallback ' => $ fallback ];
113+ } elseif (\is_int ($ part [2 ])) {
114+ if ($ part [2 ] & self ::FLAG_UNPACK_ARRAY ) {
115+ if ($ tl && $ tl ->buildMode instanceof Ast && !$ tl ->buildMode ->allowUnpacking ) {
116+ throw new AssertionError ('Cannot use unpack_array flag in Ast mode with backrefs enabled ' );
125117 }
118+ $ newPart ['unpack_vector ' ] = true ;
119+ }
120+ if ($ part [2 ] & self ::FLAG_IF_ABSENT_ABORT ) {
121+ $ newPart ['flag ' ] = ['_ ' => 'paramIsFlagAbortIfEmpty ' ];
122+ }
123+ if ($ part [2 ] & self ::FLAG_PASSTHROUGH ) {
124+ Assert::eq ($ k , $ finalK , 'Can only use passthrough flag on last element ' );
125+ $ newPart ['flag ' ] = ['_ ' => 'paramIsFlagPassthrough ' ];
126126 }
127127 }
128- $ new [] = $ newPart ;
129128 }
129+ return $ newPart ;
130+ }
131+ public function buildPath (TLContext $ tl , string $ extractor ): string
132+ {
133+ $ new = [];
134+ $ finalK = \count ($ this ->path ) - 1 ;
135+ foreach ($ this ->path as $ k => $ part ) {
136+ $ newPart = self ::arrayPathToConstructorPath ($ k , $ part , $ finalK , $ tl );
137+ $ new []= $ newPart ;
138+ }
139+ $ newPart = end ($ new );
140+
130141 $ serialized = json_encode ([$ extractor , $ this ->isFromParent , $ new ], flags: JSON_THROW_ON_ERROR );
131142 if (isset ($ tl ->buildMode ->storedByPath [$ serialized ])) {
132143 $ name = $ tl ->buildMode ->storedByPath [$ serialized ];
0 commit comments