@@ -86,12 +86,15 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
8686 $ impurePoints = [];
8787 $ isAlwaysTerminating = false ;
8888 $ normalizedExpr = $ expr ;
89+ $ classReflection = null ;
90+ $ classFound = true ;
91+ $ deferConstructorThrowPoints = false ;
8992 if ($ expr ->class instanceof Name) {
9093 $ className = $ scope ->resolveName ($ expr ->class );
9194
92- [$ constructorReflection , $ parametersAcceptor , $ constructorThrowPoints , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
93- $ throwPoints = array_merge ($ throwPoints , $ constructorThrowPoints );
95+ [$ constructorReflection , $ parametersAcceptor , $ classReflection , $ classFound , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
9496 $ impurePoints = array_merge ($ impurePoints , $ constructorImpurePoints );
97+ $ deferConstructorThrowPoints = true ;
9598
9699 if ($ parametersAcceptor !== null ) {
97100 $ normalizedExpr = ArgumentsNormalizer::reorderNewArguments ($ parametersAcceptor , $ expr ) ?? $ expr ;
@@ -176,9 +179,9 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
176179 $ throwPoints = array_merge ($ throwPoints , $ additionalThrowPoints );
177180
178181 if ($ className !== null ) {
179- [$ constructorReflection , $ parametersAcceptor , $ constructorThrowPoints , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
180- $ throwPoints = array_merge ($ throwPoints , $ constructorThrowPoints );
182+ [$ constructorReflection , $ parametersAcceptor , $ classReflection , $ classFound , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
181183 $ impurePoints = array_merge ($ impurePoints , $ constructorImpurePoints );
184+ $ deferConstructorThrowPoints = true ;
182185 } else {
183186 $ throwPoints [] = InternalThrowPoint::createImplicit ($ scope , $ expr );
184187 $ impurePoints [] = new ImpurePoint (
@@ -202,6 +205,10 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
202205 $ impurePoints = array_merge ($ impurePoints , $ argsResult ->getImpurePoints ());
203206 $ isAlwaysTerminating = $ isAlwaysTerminating || $ argsResult ->isAlwaysTerminating ();
204207
208+ if ($ deferConstructorThrowPoints ) {
209+ $ throwPoints = array_merge ($ throwPoints , $ this ->createConstructorThrowPoints ($ expr , $ scope , $ constructorReflection , $ parametersAcceptor , $ classReflection , $ classFound ));
210+ }
211+
205212 return new ExpressionResult (
206213 $ scope ,
207214 hasYield: $ hasYield ,
@@ -212,16 +219,16 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
212219 }
213220
214221 /**
215- * @return array{?MethodReflection, ?ParametersAcceptor, InternalThrowPoint[] , ImpurePoint[]}
222+ * @return array{?MethodReflection, ?ParametersAcceptor, ?ClassReflection, bool , ImpurePoint[]}
216223 */
217224 private function processConstructorReflection (string $ className , New_ $ expr , MutatingScope $ scope ): array
218225 {
219226 $ constructorReflection = null ;
220227 $ parametersAcceptor = null ;
221- $ throwPoints = [];
222228 $ impurePoints = [];
223229
224230 $ classReflection = null ;
231+ $ classFound = true ;
225232 if ($ this ->reflectionProvider ->hasClass ($ className )) {
226233 $ classReflection = $ this ->reflectionProvider ->getClass ($ className );
227234 if ($ classReflection ->hasConstructor ()) {
@@ -232,13 +239,9 @@ private function processConstructorReflection(string $className, New_ $expr, Mut
232239 $ constructorReflection ->getVariants (),
233240 $ constructorReflection ->getNamedArgumentsVariants (),
234241 );
235- $ constructorThrowPoint = $ this ->getConstructorThrowPoint ($ constructorReflection , $ parametersAcceptor , $ classReflection , $ expr , new Name \FullyQualified ($ className ), $ expr ->getArgs (), $ scope );
236- if ($ constructorThrowPoint !== null ) {
237- $ throwPoints [] = $ constructorThrowPoint ;
238- }
239242 }
240243 } else {
241- $ throwPoints [] = InternalThrowPoint:: createImplicit ( $ scope , $ expr ) ;
244+ $ classFound = false ;
242245 }
243246
244247 if ($ constructorReflection !== null ) {
@@ -262,7 +265,25 @@ private function processConstructorReflection(string $className, New_ $expr, Mut
262265 );
263266 }
264267
265- return [$ constructorReflection , $ parametersAcceptor , $ throwPoints , $ impurePoints ];
268+ return [$ constructorReflection , $ parametersAcceptor , $ classReflection , $ classFound , $ impurePoints ];
269+ }
270+
271+ /**
272+ * @return InternalThrowPoint[]
273+ */
274+ private function createConstructorThrowPoints (New_ $ expr , MutatingScope $ scope , ?MethodReflection $ constructorReflection , ?ParametersAcceptor $ parametersAcceptor , ?ClassReflection $ classReflection , bool $ classFound ): array
275+ {
276+ $ throwPoints = [];
277+ if ($ classReflection !== null && $ constructorReflection !== null && $ parametersAcceptor !== null ) {
278+ $ constructorThrowPoint = $ this ->getConstructorThrowPoint ($ constructorReflection , $ parametersAcceptor , $ classReflection , $ expr , new Name \FullyQualified ($ classReflection ->getName ()), $ expr ->getArgs (), $ scope );
279+ if ($ constructorThrowPoint !== null ) {
280+ $ throwPoints [] = $ constructorThrowPoint ;
281+ }
282+ } elseif (!$ classFound ) {
283+ $ throwPoints [] = InternalThrowPoint::createImplicit ($ scope , $ expr );
284+ }
285+
286+ return $ throwPoints ;
266287 }
267288
268289 /**
0 commit comments