Bounds get_argument_bounds()

in source/Highlights.cpp [66:134]


Bounds get_argument_bounds(
    ParameterPosition callee_parameter_position,
    ParameterPosition first_parameter_position,
    const FileLines& lines,
    const Bounds& callee_name_bounds) {
  auto current_parameter_position = first_parameter_position;
  std::size_t line_number = callee_name_bounds.line;
  auto current_line = lines.line(line_number);
  std::size_t arguments_start = callee_name_bounds.end + 2;
  if (arguments_start > current_line.length() - 1) {
    if (!lines.has_line_number(line_number + 1)) {
      return callee_name_bounds;
    }
    line_number++;
    current_line = lines.line(line_number);
    arguments_start = 0;
  }
  std::size_t end = current_line.length() - 1;
  int balanced_parentheses_counter = 1;

  while (lines.has_line_number(line_number)) {
    current_line = lines.line(line_number);
    end = current_line.length() - 1;
    for (auto i = arguments_start; i < current_line.length(); i++) {
      if (current_line[i] == '(') {
        balanced_parentheses_counter++;
      } else if (current_line[i] == ')') {
        balanced_parentheses_counter--;
      } else if (current_line[i] == ',' && balanced_parentheses_counter == 1) {
        if (current_parameter_position == callee_parameter_position) {
          end = i - 1;
          break;
        }
        current_parameter_position++;
        if (current_parameter_position == callee_parameter_position) {
          arguments_start = i + 1;
        }
      }
      if (balanced_parentheses_counter == 0) {
        end = i - 1;
        break;
      }
    }
    mt_assert(current_parameter_position <= callee_parameter_position);
    auto highlighted_portion =
        current_line.substr(arguments_start, end - arguments_start + 1);
    if (balanced_parentheses_counter == 0 ||
        (callee_parameter_position == current_parameter_position &&
         std::any_of(
             std::begin(highlighted_portion),
             std::end(highlighted_portion),
             [](unsigned char c) { return std::isalpha(c); }))) {
      break;
    }

    line_number++;
    arguments_start = 0;
  }
  // In either of these cases, we have failed to find the argument
  if (current_parameter_position < callee_parameter_position ||
      !lines.has_line_number(line_number)) {
    return callee_name_bounds;
  }
  Bounds highlight_bounds = {
      static_cast<int>(line_number),
      static_cast<int>(arguments_start),
      static_cast<int>(end)};
  return remove_surrounding_whitespace(highlight_bounds, current_line);
}