(&mut self, node: Node<'t>)
| 1195 | } |
| 1196 | |
| 1197 | fn extract_call(&mut self, node: Node<'t>) { |
| 1198 | if self.stack.is_empty() { |
| 1199 | return; |
| 1200 | } |
| 1201 | let caller = self.top_row(); |
| 1202 | let func = node |
| 1203 | .child_by_field_name("function") |
| 1204 | .or_else(|| node.named_child(0)); |
| 1205 | let Some(func) = func else { return }; |
| 1206 | let mut callee_name = String::new(); |
| 1207 | |
| 1208 | if func.kind() == "navigation_expression" { |
| 1209 | let property = func |
| 1210 | .child_by_field_name("property") |
| 1211 | .or_else(|| func.child_by_field_name("field")) |
| 1212 | .or_else(|| { |
| 1213 | let c1 = func.named_child(1); |
| 1214 | match c1 { |
| 1215 | Some(c) if c.kind() == "navigation_suffix" => (0..c.named_child_count()) |
| 1216 | .filter_map(|i| c.named_child(i)) |
| 1217 | .find(|g| g.kind() == "simple_identifier") |
| 1218 | .or(Some(c)), |
| 1219 | other => other, |
| 1220 | } |
| 1221 | }); |
| 1222 | if let Some(property) = property { |
| 1223 | let method_name = self.text(property); |
| 1224 | let receiver = func |
| 1225 | .child_by_field_name("object") |
| 1226 | .or_else(|| func.child_by_field_name("operand")) |
| 1227 | .or_else(|| func.child_by_field_name("argument")) |
| 1228 | .or_else(|| func.named_child(0)); |
| 1229 | if let Some(r) = receiver { |
| 1230 | if is_literal_receiver(r.kind()) { |
| 1231 | return; // `"literal".uppercase()` / `5.toString()` |
| 1232 | } |
| 1233 | } |
| 1234 | let recv_ident = receiver.filter(|r| { |
| 1235 | matches!(r.kind(), "identifier" | "simple_identifier" | "field_identifier") |
| 1236 | }); |
| 1237 | if let Some(r) = recv_ident { |
| 1238 | let receiver_name = self.text(r); |
| 1239 | if matches!(receiver_name, "self" | "this" | "cls" | "super") { |
| 1240 | callee_name = method_name.to_string(); |
| 1241 | } else { |
| 1242 | callee_name = format!("{receiver_name}.{method_name}"); |
| 1243 | } |
| 1244 | } else if receiver.map(|r| r.kind() == "call_expression").unwrap_or(false) { |
| 1245 | // #750 kotlin re-encode: innerNav = receiver.namedChild(0) |
| 1246 | // (NOT a function field), ws-stripped, /^[A-Z]/ gate. |
| 1247 | let inner = receiver.unwrap().named_child(0); |
| 1248 | let inner_callee = |
| 1249 | inner.map(|n| strip_js_ws(self.text(n))).unwrap_or_default(); |
| 1250 | let reencode = inner_callee |
| 1251 | .as_bytes() |
| 1252 | .first() |
| 1253 | .map(|b| b.is_ascii_uppercase()) |
| 1254 | .unwrap_or(false); |
no test coverage detected