2020use  PHPStan \Rules \Properties \ReadWritePropertiesExtension ;
2121use  PHPStan \Rules \Properties \ReadWritePropertiesExtensionProvider ;
2222use  PHPStan \ShouldNotHappenException ;
23+ use  PHPStan \TrinaryLogic ;
2324use  function  array_key_exists ;
2425use  function  array_keys ;
25- use  function  count ;
2626use  function  in_array ;
2727
2828/** @api */ 
@@ -100,6 +100,8 @@ public function getUninitializedProperties(
100100
101101$ properties
102102$ originalProperties
103+ $ initialInitializedProperties
104+ $ initializedProperties
103105foreach  ($ this getProperties () as  $ property
104106if  ($ propertyisStatic ()) {
105107continue ;
@@ -111,6 +113,11 @@ public function getUninitializedProperties(
111113continue ;
112114}
113115$ originalProperties$ propertygetName ()] = $ property
116+ $ iscreateFromBoolean ($ propertyisPromoted ());
117+ $ initialInitializedProperties$ propertygetName ()] = $ is
118+ foreach  ($ constructorsas  $ constructor
119+ $ initializedProperties$ constructor$ propertygetName ()] = $ is
120+ }
114121if  ($ propertyisPromoted ()) {
115122continue ;
116123}
@@ -138,7 +145,8 @@ public function getUninitializedProperties(
138145if  ($ constructors
139146return  [$ properties
140147}
141- $ methodsCalledFromConstructor$ this getMethodsCalledFromConstructor ($ classReflection$ this methodCalls , $ constructors
148+ 
149+ $ methodsCalledFromConstructor$ this getMethodsCalledFromConstructor ($ classReflection$ this methodCalls , $ initialInitializedProperties$ initializedProperties$ constructors
142150$ prematureAccess
143151$ additionalAssigns
144152
@@ -158,10 +166,12 @@ public function getUninitializedProperties(
158166if  ($ functiongetDeclaringClass ()->getName () !== $ classReflectiongetName ()) {
159167continue ;
160168}
161- if  (!in_array ($ functiongetName (), $ methodsCalledFromConstructor,  true )) {
169+ if  (!array_key_exists ($ functiongetName (), $ methodsCalledFromConstructor
162170continue ;
163171}
164172
173+ $ initializedPropertiesMap$ methodsCalledFromConstructor$ functiongetName ()];
174+ 
165175if  (!$ fetchname  instanceof  Identifier) {
166176continue ;
167177}
@@ -181,18 +191,18 @@ public function getUninitializedProperties(
181191unset($ properties$ propertyName
182192}
183193
184- if  (array_key_exists ($ propertyName$ originalProperties 
185- $ hasInitialization$ usageScopehasExpressionType (new  PropertyInitializationExpr ($ propertyName
186- if  (!$ hasInitializationno ()) {
194+ if  (array_key_exists ($ propertyName$ initializedPropertiesMap 
195+ $ hasInitialization$ initializedPropertiesMap [ $ propertyName ]-> or ( $ usageScopehasExpressionType (new  PropertyInitializationExpr ($ propertyName) ));
196+ if  (!$ hasInitializationno () && ! $ usage -> isPromotedPropertyWrite () ) {
187197$ additionalAssigns
188198$ propertyName
189199$ fetchgetLine (),
190200$ originalProperties$ propertyName
191201];
192202}
193203}
194- } elseif  (array_key_exists ($ propertyName$ originalProperties 
195- $ hasInitialization$ usageScopehasExpressionType (new  PropertyInitializationExpr ($ propertyName
204+ } elseif  (array_key_exists ($ propertyName$ initializedPropertiesMap 
205+ $ hasInitialization$ initializedPropertiesMap [ $ propertyName ]-> or ( $ usageScopehasExpressionType (new  PropertyInitializationExpr ($ propertyName) ));
196206if  (!$ hasInitializationyes ()) {
197207$ prematureAccess
198208$ propertyName
@@ -213,15 +223,20 @@ public function getUninitializedProperties(
213223/** 
214224 * @param MethodCall[] $methodCalls 
215225 * @param string[] $methods 
216-  * @return string[] 
226+  * @param array<string, TrinaryLogic> $initialInitializedProperties 
227+  * @param array<string, array<string, TrinaryLogic>> $initializedProperties 
228+  * @return array<string, array<string, TrinaryLogic>> 
217229 */ 
218230private  function  getMethodsCalledFromConstructor (
219231ClassReflection $ classReflection
220232array  $ methodCalls
233+ array  $ initialInitializedProperties
234+ array  $ initializedProperties
221235array  $ methods
222236): array 
223237{
224- $ originalCountcount ($ methods
238+ $ originalMap$ initializedProperties
239+ $ originalMethods$ methods
225240foreach  ($ methodCallsas  $ methodCall
226241$ methodCallNode$ methodCallgetNode ();
227242if  ($ methodCallNodeinstanceof  Array_) {
@@ -242,7 +257,10 @@ private function getMethodsCalledFromConstructor(
242257}
243258
244259$ methodName$ methodCallNodename ->toString ();
245- if  (in_array ($ methodName$ methodstrue )) {
260+ if  (array_key_exists ($ methodName$ initializedProperties
261+ foreach  ($ this getInitializedProperties ($ callScope$ initialInitializedPropertiesas  $ propertyName$ isInitialized
262+ $ initializedProperties$ methodName$ propertyName$ initializedProperties$ methodName$ propertyNameand ($ isInitialized
263+ }
246264continue ;
247265}
248266$ methodReflection$ callScopegetMethodReflection ($ calledOnType$ methodName
@@ -259,14 +277,28 @@ private function getMethodsCalledFromConstructor(
259277if  (!in_array ($ inMethodgetName (), $ methodstrue )) {
260278continue ;
261279}
280+ $ initializedProperties$ methodName$ this getInitializedProperties ($ callScope$ initialInitializedProperties
262281$ methods$ methodName
263282}
264283
265- if  ($ originalCountcount ($ methods
266- return  $ methods
284+ if  ($ originalMap$ initializedProperties$ originalMethods$ methods
285+ return  $ initializedProperties
286+ }
287+ 
288+ return  $ this getMethodsCalledFromConstructor ($ classReflection$ methodCalls$ initialInitializedProperties$ initializedProperties$ methods
289+ }
290+ 
291+ /** 
292+  * @param array<string, TrinaryLogic> $initialInitializedProperties 
293+  * @return array<string, TrinaryLogic> 
294+  */ 
295+ private  function  getInitializedProperties (Scope $ scopearray  $ initialInitializedPropertiesarray 
296+ {
297+ foreach  ($ initialInitializedPropertiesas  $ propertyName$ isInitialized
298+ $ initialInitializedProperties$ propertyName$ isInitializedor ($ scopehasExpressionType (new  PropertyInitializationExpr ($ propertyName
267299}
268300
269- return  $ this -> getMethodsCalledFromConstructor ( $ classReflection ,  $ methodCalls ,  $ methods ) ;
301+ return  $ initialInitializedProperties 
270302}
271303
272304}
0 commit comments