@@ -533,6 +533,72 @@ public function getUnresolvedPropertyPrototype(string $propertyName, ClassMember
533533 return new IntersectionTypeUnresolvedPropertyPrototypeReflection ($ propertyName , $ propertyPrototypes );
534534 }
535535
536+ public function hasInstanceProperty (string $ propertyName ): TrinaryLogic
537+ {
538+ return $ this ->intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->hasInstanceProperty ($ propertyName ));
539+ }
540+
541+ public function getInstanceProperty (string $ propertyName , ClassMemberAccessAnswerer $ scope ): ExtendedPropertyReflection
542+ {
543+ return $ this ->getUnresolvedInstancePropertyPrototype ($ propertyName , $ scope )->getTransformedProperty ();
544+ }
545+
546+ public function getUnresolvedInstancePropertyPrototype (string $ propertyName , ClassMemberAccessAnswerer $ scope ): UnresolvedPropertyPrototypeReflection
547+ {
548+ $ propertyPrototypes = [];
549+ foreach ($ this ->types as $ type ) {
550+ if (!$ type ->hasProperty ($ propertyName )->yes ()) {
551+ continue ;
552+ }
553+
554+ $ propertyPrototypes [] = $ type ->getUnresolvedInstancePropertyPrototype ($ propertyName , $ scope )->withFechedOnType ($ this );
555+ }
556+
557+ $ propertiesCount = count ($ propertyPrototypes );
558+ if ($ propertiesCount === 0 ) {
559+ throw new ShouldNotHappenException ();
560+ }
561+
562+ if ($ propertiesCount === 1 ) {
563+ return $ propertyPrototypes [0 ];
564+ }
565+
566+ return new IntersectionTypeUnresolvedPropertyPrototypeReflection ($ propertyName , $ propertyPrototypes );
567+ }
568+
569+ public function hasStaticProperty (string $ propertyName ): TrinaryLogic
570+ {
571+ return $ this ->intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->hasStaticProperty ($ propertyName ));
572+ }
573+
574+ public function getStaticProperty (string $ propertyName , ClassMemberAccessAnswerer $ scope ): ExtendedPropertyReflection
575+ {
576+ return $ this ->getUnresolvedStaticPropertyPrototype ($ propertyName , $ scope )->getTransformedProperty ();
577+ }
578+
579+ public function getUnresolvedStaticPropertyPrototype (string $ propertyName , ClassMemberAccessAnswerer $ scope ): UnresolvedPropertyPrototypeReflection
580+ {
581+ $ propertyPrototypes = [];
582+ foreach ($ this ->types as $ type ) {
583+ if (!$ type ->hasStaticProperty ($ propertyName )->yes ()) {
584+ continue ;
585+ }
586+
587+ $ propertyPrototypes [] = $ type ->getUnresolvedStaticPropertyPrototype ($ propertyName , $ scope )->withFechedOnType ($ this );
588+ }
589+
590+ $ propertiesCount = count ($ propertyPrototypes );
591+ if ($ propertiesCount === 0 ) {
592+ throw new ShouldNotHappenException ();
593+ }
594+
595+ if ($ propertiesCount === 1 ) {
596+ return $ propertyPrototypes [0 ];
597+ }
598+
599+ return new IntersectionTypeUnresolvedPropertyPrototypeReflection ($ propertyName , $ propertyPrototypes );
600+ }
601+
536602 public function canCallMethods (): TrinaryLogic
537603 {
538604 return $ this ->intersectResults (static fn (Type $ type ): TrinaryLogic => $ type ->canCallMethods ());
0 commit comments