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

Method textDocument_codeLens

src/messages/textDocument_code.cc:79–144  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

77} // namespace
78
79void MessageHandler::textDocument_codeLens(TextDocumentParam &param, ReplyOnce &reply) {
80 auto [file, wf] = findOrFail(param.textDocument.uri.getPath(), reply);
81 if (!wf)
82 return;
83
84 std::vector<CodeLens> result;
85 auto add = [&, wf = wf](const char *singular, Cmd_xref show, Range range, int num, bool force_display = false) {
86 if (!num && !force_display)
87 return;
88 std::optional<lsRange> ls_range = getLsRange(wf, range);
89 if (!ls_range)
90 return;
91 CodeLens &code_lens = result.emplace_back();
92 code_lens.range = *ls_range;
93 code_lens.command = Command();
94 code_lens.command->command = std::string(ccls_xref);
95 bool plural = num > 1 && singular[strlen(singular) - 1] != 'd';
96 code_lens.command->title = llvm::formatv("{0} {1}{2}", num, singular, plural ? "s" : "").str();
97 code_lens.command->arguments.push_back(toString(show));
98 };
99
100 std::unordered_set<Range> seen;
101 for (auto [sym, refcnt] : file->symbol2refcnt) {
102 if (refcnt <= 0 || !sym.extent.valid() || !seen.insert(sym.range).second)
103 continue;
104 switch (sym.kind) {
105 case Kind::Func: {
106 QueryFunc &func = db->getFunc(sym);
107 const QueryFunc::Def *def = func.anyDef();
108 if (!def)
109 continue;
110 std::vector<Use> base_uses = getUsesForAllBases(db, func);
111 std::vector<Use> derived_uses = getUsesForAllDerived(db, func);
112 add("ref", {sym.usr, Kind::Func, "uses"}, sym.range, func.uses.size(), base_uses.empty());
113 if (base_uses.size())
114 add("b.ref", {sym.usr, Kind::Func, "bases uses"}, sym.range, base_uses.size());
115 if (derived_uses.size())
116 add("d.ref", {sym.usr, Kind::Func, "derived uses"}, sym.range, derived_uses.size());
117 if (base_uses.empty())
118 add("base", {sym.usr, Kind::Func, "bases"}, sym.range, def->bases.size());
119 add("derived", {sym.usr, Kind::Func, "derived"}, sym.range, func.derived.size());
120 break;
121 }
122 case Kind::Type: {
123 QueryType &type = db->getType(sym);
124 add("ref", {sym.usr, Kind::Type, "uses"}, sym.range, type.uses.size(), true);
125 add("derived", {sym.usr, Kind::Type, "derived"}, sym.range, type.derived.size());
126 add("var", {sym.usr, Kind::Type, "instances"}, sym.range, type.instances.size());
127 break;
128 }
129 case Kind::Var: {
130 QueryVar &var = db->getVar(sym);
131 const QueryVar::Def *def = var.anyDef();
132 if (!def || (def->is_local() && !g_config->codeLens.localVariables))
133 continue;
134 add("ref", {sym.usr, Kind::Var, "uses"}, sym.range, var.uses.size(), def->kind != SymbolKind::Macro);
135 break;
136 }

Callers

nothing calls this directly

Calls 13

getLsRangeFunction · 0.85
CommandClass · 0.85
getUsesForAllBasesFunction · 0.85
getUsesForAllDerivedFunction · 0.85
addFunction · 0.85
replyFunction · 0.85
insertMethod · 0.80
anyDefMethod · 0.80
is_localMethod · 0.80
toStringFunction · 0.70
getPathMethod · 0.45
validMethod · 0.45

Tested by

no test coverage detected