@@ -2557,6 +2557,14 @@ public function processExprNode(
25572557 ExpressionContext $ context ,
25582558 ): ExpressionResult
25592559 {
2560+ $ existingExprResult = $ storage ->findResult ($ expr );
2561+ if ($ existingExprResult !== null ) {
2562+ if ($ nodeCallback instanceof ShallowNodeCallback) {
2563+ return $ existingExprResult ;
2564+ }
2565+ throw new ShouldNotHappenException (sprintf ('Expr %s on line %d has already been analysed ' , get_class ($ expr ), $ expr ->getStartLine ()));
2566+ }
2567+
25602568 if ($ expr instanceof Expr \CallLike && $ expr ->isFirstClassCallable ()) {
25612569 if ($ expr instanceof FuncCall) {
25622570 $ newExpr = new FunctionCallableNode ($ expr ->name , $ expr );
@@ -2575,14 +2583,6 @@ public function processExprNode(
25752583 return $ newExprResult ;
25762584 }
25772585
2578- $ existingExprResult = $ storage ->findResult ($ expr );
2579- if ($ existingExprResult !== null ) {
2580- if ($ nodeCallback instanceof ShallowNodeCallback) {
2581- return $ existingExprResult ;
2582- }
2583- throw new ShouldNotHappenException (sprintf ('Expr %s on line %d has already been analysed ' , get_class ($ expr ), $ expr ->getStartLine ()));
2584- }
2585-
25862586 $ originalScope = $ scope ;
25872587 $ this ->callNodeCallbackWithExpression ($ nodeCallback , $ expr , $ scope , $ storage , $ context );
25882588
@@ -2658,7 +2658,6 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
26582658 true ,
26592659 );
26602660 $ scope = $ result ->getScope ();
2661- $ this ->storeResult ($ storage , $ expr , $ result );
26622661 $ hasYield = $ result ->hasYield ();
26632662 $ throwPoints = $ result ->getThrowPoints ();
26642663 $ impurePoints = $ result ->getImpurePoints ();
@@ -2671,6 +2670,17 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
26712670 $ scope = $ this ->processStmtVarAnnotation ($ scope , $ storage , $ stmt , null , $ nodeCallback );
26722671 }
26732672 }
2673+
2674+ return new ExpressionResult (
2675+ $ scope ,
2676+ $ originalScope ,
2677+ $ hasYield ,
2678+ $ isAlwaysTerminating ,
2679+ $ throwPoints ,
2680+ $ impurePoints ,
2681+ static fn (): MutatingScope => $ scope ->filterByTruthyValue ($ expr ),
2682+ static fn (): MutatingScope => $ scope ->filterByFalseyValue ($ expr ),
2683+ );
26742684 } elseif ($ expr instanceof Expr \AssignOp) {
26752685 $ result = $ this ->processAssignVar (
26762686 $ scope ,
@@ -2708,7 +2718,9 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
27082718 $ expr instanceof Expr \AssignOp \Coalesce,
27092719 );
27102720 $ scope = $ result ->getScope ();
2711- $ this ->storeResult ($ storage , $ expr , $ result );
2721+ if (!$ expr instanceof Expr \AssignOp \Coalesce) {
2722+ $ this ->storeResult ($ storage , $ expr , $ result );
2723+ }
27122724 $ hasYield = $ result ->hasYield ();
27132725 $ throwPoints = $ result ->getThrowPoints ();
27142726 $ impurePoints = $ result ->getImpurePoints ();
@@ -2719,6 +2731,17 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto
27192731 ) {
27202732 $ throwPoints [] = InternalThrowPoint::createExplicit ($ scope , new ObjectType (DivisionByZeroError::class), $ expr , false );
27212733 }
2734+
2735+ return new ExpressionResult (
2736+ $ scope ,
2737+ $ originalScope ,
2738+ $ hasYield ,
2739+ $ isAlwaysTerminating ,
2740+ $ throwPoints ,
2741+ $ impurePoints ,
2742+ static fn (): MutatingScope => $ scope ->filterByTruthyValue ($ expr ),
2743+ static fn (): MutatingScope => $ scope ->filterByFalseyValue ($ expr ),
2744+ );
27222745 } elseif ($ expr instanceof FuncCall) {
27232746 $ parametersAcceptor = null ;
27242747 $ functionReflection = null ;
0 commit comments