Actions(
                        $function_stmt->stmts,
                        $this->config->exit_functions,
                        false,
                        false
                    );

                    if ($final_actions!== [\Psalm\Internal\Analyzer\ScopeAnalyzer::ACTION_END]) {
                        continue;
                    }

                    $if_clauses = \Psalm\Type\Algebra::getFormula(
                        $function_stmt->cond,
                        $this->fq_classlike_names
                           ? $this->fq_classlike_names[count($this->fq_classlike_names) - 1]
                            : null,
                        $this->file_scanner,
                        null
                    );

                    $negated_formula = \Psalm\Type\Algebra::negateFormula($if_clauses);

                    $rules = \Psalm\Type\Algebra::getTruthsFromFormula($negated_formula);

                    foreach ($rules as $var_id => $rule) {
                        foreach ($rule as $rule_part) {
                            if (count($rule_part) > 1) {
                                continue 2;
                            }
                        }

                        if (isset($existing_params[$var_id])) {
                            $param_offset = $existing_params[$var_id];

                            $var_assertions[] = new \Psalm\Storage\Assertion(
                                $param_offset,
                                $rule
                            );
                        } elseif (strpos($var_id, '$this->') === 0) {
                            $var_assertions[] = new \Psalm\Storage\Assertion(
                                $var_id,
                                $rule
                            );
                        }
                    }
                }
            }

            $storage->assertions = $var_assertions;
        }

        if (!$this->scan_deep
            && ($stmt instanceof PhpParser\Node\Stmt\Function_
                || $stmt instanceof PhpParser\Node\Stmt\ClassMethod
                || $stmt instanceof PhpParser\Node\Expr\Closure)
            && $stmt->stmts
        ) {
            // pick up func_get_args that would otherwise be missed
            foreach ($stmt->stmts as $function_stmt) {
                if ($function_stmt instanceof PhpParser\Node\Stmt\Expression
                    && $function_stmt->expr instanceof PhpParser\Node\Expr\Assign
                    && ($function_stmt->expr->expr instanceof PhpParser\Node\Expr\FuncCall)
                    && ($function_stmt->expr->expr->name instanceof PhpParser\Node\Name)
                ) {
                    $function_id = implode('\\', $function_stmt->expr->expr->name->parts);

                    if ($function_id === 'func_get_arg'
                        || $function_id === 'func_get_args'<commit_msg>Only store really simple-looking code for assertions<commit_after><?php
namespace Psalm\Internal\Visitor;

use PhpParser;
use Psalm\Aliases;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\IncludeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Codebase;
use Psalm\Internal\Codebase\CallMap;
use Psalm\Internal\Codebase\PropertyMap;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\FileIncludeException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\FileSource;
use Psalm\Issue\DuplicateClass;
use Psalm\Issue\DuplicateParam;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\MisplacedRequiredParam;
use Psalm\Issue\MissingDocblockType;
use Psalm\IssueBuffer;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Storage\PropertyStorage;
use Psalm\Type;

class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParser\NodeVisitor, FileSource
{
    /** @var Aliases */
    private $aliases;

    /** @var Aliases */
    private $file_aliases;

    /**
     * @var string[]
     */
    private $fq_classlike_names = [];

    /** @var FileScanner */
    private $file_scanner;

    /** @var Codebase */
    private $codebase;

    /** @var string */
    private $file_path;

    /** @var bool */
    private $scan_deep;

    /** @var Config */
    private $config;

    /** @var bool */
    private $queue_strings_as_possible_type = false;

    /** @var array<string, string> */
    private $class_template_types = [];

    /** @var array<string, string> */
    private $function_template_types = [];

    /** @var FunctionLikeStorage[] */
    private $functionlike_storages = [];

    /** @var FileStorage */
    private $file_storage;

    /** @var ClassLikeStorage[] */
    private $classlike_storages = [];

    /** @var class-string[] */
    private $after_classlike_check_plugins;

    /**
     * @var array<string, array<int, string>>
     */
    private $type_aliases = [];

    public function __construct(
        Codebase $codebase,
        FileStorage $file_storage,
        FileScanner $file_scanner
    ) {
        $this->codebase = $codebase;
        $this->file_scanner = $file_scanner;
        $this->file_path = $file_scanner->file_path;
        $this->scan_deep = $file_scanner->will_analyze;
        $this->config = $codebase->config;
        $this->aliases = $this->file_aliases = new Aliases();
        $this->file_storage = $file_storage;
        $this->after_classlike_check_plugins = $this->config->after_visit_classlikes;
    }

    /**
     * @param  PhpParser\Node $node
     *
     * @return null|int
     */
    public function enterNode(PhpParser\Node $node)
    {
        foreach ($node->getComments() as $comment) {
            if ($comment instanceof PhpParser\Comment\Doc) {
                try {
                    $type_alias_tokens = CommentAnalyzer::getTypeAliasesFromComment(
                        (string) $comment,
                        $this->aliases,
                        $this->type_aliases
                    );

                    foreach ($type_alias_tokens as $type_tokens) {
                        // finds issues, if there are any
                        Type::parseTokens($type_tokens);
                    }

                    $this->type_aliases += $type_alias_tokens;
                } catch (DocblockParseException $e) {
                    if (IssueBuffer::accepts(
                        new InvalidDocblock(
                            (string)$e->getMessage(),
                            new CodeLocation($this->file_scanner, $node, null, true)
                        )
                    )) {
                        // fall through
                    }
                } catch (TypeParseTreeException $e) {
                    if (IssueBuffer::accepts(
                        new InvalidDocblock(
                            (string)$e->getMessage(),
                            new CodeLocation($this->file_scanner, $node, null, true)
                        )
                    )) {
                        // fall through
                    }
                }
            }
        }

        if ($node instanceof PhpParser\Node\Stmt\Namespace_) {
            $this->file_aliases = $this->aliases;
            $this->aliases = new Aliases(
                $node->name? implode('\\', $node->name->parts) : '',
                $this->aliases->uses,
                $this->aliases->functions,
                $this->aliases->constants