(lines: &[String])
| 2662 | } |
| 2663 | |
| 2664 | fn namespace_include_thorough_violations(lines: &[String]) -> Vec<(usize, String)> { |
| 2665 | let stripped_content = strip_comments_preserving_lines(lines); |
| 2666 | let stripped_lines: Vec<&str> = stripped_content.split('\n').collect(); |
| 2667 | let mut violations = Vec::new(); |
| 2668 | let mut namespace_stack: Vec<(usize, String)> = Vec::new(); |
| 2669 | let mut last_namespace: Option<(usize, String)> = None; |
| 2670 | |
| 2671 | for (index, original_line) in lines.iter().enumerate() { |
| 2672 | let line_number = index + 1; |
| 2673 | let line_no_comments = stripped_lines.get(index).copied().unwrap_or(""); |
| 2674 | let stripped = line_no_comments.trim(); |
| 2675 | if stripped.is_empty() { |
| 2676 | continue; |
| 2677 | } |
| 2678 | |
| 2679 | let open_braces = line_no_comments.matches('{').count(); |
| 2680 | let close_braces = line_no_comments.matches('}').count(); |
| 2681 | |
| 2682 | if stripped.contains("using namespace") |
| 2683 | && regex_namespace_include_using().is_match(stripped) |
| 2684 | { |
| 2685 | let info = (line_number, namespace_include_snippet(original_line)); |
| 2686 | last_namespace = Some(info.clone()); |
| 2687 | if namespace_stack.is_empty() { |
| 2688 | namespace_stack.push(info); |
| 2689 | } |
| 2690 | } |
| 2691 | |
| 2692 | if stripped.contains("namespace") |
| 2693 | && stripped.contains('{') |
| 2694 | && regex_namespace_include_open().is_match(stripped) |
| 2695 | { |
| 2696 | let info = (line_number, namespace_include_snippet(original_line)); |
| 2697 | last_namespace = Some(info.clone()); |
| 2698 | namespace_stack.push(info); |
| 2699 | } |
| 2700 | |
| 2701 | if stripped.contains("#include") |
| 2702 | && regex_namespace_include_directive().is_match(stripped) |
| 2703 | && !namespace_stack.is_empty() |
| 2704 | { |
| 2705 | // Includes inside namespace blocks are handled by IncludeAfterNamespaceChecker. |
| 2706 | } else if stripped.contains("#include") |
| 2707 | && regex_namespace_include_directive().is_match(stripped) |
| 2708 | && !original_line.contains("// nolint") |
| 2709 | && last_namespace.is_some() |
| 2710 | { |
| 2711 | let include_snippet = namespace_include_snippet(original_line); |
| 2712 | let namespace_info = last_namespace |
| 2713 | .as_ref() |
| 2714 | .map(|(namespace_line, snippet)| (*namespace_line, snippet.as_str())); |
| 2715 | violations.push(( |
| 2716 | line_number, |
| 2717 | namespace_include_message(&include_snippet, namespace_info), |
| 2718 | )); |
| 2719 | } |
| 2720 | |
| 2721 | if close_braces > open_braces { |
no test coverage detected