code: private function findEnd(Tokens $tokens, $index)
      {
          $nextIndex = $tokens->getNextMeaningfulToken($index);
          $nextToken = $tokens[$nextIndex];
  
          while ($nextToken->equalsAny([
              '$',
              '[',
              [CT::T_DYNAMIC_PROP_BRACE_OPEN],
              [CT::T_DYNAMIC_VAR_BRACE_OPEN],
              [T_NS_SEPARATOR],
              [T_STATIC],
              [T_STRING],
              [T_VARIABLE],
          ])) {
              $blockType = Tokens::detectBlockType($nextToken);
              if (null !== $blockType) {
                  $nextIndex = $tokens->findBlockEnd($blockType['type'], $nextIndex);
              }
              $index = $nextIndex;
              $nextIndex = $tokens->getNextMeaningfulToken($nextIndex);
              $nextToken = $tokens[$nextIndex];
          }
  
          if ($nextToken->isGivenKind(T_OBJECT_OPERATOR)) {
              return $this->findEnd($tokens, $nextIndex);
          }
  
          if ($nextToken->isGivenKind(T_PAAMAYIM_NEKUDOTAYIM)) {
              return $this->findEnd($tokens, $tokens->getNextMeaningfulToken($nextIndex));
          }
  
          return $index;
      }
docs: @param Tokens $tokens
  @param int    $index
  
  @return int