@@ -81,6 +81,7 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
8181 {
8282 $ parametersAcceptor = null ;
8383 $ constructorReflection = null ;
84+ $ classReflection = null ;
8485 $ hasYield = false ;
8586 $ throwPoints = [];
8687 $ impurePoints = [];
@@ -89,8 +90,7 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
8990 if ($ expr ->class instanceof Name) {
9091 $ className = $ scope ->resolveName ($ expr ->class );
9192
92- [$ constructorReflection , $ parametersAcceptor , $ constructorThrowPoints , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
93- $ throwPoints = array_merge ($ throwPoints , $ constructorThrowPoints );
93+ [$ constructorReflection , $ classReflection , $ parametersAcceptor , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
9494 $ impurePoints = array_merge ($ impurePoints , $ constructorImpurePoints );
9595
9696 if ($ parametersAcceptor !== null ) {
@@ -136,19 +136,13 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
136136 }
137137 } else {
138138 $ nodeScopeResolver ->processStmtNode ($ expr ->class , $ scope , $ storage , $ nodeCallback , StatementContext::createTopLevel ());
139- $ declaringClass = $ constructorReflection ->getDeclaringClass ();
140- $ constructorThrowPoint = $ this ->getConstructorThrowPoint ($ constructorReflection , $ parametersAcceptor , $ classReflection , $ expr , new Name \FullyQualified ($ declaringClass ->getName ()), $ expr ->getArgs (), $ scope );
141- if ($ constructorThrowPoint !== null ) {
142- $ throwPoints [] = $ constructorThrowPoint ;
143- }
144-
145139 if (!$ constructorReflection ->hasSideEffects ()->no ()) {
146140 $ certain = $ constructorReflection ->isPure ()->no ();
147141 $ impurePoints [] = new ImpurePoint (
148142 $ scope ,
149143 $ expr ,
150144 'new ' ,
151- sprintf ('instantiation of class %s ' , $ declaringClass ->getDisplayName ()),
145+ sprintf ('instantiation of class %s ' , $ constructorReflection -> getDeclaringClass () ->getDisplayName ()),
152146 $ certain ,
153147 );
154148 }
@@ -176,11 +170,9 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
176170 $ throwPoints = array_merge ($ throwPoints , $ additionalThrowPoints );
177171
178172 if ($ className !== null ) {
179- [$ constructorReflection , $ parametersAcceptor , $ constructorThrowPoints , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
180- $ throwPoints = array_merge ($ throwPoints , $ constructorThrowPoints );
173+ [$ constructorReflection , $ classReflection , $ parametersAcceptor , $ constructorImpurePoints ] = $ this ->processConstructorReflection ($ className , $ expr , $ scope );
181174 $ impurePoints = array_merge ($ impurePoints , $ constructorImpurePoints );
182175 } else {
183- $ throwPoints [] = InternalThrowPoint::createImplicit ($ scope , $ expr );
184176 $ impurePoints [] = new ImpurePoint (
185177 $ scope ,
186178 $ expr ,
@@ -202,6 +194,16 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
202194 $ impurePoints = array_merge ($ impurePoints , $ argsResult ->getImpurePoints ());
203195 $ isAlwaysTerminating = $ isAlwaysTerminating || $ argsResult ->isAlwaysTerminating ();
204196
197+ if ($ constructorReflection !== null && $ parametersAcceptor !== null ) {
198+ $ className ??= $ constructorReflection ->getDeclaringClass ()->getName ();
199+ $ constructorThrowPoint = $ this ->getConstructorThrowPoint ($ constructorReflection , $ parametersAcceptor , $ expr , new Name \FullyQualified ($ className ), $ expr ->getArgs (), $ scope );
200+ if ($ constructorThrowPoint !== null ) {
201+ $ throwPoints [] = $ constructorThrowPoint ;
202+ }
203+ } elseif ($ classReflection === null ) {
204+ $ throwPoints [] = InternalThrowPoint::createImplicit ($ scope , $ expr );
205+ }
206+
205207 return new ExpressionResult (
206208 $ scope ,
207209 hasYield: $ hasYield ,
@@ -212,13 +214,12 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
212214 }
213215
214216 /**
215- * @return array{?MethodReflection, ?ParametersAcceptor, InternalThrowPoint[] , ImpurePoint[]}
217+ * @return array{?MethodReflection, ?ClassReflection, ?ParametersAcceptor , ImpurePoint[]}
216218 */
217219 private function processConstructorReflection (string $ className , New_ $ expr , MutatingScope $ scope ): array
218220 {
219221 $ constructorReflection = null ;
220222 $ parametersAcceptor = null ;
221- $ throwPoints = [];
222223 $ impurePoints = [];
223224
224225 $ classReflection = null ;
@@ -232,13 +233,7 @@ private function processConstructorReflection(string $className, New_ $expr, Mut
232233 $ constructorReflection ->getVariants (),
233234 $ constructorReflection ->getNamedArgumentsVariants (),
234235 );
235- $ constructorThrowPoint = $ this ->getConstructorThrowPoint ($ constructorReflection , $ parametersAcceptor , $ classReflection , $ expr , new Name \FullyQualified ($ className ), $ expr ->getArgs (), $ scope );
236- if ($ constructorThrowPoint !== null ) {
237- $ throwPoints [] = $ constructorThrowPoint ;
238- }
239236 }
240- } else {
241- $ throwPoints [] = InternalThrowPoint::createImplicit ($ scope , $ expr );
242237 }
243238
244239 if ($ constructorReflection !== null ) {
@@ -262,13 +257,13 @@ private function processConstructorReflection(string $className, New_ $expr, Mut
262257 );
263258 }
264259
265- return [$ constructorReflection , $ parametersAcceptor , $ throwPoints , $ impurePoints ];
260+ return [$ constructorReflection , $ classReflection , $ parametersAcceptor , $ impurePoints ];
266261 }
267262
268263 /**
269264 * @param list<Node\Arg> $args
270265 */
271- private function getConstructorThrowPoint (MethodReflection $ constructorReflection , ParametersAcceptor $ parametersAcceptor , ClassReflection $ classReflection , New_ $ new , Name $ className , array $ args , MutatingScope $ scope ): ?InternalThrowPoint
266+ private function getConstructorThrowPoint (MethodReflection $ constructorReflection , ParametersAcceptor $ parametersAcceptor , New_ $ new , Name $ className , array $ args , MutatingScope $ scope ): ?InternalThrowPoint
272267 {
273268 $ methodCall = new StaticCall ($ className , $ constructorReflection ->getName (), $ args );
274269 $ normalizedMethodCall = ArgumentsNormalizer::reorderStaticCallArguments ($ parametersAcceptor , $ methodCall );
@@ -293,7 +288,7 @@ private function getConstructorThrowPoint(MethodReflection $constructorReflectio
293288 return InternalThrowPoint::createExplicit ($ scope , $ throwType , $ new , true );
294289 }
295290 } elseif ($ this ->implicitThrows ) {
296- if (!$ classReflection ->is (Throwable::class)) {
291+ if (!$ constructorReflection -> getDeclaringClass () ->is (Throwable::class)) {
297292 return InternalThrowPoint::createImplicit ($ scope , $ methodCall );
298293 }
299294 }
0 commit comments