private function findStatementEnd(Tokens $tokens, $parenthesisEndIndex)
    {
        $nextIndex = $tokens->getNextMeaningfulToken($parenthesisEndIndex);
        $nextToken = $tokens[$nextIndex];

        if (!$nextToken) {
            return $parenthesisEndIndex;
        }

        if ($nextToken->equals('{')) {
            return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $nextIndex);
        }

        if ($nextToken->isGivenKind($this->getControlTokens())) {
            $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex);

            $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex);

            if ($nextToken->isGivenKind([T_IF, T_TRY, T_DO])) {
                $openingTokenKind = $nextToken->getId();

                while (true) {
                    $nextIndex = $tokens->getNextMeaningfulToken($endIndex);
                    $nextToken = isset($nextIndex) ? $tokens[$nextIndex] : null;
                    if ($nextToken && $nextToken->isGivenKind($this->getControlContinuationTokensForOpeningToken($openingTokenKind))) {
                        $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex);

                        $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex);

                        if ($nextToken->isGivenKind($this->getFinalControlContinuationTokensForOpeningToken($openingTokenKind))) {
                            return $endIndex;
                        }
                    } else {
                        break;
                    }
                }
            }

            return $endIndex;
        }

        $index = $parenthesisEndIndex;

        while (true) {
            $token = $tokens[++$index];

            // if there is some block in statement (eg lambda function) we need to skip it
            if ($token->equals('{')) {
                $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index);

                continue;
            }

            if ($token->equals(';')) {
                return $index;
            }

            if ($token->isGivenKind(T_CLOSE_TAG)) {
                return $tokens->getPrevNonWhitespace($index);
            }
        }

        throw new \RuntimeException('Statement end not found.');
    }
private function findStatementEnd(Tokens $tokens, $parenthesisEndIndex)
    {
        $nextIndex = $tokens->getNextMeaningfulToken($parenthesisEndIndex);
        $nextToken = $tokens[$nextIndex];

        if (!$nextToken) {
            return $parenthesisEndIndex;
        }

        if ($nextToken->equals('{')) {
            return $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $nextIndex);
        }

        if ($nextToken->isGivenKind($this->getControlTokens())) {
            $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex);

            $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex);

            if ($nextToken->isGivenKind([T_IF, T_TRY, T_DO])) {
                $openingTokenKind = $nextToken->getId();

                while (true) {
                    $nextIndex = $tokens->getNextMeaningfulToken($endIndex);
                    $nextToken = isset($nextIndex) ? $tokens[$nextIndex] : null;
                    if ($nextToken && $nextToken->isGivenKind($this->getControlContinuationTokensForOpeningToken($openingTokenKind))) {
                        $parenthesisEndIndex = $this->findParenthesisEnd($tokens, $nextIndex);

                        $endIndex = $this->findStatementEnd($tokens, $parenthesisEndIndex);

                        if ($nextToken->isGivenKind($this->getFinalControlContinuationTokensForOpeningToken($openingTokenKind))) {
                            return $endIndex;
                        }
                    } else {
                        break;
                    }
                }
            }

            return $endIndex;
        }

        $index = $parenthesisEndIndex;

        while (true) {
            $token = $tokens[++$index];

            
            if ($token->equals('{')) {
                $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $index);

                continue;
            }

            if ($token->equals(';')) {
                return $index;
            }

            if ($token->isGivenKind(T_CLOSE_TAG)) {
                return $tokens->getPrevNonWhitespace($index);
            }
        }

        throw new \RuntimeException('Statement end not found.');
    }
private function findStatementEnd ( Tokens $ tokens , $ parenthesisEndIndex ) { $ nextIndex = $ tokens -> getNextMeaningfulToken ( $ parenthesisEndIndex ) ; $ nextToken = $ tokens [ $ nextIndex ] ; if ( ! $ nextToken ) { return $ parenthesisEndIndex ; } if ( $ nextToken -> equals ( '{' ) ) { return $ tokens -> findBlockEnd ( Tokens :: BLOCK_TYPE_CURLY_BRACE , $ nextIndex ) ; } if ( $ nextToken -> isGivenKind ( $ this -> getControlTokens ( ) ) ) { $ parenthesisEndIndex = $ this -> findParenthesisEnd ( $ tokens , $ nextIndex ) ; $ endIndex = $ this -> findStatementEnd ( $ tokens , $ parenthesisEndIndex ) ; if ( $ nextToken -> isGivenKind ( [ T_IF , T_TRY , T_DO ] ) ) { $ openingTokenKind = $ nextToken -> getId ( ) ; while ( true ) { $ nextIndex = $ tokens -> getNextMeaningfulToken ( $ endIndex ) ; $ nextToken = isset ( $ nextIndex ) ? $ tokens [ $ nextIndex ] : null ; if ( $ nextToken && $ nextToken -> isGivenKind ( $ this -> getControlContinuationTokensForOpeningToken ( $ openingTokenKind ) ) ) { $ parenthesisEndIndex = $ this -> findParenthesisEnd ( $ tokens , $ nextIndex ) ; $ endIndex = $ this -> findStatementEnd ( $ tokens , $ parenthesisEndIndex ) ; if ( $ nextToken -> isGivenKind ( $ this -> getFinalControlContinuationTokensForOpeningToken ( $ openingTokenKind ) ) ) { return $ endIndex ; } } else { break ; } } } return $ endIndex ; } $ index = $ parenthesisEndIndex ; while ( true ) { $ token = $ tokens [ ++ $ index ] ; // if there is some block in statement (eg lambda function) we need to skip it if ( $ token -> equals ( '{' ) ) { $ index = $ tokens -> findBlockEnd ( Tokens :: BLOCK_TYPE_CURLY_BRACE , $ index ) ; continue ; } if ( $ token -> equals ( ';' ) ) { return $ index ; } if ( $ token -> isGivenKind ( T_CLOSE_TAG ) ) { return $ tokens -> getPrevNonWhitespace ( $ index ) ; } } throw new \ RuntimeException ( 'Statement end not found.' ) ; }
@param Tokens $tokens
@param int    $parenthesisEndIndex

@return int
@param Tokens $tokens @param int $parenthesisEndIndex