Returns the concatenation of the given expressions. This flattens the concatenation as appropriate.
(mut exprs: Vec<Hir>)
| 399 | /// |
| 400 | /// This flattens the concatenation as appropriate. |
| 401 | pub fn concat(mut exprs: Vec<Hir>) -> Hir { |
| 402 | match exprs.len() { |
| 403 | 0 => Hir::empty(), |
| 404 | 1 => { exprs.pop().unwrap() } |
| 405 | _ => { |
| 406 | let mut info = HirInfo::new(); |
| 407 | info.set_always_utf8(true); |
| 408 | info.set_all_assertions(true); |
| 409 | info.set_any_anchored_start(false); |
| 410 | info.set_any_anchored_end(false); |
| 411 | info.set_match_empty(true); |
| 412 | info.set_literal(true); |
| 413 | info.set_alternation_literal(true); |
| 414 | |
| 415 | // Some attributes require analyzing all sub-expressions. |
| 416 | for e in &exprs { |
| 417 | let x = info.is_always_utf8() && e.is_always_utf8(); |
| 418 | info.set_always_utf8(x); |
| 419 | |
| 420 | let x = info.is_all_assertions() && e.is_all_assertions(); |
| 421 | info.set_all_assertions(x); |
| 422 | |
| 423 | let x = |
| 424 | info.is_any_anchored_start() |
| 425 | || e.is_any_anchored_start(); |
| 426 | info.set_any_anchored_start(x); |
| 427 | |
| 428 | let x = |
| 429 | info.is_any_anchored_end() |
| 430 | || e.is_any_anchored_end(); |
| 431 | info.set_any_anchored_end(x); |
| 432 | |
| 433 | let x = info.is_match_empty() && e.is_match_empty(); |
| 434 | info.set_match_empty(x); |
| 435 | |
| 436 | let x = info.is_literal() && e.is_literal(); |
| 437 | info.set_literal(x); |
| 438 | |
| 439 | let x = |
| 440 | info.is_alternation_literal() |
| 441 | && e.is_alternation_literal(); |
| 442 | info.set_alternation_literal(x); |
| 443 | } |
| 444 | // Anchored attributes require something slightly more |
| 445 | // sophisticated. Normally, WLOG, to determine whether an |
| 446 | // expression is anchored to the start, we'd only need to check |
| 447 | // the first expression of a concatenation. However, |
| 448 | // expressions like `$\b^` are still anchored to the start, |
| 449 | // but the first expression in the concatenation *isn't* |
| 450 | // anchored to the start. So the "first" expression to look at |
| 451 | // is actually one that is either not an assertion or is |
| 452 | // specifically the StartText assertion. |
| 453 | info.set_anchored_start( |
| 454 | exprs.iter() |
| 455 | .take_while(|e| { |
| 456 | e.is_anchored_start() || e.is_all_assertions() |
| 457 | }) |
| 458 | .any(|e| { |
nothing calls this directly
no test coverage detected