@@ -42,6 +42,8 @@ public function __construct(
4242 private bool $ checkDynamicProperties ,
4343 #[AutowiredParameter(ref: '%featureToggles.checkNonStringableDynamicAccess% ' )]
4444 private bool $ checkNonStringableDynamicAccess ,
45+ #[AutowiredParameter]
46+ private bool $ checkThisOnly ,
4547 )
4648 {
4749 }
@@ -58,20 +60,7 @@ public function check(PropertyFetch $node, Scope $scope, bool $write): array
5860 $ names = array_map (static fn (ConstantStringType $ type ): string => $ type ->getValue (), $ scope ->getType ($ node ->name )->getConstantStrings ());
5961
6062 if (!$ write && $ this ->checkNonStringableDynamicAccess ) {
61- $ nameTypeResult = $ this ->ruleLevelHelper ->findTypeToCheck (
62- $ scope ,
63- $ node ->name ,
64- '' ,
65- static fn (Type $ type ) => $ type ->toString ()->isString ()->yes (),
66- );
67- $ nameType = $ nameTypeResult ->getType ();
68- if ($ nameType instanceof ErrorType || $ nameType ->toString () instanceof ErrorType || !$ nameType ->toString ()->isString ()->yes ()) {
69- $ originalNameType = $ scope ->getType ($ node ->name );
70- $ className = $ scope ->getType ($ node ->var )->describe (VerbosityLevel::typeOnly ());
71- $ errors [] = RuleErrorBuilder::message (sprintf ('Property name for %s must be a string, but %s was given. ' , $ className , $ originalNameType ->describe (VerbosityLevel::precise ())))
72- ->identifier ('property.nameNotString ' )
73- ->build ();
74- }
63+ $ errors = array_merge ($ errors , $ this ->checkNonStringableDynamicAccess ($ scope , $ node ));
7564 }
7665 }
7766
@@ -82,6 +71,41 @@ public function check(PropertyFetch $node, Scope $scope, bool $write): array
8271 return $ errors ;
8372 }
8473
74+ private function checkNonStringableDynamicAccess (Scope $ scope , PropertyFetch $ node ): array
75+ {
76+ if (
77+ $ this ->checkThisOnly
78+ && !$ this ->ruleLevelHelper ->isThis ($ node ->var )
79+ ) {
80+ return [];
81+ }
82+
83+ $ nameTypeResult = $ this ->ruleLevelHelper ->findTypeToCheck (
84+ $ scope ,
85+ $ node ->name ,
86+ '' ,
87+ static fn (Type $ type ) => $ type ->toString ()->isString ()->yes (),
88+ );
89+ $ nameType = $ nameTypeResult ->getType ();
90+ if (
91+ !$ nameType instanceof ErrorType
92+ && !$ nameType ->toString () instanceof ErrorType
93+ && $ nameType ->toString ()->isString ()->yes ()
94+ ) {
95+ return [];
96+ }
97+
98+ $ originalNameType = $ scope ->getType ($ node ->name );
99+ $ className = $ scope ->getType ($ node ->var )->describe (VerbosityLevel::typeOnly ());
100+ return [
101+ RuleErrorBuilder::message (sprintf (
102+ 'Property name for %s must be a string, but %s was given. ' ,
103+ $ className ,
104+ $ originalNameType ->describe (VerbosityLevel::precise ())
105+ ))->identifier ('property.nameNotString ' )->build (),
106+ ];
107+ }
108+
85109 /**
86110 * @return list<IdentifierRuleError>
87111 */
0 commit comments