@@ -95,6 +95,9 @@ final class ResolvedPhpDocBlock
9595 /** @var array<string, bool>|false */
9696 private array |false $ paramsImmediatelyInvokedCallable = false ;
9797
98+ /** @var array<string, bool>|false */
99+ private array |false $ paramsPureUnlessCallableIsImpure = false ;
100+
98101 /** @var array<string, ParamClosureThisTag>|false */
99102 private array |false $ paramClosureThisTags = false ;
100103
@@ -212,6 +215,7 @@ public static function createEmpty(): self
212215 $ self ->paramTags = [];
213216 $ self ->paramOutTags = [];
214217 $ self ->paramsImmediatelyInvokedCallable = [];
218+ $ self ->paramsPureUnlessCallableIsImpure = [];
215219 $ self ->paramClosureThisTags = [];
216220 $ self ->returnTag = null ;
217221 $ self ->throwsTag = null ;
@@ -276,6 +280,7 @@ public function merge(array $parents, array $parentPhpDocBlocks): self
276280 $ result ->paramTags = self ::mergeParamTags ($ this ->getParamTags (), $ parents , $ parentPhpDocBlocks );
277281 $ result ->paramOutTags = self ::mergeParamOutTags ($ this ->getParamOutTags (), $ parents , $ parentPhpDocBlocks );
278282 $ result ->paramsImmediatelyInvokedCallable = self ::mergeParamsImmediatelyInvokedCallable ($ this ->getParamsImmediatelyInvokedCallable (), $ parents , $ parentPhpDocBlocks );
283+ $ result ->paramsPureUnlessCallableIsImpure = self ::mergeParamsPureUnlessCallableIsImpure ($ this ->getParamsPureUnlessCallableIsImpure (), $ parents , $ parentPhpDocBlocks );
279284 $ result ->paramClosureThisTags = self ::mergeParamClosureThisTags ($ this ->getParamClosureThisTags (), $ parents , $ parentPhpDocBlocks );
280285 $ result ->returnTag = self ::mergeReturnTags ($ this ->getReturnTag (), $ classReflection , $ parents , $ parentPhpDocBlocks );
281286 $ result ->throwsTag = self ::mergeThrowsTags ($ this ->getThrowsTag (), $ parents );
@@ -581,6 +586,18 @@ public function getParamsImmediatelyInvokedCallable(): array
581586 return $ this ->paramsImmediatelyInvokedCallable ;
582587 }
583588
589+ /**
590+ * @return array<string, bool>
591+ */
592+ public function getParamsPureUnlessCallableIsImpure (): array
593+ {
594+ if ($ this ->paramsPureUnlessCallableIsImpure === false ) {
595+ $ this ->paramsPureUnlessCallableIsImpure = $ this ->phpDocNodeResolver ->resolveParamPureUnlessCallableIsImpure ($ this ->phpDocNode );
596+ }
597+
598+ return $ this ->paramsPureUnlessCallableIsImpure ;
599+ }
600+
584601 /**
585602 * @return array<string, ParamClosureThisTag>
586603 */
@@ -1161,6 +1178,40 @@ private static function mergeOneParentParamImmediatelyInvokedCallable(array $par
11611178 return $ paramsImmediatelyInvokedCallable ;
11621179 }
11631180
1181+ /**
1182+ * @param array<string, bool> $paramsPureUnlessCallableIsImpure
1183+ * @param array<int, self> $parents
1184+ * @param array<int, PhpDocBlock> $parentPhpDocBlocks
1185+ * @return array<string, bool>
1186+ */
1187+ private static function mergeParamsPureUnlessCallableIsImpure (array $ paramsPureUnlessCallableIsImpure , array $ parents , array $ parentPhpDocBlocks ): array
1188+ {
1189+ foreach ($ parents as $ i => $ parent ) {
1190+ $ paramsPureUnlessCallableIsImpure = self ::mergeOneParentParamPureUnlessCallableIsImpure ($ paramsPureUnlessCallableIsImpure , $ parent , $ parentPhpDocBlocks [$ i ]);
1191+ }
1192+
1193+ return $ paramsPureUnlessCallableIsImpure ;
1194+ }
1195+
1196+ /**
1197+ * @param array<string, bool> $paramsPureUnlessCallableIsImpure
1198+ * @return array<string, bool>
1199+ */
1200+ private static function mergeOneParentParamPureUnlessCallableIsImpure (array $ paramsPureUnlessCallableIsImpure , self $ parent , PhpDocBlock $ phpDocBlock ): array
1201+ {
1202+ $ parentPureUnlessCallableIsImpure = $ phpDocBlock ->transformArrayKeysWithParameterNameMapping ($ parent ->getParamsPureUnlessCallableIsImpure ());
1203+
1204+ foreach ($ parentPureUnlessCallableIsImpure as $ name => $ parentIsPureUnlessCallableIsImpure ) {
1205+ if (array_key_exists ($ name , $ paramsPureUnlessCallableIsImpure )) {
1206+ continue ;
1207+ }
1208+
1209+ $ paramsPureUnlessCallableIsImpure [$ name ] = $ parentIsPureUnlessCallableIsImpure ;
1210+ }
1211+
1212+ return $ paramsPureUnlessCallableIsImpure ;
1213+ }
1214+
11641215 /**
11651216 * @param array<string, ParamClosureThisTag> $paramsClosureThisTags
11661217 * @param array<int, self> $parents
0 commit comments