private function findStart(Tokens $tokens, $index)
    {
        while (!$tokens[$index]->equalsAny(['$', [T_VARIABLE]])) {
            if ($tokens[$index]->equals(']')) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $index);
            } elseif ($tokens[$index]->isGivenKind(CT::T_DYNAMIC_PROP_BRACE_CLOSE)) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_DYNAMIC_PROP_BRACE, $index);
            } elseif ($tokens[$index]->isGivenKind(CT::T_DYNAMIC_VAR_BRACE_CLOSE)) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_DYNAMIC_VAR_BRACE, $index);
            } elseif ($tokens[$index]->isGivenKind(CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE)) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE, $index);
            } else {
                $index = $tokens->getPrevMeaningfulToken($index);
            }
        }

        while ($tokens[$tokens->getPrevMeaningfulToken($index)]->equals('$')) {
            $index = $tokens->getPrevMeaningfulToken($index);
        }

        if ($tokens[$tokens->getPrevMeaningfulToken($index)]->isGivenKind(T_OBJECT_OPERATOR)) {
            return $this->findStart($tokens, $tokens->getPrevMeaningfulToken($index));
        }

        return $index;
    }
private function findStart(Tokens $tokens, $index)
    {
        while (!$tokens[$index]->equalsAny(['$', [T_VARIABLE]])) {
            if ($tokens[$index]->equals(']')) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $index);
            } elseif ($tokens[$index]->isGivenKind(CT::T_DYNAMIC_PROP_BRACE_CLOSE)) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_DYNAMIC_PROP_BRACE, $index);
            } elseif ($tokens[$index]->isGivenKind(CT::T_DYNAMIC_VAR_BRACE_CLOSE)) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_DYNAMIC_VAR_BRACE, $index);
            } elseif ($tokens[$index]->isGivenKind(CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE)) {
                $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE, $index);
            } else {
                $index = $tokens->getPrevMeaningfulToken($index);
            }
        }

        while ($tokens[$tokens->getPrevMeaningfulToken($index)]->equals('$')) {
            $index = $tokens->getPrevMeaningfulToken($index);
        }

        if ($tokens[$tokens->getPrevMeaningfulToken($index)]->isGivenKind(T_OBJECT_OPERATOR)) {
            return $this->findStart($tokens, $tokens->getPrevMeaningfulToken($index));
        }

        return $index;
    }
private function findStart ( Tokens $ tokens , $ index ) { while ( ! $ tokens [ $ index ] -> equalsAny ( [ '$' , [ T_VARIABLE ] ] ) ) { if ( $ tokens [ $ index ] -> equals ( ']' ) ) { $ index = $ tokens -> findBlockStart ( Tokens :: BLOCK_TYPE_INDEX_SQUARE_BRACE , $ index ) ; } elseif ( $ tokens [ $ index ] -> isGivenKind ( CT :: T_DYNAMIC_PROP_BRACE_CLOSE ) ) { $ index = $ tokens -> findBlockStart ( Tokens :: BLOCK_TYPE_DYNAMIC_PROP_BRACE , $ index ) ; } elseif ( $ tokens [ $ index ] -> isGivenKind ( CT :: T_DYNAMIC_VAR_BRACE_CLOSE ) ) { $ index = $ tokens -> findBlockStart ( Tokens :: BLOCK_TYPE_DYNAMIC_VAR_BRACE , $ index ) ; } elseif ( $ tokens [ $ index ] -> isGivenKind ( CT :: T_ARRAY_INDEX_CURLY_BRACE_CLOSE ) ) { $ index = $ tokens -> findBlockStart ( Tokens :: BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE , $ index ) ; } else { $ index = $ tokens -> getPrevMeaningfulToken ( $ index ) ; } } while ( $ tokens [ $ tokens -> getPrevMeaningfulToken ( $ index ) ] -> equals ( '$' ) ) { $ index = $ tokens -> getPrevMeaningfulToken ( $ index ) ; } if ( $ tokens [ $ tokens -> getPrevMeaningfulToken ( $ index ) ] -> isGivenKind ( T_OBJECT_OPERATOR ) ) { return $ this -> findStart ( $ tokens , $ tokens -> getPrevMeaningfulToken ( $ index ) ) ; } return $ index ; }
Find the start of a reference.

@param Tokens $tokens
@param int    $index

@return int
Find the start of a reference .