@@ -96,6 +96,9 @@ class ResolvedPhpDocBlock
9696 /** @var array<string, bool>|false */
9797 private array |false $ paramsImmediatelyInvokedCallable = false ;
9898
99+ /** @var array<string, bool>|false */
100+ private array |false $ paramsPureUnlessCallableIsImpure = false ;
101+
99102 /** @var array<string, ParamClosureThisTag>|false */
100103 private array |false $ paramClosureThisTags = false ;
101104
@@ -213,6 +216,7 @@ public static function createEmpty(): self
213216 $ self ->paramTags = [];
214217 $ self ->paramOutTags = [];
215218 $ self ->paramsImmediatelyInvokedCallable = [];
219+ $ self ->paramsPureUnlessCallableIsImpure = [];
216220 $ self ->paramClosureThisTags = [];
217221 $ self ->returnTag = null ;
218222 $ self ->throwsTag = null ;
@@ -277,6 +281,7 @@ public function merge(array $parents, array $parentPhpDocBlocks): self
277281 $ result ->paramTags = self ::mergeParamTags ($ this ->getParamTags (), $ parents , $ parentPhpDocBlocks );
278282 $ result ->paramOutTags = self ::mergeParamOutTags ($ this ->getParamOutTags (), $ parents , $ parentPhpDocBlocks );
279283 $ result ->paramsImmediatelyInvokedCallable = self ::mergeParamsImmediatelyInvokedCallable ($ this ->getParamsImmediatelyInvokedCallable (), $ parents , $ parentPhpDocBlocks );
284+ $ result ->paramsPureUnlessCallableIsImpure = self ::mergeParamsPureUnlessCallableIsImpure ($ this ->getParamsPureUnlessCallableIsImpure (), $ parents , $ parentPhpDocBlocks );
280285 $ result ->paramClosureThisTags = self ::mergeParamClosureThisTags ($ this ->getParamClosureThisTags (), $ parents , $ parentPhpDocBlocks );
281286 $ result ->returnTag = self ::mergeReturnTags ($ this ->getReturnTag (), $ classReflection , $ parents , $ parentPhpDocBlocks );
282287 $ result ->throwsTag = self ::mergeThrowsTags ($ this ->getThrowsTag (), $ parents );
@@ -582,6 +587,18 @@ public function getParamsImmediatelyInvokedCallable(): array
582587 return $ this ->paramsImmediatelyInvokedCallable ;
583588 }
584589
590+ /**
591+ * @return array<string, bool>
592+ */
593+ public function getParamsPureUnlessCallableIsImpure (): array
594+ {
595+ if ($ this ->paramsPureUnlessCallableIsImpure === false ) {
596+ $ this ->paramsPureUnlessCallableIsImpure = $ this ->phpDocNodeResolver ->resolveParamPureUnlessCallableIsImpure ($ this ->phpDocNode );
597+ }
598+
599+ return $ this ->paramsPureUnlessCallableIsImpure ;
600+ }
601+
585602 /**
586603 * @return array<string, ParamClosureThisTag>
587604 */
@@ -1162,6 +1179,40 @@ private static function mergeOneParentParamImmediatelyInvokedCallable(array $par
11621179 return $ paramsImmediatelyInvokedCallable ;
11631180 }
11641181
1182+ /**
1183+ * @param array<string, bool> $paramsPureUnlessCallableIsImpure
1184+ * @param array<int, self> $parents
1185+ * @param array<int, PhpDocBlock> $parentPhpDocBlocks
1186+ * @return array<string, bool>
1187+ */
1188+ private static function mergeParamsPureUnlessCallableIsImpure (array $ paramsPureUnlessCallableIsImpure , array $ parents , array $ parentPhpDocBlocks ): array
1189+ {
1190+ foreach ($ parents as $ i => $ parent ) {
1191+ $ paramsPureUnlessCallableIsImpure = self ::mergeOneParentParamPureUnlessCallableIsImpure ($ paramsPureUnlessCallableIsImpure , $ parent , $ parentPhpDocBlocks [$ i ]);
1192+ }
1193+
1194+ return $ paramsPureUnlessCallableIsImpure ;
1195+ }
1196+
1197+ /**
1198+ * @param array<string, bool> $paramsPureUnlessCallableIsImpure
1199+ * @return array<string, bool>
1200+ */
1201+ private static function mergeOneParentParamPureUnlessCallableIsImpure (array $ paramsPureUnlessCallableIsImpure , self $ parent , PhpDocBlock $ phpDocBlock ): array
1202+ {
1203+ $ parentPureUnlessCallableIsImpure = $ phpDocBlock ->transformArrayKeysWithParameterNameMapping ($ parent ->getParamsPureUnlessCallableIsImpure ());
1204+
1205+ foreach ($ parentPureUnlessCallableIsImpure as $ name => $ parentIsPureUnlessCallableIsImpure ) {
1206+ if (array_key_exists ($ name , $ paramsPureUnlessCallableIsImpure )) {
1207+ continue ;
1208+ }
1209+
1210+ $ paramsPureUnlessCallableIsImpure [$ name ] = $ parentIsPureUnlessCallableIsImpure ;
1211+ }
1212+
1213+ return $ paramsPureUnlessCallableIsImpure ;
1214+ }
1215+
11651216 /**
11661217 * @param array<string, ParamClosureThisTag> $paramsClosureThisTags
11671218 * @param array<int, self> $parents
0 commit comments