Find all references to a member (method, property, or constant) across all files. When `hierarchy` is `Some`, only references where the subject resolves to a class in the given set of FQNs are returned. When the subject cannot be resolved (e.g. a complex expression or an untyped variable), the reference is conservatively included. When `hierarchy` is `None`, all references with a matching membe
(
&self,
target_member: &str,
target_is_static: bool,
include_declaration: bool,
hierarchy: Option<&HashSet<String>>,
)
| 755 | /// name and static-ness are returned (the v1 behaviour, kept as a |
| 756 | /// fallback when the target class cannot be determined). |
| 757 | fn find_member_references( |
| 758 | &self, |
| 759 | target_member: &str, |
| 760 | target_is_static: bool, |
| 761 | include_declaration: bool, |
| 762 | hierarchy: Option<&HashSet<String>>, |
| 763 | ) -> Vec<Location> { |
| 764 | let mut locations = Vec::new(); |
| 765 | |
| 766 | let snapshot = self.user_file_symbol_maps(); |
| 767 | |
| 768 | for (file_uri, symbol_map) in &snapshot { |
| 769 | // First pass: name-only check to avoid unnecessary work. |
| 770 | let has_potential_match = symbol_map.spans.iter().any(|span| match &span.kind { |
| 771 | SymbolKind::MemberAccess { |
| 772 | member_name, |
| 773 | is_static, |
| 774 | .. |
| 775 | } if member_name == target_member && *is_static == target_is_static => true, |
| 776 | SymbolKind::MemberDeclaration { name, is_static } |
| 777 | if include_declaration |
| 778 | && name == target_member |
| 779 | && *is_static == target_is_static => |
| 780 | { |
| 781 | true |
| 782 | } |
| 783 | _ => false, |
| 784 | }); |
| 785 | |
| 786 | // Special check for property declarations in ClassInfo (represented as Variable spans) |
| 787 | let mut check_ast_map = false; |
| 788 | if !has_potential_match |
| 789 | && include_declaration |
| 790 | && let Some(classes) = self.get_classes_for_uri(file_uri) |
| 791 | { |
| 792 | for class in &classes { |
| 793 | for prop in &class.properties { |
| 794 | let prop_name = prop.name.strip_prefix('$').unwrap_or(&prop.name); |
| 795 | let target_name = target_member.strip_prefix('$').unwrap_or(target_member); |
| 796 | if prop_name == target_name && prop.is_static == target_is_static { |
| 797 | check_ast_map = true; |
| 798 | break; |
| 799 | } |
| 800 | } |
| 801 | if check_ast_map { |
| 802 | break; |
| 803 | } |
| 804 | } |
| 805 | } |
| 806 | |
| 807 | if !has_potential_match && !check_ast_map { |
| 808 | continue; |
| 809 | } |
| 810 | |
| 811 | let parsed_uri = match Url::parse(file_uri) { |
| 812 | Ok(u) => u, |
| 813 | Err(_) => continue, |
| 814 | }; |
no test coverage detected