| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | namespace Psalm\Internal\Analyzer\Statements\Expression; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | use PhpParser; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | use PhpParser\Node\Expr\{PostInc, PostDec, PreInc, PreDec}; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | use Psalm\Internal\Analyzer\StatementsAnalyzer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | use Psalm\CodeLocation; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | use Psalm\Context; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | use Psalm\Issue\ImpurePropertyAssignment; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | use Psalm\IssueBuffer; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use Psalm\Type; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use function strpos; | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 14 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 15 |  |  | class IncDecExpressionAnalyzer | 
            
                                                                        
                            
            
                                    
            
            
                | 16 |  |  | { | 
            
                                                                        
                            
            
                                    
            
            
                | 17 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 18 |  |  |      * @param PostInc|PostDec|PreInc|PreDec $stmt | 
            
                                                                        
                            
            
                                    
            
            
                | 19 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     public static function analyze( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |         StatementsAnalyzer $statements_analyzer, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |         PhpParser\Node\Expr $stmt, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |         Context $context | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     ) : bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |         $was_inside_assignment = $context->inside_assignment; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |         $context->inside_assignment = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |         if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |             if (!$was_inside_assignment) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |                 $context->inside_assignment = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |         if (!$was_inside_assignment) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |             $context->inside_assignment = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         if ($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |             $return_type = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |             $fake_right_expr = new PhpParser\Node\Scalar\LNumber(1, $stmt->getAttributes()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |             $statements_analyzer->node_data->setType($fake_right_expr, Type::getInt()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |             BinaryOp\NonDivArithmeticOpAnalyzer::analyze( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |                 $statements_analyzer, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |                 $statements_analyzer->node_data, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |                 $stmt->var, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |                 $fake_right_expr, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |                 $stmt, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |                 $return_type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |                 $context | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |             $stmt_type = clone $stmt_var_type; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |             $statements_analyzer->node_data->setType($stmt, $stmt_type); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |             $stmt_type->from_calculation = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |             foreach ($stmt_type->getAtomicTypes() as $atomic_type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |                 if ($atomic_type instanceof Type\Atomic\TLiteralInt) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |                     $stmt_type->addType(new Type\Atomic\TInt); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |                 } elseif ($atomic_type instanceof Type\Atomic\TLiteralFloat) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |                     $stmt_type->addType(new Type\Atomic\TFloat); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |             $var_id = ExpressionIdentifier::getArrayVarId($stmt->var, null); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |             if ($var_id && $context->mutation_free && strpos($var_id, '->')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |                 if (IssueBuffer::accepts( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |                     new ImpurePropertyAssignment( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |                         'Cannot assign to a property from a mutation-free context', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |                         new CodeLocation($statements_analyzer, $stmt->var) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |                     ), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |                     $statements_analyzer->getSuppressedIssues() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |                 )) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |                     // fall through | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |             $codebase = $statements_analyzer->getCodebase(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |             if ($var_id && isset($context->vars_in_scope[$var_id])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |                 $context->vars_in_scope[$var_id] = $stmt_type; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |                 if ($codebase->find_unused_variables && $stmt->var instanceof PhpParser\Node\Expr\Variable) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |                     $location = new CodeLocation($statements_analyzer, $stmt->var); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |                     $context->assigned_var_ids[$var_id] = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |                     $context->possibly_assigned_var_ids[$var_id] = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |                     if (!$context->inside_isset || !$context->inside_loop) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |                         $statements_analyzer->registerVariableAssignment( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |                             $var_id, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |                             $location | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |                         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                         $context->unreferenced_vars[$var_id] = [$location->getHash() => $location]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |                 // removes dependent vars from $context | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |                 $context->removeDescendents( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |                     $var_id, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |                     $context->vars_in_scope[$var_id], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |                     $return_type, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |                     $statements_analyzer | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |             $statements_analyzer->node_data->setType($stmt, Type::getMixed()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |         return true; | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 115 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 116 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |  |