src/Psalm/Context.php
public function update(
        Context $start_context,
        Context $end_context,
        $has_leaving_statements,
        array $vars_to_update,
        array &$updated_vars
    ) {
        foreach ($start_context->vars_in_scope as $var_id => $old_type) {
            // this is only true if there was some sort of type negation
            if (in_array($var_id, $vars_to_update, true)) {
                // if we're leaving, we're effectively deleting the possibility of the if types
                $new_type = !$has_leaving_statements && $end_context->hasVariable($var_id)
                    ? $end_context->vars_in_scope[$var_id]
                    : null;

                $existing_type = isset($this->vars_in_scope[$var_id]) ? $this->vars_in_scope[$var_id] : null;

                if (!$existing_type) {
                    if ($new_type) {
                        $this->vars_in_scope[$var_id] = clone $new_type;
                        $updated_vars[$var_id] = true;
                    }

                    continue;
                }

                // if the type changed within the block of statements, process the replacement
                // also never allow ourselves to remove all types from a union
                if ((!$new_type || !$old_type->equals($new_type))
                    && ($new_type || count($existing_type->getTypes()) > 1)
                ) {
                    $existing_type->substitute($old_type, $new_type);

                    if ($new_type && $new_type->from_docblock) {
                        $existing_type->setFromDocblock();
                    }

                    $updated_vars[$var_id] = true;
                }
            }
        }
    }
public function update(
        Context $start_context,
        Context $end_context,
        $has_leaving_statements,
        array $vars_to_update,
        array &$updated_vars
    ) {
        foreach ($start_context->vars_in_scope as $var_id => $old_type) {
            // this is only true if there was some sort of type negation
            if (in_array($var_id, $vars_to_update, true)) {
                // if we're leaving, we're effectively deleting the possibility of the if types
                $new_type = !$has_leaving_statements && $end_context->hasVariable($var_id)
                    ? $end_context->vars_in_scope[$var_id]
                    : null;

                $existing_type = isset($this->vars_in_scope[$var_id]) ? $this->vars_in_scope[$var_id] : null;

                if (!$existing_type) {
                    if ($new_type) {
                        $this->vars_in_scope[$var_id] = clone $new_type;
                        $updated_vars[$var_id] = true;
                    }

                    continue;
                }

                // if the type changed within the block of statements, process the replacement
                // also never allow ourselves to remove all types from a union
                if ((!$new_type || !$old_type->equals($new_type))
                    && ($new_type || count($existing_type->getTypes()) > 1)
                ) {
                    $existing_type->substitute($old_type, $new_type);

                    if ($new_type && $new_type->from_docblock) {
                        $existing_type->setFromDocblock();
                    }

                    $updated_vars[$var_id] = true;
                }
            }
        }
    }
public function update ( Context $ start_context , Context $ end_context , $ has_leaving_statements , array $ vars_to_update , array & $ updated_vars ) { foreach ( $ start_context -> vars_in_scope as $ var_id => $ old_type ) { // this is only true if there was some sort of type negation if ( in_array ( $ var_id , $ vars_to_update , true ) ) { // if we're leaving, we're effectively deleting the possibility of the if types $ new_type = ! $ has_leaving_statements && $ end_context -> hasVariable ( $ var_id ) ? $ end_context -> vars_in_scope [ $ var_id ] : null ; $ existing_type = isset ( $ this -> vars_in_scope [ $ var_id ] ) ? $ this -> vars_in_scope [ $ var_id ] : null ; if ( ! $ existing_type ) { if ( $ new_type ) { $ this -> vars_in_scope [ $ var_id ] = clone $ new_type ; $ updated_vars [ $ var_id ] = true ; } continue ; } // if the type changed within the block of statements, process the replacement // also never allow ourselves to remove all types from a union if ( ( ! $ new_type || ! $ old_type -> equals ( $ new_type ) ) && ( $ new_type || count ( $ existing_type -> getTypes ( ) ) > 1 ) ) { $ existing_type -> substitute ( $ old_type , $ new_type ) ; if ( $ new_type && $ new_type -> from_docblock ) { $ existing_type -> setFromDocblock ( ) ; } $ updated_vars [ $ var_id ] = true ; } } } }
Updates the parent context, looking at the changes within a block and then applying those changes, where
necessary, to the parent context

@param  Context     $start_context
@param  Context     $end_context
@param  bool        $has_leaving_statements   whether or not the parent scope is abandoned between
$start_context and $end_context
@param  array       $vars_to_update
@param  array       $updated_vars

@return void
Updates the parent context looking at the changes within a block and then applying those changes where necessary to the parent context