extractCall — the kotlin paths: navigation member branch (+ the #750 re-encode) and the raw-text else (paren-then-lambda / glued-invoke garbage preserved).
(&mut self, node: Node<'t>)
| 983 | /// re-encode) and the raw-text else (paren-then-lambda / glued-invoke |
| 984 | /// garbage preserved). |
| 985 | fn extract_call(&mut self, node: Node<'t>) { |
| 986 | if self.stack.is_empty() { |
| 987 | return; |
| 988 | } |
| 989 | let caller = self.top_row(); |
| 990 | let func = node |
| 991 | .child_by_field_name("function") |
| 992 | .or_else(|| node.named_child(0)); |
| 993 | let Some(func) = func else { return }; |
| 994 | let mut callee_name = String::new(); |
| 995 | |
| 996 | if func.kind() == "navigation_expression" { |
| 997 | let property = func |
| 998 | .child_by_field_name("property") |
| 999 | .or_else(|| func.child_by_field_name("field")) |
| 1000 | .or_else(|| { |
| 1001 | let c1 = func.named_child(1); |
| 1002 | match c1 { |
| 1003 | Some(c) if c.kind() == "navigation_suffix" => (0..c.named_child_count()) |
| 1004 | .filter_map(|i| c.named_child(i)) |
| 1005 | .find(|g| g.kind() == "simple_identifier") |
| 1006 | .or(Some(c)), |
| 1007 | other => other, |
| 1008 | } |
| 1009 | }); |
| 1010 | if let Some(property) = property { |
| 1011 | let method_name = self.text(property); |
| 1012 | let receiver = func |
| 1013 | .child_by_field_name("object") |
| 1014 | .or_else(|| func.child_by_field_name("operand")) |
| 1015 | .or_else(|| func.child_by_field_name("argument")) |
| 1016 | .or_else(|| func.named_child(0)); |
| 1017 | if let Some(r) = receiver { |
| 1018 | if is_literal_receiver(r.kind()) { |
| 1019 | return; // `"literal".uppercase()` / `5.toString()` |
| 1020 | } |
| 1021 | } |
| 1022 | let recv_ident = receiver.filter(|r| { |
| 1023 | matches!(r.kind(), "identifier" | "simple_identifier" | "field_identifier") |
| 1024 | }); |
| 1025 | if let Some(r) = recv_ident { |
| 1026 | let receiver_name = self.text(r); |
| 1027 | if matches!(receiver_name, "self" | "this" | "cls" | "super") { |
| 1028 | callee_name = method_name.to_string(); |
| 1029 | } else { |
| 1030 | callee_name = format!("{receiver_name}.{method_name}"); |
| 1031 | } |
| 1032 | } else if receiver.map(|r| r.kind() == "call_expression").unwrap_or(false) { |
| 1033 | // #750 kotlin re-encode: innerNav = receiver.namedChild(0) |
| 1034 | // (NOT a function field), ws-stripped, /^[A-Z]/ gate. |
| 1035 | let inner = receiver.unwrap().named_child(0); |
| 1036 | let inner_callee = |
| 1037 | inner.map(|n| strip_js_ws(self.text(n))).unwrap_or_default(); |
| 1038 | let reencode = inner_callee |
| 1039 | .as_bytes() |
| 1040 | .first() |
| 1041 | .map(|b| b.is_ascii_uppercase()) |
| 1042 | .unwrap_or(false); |
no test coverage detected