<commit_before><?php

/*
 * This file is part of Psy Shell.
 *
 * (c) 2012-2015 <NAME>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Psy\CodeCleaner;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\New_ as NewExpr;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_ as ClassStmt;
use PhpParser\Node\Stmt\Interface_ as InterfaceStmt;
use PhpParser\Node\Stmt\Trait_ as TraitStmt;
use Psy\Exception\FatalErrorException;

/**
 * Validate that classes exist.
 *
 * This pass throws a FatalErrorException rather than letting PHP run
 * headfirst into a real fatal error and die.
 */
class ValidClassNamePass extends NamespaceAwarePass
{
    const CLASS_TYPE     = 'class';
    const INTERFACE_TYPE = 'interface';
    const TRAIT_TYPE     = 'trait';

    protected $checkTraits;

    public function __construct()
    {
        $this->checkTraits = function_exists('trait_exists');
    }

    /**
     * Validate class, interface and trait statements, and `new` expressions.
     *
     * @throws FatalErrorException if a class, interface or trait is referenced which does not exist.
     * @throws FatalErrorException if a class extends something that is not a class.
     * @throws FatalErrorException if a class implements something that is not an interface.
     * @throws FatalErrorException if an interface extends something that is not an interface.
     * @throws FatalErrorException if a class, interface or trait redefines an existing class, interface or trait name.
     *
     * @param Node $node
     */
    public function leaveNode(Node $node)
    {
        if ($node instanceof ClassStmt) {
            $this->validateClassStatement($node);
        } elseif ($node instanceof InterfaceStmt) {
            $this->validateInterfaceStatement($node);
        } elseif ($node instanceof TraitStmt) {
            $this->validateTraitStatement($node);
        } elseif ($node instanceof NewExpr) {
            $this->validateNewExpression($node);
        } elseif ($node instanceof ClassConstFetch) {
            $this->validateClassConstFetchExpression($node);
        } elseif ($node instanceof StaticCall) {
            $this->validateStaticCallExpression($node);
        }
    }

    /**
     * Validate a class definition statement.
     *
     * @param ClassStmt $stmt
     */
    protected function validateClassStatement(ClassStmt $stmt)
    {
        $this->ensureCanDefine($stmt);
        if (isset($stmt->extends)) {
            $this->ensureClassExists($this->getFullyQualifiedName($stmt->extends), $stmt);
        }
        $this->ensureInterfacesExist($stmt->implements, $stmt);
    }

    /**
     * Validate an interface definition statement.
     *
     * @param InterfaceStmt $stmt
     */
    protected function validateInterfaceStatement(InterfaceStmt $stmt)<commit_msg>Fix class not found exception when defining a class which refers to itself.<commit_after><?php

/*
 * This file is part of Psy Shell.
 *
 * (c) 2012-2015 <NAME>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Psy\CodeCleaner;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\New_ as NewExpr;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Class_ as ClassStmt;
use PhpParser\Node\Stmt\Interface_ as InterfaceStmt;
use PhpParser\Node\Stmt\Trait_ as TraitStmt;
use Psy\Exception\FatalErrorException;

/**
 * Validate that classes exist.
 *
 * This pass throws a FatalErrorException rather than letting PHP run
 * headfirst into a real fatal error and die.
 */
class ValidClassNamePass extends NamespaceAwarePass
{
    const CLASS_TYPE     = 'class';
    const INTERFACE_TYPE = 'interface';
    const TRAIT_TYPE     = 'trait';

    protected $checkTraits;

    public function __construct()
    {
        $this->checkTraits = function_exists('trait_exists');
    }

    /**
     * Validate class, interface and trait definitions.
     *
     * Validate them upon entering the node, so that we know about their
     * presence and can validate constant fetches and static calls in class or
     * trait methods.
     *
     * @param Node
     */
    public function enterNode(Node $node)
    {
        parent::enterNode($node);

        if ($node instanceof ClassStmt) {
            $this->validateClassStatement($node);
        } elseif ($node instanceof InterfaceStmt) {
            $this->validateInterfaceStatement($node);
        } elseif ($node instanceof TraitStmt) {
            $this->validateTraitStatement($node);
        }
    }

    /**
     * Validate `new` expressions, class constant fetches, and static calls.
     *
     * @throws FatalErrorException if a class, interface or trait is referenced which does not exist.
     * @throws FatalErrorException if a class extends something that is not a class.
     * @throws FatalErrorException if a class implements something that is not an interface.
     * @throws FatalErrorException if an interface extends something that is not an interface.
     * @throws FatalErrorException if a class, interface or trait redefines an existing class, interface or trait name.
     *
     * @param Node $node
     */
    public function leaveNode(Node $node)
    {
        if ($node instanceof NewExpr) {
            $this->validateNewExpression($node);
        } elseif ($node instanceof ClassConstFetch) {
            $this->validateClassConstFetchExpression($node);
        } elseif ($node instanceof StaticCall) {
            $this->validateStaticCallExpression($node);
        }
    }

    /**
     * Validate a class definition statement.
     *
     * @param ClassStmt $stmt
     */
    protected function validateClassStatement(ClassStmt $stmt)
    {
        $this->ensureCanDefine($stmt);
        if (isset($stmt->extends)) {
            $this->ensureClassExists($this->getFullyQualifiedName($stmt->extends), $stmt);
        }
        $this->ensureInterfacesExist($stmt->implements, $stmt);
    }

    /**
     * Validate an interface definition statement.
     *
     * @param InterfaceStmt $stmt
     */
    protected function validateInterfaceStatement(InterfaceStmt $stmt)
{'fraction_non_alphanumeric': 0.09262141967621419, 'fraction_numerical': 0.0024906600249066002, 'mean_word_length': 2.9906832298136647, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5515154', 'n_tokens_mistral': 1741, 'n_tokens_neox': 1752, 'n_words': 540}