@@ -78,9 +78,18 @@ final class ClassReflection
78
78
/** @var ExtendedMethodReflection[] */
79
79
private array $ methods = [];
80
80
81
- /** @var ExtendedPropertyReflection[] */
81
+ /**
82
+ * @var ExtendedPropertyReflection[]
83
+ * @deprecated Use $instanceProperties or $staticProperties instead
84
+ */
82
85
private array $ properties = [];
83
86
87
+ /** @var ExtendedPropertyReflection[] */
88
+ private array $ instanceProperties = [];
89
+
90
+ /** @var ExtendedPropertyReflection[] */
91
+ private array $ staticProperties = [];
92
+
84
93
/** @var RealClassClassConstantReflection[] */
85
94
private array $ constants = [];
86
95
@@ -147,6 +156,12 @@ final class ClassReflection
147
156
/** @var array<string, bool> */
148
157
private array $ hasPropertyCache = [];
149
158
159
+ /** @var array<string, bool> */
160
+ private array $ hasInstancePropertyCache = [];
161
+
162
+ /** @var array<string, bool> */
163
+ private array $ hasStaticPropertyCache = [];
164
+
150
165
/**
151
166
* @param PropertiesClassReflectionExtension[] $propertiesClassReflectionExtensions
152
167
* @param MethodsClassReflectionExtension[] $methodsClassReflectionExtensions
@@ -460,6 +475,9 @@ private function allowsDynamicPropertiesExtensions(): bool
460
475
return false ;
461
476
}
462
477
478
+ /**
479
+ * @deprecated Use hasInstanceProperty or hasStaticProperty instead
480
+ */
463
481
public function hasProperty (string $ propertyName ): bool
464
482
{
465
483
if (array_key_exists ($ propertyName , $ this ->hasPropertyCache )) {
@@ -479,13 +497,61 @@ public function hasProperty(string $propertyName): bool
479
497
}
480
498
}
481
499
500
+ // For BC purpose
501
+ if ($ this ->getPhpExtension ()->hasStaticProperty ($ this , $ propertyName )) {
502
+ return $ this ->hasPropertyCache [$ propertyName ] = true ;
503
+ }
504
+
482
505
if ($ this ->requireExtendsPropertiesClassReflectionExtension ->hasProperty ($ this , $ propertyName )) {
483
506
return $ this ->hasPropertyCache [$ propertyName ] = true ;
484
507
}
485
508
486
509
return $ this ->hasPropertyCache [$ propertyName ] = false ;
487
510
}
488
511
512
+ public function hasInstanceProperty (string $ propertyName ): bool
513
+ {
514
+ if (array_key_exists ($ propertyName , $ this ->hasInstancePropertyCache )) {
515
+ return $ this ->hasInstancePropertyCache [$ propertyName ];
516
+ }
517
+
518
+ if ($ this ->isEnum ()) {
519
+ return $ this ->hasInstancePropertyCache [$ propertyName ] = $ this ->hasNativeProperty ($ propertyName );
520
+ }
521
+
522
+ foreach ($ this ->propertiesClassReflectionExtensions as $ i => $ extension ) {
523
+ if ($ i > 0 && !$ this ->allowsDynamicPropertiesExtensions ()) {
524
+ break ;
525
+ }
526
+ if ($ extension ->hasProperty ($ this , $ propertyName )) {
527
+ return $ this ->hasInstancePropertyCache [$ propertyName ] = true ;
528
+ }
529
+ }
530
+
531
+ if ($ this ->requireExtendsPropertiesClassReflectionExtension ->hasInstanceProperty ($ this , $ propertyName )) {
532
+ return $ this ->hasPropertyCache [$ propertyName ] = true ;
533
+ }
534
+
535
+ return $ this ->hasPropertyCache [$ propertyName ] = false ;
536
+ }
537
+
538
+ public function hasStaticProperty (string $ propertyName ): bool
539
+ {
540
+ if (array_key_exists ($ propertyName , $ this ->hasStaticPropertyCache )) {
541
+ return $ this ->hasStaticPropertyCache [$ propertyName ];
542
+ }
543
+
544
+ if ($ this ->getPhpExtension ()->hasStaticProperty ($ this , $ propertyName )) {
545
+ return $ this ->hasStaticPropertyCache [$ propertyName ] = true ;
546
+ }
547
+
548
+ if ($ this ->requireExtendsPropertiesClassReflectionExtension ->hasStaticProperty ($ this , $ propertyName )) {
549
+ return $ this ->hasStaticPropertyCache [$ propertyName ] = true ;
550
+ }
551
+
552
+ return $ this ->hasStaticPropertyCache [$ propertyName ] = false ;
553
+ }
554
+
489
555
public function hasMethod (string $ methodName ): bool
490
556
{
491
557
if (array_key_exists ($ methodName , $ this ->hasMethodCache )) {
@@ -630,6 +696,20 @@ public function evictPrivateSymbols(): void
630
696
631
697
unset($ this ->properties [$ name ]);
632
698
}
699
+ foreach ($ this ->instanceProperties as $ name => $ property ) {
700
+ if (!$ property ->isPrivate ()) {
701
+ continue ;
702
+ }
703
+
704
+ unset($ this ->instanceProperties [$ name ]);
705
+ }
706
+ foreach ($ this ->staticProperties as $ name => $ property ) {
707
+ if (!$ property ->isPrivate ()) {
708
+ continue ;
709
+ }
710
+
711
+ unset($ this ->staticProperties [$ name ]);
712
+ }
633
713
foreach ($ this ->methods as $ name => $ method ) {
634
714
if (!$ method ->isPrivate ()) {
635
715
continue ;
@@ -640,6 +720,7 @@ public function evictPrivateSymbols(): void
640
720
$ this ->getPhpExtension ()->evictPrivateSymbols ($ this ->getCacheKey ());
641
721
}
642
722
723
+ /** @deprecated Use getInstanceProperty or getStaticProperty */
643
724
public function getProperty (string $ propertyName , ClassMemberAccessAnswerer $ scope ): ExtendedPropertyReflection
644
725
{
645
726
if ($ this ->isEnum ()) {
@@ -669,6 +750,15 @@ public function getProperty(string $propertyName, ClassMemberAccessAnswerer $sco
669
750
}
670
751
}
671
752
753
+ // For BC purpose
754
+ if ($ this ->getPhpExtension ()->hasStaticProperty ($ this , $ propertyName )) {
755
+ $ property = $ this ->wrapExtendedProperty ($ this ->getPhpExtension ()->getStaticProperty ($ this , $ propertyName ));
756
+ if ($ scope ->canReadProperty ($ property )) {
757
+ return $ this ->properties [$ key ] = $ property ;
758
+ }
759
+ $ this ->properties [$ key ] = $ property ;
760
+ }
761
+
672
762
if (!isset ($ this ->properties [$ key ])) {
673
763
if ($ this ->requireExtendsPropertiesClassReflectionExtension ->hasProperty ($ this , $ propertyName )) {
674
764
$ property = $ this ->requireExtendsPropertiesClassReflectionExtension ->getProperty ($ this , $ propertyName );
@@ -683,6 +773,80 @@ public function getProperty(string $propertyName, ClassMemberAccessAnswerer $sco
683
773
return $ this ->properties [$ key ];
684
774
}
685
775
776
+ public function getInstanceProperty (string $ propertyName , ClassMemberAccessAnswerer $ scope ): ExtendedPropertyReflection
777
+ {
778
+ if ($ this ->isEnum ()) {
779
+ return $ this ->getNativeProperty ($ propertyName );
780
+ }
781
+
782
+ $ key = $ propertyName ;
783
+ if ($ scope ->isInClass ()) {
784
+ $ key = sprintf ('%s-%s ' , $ key , $ scope ->getClassReflection ()->getCacheKey ());
785
+ }
786
+
787
+ if (!isset ($ this ->instanceProperties [$ key ])) {
788
+ foreach ($ this ->propertiesClassReflectionExtensions as $ i => $ extension ) {
789
+ if ($ i > 0 && !$ this ->allowsDynamicPropertiesExtensions ()) {
790
+ break ;
791
+ }
792
+
793
+ if (!$ extension ->hasProperty ($ this , $ propertyName )) {
794
+ continue ;
795
+ }
796
+
797
+ $ property = $ this ->wrapExtendedProperty ($ extension ->getProperty ($ this , $ propertyName ));
798
+ if ($ scope ->canReadProperty ($ property )) {
799
+ return $ this ->instanceProperties [$ key ] = $ property ;
800
+ }
801
+ $ this ->instanceProperties [$ key ] = $ property ;
802
+ }
803
+ }
804
+
805
+ if (!isset ($ this ->instanceProperties [$ key ])) {
806
+ if ($ this ->requireExtendsPropertiesClassReflectionExtension ->hasInstanceProperty ($ this , $ propertyName )) {
807
+ $ property = $ this ->requireExtendsPropertiesClassReflectionExtension ->getInstanceProperty ($ this , $ propertyName );
808
+ $ this ->instanceProperties [$ key ] = $ property ;
809
+ }
810
+ }
811
+
812
+ if (!isset ($ this ->instanceProperties [$ key ])) {
813
+ throw new MissingPropertyFromReflectionException ($ this ->getName (), $ propertyName );
814
+ }
815
+
816
+ return $ this ->instanceProperties [$ key ];
817
+ }
818
+
819
+ public function getStaticProperty (string $ propertyName , ClassMemberAccessAnswerer $ scope ): ExtendedPropertyReflection
820
+ {
821
+ $ key = $ propertyName ;
822
+ if ($ scope ->isInClass ()) {
823
+ $ key = sprintf ('%s-%s ' , $ key , $ scope ->getClassReflection ()->getCacheKey ());
824
+ }
825
+
826
+ if (!isset ($ this ->staticProperties [$ key ])) {
827
+ if ($ this ->getPhpExtension ()->hasStaticProperty ($ this , $ propertyName )) {
828
+ $ property = $ this ->wrapExtendedProperty ($ this ->getPhpExtension ()->getStaticProperty ($ this , $ propertyName ));
829
+ if ($ scope ->canReadProperty ($ property )) {
830
+ return $ this ->staticProperties [$ key ] = $ property ;
831
+ }
832
+ $ this ->staticProperties [$ key ] = $ property ;
833
+ }
834
+ }
835
+
836
+ if (!isset ($ this ->staticProperties [$ key ])) {
837
+ if ($ this ->requireExtendsPropertiesClassReflectionExtension ->hasStaticProperty ($ this , $ propertyName )) {
838
+ $ property = $ this ->requireExtendsPropertiesClassReflectionExtension ->getStaticProperty ($ this , $ propertyName );
839
+ $ this ->staticProperties [$ key ] = $ property ;
840
+ }
841
+ }
842
+
843
+ if (!isset ($ this ->staticProperties [$ key ])) {
844
+ throw new MissingPropertyFromReflectionException ($ this ->getName (), $ propertyName );
845
+ }
846
+
847
+ return $ this ->staticProperties [$ key ];
848
+ }
849
+
686
850
public function hasNativeProperty (string $ propertyName ): bool
687
851
{
688
852
return $ this ->getPhpExtension ()->hasProperty ($ this , $ propertyName );
0 commit comments