code: public function getArgumentInfo(Tokens $tokens, $argumentStart, $argumentEnd)
      {
          $info = [
              'default' => null,
              'name' => null,
              'name_index' => null,
              'type' => null,
              'type_index_start' => null,
              'type_index_end' => null,
          ];
  
          $sawName = false;
          for ($index = $argumentStart; $index <= $argumentEnd; ++$index) {
              $token = $tokens[$index];
              if ($token->isComment() || $token->isWhitespace() || $token->isGivenKind(T_ELLIPSIS) || $token->equals('&')) {
                  continue;
              }
              if ($token->isGivenKind(T_VARIABLE)) {
                  $sawName = true;
                  $info['name_index'] = $index;
                  $info['name'] = $token->getContent();
  
                  continue;
              }
              if ($token->equals('=')) {
                  continue;
              }
              if ($sawName) {
                  $info['default'] .= $token->getContent();
              } else {
                  $info['type_index_start'] = ($info['type_index_start'] > 0) ? $info['type_index_start'] : $index;
                  $info['type_index_end'] = $index;
                  $info['type'] .= $token->getContent();
              }
          }
  
          return new ArgumentAnalysis(
              $info['name'],
              $info['name_index'],
              $info['default'],
              $info['type'] ? new TypeAnalysis($info['type'], $info['type_index_start'], $info['type_index_end']) : null
          );
      }
docs: @param Tokens $tokens
  @param int    $argumentStart
  @param int    $argumentEnd
  
  @return ArgumentAnalysis