(&mut self, n: Node<'t>, decorated_row: u32)
| 656 | } |
| 657 | |
| 658 | fn consider_decorator(&mut self, n: Node<'t>, decorated_row: u32) { |
| 659 | if !matches!(n.kind(), "decorator" | "annotation" | "marker_annotation" | "attribute") { |
| 660 | return; |
| 661 | } |
| 662 | let mut target: Option<Node> = None; |
| 663 | for i in 0..n.named_child_count() { |
| 664 | let Some(child) = n.named_child(i) else { continue }; |
| 665 | if child.kind() == "call_expression" { |
| 666 | target = child.child_by_field_name("function").or_else(|| child.named_child(0)); |
| 667 | if target.is_some() { |
| 668 | break; |
| 669 | } |
| 670 | } |
| 671 | if matches!( |
| 672 | child.kind(), |
| 673 | "identifier" | "member_expression" | "scoped_identifier" | "navigation_expression" |
| 674 | | "user_type" | "type_identifier" |
| 675 | ) { |
| 676 | target = Some(child); |
| 677 | break; |
| 678 | } |
| 679 | } |
| 680 | let Some(target) = target else { return }; |
| 681 | let mut name = self.text(target).to_string(); |
| 682 | if let Some(lt) = name.find('<') { |
| 683 | if lt > 0 { |
| 684 | name.truncate(lt); |
| 685 | } |
| 686 | } |
| 687 | let last_dot = name |
| 688 | .rfind('.') |
| 689 | .map(|i| i as isize) |
| 690 | .unwrap_or(-1) |
| 691 | .max(name.rfind("::").map(|i| i as isize).unwrap_or(-1)); |
| 692 | if last_dot >= 0 { |
| 693 | name = name[(last_dot as usize + 1)..].to_string(); |
| 694 | if name.starts_with(':') || name.starts_with('.') { |
| 695 | name.remove(0); |
| 696 | } |
| 697 | } |
| 698 | let name = name.trim().to_string(); |
| 699 | if name.is_empty() { |
| 700 | return; |
| 701 | } |
| 702 | self.push_ref_at(decorated_row, &name, edge_kind_index("decorates").unwrap(), n); |
| 703 | } |
| 704 | |
| 705 | // --- fn refs (PYTHON_SPEC) ------------------------------------------------------ |
| 706 |
no test coverage detected