@@ -26,6 +26,23 @@ namespace clice {
2626
2727namespace lsp = kota::ipc::lsp;
2828
29+ namespace {
30+
31+ auto zero_range () -> protocol::Range {
32+ auto pos = protocol::Position{.line = 0 , .character = 0 };
33+ return protocol::Range{.start = pos, .end = pos};
34+ }
35+
36+ auto file_location (llvm::StringRef path) -> std::optional<protocol::Location> {
37+ auto uri = lsp::URI::from_file_path (std::string (path));
38+ if (!uri) {
39+ return std::nullopt ;
40+ }
41+ return protocol::Location{.uri = uri->str (), .range = zero_range ()};
42+ }
43+
44+ } // namespace
45+
2946void Indexer::merge (const void * tu_index_data, std::size_t size) {
3047 auto tu_index = index::TUIndex::from (tu_index_data);
3148 if (tu_index.graph .paths .empty ()) {
@@ -243,10 +260,57 @@ Indexer::CursorHit Indexer::resolve_cursor(llvm::StringRef path,
243260 return {};
244261}
245262
263+ std::optional<protocol::Location>
264+ Indexer::find_include_definition (llvm::StringRef path,
265+ const protocol::Position& position,
266+ Session* session) {
267+ if (session && session->file_index && session->file_index ->mapper ) {
268+ auto offset = session->file_index ->mapper ->to_offset (position);
269+ if (!offset) {
270+ return std::nullopt ;
271+ }
272+ auto target = session->file_index ->find_include_definition (*offset);
273+ if (target && *target < session->file_index ->include_paths .size ()) {
274+ return file_location (session->file_index ->include_paths [*target]);
275+ }
276+ }
277+
278+ const std::string* doc_text = session ? &session->text : nullptr ;
279+ if (!doc_text) {
280+ return std::nullopt ;
281+ }
282+ lsp::PositionMapper doc_mapper (*doc_text, lsp::PositionEncoding::UTF16 );
283+ auto offset = doc_mapper.to_offset (position);
284+ if (!offset) {
285+ return std::nullopt ;
286+ }
287+
288+ auto proj_it = workspace.project_index .path_pool .find (path);
289+ if (proj_it == workspace.project_index .path_pool .cache .end ()) {
290+ return std::nullopt ;
291+ }
292+ auto shard_it = workspace.merged_indices .find (proj_it->second );
293+ if (shard_it == workspace.merged_indices .end ()) {
294+ return std::nullopt ;
295+ }
296+
297+ auto target = shard_it->second .find_include_definition (*offset);
298+ if (!target || *target >= workspace.project_index .path_pool .paths .size ()) {
299+ return std::nullopt ;
300+ }
301+ return file_location (workspace.project_index .path_pool .path (*target));
302+ }
303+
246304std::vector<protocol::Location> Indexer::query_relations (llvm::StringRef path,
247305 const protocol::Position& position,
248306 RelationKind kind,
249307 Session* session) {
308+ if (kind.value () == RelationKind::Definition) {
309+ if (auto include = find_include_definition (path, position, session)) {
310+ return {*include};
311+ }
312+ }
313+
250314 auto hit = resolve_cursor (path, position, session);
251315 if (hit.hash == 0 )
252316 return {};
0 commit comments