MCPcopy Create free account
hub / github.com/MaskRay/ccls / textDocument_switchSourceHeader

Method textDocument_switchSourceHeader

src/messages/textDocument_document.cc:211–271  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

209}
210
211void MessageHandler::textDocument_switchSourceHeader(TextDocumentIdentifier &param, ReplyOnce &reply) {
212 QueryFile *file;
213 WorkingFile *wf;
214 std::tie(file, wf) = findOrFail(param.uri.getPath(), reply);
215 if (!wf)
216 return reply(JsonNull{});
217 int file_id = file->id;
218
219 DocumentUri result;
220 const std::string &path = wf->filename;
221 bool is_hdr = lookupExtension(path).second;
222
223 // Vote for each interesting symbol's definitions (for header) or declarations (for non-header).
224 // Select the file with the most votes.
225 // Ignore Type symbols to skip class forward declarations and namespaces.
226 std::unordered_map<int, int> file_id2cnt;
227 for (auto [sym, refcnt] : file->symbol2refcnt) {
228 if (refcnt <= 0 || !sym.extent.valid() || sym.kind == Kind::Type)
229 continue;
230
231 if (is_hdr) {
232 withEntity(db, sym, [&](const auto &entity) {
233 for (auto &def : entity.def)
234 if (def.spell && def.file_id != file_id)
235 ++file_id2cnt[def.file_id];
236 });
237 } else {
238 for (DeclRef dr : getNonDefDeclarations(db, sym))
239 if (dr.file_id != file_id)
240 ++file_id2cnt[dr.file_id];
241 }
242 }
243 if (file_id2cnt.size()) {
244 auto best = file_id2cnt.begin();
245 for (auto it = file_id2cnt.begin(); it != file_id2cnt.end(); ++it)
246 if (it->second > best->second || (it->second == best->second && it->first < best->first))
247 best = it;
248 if (auto &def = db->files[best->first].def)
249 return reply(DocumentUri::fromPath(def->path));
250 }
251
252 if (is_hdr) {
253 // Check if `path` is in a #include entry.
254 for (QueryFile &file1 : db->files) {
255 auto &def = file1.def;
256 if (!def || lookupExtension(def->path).second)
257 continue;
258 for (IndexInclude &include : def->includes)
259 if (path == include.resolved_path)
260 return reply(DocumentUri::fromPath(def->path));
261 }
262 return reply(JsonNull{});
263 }
264
265 // Otherwise, find the #include with the same stem.
266 StringRef stem = sys::path::stem(path);
267 for (IndexInclude &include : file->def->includes)
268 if (sys::path::stem(include.resolved_path) == stem)

Callers

nothing calls this directly

Calls 8

replyFunction · 0.85
lookupExtensionFunction · 0.85
withEntityFunction · 0.85
beginMethod · 0.80
endMethod · 0.80
getPathMethod · 0.45
validMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected