@@ -124,18 +124,25 @@ public function enterNode(Node $node)
124124 );
125125 }
126126
127- /** @var array<string, array{hasSideEffects?: bool, pureUnlessCallableIsImpureParameters?: array<string, bool>}> $metadata */
127+ /** @var array<string, array{hasSideEffects?: bool, pureUnlessCallableIsImpureParameters?: array<string, bool>, pureUnlessParameterPassedParameters?: array<string, bool> }> $metadata */
128128 $ metadata = require __DIR__ . '/functionMetadata_original.php ' ;
129129 foreach ($ visitor ->functions as $ functionName ) {
130130 if (array_key_exists ($ functionName , $ metadata )) {
131131 if (isset ($ metadata [$ functionName ]['hasSideEffects ' ]) && $ metadata [$ functionName ]['hasSideEffects ' ]) {
132132 throw new ShouldNotHappenException ($ functionName );
133133 }
134134
135- if (isset ($ metadata [$ functionName ]['pureUnlessCallableIsImpureParameters ' ])) {
136- $ metadata [$ functionName ] = [
137- 'pureUnlessCallableIsImpureParameters ' => $ metadata [$ functionName ]['pureUnlessCallableIsImpureParameters ' ],
138- ];
135+ $ conditions = [];
136+ foreach (['pureUnlessCallableIsImpureParameters ' , 'pureUnlessParameterPassedParameters ' ] as $ conditionKey ) {
137+ if (!isset ($ metadata [$ functionName ][$ conditionKey ])) {
138+ continue ;
139+ }
140+
141+ $ conditions [$ conditionKey ] = $ metadata [$ functionName ][$ conditionKey ];
142+ }
143+
144+ if ($ conditions !== []) {
145+ $ metadata [$ functionName ] = $ conditions ;
139146
140147 continue ;
141148 }
@@ -197,40 +204,49 @@ public function enterNode(Node $node)
197204 * - ['pureUnlessCallableIsImpureParameters' => array<string, true>] - pure unless
198205 * one of the listed callable parameters (keyed by parameter name) receives an
199206 * impure callable, e.g. array_map()'s 'callback'.
207+ * - ['pureUnlessParameterPassedParameters' => array<string, true>] - pure unless
208+ * one of the listed (by-ref out) parameters (keyed by parameter name) receives
209+ * an argument, e.g. str_replace()'s 'count'.
200210 */
201211
202- /** @var array<string, array{hasSideEffects: bool}|array{ pureUnlessCallableIsImpureParameters: array<string, bool>}> */
212+ /** @var array<string, array{hasSideEffects? : bool, pureUnlessCallableIsImpureParameters?: array<string, bool>, pureUnlessParameterPassedParameters? : array<string, bool>}> */
203213return [
204214%s
205215];
206216php;
207217 $ content = '' ;
208218 $ escape = static fn (mixed $ value ): string => var_export ($ value , true );
209- $ encodeHasSideEffects = static fn (array $ meta ) => [$ escape ('hasSideEffects ' ), $ escape ($ meta ['hasSideEffects ' ])];
210- $ encodePureUnlessCallableIsImpureParameters = static fn (array $ meta ) => [
211- $ escape ('pureUnlessCallableIsImpureParameters ' ),
212- sprintf (
213- '[%s] ' ,
214- implode (
215- ' , ' ,
216- array_map (
217- static fn ($ key , $ param ) => sprintf ('%s => %s ' , $ escape ($ key ), $ escape ($ param )),
218- array_keys ($ meta ['pureUnlessCallableIsImpureParameters ' ]),
219- $ meta ['pureUnlessCallableIsImpureParameters ' ],
220- ),
219+ $ encodeParameterMap = static fn (array $ parameters ) => sprintf (
220+ '[%s] ' ,
221+ implode (
222+ ', ' ,
223+ array_map (
224+ static fn ($ key , $ param ) => sprintf ('%s => %s ' , $ escape ($ key ), $ escape ($ param )),
225+ array_keys ($ parameters ),
226+ $ parameters ,
221227 ),
222228 ),
223- ] ;
229+ ) ;
224230
225231 foreach ($ metadata as $ name => $ meta ) {
232+ $ entries = [];
233+ if (isset ($ meta ['hasSideEffects ' ])) {
234+ $ entries [] = sprintf ('%s => %s ' , $ escape ('hasSideEffects ' ), $ escape ($ meta ['hasSideEffects ' ]));
235+ }
236+ if (isset ($ meta ['pureUnlessCallableIsImpureParameters ' ])) {
237+ $ entries [] = sprintf ('%s => %s ' , $ escape ('pureUnlessCallableIsImpureParameters ' ), $ encodeParameterMap ($ meta ['pureUnlessCallableIsImpureParameters ' ]));
238+ }
239+ if (isset ($ meta ['pureUnlessParameterPassedParameters ' ])) {
240+ $ entries [] = sprintf ('%s => %s ' , $ escape ('pureUnlessParameterPassedParameters ' ), $ encodeParameterMap ($ meta ['pureUnlessParameterPassedParameters ' ]));
241+ }
242+ if ($ entries === []) {
243+ throw new ShouldNotHappenException ($ escape ($ meta ));
244+ }
245+
226246 $ content .= sprintf (
227- "\t%s => [%s => %s ], \n" ,
247+ "\t%s => [%s], \n" ,
228248 var_export ($ name , true ),
229- ...match (true ) {
230- isset ($ meta ['hasSideEffects ' ]) => $ encodeHasSideEffects ($ meta ),
231- isset ($ meta ['pureUnlessCallableIsImpureParameters ' ]) => $ encodePureUnlessCallableIsImpureParameters ($ meta ),
232- default => throw new ShouldNotHappenException ($ escape ($ meta )),
233- },
249+ implode (', ' , $ entries ),
234250 );
235251 }
236252
0 commit comments