Dispatch a symbol-map hit to the appropriate reference finder.
(
&self,
kind: &SymbolKind,
uri: &str,
content: &str,
span_start: u32,
include_declaration: bool,
)
| 112 | |
| 113 | /// Dispatch a symbol-map hit to the appropriate reference finder. |
| 114 | fn dispatch_symbol_references( |
| 115 | &self, |
| 116 | kind: &SymbolKind, |
| 117 | uri: &str, |
| 118 | content: &str, |
| 119 | span_start: u32, |
| 120 | include_declaration: bool, |
| 121 | ) -> Vec<Location> { |
| 122 | match kind { |
| 123 | SymbolKind::Variable { name } => { |
| 124 | // Property declarations use Variable spans (so GTD can |
| 125 | // jump to the type hint), but Find References should |
| 126 | // search for member accesses, not local variable uses. |
| 127 | if let Some(crate::symbol_map::VarDefKind::Property) = |
| 128 | self.lookup_var_def_kind_at(uri, name, span_start) |
| 129 | { |
| 130 | // Properties are never static in the Variable span |
| 131 | // context ($this->prop). Static properties use |
| 132 | // MemberAccess spans at their usage sites with |
| 133 | // is_static=true, but the declaration-site Variable |
| 134 | // span doesn't encode static-ness. Check the |
| 135 | // uri_classes_index to determine the correct flag. |
| 136 | let is_static = self |
| 137 | .get_classes_for_uri(uri) |
| 138 | .iter() |
| 139 | .flat_map(|classes| classes.iter()) |
| 140 | .flat_map(|c| c.properties.iter()) |
| 141 | .any(|p| { |
| 142 | let p_name = p.name.strip_prefix('$').unwrap_or(&p.name); |
| 143 | p_name == name && p.is_static |
| 144 | }); |
| 145 | |
| 146 | // Resolve the enclosing class to scope the search. |
| 147 | let hierarchy = self.resolve_member_declaration_hierarchy(uri, span_start); |
| 148 | return self.find_member_references( |
| 149 | name, |
| 150 | is_static, |
| 151 | include_declaration, |
| 152 | hierarchy.as_ref(), |
| 153 | ); |
| 154 | } |
| 155 | self.find_variable_references(uri, content, name, span_start, include_declaration) |
| 156 | } |
| 157 | SymbolKind::ClassReference { name, is_fqn, .. } => { |
| 158 | let ctx = self.file_context(uri); |
| 159 | let fqn = if *is_fqn { |
| 160 | name.clone() |
| 161 | } else { |
| 162 | ctx.resolve_name_at(name, span_start) |
| 163 | }; |
| 164 | self.find_class_references(&fqn, include_declaration) |
| 165 | } |
| 166 | SymbolKind::ClassDeclaration { name } => { |
| 167 | let ctx = self.file_context(uri); |
| 168 | let fqn = build_fqn(name, ctx.namespace.as_deref()); |
| 169 | self.find_class_references(&fqn, include_declaration) |
| 170 | } |
| 171 | SymbolKind::MemberAccess { |
no test coverage detected