<commit_before><?php

namespace Pinq\Parsing\PHPParser\Visitors;

/**
 * Attempts to locate a function node from the supplied function reflection.
 * If two ambigous function are found, it throws an exception.
 */
class FunctionLocatorVisitor extends \PHPParser_NodeVisitorAbstract
{
    /**
     * @var \ReflectionFunctionAbstract
     */
    private $Reflection;

    private $CurrentNamespace;
    private $NamespaceName;
    private $FunctionName;
    private $StartLine;
    private $EndLine;

    private $HasLocatedFunction = false;
    private $FunctionNode;
    private $BodyNodes;

    public function __construct(\ReflectionFunctionAbstract $Reflection)
    {
        $this->Reflection = $Reflection;
        $this->NamespaceName = $this->GetNamespace($Reflection);
        $this->FunctionName = $Reflection->getShortName();
        $this->StartLine = $Reflection->getStartLine();
        $this->EndLine = $Reflection->getEndLine();
    }

    private function GetNamespace(\ReflectionFunctionAbstract $Reflection)
    {
        return $Reflection instanceof \ReflectionMethod ? $Reflection->getDeclaringClass()->getNamespaceName() : $Reflection->getNamespaceName();
    }

    /**
     * @return boolean
     */
    public function HasLocatedFunction()
    {
        return $this->HasLocatedFunction;
    }

    /**
     * @return \PHPParser_Node
     */
    public function GetFunctionNode()
    {
        return $this->FunctionNode;
    }

    /**
     * @return \PHPParser_Node[]
     */
    public function GetBodyNodes()
    {
        return $this->BodyNodes;
    }

    private function MatchesFunctionName($FunctionName)
    {
        return $this->NamespaceName === $this->CurrentNamespace  && $this->FunctionName === $FunctionName;
    }

    public function enterNode(\PHPParser_Node $Node)
    {
        if ($Node instanceof \PHPParser_Node_Stmt_Namespace) {
            $this->CurrentNamespace = (string)$Node->name;
        }

        if($Node->getAttribute('startLine') === $this->StartLine
                && $Node->getAttribute('endLine') === $this->EndLine) {

            switch (true) {

                case $Node instanceof \PHPParser_Node_Stmt_Function && $this->MatchesFunctionName($Node->name):
                case $Node instanceof \PHPParser_Node_Stmt_ClassMethod && $this->MatchesFunctionName($Node->name):
                case $Node instanceof \PHPParser_Node_Expr_Closure && $this->MatchesFunctionName('{closure}'):
                    $this->FoundFunctionNode($Node);
                    break;
<commit_msg>HHVM compatibility fix<commit_after><?php

namespace Pinq\Parsing\PHPParser\Visitors;

define('IS_HHVM', defined('HHVM_VERSION'));

/**
 * Attempts to locate a function node from the supplied function reflection.
 * If two ambigous function are found, it throws an exception.
 */
class FunctionLocatorVisitor extends \PHPParser_NodeVisitorAbstract
{
    /**
     * @var \ReflectionFunctionAbstract
     */
    private $Reflection;

    private $CurrentNamespace;
    private $NamespaceName;
    private $FunctionName;
    private $StartLine;
    private $EndLine;

    private $HasLocatedFunction = false;
    private $FunctionNode;
    private $BodyNodes;

    public function __construct(\ReflectionFunctionAbstract $Reflection)
    {
        $this->Reflection = $Reflection;
        $this->NamespaceName = $this->GetNamespace($Reflection);
        $this->FunctionName = $Reflection->getShortName();
        $this->StartLine = $Reflection->getStartLine();
        $this->EndLine = $Reflection->getEndLine();
    }

    private function GetNamespace(\ReflectionFunctionAbstract $Reflection)
    {
        return $Reflection instanceof \ReflectionMethod ? $Reflection->getDeclaringClass()->getNamespaceName() : $Reflection->getNamespaceName();
    }

    /**
     * @return boolean
     */
    public function HasLocatedFunction()
    {
        return $this->HasLocatedFunction;
    }

    /**
     * @return \PHPParser_Node
     */
    public function GetFunctionNode()
    {
        return $this->FunctionNode;
    }

    /**
     * @return \PHPParser_Node[]
     */
    public function GetBodyNodes()
    {
        return $this->BodyNodes;
    }

    private function MatchesFunctionName($FunctionName)
    {
        //HHVM Compatibility: hhvm does not return namespaces for closures :/
        if(IS_HHVM) {
            return $this->FunctionName === $FunctionName;
        }
        else {
            return $this->NamespaceName === $this->CurrentNamespace  && $this->FunctionName === $FunctionName;
        }
    }

    public function enterNode(\PHPParser_Node $Node)
    {
        if ($Node instanceof \PHPParser_Node_Stmt_Namespace) {
            $this->CurrentNamespace = (string)$Node->name;
        }

        if($Node->getAttribute('startLine') === $this->StartLine
                && $Node->getAttribute('endLine') === $this->EndLine) {

            switch (true) {

                case $Node instanceof \PHPParser_Node_Stmt_Function && $this->MatchesFunctionName($Node->name):
                case $Node instanceof \PHPParser_Node_Stmt_ClassMethod && $this->MatchesFunctionName($Node->name):
                case $Node instanceof \PHPParser_Node_Expr_Closure && $this->MatchesFunctionName('{closure}'):
                    $this->FoundFunctionNode($Node);
                    break;

{'fraction_non_alphanumeric': 0.11833987661245092, 'fraction_numerical': 0.0, 'mean_word_length': 2.772919605077574, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 64, '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': '6200600', 'n_tokens_mistral': 1421, 'n_tokens_neox': 1409, 'n_words': 288}