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