@@ -97,6 +97,14 @@ class IntersectionType implements CompoundType
9797
9898 private ?TrinaryLogic $ isConstantScalarValue = null ;
9999
100+ private ?TrinaryLogic $ isCallable = null ;
101+
102+ /** @var array<string, Type> */
103+ private array $ cachedGetOffsetValueType = [];
104+
105+ /** @var array<string, TrinaryLogic> */
106+ private array $ cachedHasOffsetValueType = [];
107+
100108 /**
101109 * @api
102110 * @param list<Type> $types
@@ -910,6 +918,15 @@ public function isOffsetAccessLegal(): TrinaryLogic
910918 }
911919
912920 public function hasOffsetValueType (Type $ offsetType ): TrinaryLogic
921+ {
922+ $ cacheKey = $ offsetType ->describe (VerbosityLevel::cache ());
923+ if (isset ($ this ->cachedHasOffsetValueType [$ cacheKey ])) {
924+ return $ this ->cachedHasOffsetValueType [$ cacheKey ];
925+ }
926+ return $ this ->cachedHasOffsetValueType [$ cacheKey ] = $ this ->doHasOffsetValueType ($ offsetType );
927+ }
928+
929+ private function doHasOffsetValueType (Type $ offsetType ): TrinaryLogic
913930 {
914931 if ($ this ->isList ()->yes ()) {
915932 $ arrayKeyOffsetType = $ offsetType ->toArrayKey ();
@@ -964,6 +981,15 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
964981 }
965982
966983 public function getOffsetValueType (Type $ offsetType ): Type
984+ {
985+ $ cacheKey = $ offsetType ->describe (VerbosityLevel::cache ());
986+ if (isset ($ this ->cachedGetOffsetValueType [$ cacheKey ])) {
987+ return $ this ->cachedGetOffsetValueType [$ cacheKey ];
988+ }
989+ return $ this ->cachedGetOffsetValueType [$ cacheKey ] = $ this ->doGetOffsetValueType ($ offsetType );
990+ }
991+
992+ private function doGetOffsetValueType (Type $ offsetType ): Type
967993 {
968994 $ result = $ this ->intersectTypes (static fn (Type $ type ): Type => $ type ->getOffsetValueType ($ offsetType ));
969995 if ($ this ->isOversizedArray ()->yes ()) {
@@ -1181,7 +1207,7 @@ public function getEnumCaseObject(): ?EnumCaseObjectType
11811207
11821208 public function isCallable (): TrinaryLogic
11831209 {
1184- return $ this ->intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->isCallable ());
1210+ return $ this ->isCallable ??= $ this -> intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->isCallable ());
11851211 }
11861212
11871213 public function getCallableParametersAcceptors (ClassMemberAccessAnswerer $ scope ): array
0 commit comments