(source: string)
| 549 | const LONE_MACRO_LINE_RE = /^[ \t]*([A-Z][A-Z0-9_]{3,})[ \t]*(?:\/\/[^\n\r]*|\/\*[^\n\r]*\*\/[ \t]*)?\r?$/; |
| 550 | const LONE_MACRO_CONTINUATION_END_RE = /[=+\-*/%&|^<>?:,(\\]$/; |
| 551 | export function blankLoneMacroLines(source: string): string { |
| 552 | if (!/^[ \t]*[A-Z][A-Z0-9_]{3,}[ \t]*\r?$/m.test(source)) return source; |
| 553 | const lines = source.split('\n'); |
| 554 | const content = (l: string): string => l.replace(/\r$/, '').trim(); |
| 555 | let changed = false; |
| 556 | for (let i = 0; i < lines.length; i++) { |
| 557 | const line = lines[i] as string; |
| 558 | const m = LONE_MACRO_LINE_RE.exec(line); |
| 559 | if (!m) continue; |
| 560 | // Underscore requirement rides the macro convention (FMT_BEGIN_NAMESPACE, |
| 561 | // Q_OBJECT); a solid all-caps word (`NDEBUG`-style) alone is too risky. |
| 562 | if (!(m[1] as string).includes('_')) continue; |
| 563 | let prev = i - 1; |
| 564 | while (prev >= 0 && content(lines[prev] as string) === '') prev--; |
| 565 | if (prev >= 0 && LONE_MACRO_CONTINUATION_END_RE.test(content(lines[prev] as string))) continue; |
| 566 | let next = i + 1; |
| 567 | while (next < lines.length && content(lines[next] as string) === '') next++; |
| 568 | if (next < lines.length) { |
| 569 | const first = content(lines[next] as string)[0]; |
| 570 | if (!first || !/[A-Za-z_#{}~]/.test(first)) continue; |
| 571 | } |
| 572 | const start = line.indexOf(m[1] as string); |
| 573 | lines[i] = |
| 574 | line.slice(0, start) + ' '.repeat((m[1] as string).length) + line.slice(start + (m[1] as string).length); |
| 575 | changed = true; |
| 576 | } |
| 577 | return changed ? lines.join('\n') : source; |
| 578 | } |
| 579 | |
| 580 | /** |
| 581 | * Blank an export/visibility macro sitting in front of a *member* or *method* |
no test coverage detected