extractCall — the Java method_invocation paths.
(&mut self, node: Node<'t>)
| 824 | |
| 825 | /// extractCall — the Java method_invocation paths. |
| 826 | fn extract_call(&mut self, node: Node<'t>) { |
| 827 | if self.stack.is_empty() { |
| 828 | return; |
| 829 | } |
| 830 | let caller = self.top_row(); |
| 831 | let name_field = node.child_by_field_name("name"); |
| 832 | let object_field = node |
| 833 | .child_by_field_name("object") |
| 834 | .or_else(|| node.child_by_field_name("scope")); |
| 835 | |
| 836 | let mut callee_name = String::new(); |
| 837 | if let (Some(name_field), Some(object_field)) = (name_field, object_field) { |
| 838 | let method_name = self.text(name_field); |
| 839 | |
| 840 | // Static-factory / fluent chain: `Foo.getInstance().bar()` → |
| 841 | // `<inner-receiver>.<inner-method>().<method>` (#645/#608). |
| 842 | if !method_name.is_empty() && object_field.kind() == "method_invocation" { |
| 843 | let inner_obj = object_field.child_by_field_name("object"); |
| 844 | let inner_name = object_field.child_by_field_name("name"); |
| 845 | if let (Some(io), Some(inm)) = (inner_obj, inner_name) { |
| 846 | let callee = format!("{}.{}().{}", self.text(io), self.text(inm), method_name); |
| 847 | self.push_ref_at(caller, &callee, edge_kind_index("calls").unwrap(), node); |
| 848 | return; |
| 849 | } |
| 850 | } |
| 851 | |
| 852 | // `this.userbo.toLogin2()` — unwrap the field after `this.`. |
| 853 | let receiver_name = if object_field.kind() == "field_access" { |
| 854 | let inner = object_field.child_by_field_name("object"); |
| 855 | let fld = object_field.child_by_field_name("field"); |
| 856 | match (inner, fld) { |
| 857 | (Some(inner), Some(fld)) |
| 858 | if matches!(inner.kind(), "this" | "this_expression") => |
| 859 | { |
| 860 | self.text(fld).to_string() |
| 861 | } |
| 862 | _ => self.text(object_field).to_string(), |
| 863 | } |
| 864 | } else { |
| 865 | self.text(object_field).to_string() |
| 866 | }; |
| 867 | let receiver_name = receiver_name.strip_prefix('$').unwrap_or(&receiver_name); |
| 868 | |
| 869 | if !method_name.is_empty() { |
| 870 | if matches!(receiver_name, "self" | "this" | "cls" | "super" | "parent" | "static") { |
| 871 | callee_name = method_name.to_string(); |
| 872 | } else { |
| 873 | callee_name = format!("{receiver_name}.{method_name}"); |
| 874 | } |
| 875 | } |
| 876 | } else { |
| 877 | // Bare call `foo()` — the generic tail: function field ?? first child. |
| 878 | let func = node |
| 879 | .child_by_field_name("function") |
| 880 | .or_else(|| node.named_child(0)); |
| 881 | if let Some(func) = func { |
| 882 | callee_name = self.text(func).to_string(); |
| 883 | } |
no test coverage detected