* Removes all useless semicolons * @param str * @return formatted string */
| 40 | * @return formatted string |
| 41 | */ |
| 42 | string remove_semicolons(string_view str, bool is_gen2) { |
| 43 | string result; |
| 44 | size_t line_end = size_t(-1); |
| 45 | int par_balance = 0; // () |
| 46 | int sq_braces_balance = 0; // [] |
| 47 | int braces_balance = 0; // {} |
| 48 | vector<NoCommentReason> disables; |
| 49 | do { |
| 50 | size_t offset = line_end + 1; |
| 51 | line_end = str.find('\n', offset); |
| 52 | // bool is_eof = str.size() <= offset; |
| 53 | // bool indent_non_zero = (!is_eof && (str.at(offset) == ' ' || str.at(offset) == '\t')); |
| 54 | auto last_char_idx = offset + format::find_comma_place(str.substr(offset, line_end - offset)); |
| 55 | auto cur_line = str.substr(offset, last_char_idx - offset + 1); |
| 56 | for (size_t i = 0; i < cur_line.size(); i++) { |
| 57 | const auto c = cur_line.at(i); |
| 58 | if (c == '\\') { |
| 59 | i++; |
| 60 | continue; |
| 61 | } |
| 62 | optional<NoCommentReason> maybe_reason; |
| 63 | if (disables.empty() && c == '/' && cur_line.size() > i + 1 && cur_line.at(i + 1) == '/') { |
| 64 | break; |
| 65 | } |
| 66 | if (c == '"') { |
| 67 | maybe_reason = NoCommentReason::String; |
| 68 | } else if (c == '/' && cur_line.size() > i + 1 && cur_line.at(i + 1) == '*') { |
| 69 | maybe_reason = NoCommentReason::OpenComment; |
| 70 | } else if (c == '*' && cur_line.size() > i + 1 && cur_line.at(i + 1) == '/') { |
| 71 | maybe_reason = NoCommentReason::CloseComment; |
| 72 | } |
| 73 | if (maybe_reason) { |
| 74 | if (!disables.empty() && disables.back() == maybe_reason) { |
| 75 | disables.pop_back(); |
| 76 | } else { |
| 77 | if (maybe_reason == NoCommentReason::OpenComment) { |
| 78 | maybe_reason = NoCommentReason::CloseComment; |
| 79 | } |
| 80 | if (disables.empty() || disables.back() != NoCommentReason::String) { |
| 81 | disables.emplace_back(maybe_reason.value()); |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | if (!disables.empty()) { |
| 86 | continue; |
| 87 | } |
| 88 | switch (c) { |
| 89 | case '(': par_balance += 1; break; |
| 90 | case ')': par_balance -= 1; break; |
| 91 | case '[': sq_braces_balance += 1; break; |
| 92 | case ']': sq_braces_balance -= 1; break; |
| 93 | case '{': braces_balance += 1; break; |
| 94 | case '}': braces_balance -= 1; break; |
| 95 | default: break; |
| 96 | } |
| 97 | } |
| 98 | if (par_balance == 0 && (braces_balance == 0 || is_gen2) && |
| 99 | sq_braces_balance == 0 && |
no test coverage detected