Rename hierarchies to $ccls/{call,inheritance,member}

bool flat = false; -> bool hierarchy = false; (set it to true to enable hierarchical view)

Delete $ccls/callers (which is what $ccls/call does now)
This commit is contained in:
Fangrui Song 2018-09-13 00:18:37 -07:00
parent a174105abe
commit 70deeca8ad
8 changed files with 137 additions and 208 deletions

View File

@ -209,11 +209,10 @@ target_sources(ccls PRIVATE
) )
target_sources(ccls PRIVATE target_sources(ccls PRIVATE
src/messages/ccls_callHierarchy.cc src/messages/ccls_call.cc
src/messages/ccls_callers.cc
src/messages/ccls_fileInfo.cc src/messages/ccls_fileInfo.cc
src/messages/ccls_inheritanceHierarchy.cc src/messages/ccls_inheritance.cc
src/messages/ccls_memberHierarchy.cc src/messages/ccls_member.cc
src/messages/ccls_navigate.cc src/messages/ccls_navigate.cc
src/messages/ccls_reload.cc src/messages/ccls_reload.cc
src/messages/ccls_vars.cc src/messages/ccls_vars.cc

39
src/hierarchy.hh Normal file
View File

@ -0,0 +1,39 @@
/* Copyright 2017-2018 ccls Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#pragma once
#include "lsp.h"
#include <algorithm>
#include <queue>
template <typename Node>
void FlattenHierarchy(const Node &root, Out_LocationList &out) {
std::queue<const Node *> q;
for (auto &entry : root.children)
q.push(&entry);
while (q.size()) {
auto *entry = q.front();
q.pop();
if (entry->location.uri.raw_uri.size())
out.result.push_back({entry->location});
for (auto &entry1 : entry->children)
q.push(&entry1);
}
std::sort(out.result.begin(), out.result.end());
out.result.erase(std::unique(out.result.begin(), out.result.end()),
out.result.end());
}

View File

@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "hierarchy.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h" #include "query_utils.h"
@ -22,7 +23,7 @@ using namespace ccls;
namespace { namespace {
MethodType kMethodType = "$ccls/callHierarchy"; MethodType kMethodType = "$ccls/call";
enum class CallType : uint8_t { enum class CallType : uint8_t {
Direct = 0, Direct = 0,
@ -36,7 +37,7 @@ bool operator&(CallType lhs, CallType rhs) {
return uint8_t(lhs) & uint8_t(rhs); return uint8_t(lhs) & uint8_t(rhs);
} }
struct In_CclsCallHierarchy : public RequestInMessage { struct In_CclsCall : public RequestInMessage {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
struct Params { struct Params {
@ -56,15 +57,16 @@ struct In_CclsCallHierarchy : public RequestInMessage {
CallType callType = CallType::All; CallType callType = CallType::All;
bool qualified = true; bool qualified = true;
int levels = 1; int levels = 1;
bool hierarchy = false;
}; };
Params params; Params params;
}; };
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, textDocument, position, id, MAKE_REFLECT_STRUCT(In_CclsCall::Params, textDocument, position, id,
callee, callType, qualified, levels); callee, callType, qualified, levels, hierarchy);
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params); MAKE_REFLECT_STRUCT(In_CclsCall, id, params);
REGISTER_IN_MESSAGE(In_CclsCallHierarchy); REGISTER_IN_MESSAGE(In_CclsCall);
struct Out_CclsCallHierarchy : public lsOutMessage<Out_CclsCallHierarchy> { struct Out_CclsCall : public lsOutMessage<Out_CclsCall> {
struct Entry { struct Entry {
Usr usr; Usr usr;
std::string id; std::string id;
@ -79,12 +81,12 @@ struct Out_CclsCallHierarchy : public lsOutMessage<Out_CclsCallHierarchy> {
lsRequestId id; lsRequestId id;
std::optional<Entry> result; std::optional<Entry> result;
}; };
MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, id, name, location, callType, MAKE_REFLECT_STRUCT(Out_CclsCall::Entry, id, name, location, callType,
numChildren, children); numChildren, children);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, jsonrpc, id, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCall, jsonrpc, id,
result); result);
bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee, bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee,
CallType call_type, bool qualified, int levels) { CallType call_type, bool qualified, int levels) {
const QueryFunc &func = m->db->Func(entry->usr); const QueryFunc &func = m->db->Func(entry->usr);
const QueryFunc::Def *def = func.AnyDef(); const QueryFunc::Def *def = func.AnyDef();
@ -94,7 +96,7 @@ bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee,
auto handle = [&](Use use, CallType call_type1) { auto handle = [&](Use use, CallType call_type1) {
entry->numChildren++; entry->numChildren++;
if (levels > 0) { if (levels > 0) {
Out_CclsCallHierarchy::Entry entry1; Out_CclsCall::Entry entry1;
entry1.id = std::to_string(use.usr); entry1.id = std::to_string(use.usr);
entry1.usr = use.usr; entry1.usr = use.usr;
if (auto loc = GetLsLocation(m->db, m->working_files, use)) if (auto loc = GetLsLocation(m->db, m->working_files, use))
@ -160,17 +162,17 @@ bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee,
return true; return true;
} }
struct Handler_CclsCallHierarchy : BaseMessageHandler<In_CclsCallHierarchy> { struct Handler_CclsCall : BaseMessageHandler<In_CclsCall> {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
std::optional<Out_CclsCallHierarchy::Entry> std::optional<Out_CclsCall::Entry>
BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified, BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified,
int levels) { int levels) {
const auto *def = db->Func(root_usr).AnyDef(); const auto *def = db->Func(root_usr).AnyDef();
if (!def) if (!def)
return {}; return {};
Out_CclsCallHierarchy::Entry entry; Out_CclsCall::Entry entry;
entry.id = std::to_string(root_usr); entry.id = std::to_string(root_usr);
entry.usr = root_usr; entry.usr = root_usr;
entry.callType = CallType::Direct; entry.callType = CallType::Direct;
@ -183,9 +185,9 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler<In_CclsCallHierarchy> {
return entry; return entry;
} }
void Run(In_CclsCallHierarchy *request) override { void Run(In_CclsCall *request) override {
auto &params = request->params; auto &params = request->params;
Out_CclsCallHierarchy out; Out_CclsCall out;
out.id = request->id; out.id = request->id;
if (params.id.size()) { if (params.id.size()) {
@ -194,7 +196,7 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler<In_CclsCallHierarchy> {
} catch (...) { } catch (...) {
return; return;
} }
Out_CclsCallHierarchy::Entry entry; Out_CclsCall::Entry entry;
entry.id = std::to_string(params.usr); entry.id = std::to_string(params.usr);
entry.usr = params.usr; entry.usr = params.usr;
entry.callType = CallType::Direct; entry.callType = CallType::Direct;
@ -219,9 +221,17 @@ struct Handler_CclsCallHierarchy : BaseMessageHandler<In_CclsCallHierarchy> {
} }
} }
pipeline::WriteStdout(kMethodType, out); if (params.hierarchy) {
pipeline::WriteStdout(kMethodType, out);
return;
}
Out_LocationList out1;
out1.id = request->id;
if (out.result)
FlattenHierarchy<Out_CclsCall::Entry>(*out.result, out1);
pipeline::WriteStdout(kMethodType, out1);
} }
}; };
REGISTER_MESSAGE_HANDLER(Handler_CclsCallHierarchy); REGISTER_MESSAGE_HANDLER(Handler_CclsCall);
} // namespace } // namespace

View File

@ -1,62 +0,0 @@
/* Copyright 2017-2018 ccls Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "message_handler.h"
#include "pipeline.hh"
#include "query_utils.h"
using namespace ccls;
namespace {
MethodType kMethodType = "$ccls/callers";
struct In_CclsCallers : public RequestInMessage {
MethodType GetMethodType() const override { return kMethodType; }
lsTextDocumentPositionParams params;
};
MAKE_REFLECT_STRUCT(In_CclsCallers, id, params);
REGISTER_IN_MESSAGE(In_CclsCallers);
struct Handler_CclsCallers : BaseMessageHandler<In_CclsCallers> {
MethodType GetMethodType() const override { return kMethodType; }
void Run(In_CclsCallers *request) override {
QueryFile *file;
if (!FindFileOrFail(db, project, request->id,
request->params.textDocument.uri.GetPath(), &file)) {
return;
}
WorkingFile *working_file =
working_files->GetFileByFilename(file->def->path);
Out_LocationList out;
out.id = request->id;
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, request->params.position)) {
if (sym.kind == SymbolKind::Func) {
QueryFunc &func = db->GetFunc(sym);
std::vector<Use> uses = func.uses;
for (Use func_ref : GetUsesForAllBases(db, func))
uses.push_back(func_ref);
for (Use func_ref : GetUsesForAllDerived(db, func))
uses.push_back(func_ref);
out.result = GetLsLocationExs(db, working_files, uses);
break;
}
}
pipeline::WriteStdout(kMethodType, out);
}
};
REGISTER_MESSAGE_HANDLER(Handler_CclsCallers);
} // namespace

View File

@ -13,18 +13,18 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "hierarchy.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h" #include "query_utils.h"
using namespace ccls; using namespace ccls;
#include <queue>
#include <unordered_set> #include <unordered_set>
namespace { namespace {
MethodType kMethodType = "$ccls/inheritanceHierarchy"; MethodType kMethodType = "$ccls/inheritance";
struct In_CclsInheritanceHierarchy : public RequestInMessage { struct In_CclsInheritance : public RequestInMessage {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
struct Params { struct Params {
// If id+kind are specified, expand a node; otherwise textDocument+position // If id+kind are specified, expand a node; otherwise textDocument+position
@ -40,17 +40,17 @@ struct In_CclsInheritanceHierarchy : public RequestInMessage {
bool derived = false; bool derived = false;
bool qualified = true; bool qualified = true;
int levels = 1; int levels = 1;
bool flat = false; bool hierarchy = false;
} params; } params;
}; };
MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy::Params, textDocument, position, MAKE_REFLECT_STRUCT(In_CclsInheritance::Params, textDocument, position,
id, kind, derived, qualified, levels, flat); id, kind, derived, qualified, levels, hierarchy);
MAKE_REFLECT_STRUCT(In_CclsInheritanceHierarchy, id, params); MAKE_REFLECT_STRUCT(In_CclsInheritance, id, params);
REGISTER_IN_MESSAGE(In_CclsInheritanceHierarchy); REGISTER_IN_MESSAGE(In_CclsInheritance);
struct Out_CclsInheritanceHierarchy struct Out_CclsInheritance
: public lsOutMessage<Out_CclsInheritanceHierarchy> { : public lsOutMessage<Out_CclsInheritance> {
struct Entry { struct Entry {
Usr usr; Usr usr;
std::string id; std::string id;
@ -66,16 +66,16 @@ struct Out_CclsInheritanceHierarchy
lsRequestId id; lsRequestId id;
std::optional<Entry> result; std::optional<Entry> result;
}; };
MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, id, kind, name, MAKE_REFLECT_STRUCT(Out_CclsInheritance::Entry, id, kind, name,
location, numChildren, children); location, numChildren, children);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, jsonrpc, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritance, jsonrpc,
id, result); id, result);
bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry,
bool derived, bool qualified, int levels); bool derived, bool qualified, int levels);
template <typename Q> template <typename Q>
bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, bool ExpandHelper(MessageHandler *m, Out_CclsInheritance::Entry *entry,
bool derived, bool qualified, int levels, Q &entity) { bool derived, bool qualified, int levels, Q &entity) {
const auto *def = entity.AnyDef(); const auto *def = entity.AnyDef();
if (def) { if (def) {
@ -97,7 +97,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
for (auto usr : entity.derived) { for (auto usr : entity.derived) {
if (!seen.insert(usr).second) if (!seen.insert(usr).second)
continue; continue;
Out_CclsInheritanceHierarchy::Entry entry1; Out_CclsInheritance::Entry entry1;
entry1.id = std::to_string(usr); entry1.id = std::to_string(usr);
entry1.usr = usr; entry1.usr = usr;
entry1.kind = entry->kind; entry1.kind = entry->kind;
@ -112,7 +112,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
for (auto usr : def->bases) { for (auto usr : def->bases) {
if (!seen.insert(usr).second) if (!seen.insert(usr).second)
continue; continue;
Out_CclsInheritanceHierarchy::Entry entry1; Out_CclsInheritance::Entry entry1;
entry1.id = std::to_string(usr); entry1.id = std::to_string(usr);
entry1.usr = usr; entry1.usr = usr;
entry1.kind = entry->kind; entry1.kind = entry->kind;
@ -126,7 +126,7 @@ bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
return true; return true;
} }
bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry, bool Expand(MessageHandler *m, Out_CclsInheritance::Entry *entry,
bool derived, bool qualified, int levels) { bool derived, bool qualified, int levels) {
if (entry->kind == SymbolKind::Func) if (entry->kind == SymbolKind::Func)
return ExpandHelper(m, entry, derived, qualified, levels, return ExpandHelper(m, entry, derived, qualified, levels,
@ -136,13 +136,13 @@ bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
m->db->Type(entry->usr)); m->db->Type(entry->usr));
} }
struct Handler_CclsInheritanceHierarchy struct Handler_CclsInheritance
: BaseMessageHandler<In_CclsInheritanceHierarchy> { : BaseMessageHandler<In_CclsInheritance> {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
std::optional<Out_CclsInheritanceHierarchy::Entry> std::optional<Out_CclsInheritance::Entry>
BuildInitial(SymbolRef sym, bool derived, bool qualified, int levels) { BuildInitial(SymbolRef sym, bool derived, bool qualified, int levels) {
Out_CclsInheritanceHierarchy::Entry entry; Out_CclsInheritance::Entry entry;
entry.id = std::to_string(sym.usr); entry.id = std::to_string(sym.usr);
entry.usr = sym.usr; entry.usr = sym.usr;
entry.kind = sym.kind; entry.kind = sym.kind;
@ -150,18 +150,18 @@ struct Handler_CclsInheritanceHierarchy
return entry; return entry;
} }
void Run(In_CclsInheritanceHierarchy *request) override { void Run(In_CclsInheritance *request) override {
auto &params = request->params; auto &params = request->params;
Out_CclsInheritanceHierarchy out; Out_CclsInheritance out;
out.id = request->id; out.id = request->id;
if (!params.flat && params.id.size()) { if (params.id.size()) {
try { try {
params.usr = std::stoull(params.id); params.usr = std::stoull(params.id);
} catch (...) { } catch (...) {
return; return;
} }
Out_CclsInheritanceHierarchy::Entry entry; Out_CclsInheritance::Entry entry;
entry.id = std::to_string(params.usr); entry.id = std::to_string(params.usr);
entry.usr = params.usr; entry.usr = params.usr;
entry.kind = params.kind; entry.kind = params.kind;
@ -184,31 +184,17 @@ struct Handler_CclsInheritanceHierarchy
} }
} }
if (!params.flat) { if (params.hierarchy) {
pipeline::WriteStdout(kMethodType, out); pipeline::WriteStdout(kMethodType, out);
return; return;
} }
Out_LocationList out1; Out_LocationList out1;
out1.id = request->id; out1.id = request->id;
if (out.result) { if (out.result)
std::queue<Out_CclsInheritanceHierarchy::Entry *> q; FlattenHierarchy<Out_CclsInheritance::Entry>(*out.result, out1);
for (auto &entry1 : out.result->children)
q.push(&entry1);
while (q.size()) {
auto *entry = q.front();
q.pop();
if (entry->location.uri.raw_uri.size())
out1.result.push_back({entry->location});
for (auto &entry1 : entry->children)
q.push(&entry1);
}
std::sort(out1.result.begin(), out1.result.end());
out1.result.erase(std::unique(out1.result.begin(), out1.result.end()),
out1.result.end());
}
pipeline::WriteStdout(kMethodType, out1); pipeline::WriteStdout(kMethodType, out1);
} }
}; };
REGISTER_MESSAGE_HANDLER(Handler_CclsInheritanceHierarchy); REGISTER_MESSAGE_HANDLER(Handler_CclsInheritance);
} // namespace } // namespace

View File

@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
==============================================================================*/ ==============================================================================*/
#include "hierarchy.hh"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h" #include "query_utils.h"
@ -21,13 +22,12 @@ using namespace ccls;
#include <clang/AST/Type.h> #include <clang/AST/Type.h>
using namespace clang; using namespace clang;
#include <queue>
#include <unordered_set> #include <unordered_set>
namespace { namespace {
MethodType kMethodType = "$ccls/memberHierarchy"; MethodType kMethodType = "$ccls/member";
struct In_CclsMemberHierarchy : public RequestInMessage { struct In_CclsMember : public RequestInMessage {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
struct Params { struct Params {
@ -42,16 +42,16 @@ struct In_CclsMemberHierarchy : public RequestInMessage {
bool qualified = false; bool qualified = false;
int levels = 1; int levels = 1;
bool flat = false; bool hierarchy = false;
} params; } params;
}; };
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id, MAKE_REFLECT_STRUCT(In_CclsMember::Params, textDocument, position, id,
qualified, levels, flat); qualified, levels, hierarchy);
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); MAKE_REFLECT_STRUCT(In_CclsMember, id, params);
REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); REGISTER_IN_MESSAGE(In_CclsMember);
struct Out_CclsMemberHierarchy : public lsOutMessage<Out_CclsMemberHierarchy> { struct Out_CclsMember : public lsOutMessage<Out_CclsMember> {
struct Entry { struct Entry {
Usr usr; Usr usr;
std::string id; std::string id;
@ -67,21 +67,21 @@ struct Out_CclsMemberHierarchy : public lsOutMessage<Out_CclsMemberHierarchy> {
lsRequestId id; lsRequestId id;
std::optional<Entry> result; std::optional<Entry> result;
}; };
MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, id, name, fieldName, MAKE_REFLECT_STRUCT(Out_CclsMember::Entry, id, name, fieldName,
location, numChildren, children); location, numChildren, children);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, jsonrpc, id, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMember, jsonrpc, id,
result); result);
bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry,
bool qualified, int levels); bool qualified, int levels);
// Add a field to |entry| which is a Func/Type. // Add a field to |entry| which is a Func/Type.
void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, void DoField(MessageHandler *m, Out_CclsMember::Entry *entry,
const QueryVar &var, int64_t offset, bool qualified, int levels) { const QueryVar &var, int64_t offset, bool qualified, int levels) {
const QueryVar::Def *def1 = var.AnyDef(); const QueryVar::Def *def1 = var.AnyDef();
if (!def1) if (!def1)
return; return;
Out_CclsMemberHierarchy::Entry entry1; Out_CclsMember::Entry entry1;
// With multiple inheritance, the offset is incorrect. // With multiple inheritance, the offset is incorrect.
if (offset >= 0) { if (offset >= 0) {
if (offset / 8 < 10) if (offset / 8 < 10)
@ -118,7 +118,7 @@ void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
} }
// Expand a type node by adding members recursively to it. // Expand a type node by adding members recursively to it.
bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry, bool Expand(MessageHandler *m, Out_CclsMember::Entry *entry,
bool qualified, int levels) { bool qualified, int levels) {
if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) {
entry->name = ClangBuiltinTypeName(int(entry->usr)); entry->name = ClangBuiltinTypeName(int(entry->usr));
@ -139,15 +139,16 @@ bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
const auto *def = stack.back()->AnyDef(); const auto *def = stack.back()->AnyDef();
stack.pop_back(); stack.pop_back();
if (def) { if (def) {
EachDefinedType(m->db, def->bases, [&](QueryType &type1) { for (Usr usr : def->bases) {
if (!seen.count(type1.usr)) { auto &type1 = m->db->Type(usr);
if (type1.def.size()) {
seen.insert(type1.usr); seen.insert(type1.usr);
stack.push_back(&type1); stack.push_back(&type1);
} }
}); }
if (def->alias_of) { if (def->alias_of) {
const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef(); const QueryType::Def *def1 = m->db->Type(def->alias_of).AnyDef();
Out_CclsMemberHierarchy::Entry entry1; Out_CclsMember::Entry entry1;
entry1.id = std::to_string(def->alias_of); entry1.id = std::to_string(def->alias_of);
entry1.usr = def->alias_of; entry1.usr = def->alias_of;
if (def1 && def1->spell) { if (def1 && def1->spell) {
@ -185,11 +186,11 @@ bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
return true; return true;
} }
struct Handler_CclsMemberHierarchy struct Handler_CclsMember
: BaseMessageHandler<In_CclsMemberHierarchy> { : BaseMessageHandler<In_CclsMember> {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
std::optional<Out_CclsMemberHierarchy::Entry> std::optional<Out_CclsMember::Entry>
BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) { BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) {
switch (kind) { switch (kind) {
default: default:
@ -199,7 +200,7 @@ struct Handler_CclsMemberHierarchy
if (!def) if (!def)
return {}; return {};
Out_CclsMemberHierarchy::Entry entry; Out_CclsMember::Entry entry;
// Not type, |id| is invalid. // Not type, |id| is invalid.
entry.name = def->Name(qualified); entry.name = def->Name(qualified);
if (def->spell) { if (def->spell) {
@ -207,9 +208,11 @@ struct Handler_CclsMemberHierarchy
GetLsLocation(db, working_files, *def->spell)) GetLsLocation(db, working_files, *def->spell))
entry.location = *loc; entry.location = *loc;
} }
EachDefinedVar(db, def->vars, [&](QueryVar &var) { for (Usr usr : def->vars) {
DoField(this, &entry, var, -1, qualified, levels - 1); auto &var = db->Var(usr);
}); if (var.def.size())
DoField(this, &entry, var, -1, qualified, levels - 1);
}
return entry; return entry;
} }
case SymbolKind::Type: { case SymbolKind::Type: {
@ -217,7 +220,7 @@ struct Handler_CclsMemberHierarchy
if (!def) if (!def)
return {}; return {};
Out_CclsMemberHierarchy::Entry entry; Out_CclsMember::Entry entry;
entry.id = std::to_string(root_usr); entry.id = std::to_string(root_usr);
entry.usr = root_usr; entry.usr = root_usr;
if (def->spell) { if (def->spell) {
@ -231,9 +234,9 @@ struct Handler_CclsMemberHierarchy
} }
} }
void Run(In_CclsMemberHierarchy *request) override { void Run(In_CclsMember *request) override {
auto &params = request->params; auto &params = request->params;
Out_CclsMemberHierarchy out; Out_CclsMember out;
out.id = request->id; out.id = request->id;
if (params.id.size()) { if (params.id.size()) {
@ -242,7 +245,7 @@ struct Handler_CclsMemberHierarchy
} catch (...) { } catch (...) {
return; return;
} }
Out_CclsMemberHierarchy::Entry entry; Out_CclsMember::Entry entry;
entry.id = std::to_string(params.usr); entry.id = std::to_string(params.usr);
entry.usr = params.usr; entry.usr = params.usr;
// entry.name is empty as it is known by the client. // entry.name is empty as it is known by the client.
@ -277,31 +280,17 @@ struct Handler_CclsMemberHierarchy
} }
} }
if (!params.flat) { if (params.hierarchy) {
pipeline::WriteStdout(kMethodType, out); pipeline::WriteStdout(kMethodType, out);
return; return;
} }
Out_LocationList out1; Out_LocationList out1;
out1.id = request->id; out1.id = request->id;
if (out.result) { if (out.result)
std::queue<Out_CclsMemberHierarchy::Entry *> q; FlattenHierarchy<Out_CclsMember::Entry>(*out.result, out1);
for (auto &entry1 : out.result->children)
q.push(&entry1);
while (q.size()) {
auto *entry = q.front();
q.pop();
if (entry->location.uri.raw_uri.size())
out1.result.push_back({entry->location});
for (auto &entry1 : entry->children)
q.push(&entry1);
}
std::sort(out1.result.begin(), out1.result.end());
out1.result.erase(std::unique(out1.result.begin(), out1.result.end()),
out1.result.end());
}
pipeline::WriteStdout(kMethodType, out1); pipeline::WriteStdout(kMethodType, out1);
} }
}; };
REGISTER_MESSAGE_HANDLER(Handler_CclsMemberHierarchy); REGISTER_MESSAGE_HANDLER(Handler_CclsMember);
} // namespace } // namespace

View File

@ -167,18 +167,6 @@ std::vector<Use> GetUsesForAllDerived(DB *db, QueryFunc &root) {
return ret; return ret;
} }
std::optional<lsPosition> GetLsPosition(WorkingFile *wfile,
const Position &position) {
if (!wfile || wfile->index_lines.empty())
return lsPosition{position.line, position.column};
int column = position.column;
if (std::optional<int> start =
wfile->GetBufferPosFromIndexPos(position.line, &column, false))
return lsPosition{*start, column};
return std::nullopt;
}
std::optional<lsRange> GetLsRange(WorkingFile *wfile, std::optional<lsRange> GetLsRange(WorkingFile *wfile,
const Range &location) { const Range &location) {
if (!wfile || wfile->index_lines.empty()) if (!wfile || wfile->index_lines.empty())

View File

@ -34,8 +34,6 @@ std::vector<Use> GetNonDefDeclarations(DB *db, SymbolIdx sym);
std::vector<Use> GetUsesForAllBases(DB *db, QueryFunc &root); std::vector<Use> GetUsesForAllBases(DB *db, QueryFunc &root);
std::vector<Use> GetUsesForAllDerived(DB *db, QueryFunc &root); std::vector<Use> GetUsesForAllDerived(DB *db, QueryFunc &root);
std::optional<lsPosition> GetLsPosition(WorkingFile *working_file,
const Position &position);
std::optional<lsRange> GetLsRange(WorkingFile *working_file, std::optional<lsRange> GetLsRange(WorkingFile *working_file,
const Range &location); const Range &location);
lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path);
@ -105,21 +103,3 @@ void EachDefinedFunc(DB *db, const std::vector<Usr> &usrs, Fn &&fn) {
fn(obj); fn(obj);
} }
} }
template <typename Fn>
void EachDefinedType(DB *db, const std::vector<Usr> &usrs, Fn &&fn) {
for (Usr usr : usrs) {
auto &obj = db->Type(usr);
if (!obj.def.empty())
fn(obj);
}
}
template <typename Fn>
void EachDefinedVar(DB *db, const std::vector<Usr> &usrs, Fn &&fn) {
for (Usr usr : usrs) {
auto &obj = db->Var(usr);
if (!obj.def.empty())
fn(obj);
}
}