private function findFunction(Tokens $tokens, $name, $startIndex, $endIndex)
    {
        $function = $tokens->findSequence([
            [T_FUNCTION],
            [T_STRING, $name],
            '(',
        ], $startIndex, $endIndex, false);

        if (null === $function) {
            return null;
        }

        // keep only the indexes
        $function = array_keys($function);

        // find previous block, saving method modifiers for later use
        $possibleModifiers = [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC, T_ABSTRACT, T_FINAL];
        $modifiers = [];

        $prevBlock = $tokens->getPrevMeaningfulToken($function[0]);
        while (null !== $prevBlock && $tokens[$prevBlock]->isGivenKind($possibleModifiers)) {
            $modifiers[$tokens[$prevBlock]->getId()] = $prevBlock;
            $prevBlock = $tokens->getPrevMeaningfulToken($prevBlock);
        }

        if (isset($modifiers[T_ABSTRACT])) {
            // abstract methods have no body
            $bodyStart = null;
            $funcEnd = $tokens->getNextTokenOfKind($function[2], [';']);
        } else {
            // find method body start and the end of the function definition
            $bodyStart = $tokens->getNextTokenOfKind($function[2], ['{']);
            $funcEnd = null !== $bodyStart ? $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $bodyStart) : null;
        }

        return [
            'nameIndex' => $function[1],
            'startIndex' => $prevBlock + 1,
            'endIndex' => $funcEnd,
            'bodyIndex' => $bodyStart,
            'modifiers' => $modifiers,
        ];
    }
private function findFunction(Tokens $tokens, $name, $startIndex, $endIndex)
    {
        $function = $tokens->findSequence([
            [T_FUNCTION],
            [T_STRING, $name],
            '(',
        ], $startIndex, $endIndex, false);

        if (null === $function) {
            return null;
        }

        
        $function = array_keys($function);

        
        $possibleModifiers = [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC, T_ABSTRACT, T_FINAL];
        $modifiers = [];

        $prevBlock = $tokens->getPrevMeaningfulToken($function[0]);
        while (null !== $prevBlock && $tokens[$prevBlock]->isGivenKind($possibleModifiers)) {
            $modifiers[$tokens[$prevBlock]->getId()] = $prevBlock;
            $prevBlock = $tokens->getPrevMeaningfulToken($prevBlock);
        }

        if (isset($modifiers[T_ABSTRACT])) {
            
            $bodyStart = null;
            $funcEnd = $tokens->getNextTokenOfKind($function[2], [';']);
        } else {
            
            $bodyStart = $tokens->getNextTokenOfKind($function[2], ['{']);
            $funcEnd = null !== $bodyStart ? $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $bodyStart) : null;
        }

        return [
            'nameIndex' => $function[1],
            'startIndex' => $prevBlock + 1,
            'endIndex' => $funcEnd,
            'bodyIndex' => $bodyStart,
            'modifiers' => $modifiers,
        ];
    }
private function findFunction ( Tokens $ tokens , $ name , $ startIndex , $ endIndex ) { $ function = $ tokens -> findSequence ( [ [ T_FUNCTION ] , [ T_STRING , $ name ] , '(' , ] , $ startIndex , $ endIndex , false ) ; if ( null === $ function ) { return null ; } // keep only the indexes $ function = array_keys ( $ function ) ; // find previous block, saving method modifiers for later use $ possibleModifiers = [ T_PUBLIC , T_PROTECTED , T_PRIVATE , T_STATIC , T_ABSTRACT , T_FINAL ] ; $ modifiers = [ ] ; $ prevBlock = $ tokens -> getPrevMeaningfulToken ( $ function [ 0 ] ) ; while ( null !== $ prevBlock && $ tokens [ $ prevBlock ] -> isGivenKind ( $ possibleModifiers ) ) { $ modifiers [ $ tokens [ $ prevBlock ] -> getId ( ) ] = $ prevBlock ; $ prevBlock = $ tokens -> getPrevMeaningfulToken ( $ prevBlock ) ; } if ( isset ( $ modifiers [ T_ABSTRACT ] ) ) { // abstract methods have no body $ bodyStart = null ; $ funcEnd = $ tokens -> getNextTokenOfKind ( $ function [ 2 ] , [ ';' ] ) ; } else { // find method body start and the end of the function definition $ bodyStart = $ tokens -> getNextTokenOfKind ( $ function [ 2 ] , [ '{' ] ) ; $ funcEnd = null !== $ bodyStart ? $ tokens -> findBlockEnd ( Tokens :: BLOCK_TYPE_CURLY_BRACE , $ bodyStart ) : null ; } return [ 'nameIndex' => $ function [ 1 ] , 'startIndex' => $ prevBlock + 1 , 'endIndex' => $ funcEnd , 'bodyIndex' => $ bodyStart , 'modifiers' => $ modifiers , ] ; }
Find a function or method matching a given name within certain bounds.

@param Tokens $tokens     the Tokens instance
@param string $name       the function/Method name
@param int    $startIndex the search start index
@param int    $endIndex   the search end index

@return null|array An associative array, if a match is found:

- nameIndex (int): The index of the function/method name.
- startIndex (int): The index of the function/method start.
- endIndex (int): The index of the function/method end.
- bodyIndex (int): The index of the function/method body.
- modifiers (array): The modifiers as array keys and their index as
the values, e.g. array(T_PUBLIC => 10)
Find a function or method matching a given name within certain bounds .