Entry point for `textDocument/implementation`. Returns a list of locations where the symbol under the cursor is concretely implemented. Returns `None` if the cursor is not on a resolvable interface/abstract symbol.
(
&self,
uri: &str,
content: &str,
position: Position,
)
| 49 | /// concretely implemented. Returns `None` if the cursor is not on a |
| 50 | /// resolvable interface/abstract symbol. |
| 51 | pub(crate) fn resolve_implementation( |
| 52 | &self, |
| 53 | uri: &str, |
| 54 | content: &str, |
| 55 | position: Position, |
| 56 | ) -> Option<Vec<Location>> { |
| 57 | // ── 1. Extract the word under the cursor ──────────────────────── |
| 58 | // Primary path: consult the precomputed symbol map. |
| 59 | let symbol = self.lookup_symbol_at_position(uri, content, position); |
| 60 | |
| 61 | if let Some(ref sym) = symbol { |
| 62 | match &sym.kind { |
| 63 | // Member access — delegate directly to member implementation |
| 64 | // resolution using the structured symbol information. |
| 65 | SymbolKind::MemberAccess { member_name, .. } => { |
| 66 | let ctx = self.file_context(uri); |
| 67 | return self.resolve_member_implementations( |
| 68 | uri, |
| 69 | content, |
| 70 | position, |
| 71 | member_name.as_str(), |
| 72 | &ctx, |
| 73 | ); |
| 74 | } |
| 75 | // Class reference or declaration — resolve as a class/interface name. |
| 76 | SymbolKind::ClassReference { name, .. } | SymbolKind::ClassDeclaration { name } => { |
| 77 | let ctx = self.file_context(uri); |
| 78 | return self.resolve_class_implementation(uri, content, name, &ctx, sym.start); |
| 79 | } |
| 80 | // self/static/parent — resolve the keyword to the current |
| 81 | // class and check whether it is an interface/abstract. |
| 82 | SymbolKind::SelfStaticParent(ssp_kind) => { |
| 83 | let ctx = self.file_context(uri); |
| 84 | let class_loader = self.class_loader(&ctx); |
| 85 | let current_class = find_class_at_offset(&ctx.classes, sym.start); |
| 86 | let target = match ssp_kind { |
| 87 | SelfStaticParentKind::Parent => current_class |
| 88 | .and_then(|cc| cc.parent_class.as_deref()) |
| 89 | .and_then(|p| class_loader(p).map(Arc::unwrap_or_clone)), |
| 90 | _ => current_class.cloned(), |
| 91 | }; |
| 92 | if let Some(ref t) = target { |
| 93 | return self |
| 94 | .resolve_class_implementation(uri, content, &t.name, &ctx, sym.start); |
| 95 | } |
| 96 | return None; |
| 97 | } |
| 98 | // Member declaration — reverse jump: from a concrete method |
| 99 | // definition to the interface/abstract method it implements. |
| 100 | SymbolKind::MemberDeclaration { name, .. } => { |
| 101 | let ctx = self.file_context(uri); |
| 102 | let class_loader = self.class_loader(&ctx); |
| 103 | let current_class = find_class_at_offset(&ctx.classes, sym.start); |
| 104 | if let Some(cls) = current_class { |
| 105 | return self.resolve_reverse_implementation( |
| 106 | uri, |
| 107 | content, |
| 108 | cls, |
no test coverage detected