(
line: &str,
class_names: &HashSet<String>,
)
| 3342 | } |
| 3343 | |
| 3344 | fn classify_noexcept_line( |
| 3345 | line: &str, |
| 3346 | class_names: &HashSet<String>, |
| 3347 | ) -> Option<(&'static str, usize)> { |
| 3348 | let code = strip_line_comment_code(line); |
| 3349 | let stripped = code.trim(); |
| 3350 | if stripped.is_empty() || stripped.starts_with('#') { |
| 3351 | return None; |
| 3352 | } |
| 3353 | |
| 3354 | if let Some(matched) = regex_destructor_decl().find(&code) { |
| 3355 | let tilde_pos = matched.start(); |
| 3356 | let prefix = code[..tilde_pos].trim_end(); |
| 3357 | if !prefix.ends_with("->") && !prefix.ends_with('.') { |
| 3358 | let paren = code[matched.start()..].find('(')? + matched.start(); |
| 3359 | let close = find_close_paren(&code, paren)?; |
| 3360 | let inside = code[paren + 1..close].trim(); |
| 3361 | if inside.is_empty() || inside == "void" { |
| 3362 | return Some(("destructor", paren)); |
| 3363 | } |
| 3364 | } |
| 3365 | } |
| 3366 | |
| 3367 | if let Some(matched) = regex_operator_assign_decl().find(&code) { |
| 3368 | let paren = code[matched.start()..].find('(')? + matched.start(); |
| 3369 | return Some(("assignment operator", paren)); |
| 3370 | } |
| 3371 | |
| 3372 | for name in class_names { |
| 3373 | let pattern = format!(r"\b{}\s*\(", regex::escape(name)); |
| 3374 | let Ok(regex) = Regex::new(&pattern) else { |
| 3375 | continue; |
| 3376 | }; |
| 3377 | for matched in regex.find_iter(&code) { |
| 3378 | let prefix = code[..matched.start()].trim(); |
| 3379 | if !NOEXCEPT_CTOR_QUALS.contains(&prefix) { |
| 3380 | continue; |
| 3381 | } |
| 3382 | let paren = matched.end() - 1; |
| 3383 | let rest = code[paren + 1..].trim_start(); |
| 3384 | let copy_prefix = format!("const {name}"); |
| 3385 | if rest.starts_with(©_prefix) { |
| 3386 | let after = rest[copy_prefix.len()..].trim_start(); |
| 3387 | if after.starts_with('&') { |
| 3388 | return Some(("copy constructor", paren)); |
| 3389 | } |
| 3390 | } |
| 3391 | if rest.starts_with(name) { |
| 3392 | let after = rest[name.len()..].trim_start(); |
| 3393 | if after.starts_with("&&") { |
| 3394 | return Some(("move constructor", paren)); |
| 3395 | } |
| 3396 | } |
| 3397 | if rest.starts_with(')') |
| 3398 | || rest.starts_with("void") && rest[4..].trim_start().starts_with(')') |
| 3399 | { |
| 3400 | return Some(("default constructor", paren)); |
| 3401 | } |
no test coverage detected