captureFnRefCandidates for the TS/JS spec. Returns (candidate, mode) pairs.
(container: Node, mode: Mode, src: &str)
| 45 | |
| 46 | /// captureFnRefCandidates for the TS/JS spec. Returns (candidate, mode) pairs. |
| 47 | pub fn capture(container: Node, mode: Mode, src: &str) -> Vec<(Candidate, Mode)> { |
| 48 | let mut value_nodes: Vec<Node> = Vec::new(); |
| 49 | |
| 50 | match mode { |
| 51 | Mode::Args | Mode::List => { |
| 52 | for i in 0..container.named_child_count() { |
| 53 | if let Some(c) = container.named_child(i) { |
| 54 | value_nodes.push(c); |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | Mode::Rhs => { |
| 59 | if let Some(rhs) = container.child_by_field_name("right") { |
| 60 | // Param-storage skip: `this.status = status` — LHS's trailing |
| 61 | // identifier equals the RHS text ⇒ a stored local/parameter. |
| 62 | let lhs_text = container |
| 63 | .child_by_field_name("left") |
| 64 | .map(|l| &src[l.byte_range()]) |
| 65 | .unwrap_or(""); |
| 66 | let lhs_last = super::util::lhs_last_name() |
| 67 | .captures(lhs_text) |
| 68 | .and_then(|c| c.get(1)) |
| 69 | .map(|m| m.as_str()); |
| 70 | let rhs_text = src[rhs.byte_range()].trim(); |
| 71 | if !(lhs_last.is_some() && lhs_last == Some(rhs_text)) { |
| 72 | value_nodes.push(rhs); |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | Mode::Value => { |
| 77 | if let Some(v) = container.child_by_field_name("value") { |
| 78 | value_nodes.push(v); |
| 79 | } |
| 80 | } |
| 81 | Mode::VarInit => { |
| 82 | // Destructuring extracts DATA, never a function alias. |
| 83 | let name_node = container.child_by_field_name("name"); |
| 84 | let is_pattern = name_node |
| 85 | .map(|n| matches!(n.kind(), "object_pattern" | "array_pattern")) |
| 86 | .unwrap_or(false); |
| 87 | if !is_pattern { |
| 88 | if let Some(v) = container.child_by_field_name("value") { |
| 89 | value_nodes.push(v); |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | let mut out = Vec::new(); |
| 96 | for v in value_nodes { |
| 97 | for (name, node) in normalize(v, src) { |
| 98 | if name.is_empty() || stoplisted(&name) { |
| 99 | continue; |
| 100 | } |
| 101 | let p = node.start_position(); |
| 102 | out.push(( |
| 103 | Candidate { |
| 104 | name, |
no test coverage detected