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