@@ -96,6 +96,14 @@ class IntersectionType implements CompoundType
9696
9797 private ?TrinaryLogic $ isConstantScalarValue = null ;
9898
99+ private ?TrinaryLogic $ isCallable = null ;
100+
101+ /** @var array<string, Type> */
102+ private array $ cachedGetOffsetValueType = [];
103+
104+ /** @var array<string, TrinaryLogic> */
105+ private array $ cachedHasOffsetValueType = [];
106+
99107 /**
100108 * @api
101109 * @param list<Type> $types
@@ -903,6 +911,15 @@ public function isOffsetAccessLegal(): TrinaryLogic
903911 }
904912
905913 public function hasOffsetValueType (Type $ offsetType ): TrinaryLogic
914+ {
915+ $ cacheKey = $ offsetType ->describe (VerbosityLevel::cache ());
916+ if (isset ($ this ->cachedHasOffsetValueType [$ cacheKey ])) {
917+ return $ this ->cachedHasOffsetValueType [$ cacheKey ];
918+ }
919+ return $ this ->cachedHasOffsetValueType [$ cacheKey ] = $ this ->doHasOffsetValueType ($ offsetType );
920+ }
921+
922+ private function doHasOffsetValueType (Type $ offsetType ): TrinaryLogic
906923 {
907924 if ($ this ->isList ()->yes ()) {
908925 $ arrayKeyOffsetType = $ offsetType ->toArrayKey ();
@@ -957,6 +974,15 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
957974 }
958975
959976 public function getOffsetValueType (Type $ offsetType ): Type
977+ {
978+ $ cacheKey = $ offsetType ->describe (VerbosityLevel::cache ());
979+ if (isset ($ this ->cachedGetOffsetValueType [$ cacheKey ])) {
980+ return $ this ->cachedGetOffsetValueType [$ cacheKey ];
981+ }
982+ return $ this ->cachedGetOffsetValueType [$ cacheKey ] = $ this ->doGetOffsetValueType ($ offsetType );
983+ }
984+
985+ private function doGetOffsetValueType (Type $ offsetType ): Type
960986 {
961987 $ result = $ this ->intersectTypes (static fn (Type $ type ): Type => $ type ->getOffsetValueType ($ offsetType ));
962988 if ($ this ->isOversizedArray ()->yes ()) {
@@ -1174,7 +1200,7 @@ public function getEnumCaseObject(): ?EnumCaseObjectType
11741200
11751201 public function isCallable (): TrinaryLogic
11761202 {
1177- return $ this ->intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->isCallable ());
1203+ return $ this ->isCallable ??= $ this -> intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->isCallable ());
11781204 }
11791205
11801206 public function getCallableParametersAcceptors (ClassMemberAccessAnswerer $ scope ): array
0 commit comments