mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 18:11:57 +00:00
Redesign SymbolRef, Ref, Use
Remove lsLocationEx
This commit is contained in:
parent
38feb8d277
commit
6ec032c2a0
@ -249,8 +249,6 @@ struct Config {
|
|||||||
} workspaceSymbol;
|
} workspaceSymbol;
|
||||||
|
|
||||||
struct Xref {
|
struct Xref {
|
||||||
// If true, |Location[]| response will include lexical container.
|
|
||||||
bool container = false;
|
|
||||||
// Maximum number of definition/reference/... results.
|
// Maximum number of definition/reference/... results.
|
||||||
int maxNum = 2000;
|
int maxNum = 2000;
|
||||||
} xref;
|
} xref;
|
||||||
@ -274,7 +272,7 @@ MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist,
|
|||||||
multiVersionWhitelist, onChange, threads, trackDependency,
|
multiVersionWhitelist, onChange, threads, trackDependency,
|
||||||
whitelist);
|
whitelist);
|
||||||
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
||||||
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
MAKE_REFLECT_STRUCT(Config::Xref, maxNum);
|
||||||
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
||||||
compilationDatabaseDirectory, cacheDirectory, cacheFormat,
|
compilationDatabaseDirectory, cacheDirectory, cacheFormat,
|
||||||
clang, client, codeLens, completion, diagnostics, highlight,
|
clang, client, codeLens, completion, diagnostics, highlight,
|
||||||
|
289
src/indexer.cc
289
src/indexer.cc
@ -117,50 +117,109 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts,
|
|||||||
BInfo.second);
|
BInfo.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolKind GetSymbolKind(const Decl *D) {
|
SymbolKind GetSymbolKind(const Decl *D, lsSymbolKind &kind) {
|
||||||
switch (D->getKind()) {
|
switch (D->getKind()) {
|
||||||
case Decl::TranslationUnit:
|
case Decl::LinkageSpec:
|
||||||
return SymbolKind::File;
|
return SymbolKind::Invalid;
|
||||||
case Decl::ObjCMethod:
|
|
||||||
case Decl::FunctionTemplate:
|
|
||||||
case Decl::Function:
|
|
||||||
case Decl::CXXMethod:
|
|
||||||
case Decl::CXXConstructor:
|
|
||||||
case Decl::CXXConversion:
|
|
||||||
case Decl::CXXDestructor:
|
|
||||||
return SymbolKind::Func;
|
|
||||||
case Decl::Namespace:
|
case Decl::Namespace:
|
||||||
|
kind = lsSymbolKind::Namespace;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::NamespaceAlias:
|
case Decl::NamespaceAlias:
|
||||||
|
kind = lsSymbolKind::TypeAlias;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::ObjCCategory:
|
case Decl::ObjCCategory:
|
||||||
|
case Decl::ObjCImplementation:
|
||||||
case Decl::ObjCInterface:
|
case Decl::ObjCInterface:
|
||||||
case Decl::ObjCProtocol:
|
case Decl::ObjCProtocol:
|
||||||
|
kind = lsSymbolKind::Interface;
|
||||||
|
return SymbolKind::Type;
|
||||||
|
case Decl::ObjCMethod:
|
||||||
|
kind = lsSymbolKind::Method;
|
||||||
|
return SymbolKind::Func;
|
||||||
|
case Decl::ObjCProperty:
|
||||||
|
kind = lsSymbolKind::Property;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::ClassTemplate:
|
case Decl::ClassTemplate:
|
||||||
|
kind = lsSymbolKind::Class;
|
||||||
|
return SymbolKind::Type;
|
||||||
|
case Decl::FunctionTemplate:
|
||||||
|
kind = lsSymbolKind::Function;
|
||||||
|
return SymbolKind::Func;
|
||||||
case Decl::TypeAliasTemplate:
|
case Decl::TypeAliasTemplate:
|
||||||
|
kind = lsSymbolKind::TypeAlias;
|
||||||
|
return SymbolKind::Type;
|
||||||
|
case Decl::VarTemplate:
|
||||||
|
kind = lsSymbolKind::Variable;
|
||||||
|
return SymbolKind::Var;
|
||||||
case Decl::TemplateTemplateParm:
|
case Decl::TemplateTemplateParm:
|
||||||
|
kind = lsSymbolKind::TypeParameter;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::Enum:
|
case Decl::Enum:
|
||||||
case Decl::Record:
|
kind = lsSymbolKind::Enum;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::CXXRecord:
|
case Decl::CXXRecord:
|
||||||
|
case Decl::Record:
|
||||||
|
kind = lsSymbolKind::Class;
|
||||||
|
// spec has no Union, use Class
|
||||||
|
if (auto *RD = dyn_cast<RecordDecl>(D))
|
||||||
|
if (RD->getTagKind() == TTK_Struct)
|
||||||
|
kind = lsSymbolKind::Struct;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::ClassTemplateSpecialization:
|
case Decl::ClassTemplateSpecialization:
|
||||||
case Decl::ClassTemplatePartialSpecialization:
|
case Decl::ClassTemplatePartialSpecialization:
|
||||||
|
kind = lsSymbolKind::Class;
|
||||||
|
return SymbolKind::Type;
|
||||||
case Decl::TypeAlias:
|
case Decl::TypeAlias:
|
||||||
case Decl::Typedef:
|
case Decl::Typedef:
|
||||||
case Decl::UnresolvedUsingTypename:
|
case Decl::UnresolvedUsingTypename:
|
||||||
|
kind = lsSymbolKind::TypeAlias;
|
||||||
return SymbolKind::Type;
|
return SymbolKind::Type;
|
||||||
case Decl::ObjCProperty:
|
|
||||||
case Decl::VarTemplate:
|
|
||||||
case Decl::Binding:
|
case Decl::Binding:
|
||||||
|
kind = lsSymbolKind::Variable;
|
||||||
|
return SymbolKind::Var;
|
||||||
case Decl::Field:
|
case Decl::Field:
|
||||||
case Decl::ObjCIvar:
|
case Decl::ObjCIvar:
|
||||||
|
kind = lsSymbolKind::Field;
|
||||||
|
return SymbolKind::Var;
|
||||||
|
case Decl::Function:
|
||||||
|
kind = lsSymbolKind::Function;
|
||||||
|
return SymbolKind::Func;
|
||||||
|
case Decl::CXXMethod: {
|
||||||
|
const auto *MD = cast<CXXMethodDecl>(D);
|
||||||
|
kind = MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method;
|
||||||
|
return SymbolKind::Func;
|
||||||
|
}
|
||||||
|
case Decl::CXXConstructor:
|
||||||
|
kind = lsSymbolKind::Constructor;
|
||||||
|
return SymbolKind::Func;
|
||||||
|
case Decl::CXXConversion:
|
||||||
|
case Decl::CXXDestructor:
|
||||||
|
kind = lsSymbolKind::Method;
|
||||||
|
return SymbolKind::Func;
|
||||||
case Decl::Var:
|
case Decl::Var:
|
||||||
case Decl::ParmVar:
|
|
||||||
case Decl::ImplicitParam:
|
|
||||||
case Decl::Decomposition:
|
case Decl::Decomposition:
|
||||||
|
kind = lsSymbolKind::Variable;
|
||||||
|
return SymbolKind::Var;
|
||||||
|
case Decl::ImplicitParam:
|
||||||
|
case Decl::ParmVar:
|
||||||
|
// ccls extension
|
||||||
|
kind = lsSymbolKind::Parameter;
|
||||||
|
return SymbolKind::Var;
|
||||||
case Decl::VarTemplateSpecialization:
|
case Decl::VarTemplateSpecialization:
|
||||||
case Decl::VarTemplatePartialSpecialization:
|
case Decl::VarTemplatePartialSpecialization:
|
||||||
case Decl::EnumConstant:
|
kind = lsSymbolKind::Variable;
|
||||||
case Decl::UnresolvedUsingValue:
|
|
||||||
return SymbolKind::Var;
|
return SymbolKind::Var;
|
||||||
|
case Decl::EnumConstant:
|
||||||
|
kind = lsSymbolKind::EnumMember;
|
||||||
|
return SymbolKind::Var;
|
||||||
|
case Decl::UnresolvedUsingValue:
|
||||||
|
kind = lsSymbolKind::Variable;
|
||||||
|
return SymbolKind::Var;
|
||||||
|
case Decl::TranslationUnit:
|
||||||
|
return SymbolKind::Invalid;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
LOG_S(INFO) << "unhandled " << int(D->getKind());
|
||||||
return SymbolKind::Invalid;
|
return SymbolKind::Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,23 +480,6 @@ public:
|
|||||||
return it->second.usr;
|
return it->second.usr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Use GetUse(IndexFile *db, int lid, Range range, const DeclContext *DC,
|
|
||||||
Role role) const {
|
|
||||||
if (!DC)
|
|
||||||
return {{range, 0, SymbolKind::File, role}, lid};
|
|
||||||
const Decl *D = cast<Decl>(DC);
|
|
||||||
switch (GetSymbolKind(D)) {
|
|
||||||
case SymbolKind::Func:
|
|
||||||
return {{range, db->ToFunc(GetUsr(D)).usr, SymbolKind::Func, role}, lid};
|
|
||||||
case SymbolKind::Type:
|
|
||||||
return {{range, db->ToType(GetUsr(D)).usr, SymbolKind::Type, role}, lid};
|
|
||||||
case SymbolKind::Var:
|
|
||||||
return {{range, db->ToVar(GetUsr(D)).usr, SymbolKind::Var, role}, lid};
|
|
||||||
default:
|
|
||||||
return {{range, 0, SymbolKind::File, role}, lid};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintingPolicy GetDefaultPolicy() const {
|
PrintingPolicy GetDefaultPolicy() const {
|
||||||
PrintingPolicy PP(Ctx->getLangOpts());
|
PrintingPolicy PP(Ctx->getLangOpts());
|
||||||
PP.AnonymousTagLocations = false;
|
PP.AnonymousTagLocations = false;
|
||||||
@ -590,7 +632,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
Range spell =
|
Range spell =
|
||||||
FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell));
|
FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell));
|
||||||
Use use{{spell, 0, SymbolKind::File, Role::Dynamic}, lid};
|
Use use{{spell, Role::Dynamic}, lid};
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
db->ToFunc(usr).uses.push_back(use);
|
db->ToFunc(usr).uses.push_back(use);
|
||||||
@ -704,7 +746,8 @@ public:
|
|||||||
IndexFunc *func = nullptr;
|
IndexFunc *func = nullptr;
|
||||||
IndexType *type = nullptr;
|
IndexType *type = nullptr;
|
||||||
IndexVar *var = nullptr;
|
IndexVar *var = nullptr;
|
||||||
SymbolKind kind = GetSymbolKind(D);
|
lsSymbolKind ls_kind;
|
||||||
|
SymbolKind kind = GetSymbolKind(D, ls_kind);
|
||||||
|
|
||||||
if (is_def)
|
if (is_def)
|
||||||
switch (D->getKind()) {
|
switch (D->getKind()) {
|
||||||
@ -734,19 +777,20 @@ public:
|
|||||||
|
|
||||||
auto do_def_decl = [&](auto *entity) {
|
auto do_def_decl = [&](auto *entity) {
|
||||||
if (is_def) {
|
if (is_def) {
|
||||||
entity->def.spell = GetUse(db, lid, loc, SemDC, role);
|
entity->def.spell = {{loc, role}, lid};
|
||||||
SourceRange R = OrigD->getSourceRange();
|
SourceRange R = OrigD->getSourceRange();
|
||||||
entity->def.extent =
|
entity->def.extent = {
|
||||||
GetUse(db, lid,
|
{R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc,
|
||||||
R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc,
|
Role::None},
|
||||||
LexDC, Role::None);
|
lid};
|
||||||
|
GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind);
|
||||||
} else if (is_decl) {
|
} else if (is_decl) {
|
||||||
DeclRef &dr = entity->declarations.emplace_back();
|
DeclRef &dr = entity->declarations.emplace_back();
|
||||||
static_cast<Use&>(dr) = GetUse(db, lid, loc, LexDC, role);
|
static_cast<Use&>(dr) = {{loc, role}, lid};
|
||||||
SourceRange R = OrigD->getSourceRange();
|
SourceRange R = OrigD->getSourceRange();
|
||||||
dr.extent = R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc;
|
dr.extent = R.getBegin().isFileID() ? FromTokenRange(SM, Lang, R) : loc;
|
||||||
} else {
|
} else {
|
||||||
entity->uses.push_back(GetUse(db, lid, loc, LexDC, role));
|
entity->uses.push_back({{loc, role}, lid});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (entity->def.comments[0] == '\0' && g_config->index.comments)
|
if (entity->def.comments[0] == '\0' && g_config->index.comments)
|
||||||
@ -761,6 +805,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
case SymbolKind::Func:
|
case SymbolKind::Func:
|
||||||
func = &db->ToFunc(usr);
|
func = &db->ToFunc(usr);
|
||||||
|
func->def.kind = ls_kind;
|
||||||
// Mark as Role::Implicit to span one more column to the left/right.
|
// Mark as Role::Implicit to span one more column to the left/right.
|
||||||
if (!is_def && !is_decl &&
|
if (!is_def && !is_decl &&
|
||||||
(D->getKind() == Decl::CXXConstructor ||
|
(D->getKind() == Decl::CXXConstructor ||
|
||||||
@ -773,17 +818,18 @@ public:
|
|||||||
SetName(D, info->short_name, info->qualified, func->def);
|
SetName(D, info->short_name, info->qualified, func->def);
|
||||||
if (is_def || is_decl) {
|
if (is_def || is_decl) {
|
||||||
const Decl *DC = cast<Decl>(SemDC);
|
const Decl *DC = cast<Decl>(SemDC);
|
||||||
if (GetSymbolKind(DC) == SymbolKind::Type)
|
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type)
|
||||||
db->ToType(GetUsr(DC)).def.funcs.push_back(usr);
|
db->ToType(GetUsr(DC)).def.funcs.push_back(usr);
|
||||||
} else {
|
} else {
|
||||||
const Decl *DC = cast<Decl>(LexDC);
|
const Decl *DC = cast<Decl>(LexDC);
|
||||||
if (GetSymbolKind(DC) == SymbolKind::Func)
|
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func)
|
||||||
db->ToFunc(GetUsr(DC))
|
db->ToFunc(GetUsr(DC))
|
||||||
.def.callees.push_back({{loc, usr, SymbolKind::Func, role}});
|
.def.callees.push_back({loc, usr, SymbolKind::Func, role});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
type = &db->ToType(usr);
|
type = &db->ToType(usr);
|
||||||
|
type->def.kind = ls_kind;
|
||||||
do_def_decl(type);
|
do_def_decl(type);
|
||||||
if (Spell != Loc)
|
if (Spell != Loc)
|
||||||
AddMacroUse(db, SM, usr, SymbolKind::Type, Spell);
|
AddMacroUse(db, SM, usr, SymbolKind::Type, Spell);
|
||||||
@ -791,12 +837,13 @@ public:
|
|||||||
SetName(D, info->short_name, info->qualified, type->def);
|
SetName(D, info->short_name, info->qualified, type->def);
|
||||||
if (is_def || is_decl) {
|
if (is_def || is_decl) {
|
||||||
const Decl *DC = cast<Decl>(SemDC);
|
const Decl *DC = cast<Decl>(SemDC);
|
||||||
if (GetSymbolKind(DC) == SymbolKind::Type)
|
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type)
|
||||||
db->ToType(GetUsr(DC)).def.types.push_back(usr);
|
db->ToType(GetUsr(DC)).def.types.push_back(usr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SymbolKind::Var:
|
case SymbolKind::Var:
|
||||||
var = &db->ToVar(usr);
|
var = &db->ToVar(usr);
|
||||||
|
var->def.kind = ls_kind;
|
||||||
do_def_decl(var);
|
do_def_decl(var);
|
||||||
if (Spell != Loc)
|
if (Spell != Loc)
|
||||||
AddMacroUse(db, SM, usr, SymbolKind::Var, Spell);
|
AddMacroUse(db, SM, usr, SymbolKind::Var, Spell);
|
||||||
@ -809,7 +856,7 @@ public:
|
|||||||
T = FD->getType();
|
T = FD->getType();
|
||||||
if (is_def || is_decl) {
|
if (is_def || is_decl) {
|
||||||
const Decl *DC = cast<Decl>(SemDC);
|
const Decl *DC = cast<Decl>(SemDC);
|
||||||
if (GetSymbolKind(DC) == SymbolKind::Func)
|
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func)
|
||||||
db->ToFunc(GetUsr(DC)).def.vars.push_back(usr);
|
db->ToFunc(GetUsr(DC)).def.vars.push_back(usr);
|
||||||
else if (auto *ND = dyn_cast<NamespaceDecl>(SemDC))
|
else if (auto *ND = dyn_cast<NamespaceDecl>(SemDC))
|
||||||
db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1);
|
db->ToType(GetUsr(ND)).def.vars.emplace_back(usr, -1);
|
||||||
@ -828,14 +875,15 @@ public:
|
|||||||
Usr usr1 = GetUsr(D1, &info1);
|
Usr usr1 = GetUsr(D1, &info1);
|
||||||
IndexType &type1 = db->ToType(usr1);
|
IndexType &type1 = db->ToType(usr1);
|
||||||
SourceLocation L1 = D1->getLocation();
|
SourceLocation L1 = D1->getLocation();
|
||||||
type1.def.spell =
|
type1.def.spell = {
|
||||||
GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC,
|
{FromTokenRange(SM, Lang, {L1, L1}), Role::Definition},
|
||||||
Role::Definition);
|
lid};
|
||||||
type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1),
|
type1.def.extent = {{FromTokenRange(SM, Lang, R1), Role::None},
|
||||||
LexDC, Role::None);
|
lid};
|
||||||
type1.def.detailed_name = Intern(info1->short_name);
|
type1.def.detailed_name = Intern(info1->short_name);
|
||||||
type1.def.short_name_size = int16_t(info1->short_name.size());
|
type1.def.short_name_size = int16_t(info1->short_name.size());
|
||||||
type1.def.kind = lsSymbolKind::TypeParameter;
|
type1.def.kind = lsSymbolKind::TypeParameter;
|
||||||
|
type1.def.parent_kind = lsSymbolKind::Class;
|
||||||
var->def.type = usr1;
|
var->def.type = usr1;
|
||||||
type1.instances.push_back(usr);
|
type1.instances.push_back(usr);
|
||||||
break;
|
break;
|
||||||
@ -852,11 +900,11 @@ public:
|
|||||||
// e.g. lambda parameter
|
// e.g. lambda parameter
|
||||||
SourceLocation L = D->getLocation();
|
SourceLocation L = D->getLocation();
|
||||||
if (SM.getFileID(L) == LocFID) {
|
if (SM.getFileID(L) == LocFID) {
|
||||||
var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}),
|
var->def.spell = {
|
||||||
SemDC, Role::Definition);
|
{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid};
|
||||||
var->def.extent =
|
var->def.extent = {
|
||||||
GetUse(db, lid, FromTokenRange(SM, Lang, D->getSourceRange()),
|
{FromTokenRange(SM, Lang, D->getSourceRange()), Role::None}, lid};
|
||||||
LexDC, Role::None);
|
var->def.parent_kind = lsSymbolKind::Method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -864,7 +912,6 @@ public:
|
|||||||
|
|
||||||
switch (D->getKind()) {
|
switch (D->getKind()) {
|
||||||
case Decl::Namespace:
|
case Decl::Namespace:
|
||||||
type->def.kind = lsSymbolKind::Namespace;
|
|
||||||
if (D->isFirstDecl()) {
|
if (D->isFirstDecl()) {
|
||||||
auto *ND = cast<NamespaceDecl>(D);
|
auto *ND = cast<NamespaceDecl>(D);
|
||||||
auto *ND1 = cast<Decl>(ND->getParent());
|
auto *ND1 = cast<Decl>(ND->getParent());
|
||||||
@ -876,7 +923,6 @@ public:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Decl::NamespaceAlias: {
|
case Decl::NamespaceAlias: {
|
||||||
type->def.kind = lsSymbolKind::TypeAlias;
|
|
||||||
auto *NAD = cast<NamespaceAliasDecl>(D);
|
auto *NAD = cast<NamespaceAliasDecl>(D);
|
||||||
if (const NamespaceDecl *ND = NAD->getNamespace()) {
|
if (const NamespaceDecl *ND = NAD->getNamespace()) {
|
||||||
Usr usr1 = GetUsr(ND);
|
Usr usr1 = GetUsr(ND);
|
||||||
@ -885,36 +931,6 @@ public:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Decl::ObjCCategory:
|
|
||||||
case Decl::ObjCImplementation:
|
|
||||||
case Decl::ObjCInterface:
|
|
||||||
case Decl::ObjCProtocol:
|
|
||||||
type->def.kind = lsSymbolKind::Interface;
|
|
||||||
break;
|
|
||||||
case Decl::ObjCMethod:
|
|
||||||
func->def.kind = lsSymbolKind::Method;
|
|
||||||
break;
|
|
||||||
case Decl::ObjCProperty:
|
|
||||||
var->def.kind = lsSymbolKind::Property;
|
|
||||||
break;
|
|
||||||
case Decl::ClassTemplate:
|
|
||||||
type->def.kind = lsSymbolKind::Class;
|
|
||||||
break;
|
|
||||||
case Decl::FunctionTemplate:
|
|
||||||
func->def.kind = lsSymbolKind::Function;
|
|
||||||
break;
|
|
||||||
case Decl::TypeAliasTemplate:
|
|
||||||
type->def.kind = lsSymbolKind::TypeAlias;
|
|
||||||
break;
|
|
||||||
case Decl::VarTemplate:
|
|
||||||
var->def.kind = lsSymbolKind::Variable;
|
|
||||||
break;
|
|
||||||
case Decl::TemplateTemplateParm:
|
|
||||||
type->def.kind = lsSymbolKind::TypeParameter;
|
|
||||||
break;
|
|
||||||
case Decl::Enum:
|
|
||||||
type->def.kind = lsSymbolKind::Enum;
|
|
||||||
break;
|
|
||||||
case Decl::CXXRecord:
|
case Decl::CXXRecord:
|
||||||
if (is_def) {
|
if (is_def) {
|
||||||
auto *RD = dyn_cast<CXXRecordDecl>(D);
|
auto *RD = dyn_cast<CXXRecordDecl>(D);
|
||||||
@ -930,9 +946,6 @@ public:
|
|||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case Decl::Record:
|
case Decl::Record:
|
||||||
if (auto *RD = dyn_cast<RecordDecl>(D)) {
|
if (auto *RD = dyn_cast<RecordDecl>(D)) {
|
||||||
// spec has no Union, use Class
|
|
||||||
type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct
|
|
||||||
: lsSymbolKind::Class;
|
|
||||||
if (type->def.detailed_name[0] == '\0' && info->short_name.empty()) {
|
if (type->def.detailed_name[0] == '\0' && info->short_name.empty()) {
|
||||||
StringRef Tag;
|
StringRef Tag;
|
||||||
switch (RD->getTagKind()) {
|
switch (RD->getTagKind()) {
|
||||||
@ -990,7 +1003,6 @@ public:
|
|||||||
case Decl::TypeAlias:
|
case Decl::TypeAlias:
|
||||||
case Decl::Typedef:
|
case Decl::Typedef:
|
||||||
case Decl::UnresolvedUsingTypename:
|
case Decl::UnresolvedUsingTypename:
|
||||||
type->def.kind = lsSymbolKind::TypeAlias;
|
|
||||||
if (auto *TD = dyn_cast<TypedefNameDecl>(D)) {
|
if (auto *TD = dyn_cast<TypedefNameDecl>(D)) {
|
||||||
bool specialization = false;
|
bool specialization = false;
|
||||||
QualType T = TD->getUnderlyingType();
|
QualType T = TD->getUnderlyingType();
|
||||||
@ -1002,29 +1014,14 @@ public:
|
|||||||
if (specialization) {
|
if (specialization) {
|
||||||
const TypeSourceInfo *TSI = TD->getTypeSourceInfo();
|
const TypeSourceInfo *TSI = TD->getTypeSourceInfo();
|
||||||
SourceLocation L1 = TSI->getTypeLoc().getBeginLoc();
|
SourceLocation L1 = TSI->getTypeLoc().getBeginLoc();
|
||||||
if (SM.getFileID(L1) == LocFID) {
|
if (SM.getFileID(L1) == LocFID)
|
||||||
Range loc1 = FromTokenRange(SM, Lang, {L1, L1});
|
|
||||||
type1.uses.push_back(
|
type1.uses.push_back(
|
||||||
GetUse(db, lid, loc1, LexDC, Role::Reference));
|
{{FromTokenRange(SM, Lang, {L1, L1}), Role::Reference}, lid});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Decl::Binding:
|
case Decl::CXXMethod:
|
||||||
var->def.kind = lsSymbolKind::Variable;
|
|
||||||
break;
|
|
||||||
case Decl::Field:
|
|
||||||
case Decl::ObjCIvar:
|
|
||||||
var->def.kind = lsSymbolKind::Field;
|
|
||||||
break;
|
|
||||||
case Decl::Function:
|
|
||||||
func->def.kind = lsSymbolKind::Function;
|
|
||||||
break;
|
|
||||||
case Decl::CXXMethod: {
|
|
||||||
const auto *MD = cast<CXXMethodDecl>(D);
|
|
||||||
func->def.kind =
|
|
||||||
MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method;
|
|
||||||
if (is_def || is_decl) {
|
if (is_def || is_decl) {
|
||||||
if (auto *ND = dyn_cast<NamedDecl>(D)) {
|
if (auto *ND = dyn_cast<NamedDecl>(D)) {
|
||||||
SmallVector<const NamedDecl *, 8> OverDecls;
|
SmallVector<const NamedDecl *, 8> OverDecls;
|
||||||
@ -1037,29 +1034,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case Decl::CXXConstructor:
|
|
||||||
func->def.kind = lsSymbolKind::Constructor;
|
|
||||||
break;
|
|
||||||
case Decl::CXXConversion:
|
|
||||||
case Decl::CXXDestructor:
|
|
||||||
func->def.kind = lsSymbolKind::Method;
|
|
||||||
break;
|
|
||||||
case Decl::Var:
|
|
||||||
case Decl::Decomposition:
|
|
||||||
var->def.kind = lsSymbolKind::Variable;
|
|
||||||
break;
|
|
||||||
case Decl::ImplicitParam:
|
|
||||||
case Decl::ParmVar:
|
|
||||||
// ccls extension
|
|
||||||
var->def.kind = lsSymbolKind::Parameter;
|
|
||||||
break;
|
|
||||||
case Decl::VarTemplateSpecialization:
|
|
||||||
case Decl::VarTemplatePartialSpecialization:
|
|
||||||
var->def.kind = lsSymbolKind::Variable;
|
|
||||||
break;
|
|
||||||
case Decl::EnumConstant:
|
case Decl::EnumConstant:
|
||||||
var->def.kind = lsSymbolKind::EnumMember;
|
|
||||||
if (is_def && strchr(var->def.detailed_name, '=') == nullptr) {
|
if (is_def && strchr(var->def.detailed_name, '=') == nullptr) {
|
||||||
auto *ECD = cast<EnumConstantDecl>(D);
|
auto *ECD = cast<EnumConstantDecl>(D);
|
||||||
const auto &Val = ECD->getInitVal();
|
const auto &Val = ECD->getInitVal();
|
||||||
@ -1069,11 +1044,7 @@ public:
|
|||||||
var->def.hover = Intern(var->def.detailed_name + init);
|
var->def.hover = Intern(var->def.detailed_name + init);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Decl::UnresolvedUsingValue:
|
|
||||||
var->def.kind = lsSymbolKind::Variable;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOG_S(INFO) << "Unhandled " << int(D->getKind());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1131,16 +1102,17 @@ public:
|
|||||||
IndexVar &var = db->ToVar(usr);
|
IndexVar &var = db->ToVar(usr);
|
||||||
auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID);
|
auto range = FromTokenRange(SM, Lang, {L, L}, &UniqueID);
|
||||||
var.def.kind = lsSymbolKind::Macro;
|
var.def.kind = lsSymbolKind::Macro;
|
||||||
|
var.def.parent_kind = lsSymbolKind::File;
|
||||||
if (var.def.spell) {
|
if (var.def.spell) {
|
||||||
DeclRef &d = var.declarations.emplace_back();
|
DeclRef &d = var.declarations.emplace_back();
|
||||||
static_cast<Use&>(d) = *var.def.spell;
|
static_cast<Use&>(d) = *var.def.spell;
|
||||||
d.extent = var.def.spell->range;
|
d.extent = var.def.spell->range;
|
||||||
}
|
}
|
||||||
var.def.spell = Use{{range, 0, SymbolKind::File, Role::Definition}};
|
var.def.spell = Use{{range, Role::Definition}};
|
||||||
const MacroInfo *MI = MD->getMacroInfo();
|
const MacroInfo *MI = MD->getMacroInfo();
|
||||||
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
|
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
|
||||||
range = FromTokenRange(SM, param.Ctx->getLangOpts(), R);
|
range = FromTokenRange(SM, param.Ctx->getLangOpts(), R);
|
||||||
var.def.extent = Use{{range, 0, SymbolKind::File, Role::None}};
|
var.def.extent = Use{{range, Role::None}};
|
||||||
if (var.def.detailed_name[0] == '\0') {
|
if (var.def.detailed_name[0] == '\0') {
|
||||||
var.def.detailed_name = Intern(Name);
|
var.def.detailed_name = Intern(Name);
|
||||||
var.def.short_name_size = Name.size();
|
var.def.short_name_size = Name.size();
|
||||||
@ -1162,8 +1134,8 @@ public:
|
|||||||
if (IndexFile *db = param.ConsumeFile(*FE)) {
|
if (IndexFile *db = param.ConsumeFile(*FE)) {
|
||||||
IndexVar &var = db->ToVar(GetMacro(Tok).second);
|
IndexVar &var = db->ToVar(GetMacro(Tok).second);
|
||||||
var.uses.push_back(
|
var.uses.push_back(
|
||||||
{{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID), 0,
|
{{FromTokenRange(SM, param.Ctx->getLangOpts(), {L, L}, &UniqueID),
|
||||||
SymbolKind::File, Role::Dynamic}});
|
Role::Dynamic}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void MacroUndefined(const Token &Tok, const MacroDefinition &MD,
|
void MacroUndefined(const Token &Tok, const MacroDefinition &MD,
|
||||||
@ -1198,7 +1170,7 @@ public:
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
const int IndexFile::kMajorVersion = 18;
|
const int IndexFile::kMajorVersion = 19;
|
||||||
const int IndexFile::kMinorVersion = 0;
|
const int IndexFile::kMinorVersion = 0;
|
||||||
|
|
||||||
IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path,
|
IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path,
|
||||||
@ -1390,10 +1362,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs,
|
|||||||
}
|
}
|
||||||
} // namespace ccls::idx
|
} // namespace ccls::idx
|
||||||
|
|
||||||
// |SymbolRef| is serialized this way.
|
void Reflect(Reader &vis, SymbolRef &v) {
|
||||||
// |Use| also uses this though it has an extra field |file|,
|
|
||||||
// which is not used by Index* so it does not need to be serialized.
|
|
||||||
void Reflect(Reader &vis, Reference &v) {
|
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
if (vis.Format() == SerializeFormat::Json) {
|
||||||
std::string t = vis.GetString();
|
std::string t = vis.GetString();
|
||||||
char *s = const_cast<char *>(t.c_str());
|
char *s = const_cast<char *>(t.c_str());
|
||||||
@ -1409,7 +1378,7 @@ void Reflect(Reader &vis, Reference &v) {
|
|||||||
Reflect(vis, v.role);
|
Reflect(vis, v.role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, Reference &v) {
|
void Reflect(Writer &vis, SymbolRef &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
if (vis.Format() == SerializeFormat::Json) {
|
||||||
char buf[99];
|
char buf[99];
|
||||||
snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d",
|
snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d",
|
||||||
@ -1430,25 +1399,24 @@ void Reflect(Reader &vis, Use &v) {
|
|||||||
char *s = const_cast<char *>(t.c_str());
|
char *s = const_cast<char *>(t.c_str());
|
||||||
v.range = Range::FromString(s);
|
v.range = Range::FromString(s);
|
||||||
s = strchr(s, '|');
|
s = strchr(s, '|');
|
||||||
v.usr = strtoull(s + 1, &s, 10);
|
|
||||||
v.kind = static_cast<SymbolKind>(strtol(s + 1, &s, 10));
|
|
||||||
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
||||||
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
||||||
} else {
|
} else {
|
||||||
Reflect(vis, static_cast<Reference &>(v));
|
Reflect(vis, v.range);
|
||||||
|
Reflect(vis, v.role);
|
||||||
Reflect(vis, v.file_id);
|
Reflect(vis, v.file_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, Use &v) {
|
void Reflect(Writer &vis, Use &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
if (vis.Format() == SerializeFormat::Json) {
|
||||||
char buf[99];
|
char buf[99];
|
||||||
snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d|%d",
|
snprintf(buf, sizeof buf, "%s|%d|%d", v.range.ToString().c_str(),
|
||||||
v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role),
|
int(v.role), v.file_id);
|
||||||
v.file_id);
|
|
||||||
std::string s(buf);
|
std::string s(buf);
|
||||||
Reflect(vis, s);
|
Reflect(vis, s);
|
||||||
} else {
|
} else {
|
||||||
Reflect(vis, static_cast<Reference &>(v));
|
Reflect(vis, v.range);
|
||||||
|
Reflect(vis, v.role);
|
||||||
Reflect(vis, v.file_id);
|
Reflect(vis, v.file_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1460,9 +1428,7 @@ void Reflect(Reader &vis, DeclRef &v) {
|
|||||||
v.range = Range::FromString(s);
|
v.range = Range::FromString(s);
|
||||||
s = strchr(s, '|') + 1;
|
s = strchr(s, '|') + 1;
|
||||||
v.extent = Range::FromString(s);
|
v.extent = Range::FromString(s);
|
||||||
s = strchr(s, '|') + 1;
|
s = strchr(s, '|');
|
||||||
v.usr = strtoull(s, &s, 10);
|
|
||||||
v.kind = static_cast<SymbolKind>(strtol(s + 1, &s, 10));
|
|
||||||
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
||||||
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
||||||
} else {
|
} else {
|
||||||
@ -1473,9 +1439,8 @@ void Reflect(Reader &vis, DeclRef &v) {
|
|||||||
void Reflect(Writer &vis, DeclRef &v) {
|
void Reflect(Writer &vis, DeclRef &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
if (vis.Format() == SerializeFormat::Json) {
|
||||||
char buf[99];
|
char buf[99];
|
||||||
snprintf(buf, sizeof buf, "%s|%s|%" PRIu64 "|%d|%d|%d",
|
snprintf(buf, sizeof buf, "%s|%s|%d|%d", v.range.ToString().c_str(),
|
||||||
v.range.ToString().c_str(), v.extent.ToString().c_str(), v.usr,
|
v.extent.ToString().c_str(), int(v.role), v.file_id);
|
||||||
int(v.kind), int(v.role), v.file_id);
|
|
||||||
std::string s(buf);
|
std::string s(buf);
|
||||||
Reflect(vis, s);
|
Reflect(vis, s);
|
||||||
} else {
|
} else {
|
||||||
|
@ -49,28 +49,36 @@ struct SymbolIdx {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind);
|
MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind);
|
||||||
|
|
||||||
struct Reference {
|
// |id,kind| refer to the referenced entity.
|
||||||
|
struct SymbolRef {
|
||||||
Range range;
|
Range range;
|
||||||
Usr usr;
|
Usr usr;
|
||||||
SymbolKind kind;
|
SymbolKind kind;
|
||||||
Role role;
|
Role role;
|
||||||
|
|
||||||
bool Valid() const { return range.Valid(); }
|
|
||||||
operator SymbolIdx() const { return {usr, kind}; }
|
operator SymbolIdx() const { return {usr, kind}; }
|
||||||
std::tuple<Range, Usr, SymbolKind, Role> ToTuple() const {
|
std::tuple<Range, Usr, SymbolKind, Role> ToTuple() const {
|
||||||
return std::make_tuple(range, usr, kind, role);
|
return std::make_tuple(range, usr, kind, role);
|
||||||
}
|
}
|
||||||
bool operator==(const Reference &o) const { return ToTuple() == o.ToTuple(); }
|
bool operator==(const SymbolRef &o) const { return ToTuple() == o.ToTuple(); }
|
||||||
bool operator<(const Reference &o) const { return ToTuple() < o.ToTuple(); }
|
bool Valid() const { return range.Valid(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// |id,kind| refer to the referenced entity.
|
|
||||||
struct SymbolRef : Reference {};
|
|
||||||
MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role);
|
MAKE_HASHABLE(SymbolRef, t.range, t.usr, t.kind, t.role);
|
||||||
|
|
||||||
|
struct Ref {
|
||||||
|
Range range;
|
||||||
|
Role role;
|
||||||
|
|
||||||
|
bool Valid() const { return range.Valid(); }
|
||||||
|
std::tuple<Range, Role> ToTuple() const {
|
||||||
|
return std::make_tuple(range, role);
|
||||||
|
}
|
||||||
|
bool operator==(const Ref &o) const { return ToTuple() == o.ToTuple(); }
|
||||||
|
bool operator<(const Ref &o) const { return ToTuple() < o.ToTuple(); }
|
||||||
|
};
|
||||||
|
|
||||||
// Represents an occurrence of a variable/type, |usr,kind| refer to the lexical
|
// Represents an occurrence of a variable/type, |usr,kind| refer to the lexical
|
||||||
// parent.
|
// parent.
|
||||||
struct Use : Reference {
|
struct Use : Ref {
|
||||||
// |file| is used in Query* but not in Index*
|
// |file| is used in Query* but not in Index*
|
||||||
int file_id = -1;
|
int file_id = -1;
|
||||||
bool operator==(const Use &o) const {
|
bool operator==(const Use &o) const {
|
||||||
@ -85,8 +93,8 @@ struct DeclRef : Use {
|
|||||||
};
|
};
|
||||||
MAKE_HASHABLE(DeclRef, t.range, t.file_id)
|
MAKE_HASHABLE(DeclRef, t.range, t.file_id)
|
||||||
|
|
||||||
void Reflect(Reader &visitor, Reference &value);
|
void Reflect(Reader &visitor, SymbolRef &value);
|
||||||
void Reflect(Writer &visitor, Reference &value);
|
void Reflect(Writer &visitor, SymbolRef &value);
|
||||||
void Reflect(Reader &visitor, Use &value);
|
void Reflect(Reader &visitor, Use &value);
|
||||||
void Reflect(Writer &visitor, Use &value);
|
void Reflect(Writer &visitor, Use &value);
|
||||||
void Reflect(Reader &visitor, DeclRef &value);
|
void Reflect(Reader &visitor, DeclRef &value);
|
||||||
@ -115,74 +123,71 @@ struct FuncDef : NameMixin<FuncDef> {
|
|||||||
|
|
||||||
// Method this method overrides.
|
// Method this method overrides.
|
||||||
std::vector<Usr> bases;
|
std::vector<Usr> bases;
|
||||||
|
|
||||||
// Local variables or parameters.
|
// Local variables or parameters.
|
||||||
std::vector<Usr> vars;
|
std::vector<Usr> vars;
|
||||||
|
|
||||||
// Functions that this function calls.
|
// Functions that this function calls.
|
||||||
std::vector<SymbolRef> callees;
|
std::vector<SymbolRef> callees;
|
||||||
|
|
||||||
int file_id = -1;
|
int file_id = -1; // not serialized
|
||||||
int16_t qual_name_offset = 0;
|
int16_t qual_name_offset = 0;
|
||||||
int16_t short_name_offset = 0;
|
int16_t short_name_offset = 0;
|
||||||
int16_t short_name_size = 0;
|
int16_t short_name_size = 0;
|
||||||
lsSymbolKind kind = lsSymbolKind::Unknown;
|
lsSymbolKind kind = lsSymbolKind::Unknown;
|
||||||
|
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
|
||||||
uint8_t storage = clang::SC_None;
|
uint8_t storage = clang::SC_None;
|
||||||
|
|
||||||
std::vector<Usr> GetBases() const { return bases; }
|
std::vector<Usr> GetBases() const { return bases; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(FuncDef, detailed_name, qual_name_offset, short_name_offset,
|
MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, extent,
|
||||||
short_name_size, kind, storage, hover, comments, spell,
|
bases, vars, callees, qual_name_offset, short_name_offset,
|
||||||
extent, bases, vars, callees);
|
short_name_size, kind, parent_kind, storage);
|
||||||
|
|
||||||
struct IndexFunc : NameMixin<IndexFunc> {
|
struct IndexFunc : NameMixin<IndexFunc> {
|
||||||
using Def = FuncDef;
|
using Def = FuncDef;
|
||||||
Usr usr;
|
Usr usr;
|
||||||
Def def;
|
Def def;
|
||||||
std::vector<DeclRef> declarations;
|
std::vector<DeclRef> declarations;
|
||||||
std::vector<Use> uses;
|
|
||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
|
std::vector<Use> uses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeDef : NameMixin<TypeDef> {
|
struct TypeDef : NameMixin<TypeDef> {
|
||||||
const char *detailed_name = "";
|
const char *detailed_name = "";
|
||||||
const char *hover = "";
|
const char *hover = "";
|
||||||
const char *comments = "";
|
const char *comments = "";
|
||||||
|
|
||||||
Maybe<Use> spell;
|
Maybe<Use> spell;
|
||||||
Maybe<Use> extent;
|
Maybe<Use> extent;
|
||||||
|
|
||||||
std::vector<Usr> bases;
|
std::vector<Usr> bases;
|
||||||
|
|
||||||
// Types, functions, and variables defined in this type.
|
// Types, functions, and variables defined in this type.
|
||||||
std::vector<Usr> types;
|
|
||||||
std::vector<Usr> funcs;
|
std::vector<Usr> funcs;
|
||||||
|
std::vector<Usr> types;
|
||||||
std::vector<std::pair<Usr, int64_t>> vars;
|
std::vector<std::pair<Usr, int64_t>> vars;
|
||||||
|
|
||||||
// If set, then this is the same underlying type as the given value (ie, this
|
// If set, then this is the same underlying type as the given value (ie, this
|
||||||
// type comes from a using or typedef statement).
|
// type comes from a using or typedef statement).
|
||||||
Usr alias_of = 0;
|
Usr alias_of = 0;
|
||||||
|
int file_id = -1; // not serialized
|
||||||
int file_id = -1;
|
|
||||||
int16_t qual_name_offset = 0;
|
int16_t qual_name_offset = 0;
|
||||||
int16_t short_name_offset = 0;
|
int16_t short_name_offset = 0;
|
||||||
int16_t short_name_size = 0;
|
int16_t short_name_size = 0;
|
||||||
lsSymbolKind kind = lsSymbolKind::Unknown;
|
lsSymbolKind kind = lsSymbolKind::Unknown;
|
||||||
|
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
|
||||||
|
|
||||||
std::vector<Usr> GetBases() const { return bases; }
|
std::vector<Usr> GetBases() const { return bases; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(TypeDef, detailed_name, qual_name_offset, short_name_offset,
|
MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, extent,
|
||||||
short_name_size, kind, hover, comments, spell, extent,
|
bases, funcs, types, vars, alias_of, qual_name_offset,
|
||||||
alias_of, bases, types, funcs, vars);
|
short_name_offset, short_name_size, kind, parent_kind);
|
||||||
|
|
||||||
struct IndexType {
|
struct IndexType {
|
||||||
using Def = TypeDef;
|
using Def = TypeDef;
|
||||||
Usr usr;
|
Usr usr;
|
||||||
Def def;
|
Def def;
|
||||||
std::vector<DeclRef> declarations;
|
std::vector<DeclRef> declarations;
|
||||||
std::vector<Use> uses;
|
|
||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
std::vector<Usr> instances;
|
std::vector<Usr> instances;
|
||||||
|
std::vector<Use> uses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VarDef : NameMixin<VarDef> {
|
struct VarDef : NameMixin<VarDef> {
|
||||||
@ -195,27 +200,29 @@ struct VarDef : NameMixin<VarDef> {
|
|||||||
|
|
||||||
// Type of the variable.
|
// Type of the variable.
|
||||||
Usr type = 0;
|
Usr type = 0;
|
||||||
|
int file_id = -1; // not serialized
|
||||||
int file_id = -1;
|
|
||||||
int16_t qual_name_offset = 0;
|
int16_t qual_name_offset = 0;
|
||||||
int16_t short_name_offset = 0;
|
int16_t short_name_offset = 0;
|
||||||
int16_t short_name_size = 0;
|
int16_t short_name_size = 0;
|
||||||
|
|
||||||
lsSymbolKind kind = lsSymbolKind::Unknown;
|
lsSymbolKind kind = lsSymbolKind::Unknown;
|
||||||
|
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
|
||||||
// Note a variable may have instances of both |None| and |Extern|
|
// Note a variable may have instances of both |None| and |Extern|
|
||||||
// (declaration).
|
// (declaration).
|
||||||
uint8_t storage = clang::SC_None;
|
uint8_t storage = clang::SC_None;
|
||||||
|
|
||||||
bool is_local() const {
|
bool is_local() const {
|
||||||
return spell && spell->kind == SymbolKind::Func &&
|
return spell &&
|
||||||
|
(parent_kind == lsSymbolKind::Function ||
|
||||||
|
parent_kind == lsSymbolKind::Method ||
|
||||||
|
parent_kind == lsSymbolKind::StaticMethod) &&
|
||||||
storage == clang::SC_None;
|
storage == clang::SC_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Usr> GetBases() const { return {}; }
|
std::vector<Usr> GetBases() const { return {}; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(VarDef, detailed_name, qual_name_offset, short_name_offset,
|
MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, extent, type,
|
||||||
short_name_size, hover, comments, spell, extent, type, kind,
|
qual_name_offset, short_name_offset, short_name_size, kind,
|
||||||
storage);
|
parent_kind, storage);
|
||||||
|
|
||||||
struct IndexVar {
|
struct IndexVar {
|
||||||
using Def = VarDef;
|
using Def = VarDef;
|
||||||
|
11
src/lsp.h
11
src/lsp.h
@ -198,15 +198,6 @@ enum class lsSymbolKind : uint8_t {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);
|
MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);
|
||||||
|
|
||||||
// ccls extension
|
|
||||||
struct lsLocationEx : lsLocation {
|
|
||||||
std::optional<std::string_view> containerName;
|
|
||||||
std::optional<lsSymbolKind> parentKind;
|
|
||||||
// Avoid circular dependency on symbol.h
|
|
||||||
std::optional<uint16_t> role;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role);
|
|
||||||
|
|
||||||
struct lsTextDocumentIdentifier {
|
struct lsTextDocumentIdentifier {
|
||||||
lsDocumentUri uri;
|
lsDocumentUri uri;
|
||||||
};
|
};
|
||||||
@ -346,6 +337,6 @@ void Reflect(TVisitor &visitor, Out_ShowLogMessage &value) {
|
|||||||
|
|
||||||
struct Out_LocationList : public lsOutMessage<Out_LocationList> {
|
struct Out_LocationList : public lsOutMessage<Out_LocationList> {
|
||||||
lsRequestId id;
|
lsRequestId id;
|
||||||
std::vector<lsLocationEx> result;
|
std::vector<lsLocation> result;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result);
|
MAKE_REFLECT_STRUCT(Out_LocationList, jsonrpc, id, result);
|
||||||
|
@ -156,24 +156,15 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) {
|
|||||||
const QueryFunc::Def *def = func.AnyDef();
|
const QueryFunc::Def *def = func.AnyDef();
|
||||||
if (!def)
|
if (!def)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
if (def->spell)
|
|
||||||
parent_kind = GetSymbolKind(db, *def->spell);
|
|
||||||
if (parent_kind == lsSymbolKind::Unknown) {
|
|
||||||
for (Use use : func.declarations) {
|
|
||||||
parent_kind = GetSymbolKind(db, use);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Don't highlight overloadable operators or implicit lambda ->
|
// Don't highlight overloadable operators or implicit lambda ->
|
||||||
// std::function constructor.
|
// std::function constructor.
|
||||||
std::string_view short_name = def->Name(false);
|
std::string_view short_name = def->Name(false);
|
||||||
if (short_name.compare(0, 8, "operator") == 0)
|
if (short_name.compare(0, 8, "operator") == 0)
|
||||||
continue; // applies to for loop
|
continue; // applies to for loop
|
||||||
if (def->spell)
|
|
||||||
parent_kind = GetSymbolKind(db, *def->spell);
|
|
||||||
kind = def->kind;
|
kind = def->kind;
|
||||||
storage = def->storage;
|
storage = def->storage;
|
||||||
detailed_name = short_name;
|
detailed_name = short_name;
|
||||||
|
parent_kind = def->parent_kind;
|
||||||
|
|
||||||
// Check whether the function name is actually there.
|
// Check whether the function name is actually there.
|
||||||
// If not, do not publish the semantic highlight.
|
// If not, do not publish the semantic highlight.
|
||||||
@ -200,7 +191,7 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) {
|
|||||||
kind = def.kind;
|
kind = def.kind;
|
||||||
detailed_name = def.detailed_name;
|
detailed_name = def.detailed_name;
|
||||||
if (def.spell) {
|
if (def.spell) {
|
||||||
parent_kind = GetSymbolKind(db, *def.spell);
|
parent_kind = def.parent_kind;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,13 +205,7 @@ void EmitSemanticHighlighting(DB *db, WorkingFile *wfile, QueryFile *file) {
|
|||||||
storage = def.storage;
|
storage = def.storage;
|
||||||
detailed_name = def.detailed_name;
|
detailed_name = def.detailed_name;
|
||||||
if (def.spell) {
|
if (def.spell) {
|
||||||
parent_kind = GetSymbolKind(db, *def.spell);
|
parent_kind = def.parent_kind;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parent_kind == lsSymbolKind::Unknown) {
|
|
||||||
for (Use use : var.declarations) {
|
|
||||||
parent_kind = GetSymbolKind(db, use);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,8 @@ struct Out_CclsCall : public lsOutMessage<Out_CclsCall> {
|
|||||||
int numChildren;
|
int numChildren;
|
||||||
// Empty if the |levels| limit is reached.
|
// Empty if the |levels| limit is reached.
|
||||||
std::vector<Entry> children;
|
std::vector<Entry> children;
|
||||||
|
bool operator==(const Entry &o) const { return location == o.location; }
|
||||||
|
bool operator<(const Entry &o) const { return location < o.location; }
|
||||||
};
|
};
|
||||||
|
|
||||||
lsRequestId id;
|
lsRequestId id;
|
||||||
@ -94,13 +96,14 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee,
|
|||||||
entry->numChildren = 0;
|
entry->numChildren = 0;
|
||||||
if (!def)
|
if (!def)
|
||||||
return false;
|
return false;
|
||||||
auto handle = [&](Use use, CallType call_type1) {
|
auto handle = [&](SymbolRef sym, int file_id, CallType call_type1) {
|
||||||
entry->numChildren++;
|
entry->numChildren++;
|
||||||
if (levels > 0) {
|
if (levels > 0) {
|
||||||
Out_CclsCall::Entry entry1;
|
Out_CclsCall::Entry entry1;
|
||||||
entry1.id = std::to_string(use.usr);
|
entry1.id = std::to_string(sym.usr);
|
||||||
entry1.usr = use.usr;
|
entry1.usr = sym.usr;
|
||||||
if (auto loc = GetLsLocation(m->db, m->working_files, use))
|
if (auto loc = GetLsLocation(m->db, m->working_files,
|
||||||
|
Use{{sym.range, sym.role}, file_id}))
|
||||||
entry1.location = *loc;
|
entry1.location = *loc;
|
||||||
entry1.callType = call_type1;
|
entry1.callType = call_type1;
|
||||||
if (Expand(m, &entry1, callee, call_type, qualified, levels - 1))
|
if (Expand(m, &entry1, callee, call_type, qualified, levels - 1))
|
||||||
@ -110,14 +113,22 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee,
|
|||||||
auto handle_uses = [&](const QueryFunc &func, CallType call_type) {
|
auto handle_uses = [&](const QueryFunc &func, CallType call_type) {
|
||||||
if (callee) {
|
if (callee) {
|
||||||
if (const auto *def = func.AnyDef())
|
if (const auto *def = func.AnyDef())
|
||||||
for (SymbolRef ref : def->callees)
|
for (SymbolRef sym : def->callees)
|
||||||
if (ref.kind == SymbolKind::Func)
|
if (sym.kind == SymbolKind::Func)
|
||||||
handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id},
|
handle(sym, def->file_id, call_type);
|
||||||
call_type);
|
|
||||||
} else {
|
} else {
|
||||||
for (Use use : func.uses)
|
for (Use use : func.uses) {
|
||||||
if (use.kind == SymbolKind::Func)
|
const QueryFile &file1 = m->db->files[use.file_id];
|
||||||
handle(use, call_type);
|
Maybe<SymbolRef> best_sym;
|
||||||
|
for (auto [sym, refcnt] : file1.outline2refcnt)
|
||||||
|
if (refcnt > 0 && sym.kind == SymbolKind::Func &&
|
||||||
|
sym.range.start <= use.range.start &&
|
||||||
|
use.range.end <= sym.range.end &&
|
||||||
|
(!best_sym || best_sym->range.start < sym.range.start))
|
||||||
|
best_sym = sym;
|
||||||
|
if (best_sym)
|
||||||
|
handle(*best_sym, use.file_id, call_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -160,6 +171,11 @@ bool Expand(MessageHandler *m, Out_CclsCall::Entry *entry, bool callee,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(entry->children.begin(), entry->children.end());
|
||||||
|
entry->children.erase(
|
||||||
|
std::unique(entry->children.begin(), entry->children.end()),
|
||||||
|
entry->children.end());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ struct Handler_CclsNavigate : BaseMessageHandler<In_CclsNavigate> {
|
|||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
if (res)
|
if (res)
|
||||||
if (auto ls_range = GetLsRange(wfile, *res)) {
|
if (auto ls_range = GetLsRange(wfile, *res)) {
|
||||||
lsLocationEx &ls_loc = out.result.emplace_back();
|
lsLocation &ls_loc = out.result.emplace_back();
|
||||||
ls_loc.uri = params.textDocument.uri;
|
ls_loc.uri = params.textDocument.uri;
|
||||||
ls_loc.range = *ls_range;
|
ls_loc.range = *ls_range;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ struct Handler_CclsVars : BaseMessageHandler<In_CclsVars> {
|
|||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
}
|
}
|
||||||
case SymbolKind::Type:
|
case SymbolKind::Type:
|
||||||
out.result = GetLsLocationExs(
|
out.result = GetLsLocations(
|
||||||
db, working_files,
|
db, working_files,
|
||||||
GetVarDeclarations(db, db->Type(usr).instances, params.kind));
|
GetVarDeclarations(db, db->Type(usr).instances, params.kind));
|
||||||
break;
|
break;
|
||||||
|
@ -117,19 +117,19 @@ struct Handler_TextDocumentCodeLens
|
|||||||
code_lens.command->arguments.push_back(ToString(show));
|
code_lens.command->arguments.push_back(ToString(show));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ToSpell = [&](Use use) {
|
auto ToSpell = [&](SymbolRef sym, int file_id) -> Use {
|
||||||
Maybe<Use> def = GetDefinitionSpell(db, use);
|
Maybe<Use> def = GetDefinitionSpell(db, sym);
|
||||||
if (def && def->file_id == use.file_id &&
|
if (def && def->file_id == file_id &&
|
||||||
def->range.start.line == use.range.start.line)
|
def->range.start.line == sym.range.start.line)
|
||||||
return *def;
|
return *def;
|
||||||
return use;
|
return {{sym.range, sym.role}, file_id};
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_set<Range> seen;
|
std::unordered_set<Range> seen;
|
||||||
for (auto [sym, refcnt] : file->outline2refcnt) {
|
for (auto [sym, refcnt] : file->outline2refcnt) {
|
||||||
if (refcnt <= 0 || !seen.insert(sym.range).second)
|
if (refcnt <= 0 || !seen.insert(sym.range).second)
|
||||||
continue;
|
continue;
|
||||||
Use use = ToSpell({{sym.range, sym.usr, sym.kind, sym.role}, file->id});
|
Use use = ToSpell(sym, file->id);
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Func: {
|
case SymbolKind::Func: {
|
||||||
QueryFunc &func = db->GetFunc(sym);
|
QueryFunc &func = db->GetFunc(sym);
|
||||||
|
@ -33,13 +33,6 @@ struct In_TextDocumentDefinition : public RequestInMessage {
|
|||||||
MAKE_REFLECT_STRUCT(In_TextDocumentDefinition, id, params);
|
MAKE_REFLECT_STRUCT(In_TextDocumentDefinition, id, params);
|
||||||
REGISTER_IN_MESSAGE(In_TextDocumentDefinition);
|
REGISTER_IN_MESSAGE(In_TextDocumentDefinition);
|
||||||
|
|
||||||
struct Out_TextDocumentDefinition
|
|
||||||
: public lsOutMessage<Out_TextDocumentDefinition> {
|
|
||||||
lsRequestId id;
|
|
||||||
std::vector<lsLocationEx> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
|
||||||
|
|
||||||
std::vector<Use> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) {
|
std::vector<Use> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) {
|
||||||
switch (sym.kind) {
|
switch (sym.kind) {
|
||||||
case SymbolKind::Var: {
|
case SymbolKind::Var: {
|
||||||
@ -73,7 +66,7 @@ struct Handler_TextDocumentDefinition
|
|||||||
params.textDocument.uri.GetPath(), &file, &file_id))
|
params.textDocument.uri.GetPath(), &file, &file_id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Out_TextDocumentDefinition out;
|
Out_LocationList out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
|
||||||
Maybe<Use> on_def;
|
Maybe<Use> on_def;
|
||||||
@ -110,7 +103,7 @@ struct Handler_TextDocumentDefinition
|
|||||||
if (uses.empty() && on_def)
|
if (uses.empty() && on_def)
|
||||||
uses.push_back(*on_def);
|
uses.push_back(*on_def);
|
||||||
}
|
}
|
||||||
auto locs = GetLsLocationExs(db, working_files, uses);
|
auto locs = GetLsLocations(db, working_files, uses);
|
||||||
out.result.insert(out.result.end(), locs.begin(), locs.end());
|
out.result.insert(out.result.end(), locs.begin(), locs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,9 +116,8 @@ struct Handler_TextDocumentDefinition
|
|||||||
// Check #include
|
// Check #include
|
||||||
for (const IndexInclude &include : file->def->includes) {
|
for (const IndexInclude &include : file->def->includes) {
|
||||||
if (include.line == ls_pos.line) {
|
if (include.line == ls_pos.line) {
|
||||||
lsLocationEx result;
|
out.result.push_back(
|
||||||
result.uri = lsDocumentUri::FromPath(include.resolved_path);
|
lsLocation{lsDocumentUri::FromPath(include.resolved_path)});
|
||||||
out.result.push_back(result);
|
|
||||||
range = {{0, 0}, {0, 0}};
|
range = {{0, 0}, {0, 0}};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -184,9 +176,8 @@ struct Handler_TextDocumentDefinition
|
|||||||
if (best_sym.kind != SymbolKind::Invalid) {
|
if (best_sym.kind != SymbolKind::Invalid) {
|
||||||
Maybe<Use> use = GetDefinitionSpell(db, best_sym);
|
Maybe<Use> use = GetDefinitionSpell(db, best_sym);
|
||||||
assert(use);
|
assert(use);
|
||||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
if (auto loc = GetLsLocation(db, working_files, *use))
|
||||||
g_config->xref.container))
|
out.result.push_back(*loc);
|
||||||
out.result.push_back(*ls_loc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,11 +80,9 @@ struct Handler_TextDocumentDocumentHighlight
|
|||||||
return usr == sym1.usr && kind == sym1.kind;
|
return usr == sym1.usr && kind == sym1.kind;
|
||||||
}))
|
}))
|
||||||
continue;
|
continue;
|
||||||
if (auto ls_loc =
|
if (auto loc = GetLsLocation(db, working_files, sym, file_id)) {
|
||||||
GetLsLocation(db, working_files,
|
|
||||||
Use{{sym.range, usr, kind, sym.role}, file_id})) {
|
|
||||||
lsDocumentHighlight highlight;
|
lsDocumentHighlight highlight;
|
||||||
highlight.range = ls_loc->range;
|
highlight.range = loc->range;
|
||||||
if (sym.role & Role::Write)
|
if (sym.role & Role::Write)
|
||||||
highlight.kind = lsDocumentHighlight::Write;
|
highlight.kind = lsDocumentHighlight::Write;
|
||||||
else if (sym.role & Role::Read)
|
else if (sym.role & Role::Read)
|
||||||
|
@ -107,10 +107,8 @@ struct Handler_TextDocumentDocumentSymbol
|
|||||||
for (auto [sym, refcnt] : symbol2refcnt)
|
for (auto [sym, refcnt] : symbol2refcnt)
|
||||||
if (refcnt > 0 && params.startLine <= sym.range.start.line &&
|
if (refcnt > 0 && params.startLine <= sym.range.start.line &&
|
||||||
sym.range.start.line <= params.endLine)
|
sym.range.start.line <= params.endLine)
|
||||||
if (auto ls_loc = GetLsLocation(
|
if (auto loc = GetLsLocation(db, working_files, sym, file_id))
|
||||||
db, working_files,
|
out.result.push_back(loc->range);
|
||||||
Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id}))
|
|
||||||
out.result.push_back(ls_loc->range);
|
|
||||||
std::sort(out.result.begin(), out.result.end());
|
std::sort(out.result.begin(), out.result.end());
|
||||||
pipeline::WriteStdout(kMethodType, out);
|
pipeline::WriteStdout(kMethodType, out);
|
||||||
} else if (g_config->client.hierarchicalDocumentSymbolSupport) {
|
} else if (g_config->client.hierarchicalDocumentSymbolSupport) {
|
||||||
@ -213,10 +211,8 @@ struct Handler_TextDocumentDocumentSymbol
|
|||||||
(sym.kind == SymbolKind::Var &&
|
(sym.kind == SymbolKind::Var &&
|
||||||
IgnoreVar(db->GetVar(sym).AnyDef())))
|
IgnoreVar(db->GetVar(sym).AnyDef())))
|
||||||
continue;
|
continue;
|
||||||
if (std::optional<lsLocation> location = GetLsLocation(
|
if (auto loc = GetLsLocation(db, working_files, sym, file_id)) {
|
||||||
db, working_files,
|
info->location = *loc;
|
||||||
Use{{sym.range, sym.usr, sym.kind, sym.role}, file_id})) {
|
|
||||||
info->location = *location;
|
|
||||||
out.result.push_back(*info);
|
out.result.push_back(*info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ struct Handler_TextDocumentImplementation
|
|||||||
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
FindSymbolsAtLocation(working_file, file, request->params.position)) {
|
||||||
if (sym.kind == SymbolKind::Type) {
|
if (sym.kind == SymbolKind::Type) {
|
||||||
QueryType &type = db->GetType(sym);
|
QueryType &type = db->GetType(sym);
|
||||||
out.result = GetLsLocationExs(db, working_files,
|
out.result = GetLsLocations(db, working_files,
|
||||||
GetTypeDeclarations(db, type.derived));
|
GetTypeDeclarations(db, type.derived));
|
||||||
break;
|
break;
|
||||||
} else if (sym.kind == SymbolKind::Func) {
|
} else if (sym.kind == SymbolKind::Func) {
|
||||||
QueryFunc &func = db->GetFunc(sym);
|
QueryFunc &func = db->GetFunc(sym);
|
||||||
out.result = GetLsLocationExs(db, working_files,
|
out.result = GetLsLocations(db, working_files,
|
||||||
GetFuncDeclarations(db, func.derived));
|
GetFuncDeclarations(db, func.derived));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,6 @@ MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position,
|
|||||||
MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params);
|
MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params);
|
||||||
REGISTER_IN_MESSAGE(In_TextDocumentReferences);
|
REGISTER_IN_MESSAGE(In_TextDocumentReferences);
|
||||||
|
|
||||||
struct Out_TextDocumentReferences
|
|
||||||
: public lsOutMessage<Out_TextDocumentReferences> {
|
|
||||||
lsRequestId id;
|
|
||||||
std::vector<lsLocationEx> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentReferences, jsonrpc, id, result);
|
|
||||||
|
|
||||||
struct Handler_TextDocumentReferences
|
struct Handler_TextDocumentReferences
|
||||||
: BaseMessageHandler<In_TextDocumentReferences> {
|
: BaseMessageHandler<In_TextDocumentReferences> {
|
||||||
MethodType GetMethodType() const override { return kMethodType; }
|
MethodType GetMethodType() const override { return kMethodType; }
|
||||||
@ -67,7 +60,7 @@ struct Handler_TextDocumentReferences
|
|||||||
if (!FindFileOrFail(db, project, request->id,
|
if (!FindFileOrFail(db, project, request->id,
|
||||||
params.textDocument.uri.GetPath(), &file))
|
params.textDocument.uri.GetPath(), &file))
|
||||||
return;
|
return;
|
||||||
Out_TextDocumentReferences out;
|
Out_LocationList out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -75,7 +68,6 @@ struct Handler_TextDocumentReferences
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool container = g_config->xref.container;
|
|
||||||
std::unordered_set<Use> seen_uses;
|
std::unordered_set<Use> seen_uses;
|
||||||
int line = params.position.line;
|
int line = params.position.line;
|
||||||
|
|
||||||
@ -93,11 +85,8 @@ struct Handler_TextDocumentReferences
|
|||||||
if (Role(use.role & params.context.role) == params.context.role &&
|
if (Role(use.role & params.context.role) == params.context.role &&
|
||||||
!(use.role & params.context.excludeRole) &&
|
!(use.role & params.context.excludeRole) &&
|
||||||
seen_uses.insert(use).second)
|
seen_uses.insert(use).second)
|
||||||
if (std::optional<lsLocationEx> ls_loc =
|
if (auto loc = GetLsLocation(db, working_files, use)) {
|
||||||
GetLsLocationEx(db, working_files, use, container)) {
|
out.result.push_back(*loc);
|
||||||
if (container)
|
|
||||||
ls_loc->parentKind = parent_kind;
|
|
||||||
out.result.push_back(*ls_loc);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
WithEntity(db, sym, [&](const auto &entity) {
|
WithEntity(db, sym, [&](const auto &entity) {
|
||||||
@ -145,10 +134,9 @@ struct Handler_TextDocumentReferences
|
|||||||
for (const IndexInclude &include : file1.def->includes)
|
for (const IndexInclude &include : file1.def->includes)
|
||||||
if (include.resolved_path == path) {
|
if (include.resolved_path == path) {
|
||||||
// Another file |file1| has the same include line.
|
// Another file |file1| has the same include line.
|
||||||
lsLocationEx result;
|
lsLocation &loc = out.result.emplace_back();
|
||||||
result.uri = lsDocumentUri::FromPath(file1.def->path);
|
loc.uri = lsDocumentUri::FromPath(file1.def->path);
|
||||||
result.range.start.line = result.range.end.line = include.line;
|
loc.range.start.line = loc.range.end.line = include.line;
|
||||||
out.result.push_back(std::move(result));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,6 @@ struct In_TextDocumentTypeDefinition : public RequestInMessage {
|
|||||||
MAKE_REFLECT_STRUCT(In_TextDocumentTypeDefinition, id, params);
|
MAKE_REFLECT_STRUCT(In_TextDocumentTypeDefinition, id, params);
|
||||||
REGISTER_IN_MESSAGE(In_TextDocumentTypeDefinition);
|
REGISTER_IN_MESSAGE(In_TextDocumentTypeDefinition);
|
||||||
|
|
||||||
struct Out_TextDocumentTypeDefinition
|
|
||||||
: public lsOutMessage<Out_TextDocumentTypeDefinition> {
|
|
||||||
lsRequestId id;
|
|
||||||
std::vector<lsLocationEx> result;
|
|
||||||
};
|
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentTypeDefinition, jsonrpc, id, result);
|
|
||||||
|
|
||||||
struct Handler_TextDocumentTypeDefinition
|
struct Handler_TextDocumentTypeDefinition
|
||||||
: BaseMessageHandler<In_TextDocumentTypeDefinition> {
|
: BaseMessageHandler<In_TextDocumentTypeDefinition> {
|
||||||
MethodType GetMethodType() const override { return kMethodType; }
|
MethodType GetMethodType() const override { return kMethodType; }
|
||||||
@ -47,19 +40,17 @@ struct Handler_TextDocumentTypeDefinition
|
|||||||
WorkingFile *working_file =
|
WorkingFile *working_file =
|
||||||
working_files->GetFileByFilename(file->def->path);
|
working_files->GetFileByFilename(file->def->path);
|
||||||
|
|
||||||
Out_TextDocumentTypeDefinition out;
|
Out_LocationList out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
auto Add = [&](const QueryType &type) {
|
auto Add = [&](const QueryType &type) {
|
||||||
for (const auto &def : type.def)
|
for (const auto &def : type.def)
|
||||||
if (def.spell) {
|
if (def.spell) {
|
||||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *def.spell,
|
if (auto ls_loc = GetLsLocation(db, working_files, *def.spell))
|
||||||
g_config->xref.container))
|
|
||||||
out.result.push_back(*ls_loc);
|
out.result.push_back(*ls_loc);
|
||||||
}
|
}
|
||||||
if (out.result.empty())
|
if (out.result.empty())
|
||||||
for (const DeclRef &dr : type.declarations)
|
for (const DeclRef &dr : type.declarations)
|
||||||
if (auto ls_loc = GetLsLocationEx(db, working_files, dr,
|
if (auto ls_loc = GetLsLocation(db, working_files, dr))
|
||||||
g_config->xref.container))
|
|
||||||
out.result.push_back(*ls_loc);
|
out.result.push_back(*ls_loc);
|
||||||
};
|
};
|
||||||
for (SymbolRef sym :
|
for (SymbolRef sym :
|
||||||
|
18
src/query.cc
18
src/query.cc
@ -34,8 +34,6 @@ void AssignFileId(const Lid2file_id &lid2file_id, int file_id, Use &use) {
|
|||||||
use.file_id = file_id;
|
use.file_id = file_id;
|
||||||
else
|
else
|
||||||
use.file_id = lid2file_id.find(use.file_id)->second;
|
use.file_id = lid2file_id.find(use.file_id)->second;
|
||||||
if (use.kind == SymbolKind::File)
|
|
||||||
use.usr = use.file_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -238,7 +236,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
|
|||||||
SymbolKind kind, Use &use, int delta, int k = 1) {
|
SymbolKind kind, Use &use, int delta, int k = 1) {
|
||||||
use.file_id =
|
use.file_id =
|
||||||
use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second;
|
use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second;
|
||||||
SymbolRef sym{{use.range, usr, kind, use.role}};
|
SymbolRef sym{use.range, usr, kind, use.role};
|
||||||
if (k & 1) {
|
if (k & 1) {
|
||||||
int &v = files[use.file_id].symbol2refcnt[sym];
|
int &v = files[use.file_id].symbol2refcnt[sym];
|
||||||
v += delta;
|
v += delta;
|
||||||
@ -258,7 +256,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
|
|||||||
SymbolKind kind, DeclRef &dr, int delta) {
|
SymbolKind kind, DeclRef &dr, int delta) {
|
||||||
Ref(lid2fid, usr, kind, dr, delta, 1);
|
Ref(lid2fid, usr, kind, dr, delta, 1);
|
||||||
files[dr.file_id]
|
files[dr.file_id]
|
||||||
.outline2refcnt[SymbolRef{{dr.extent, usr, kind, dr.role}}] += delta;
|
.outline2refcnt[SymbolRef{dr.extent, usr, kind, dr.role}] += delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto UpdateUses =
|
auto UpdateUses =
|
||||||
@ -401,12 +399,12 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
|
|||||||
if (def.spell) {
|
if (def.spell) {
|
||||||
AssignFileId(lid2file_id, file_id, *def.spell);
|
AssignFileId(lid2file_id, file_id, *def.spell);
|
||||||
files[def.spell->file_id].symbol2refcnt[{
|
files[def.spell->file_id].symbol2refcnt[{
|
||||||
{def.spell->range, u.first, SymbolKind::Func, def.spell->role}}]++;
|
def.spell->range, u.first, SymbolKind::Func, def.spell->role}]++;
|
||||||
}
|
}
|
||||||
if (def.extent) {
|
if (def.extent) {
|
||||||
AssignFileId(lid2file_id, file_id, *def.extent);
|
AssignFileId(lid2file_id, file_id, *def.extent);
|
||||||
files[def.extent->file_id].outline2refcnt[{
|
files[def.extent->file_id].outline2refcnt[{
|
||||||
{def.extent->range, u.first, SymbolKind::Func, def.extent->role}}]++;
|
def.extent->range, u.first, SymbolKind::Func, def.extent->role}]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto R = func_usr.try_emplace({u.first}, func_usr.size());
|
auto R = func_usr.try_emplace({u.first}, func_usr.size());
|
||||||
@ -428,12 +426,12 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
|
|||||||
if (def.spell) {
|
if (def.spell) {
|
||||||
AssignFileId(lid2file_id, file_id, *def.spell);
|
AssignFileId(lid2file_id, file_id, *def.spell);
|
||||||
files[def.spell->file_id].symbol2refcnt[{
|
files[def.spell->file_id].symbol2refcnt[{
|
||||||
{def.spell->range, u.first, SymbolKind::Type, def.spell->role}}]++;
|
def.spell->range, u.first, SymbolKind::Type, def.spell->role}]++;
|
||||||
}
|
}
|
||||||
if (def.extent) {
|
if (def.extent) {
|
||||||
AssignFileId(lid2file_id, file_id, *def.extent);
|
AssignFileId(lid2file_id, file_id, *def.extent);
|
||||||
files[def.extent->file_id].outline2refcnt[{
|
files[def.extent->file_id].outline2refcnt[{
|
||||||
{def.extent->range, u.first, SymbolKind::Type, def.extent->role}}]++;
|
def.extent->range, u.first, SymbolKind::Type, def.extent->role}]++;
|
||||||
}
|
}
|
||||||
auto R = type_usr.try_emplace({u.first}, type_usr.size());
|
auto R = type_usr.try_emplace({u.first}, type_usr.size());
|
||||||
if (R.second)
|
if (R.second)
|
||||||
@ -454,12 +452,12 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
|
|||||||
if (def.spell) {
|
if (def.spell) {
|
||||||
AssignFileId(lid2file_id, file_id, *def.spell);
|
AssignFileId(lid2file_id, file_id, *def.spell);
|
||||||
files[def.spell->file_id].symbol2refcnt[{
|
files[def.spell->file_id].symbol2refcnt[{
|
||||||
{def.spell->range, u.first, SymbolKind::Var, def.spell->role}}]++;
|
def.spell->range, u.first, SymbolKind::Var, def.spell->role}]++;
|
||||||
}
|
}
|
||||||
if (def.extent) {
|
if (def.extent) {
|
||||||
AssignFileId(lid2file_id, file_id, *def.extent);
|
AssignFileId(lid2file_id, file_id, *def.extent);
|
||||||
files[def.extent->file_id].outline2refcnt[{
|
files[def.extent->file_id].outline2refcnt[{
|
||||||
{def.extent->range, u.first, SymbolKind::Var, def.extent->role}}]++;
|
def.extent->range, u.first, SymbolKind::Var, def.extent->role}]++;
|
||||||
}
|
}
|
||||||
auto R = var_usr.try_emplace({u.first}, var_usr.size());
|
auto R = var_usr.try_emplace({u.first}, var_usr.size());
|
||||||
if (R.second)
|
if (R.second)
|
||||||
|
@ -85,17 +85,17 @@ struct QueryFunc : QueryEntity<QueryFunc, FuncDef> {
|
|||||||
Usr usr;
|
Usr usr;
|
||||||
llvm::SmallVector<Def, 1> def;
|
llvm::SmallVector<Def, 1> def;
|
||||||
std::vector<DeclRef> declarations;
|
std::vector<DeclRef> declarations;
|
||||||
std::vector<Use> uses;
|
|
||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
|
std::vector<Use> uses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryType : QueryEntity<QueryType, TypeDef> {
|
struct QueryType : QueryEntity<QueryType, TypeDef> {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
llvm::SmallVector<Def, 1> def;
|
llvm::SmallVector<Def, 1> def;
|
||||||
std::vector<DeclRef> declarations;
|
std::vector<DeclRef> declarations;
|
||||||
std::vector<Use> uses;
|
|
||||||
std::vector<Usr> derived;
|
std::vector<Usr> derived;
|
||||||
std::vector<Usr> instances;
|
std::vector<Usr> instances;
|
||||||
|
std::vector<Use> uses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryVar : QueryEntity<QueryVar, VarDef> {
|
struct QueryVar : QueryEntity<QueryVar, VarDef> {
|
||||||
|
@ -61,8 +61,7 @@ Maybe<Use> GetDefinitionSpell(DB *db, SymbolIdx sym) {
|
|||||||
Maybe<Use> GetDefinitionExtent(DB *db, SymbolIdx sym) {
|
Maybe<Use> GetDefinitionExtent(DB *db, SymbolIdx sym) {
|
||||||
// Used to jump to file.
|
// Used to jump to file.
|
||||||
if (sym.kind == SymbolKind::File)
|
if (sym.kind == SymbolKind::File)
|
||||||
return Use{{Range{{0, 0}, {0, 0}}, sym.usr, sym.kind, Role::None},
|
return Use{{Range{{0, 0}, {0, 0}}, Role::None}, int(sym.usr)};
|
||||||
int(sym.usr)};
|
|
||||||
Maybe<Use> ret;
|
Maybe<Use> ret;
|
||||||
EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); });
|
EachEntityDef(db, sym, [&](const auto &def) { return !(ret = def.extent); });
|
||||||
return ret;
|
return ret;
|
||||||
@ -216,40 +215,27 @@ lsDocumentUri GetLsDocumentUri(DB *db, int file_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *working_files,
|
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles,
|
||||||
Use use) {
|
Use use) {
|
||||||
std::string path;
|
std::string path;
|
||||||
lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path);
|
lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path);
|
||||||
std::optional<lsRange> range =
|
std::optional<lsRange> range =
|
||||||
GetLsRange(working_files->GetFileByFilename(path), use.range);
|
GetLsRange(wfiles->GetFileByFilename(path), use.range);
|
||||||
if (!range)
|
if (!range)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
return lsLocation{uri, *range};
|
return lsLocation{uri, *range};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<lsLocationEx> GetLsLocationEx(DB *db, WorkingFiles *working_files,
|
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles,
|
||||||
Use use, bool container) {
|
SymbolRef sym, int file_id) {
|
||||||
std::optional<lsLocation> ls_loc = GetLsLocation(db, working_files, use);
|
return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id});
|
||||||
if (!ls_loc)
|
|
||||||
return std::nullopt;
|
|
||||||
lsLocationEx ret;
|
|
||||||
ret.lsLocation::operator=(*ls_loc);
|
|
||||||
if (container) {
|
|
||||||
ret.role = uint16_t(use.role);
|
|
||||||
EachEntityDef(db, use, [&](const auto &def) {
|
|
||||||
ret.containerName = std::string_view(def.detailed_name);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<lsLocationEx> GetLsLocationExs(DB *db, WorkingFiles *working_files,
|
std::vector<lsLocation> GetLsLocations(DB *db, WorkingFiles *wfiles,
|
||||||
const std::vector<Use> &uses) {
|
const std::vector<Use> &uses) {
|
||||||
std::vector<lsLocationEx> ret;
|
std::vector<lsLocation> ret;
|
||||||
for (Use use : uses)
|
for (Use use : uses)
|
||||||
if (auto loc =
|
if (auto loc = GetLsLocation(db, wfiles, use))
|
||||||
GetLsLocationEx(db, working_files, use, g_config->xref.container))
|
|
||||||
ret.push_back(*loc);
|
ret.push_back(*loc);
|
||||||
std::sort(ret.begin(), ret.end());
|
std::sort(ret.begin(), ret.end());
|
||||||
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
ret.erase(std::unique(ret.begin(), ret.end()), ret.end());
|
||||||
|
@ -39,12 +39,11 @@ std::optional<lsRange> GetLsRange(WorkingFile *working_file,
|
|||||||
lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path);
|
lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path);
|
||||||
lsDocumentUri GetLsDocumentUri(DB *db, int file_id);
|
lsDocumentUri GetLsDocumentUri(DB *db, int file_id);
|
||||||
|
|
||||||
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *working_files,
|
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles, Use use);
|
||||||
Use use);
|
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles,
|
||||||
std::optional<lsLocationEx> GetLsLocationEx(DB *db, WorkingFiles *working_files,
|
SymbolRef sym, int file_id);
|
||||||
Use use, bool container);
|
std::vector<lsLocation> GetLsLocations(DB *db, WorkingFiles *wfiles,
|
||||||
std::vector<lsLocationEx> GetLsLocationExs(DB *db, WorkingFiles *working_files,
|
const std::vector<Use> &uses);
|
||||||
const std::vector<Use> &refs);
|
|
||||||
// Returns a symbol. The symbol will *NOT* have a location assigned.
|
// Returns a symbol. The symbol will *NOT* have a location assigned.
|
||||||
std::optional<lsSymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
|
std::optional<lsSymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
|
||||||
bool detailed);
|
bool detailed);
|
||||||
|
@ -255,45 +255,49 @@ template <typename Def> void ReflectShortName(Writer &visitor, Def &def) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) {
|
|
||||||
REFLECT_MEMBER_START();
|
|
||||||
REFLECT_MEMBER2("usr", value.usr);
|
|
||||||
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
|
||||||
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
|
|
||||||
ReflectShortName(visitor, value.def);
|
|
||||||
REFLECT_MEMBER2("kind", value.def.kind);
|
|
||||||
ReflectHoverAndComments(visitor, value.def);
|
|
||||||
REFLECT_MEMBER2("declarations", value.declarations);
|
|
||||||
REFLECT_MEMBER2("spell", value.def.spell);
|
|
||||||
REFLECT_MEMBER2("extent", value.def.extent);
|
|
||||||
REFLECT_MEMBER2("alias_of", value.def.alias_of);
|
|
||||||
REFLECT_MEMBER2("bases", value.def.bases);
|
|
||||||
REFLECT_MEMBER2("derived", value.derived);
|
|
||||||
REFLECT_MEMBER2("types", value.def.types);
|
|
||||||
REFLECT_MEMBER2("funcs", value.def.funcs);
|
|
||||||
REFLECT_MEMBER2("vars", value.def.vars);
|
|
||||||
REFLECT_MEMBER2("instances", value.instances);
|
|
||||||
REFLECT_MEMBER2("uses", value.uses);
|
|
||||||
REFLECT_MEMBER_END();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) {
|
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) {
|
||||||
REFLECT_MEMBER_START();
|
REFLECT_MEMBER_START();
|
||||||
REFLECT_MEMBER2("usr", value.usr);
|
REFLECT_MEMBER2("usr", value.usr);
|
||||||
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
||||||
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
|
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
|
||||||
ReflectShortName(visitor, value.def);
|
ReflectShortName(visitor, value.def);
|
||||||
REFLECT_MEMBER2("kind", value.def.kind);
|
REFLECT_MEMBER2("spell", value.def.spell);
|
||||||
REFLECT_MEMBER2("storage", value.def.storage);
|
REFLECT_MEMBER2("extent", value.def.extent);
|
||||||
ReflectHoverAndComments(visitor, value.def);
|
ReflectHoverAndComments(visitor, value.def);
|
||||||
|
REFLECT_MEMBER2("bases", value.def.bases);
|
||||||
|
REFLECT_MEMBER2("vars", value.def.vars);
|
||||||
|
REFLECT_MEMBER2("callees", value.def.callees);
|
||||||
|
REFLECT_MEMBER2("kind", value.def.kind);
|
||||||
|
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
|
||||||
|
REFLECT_MEMBER2("storage", value.def.storage);
|
||||||
|
|
||||||
REFLECT_MEMBER2("declarations", value.declarations);
|
REFLECT_MEMBER2("declarations", value.declarations);
|
||||||
|
REFLECT_MEMBER2("derived", value.derived);
|
||||||
|
REFLECT_MEMBER2("uses", value.uses);
|
||||||
|
REFLECT_MEMBER_END();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) {
|
||||||
|
REFLECT_MEMBER_START();
|
||||||
|
REFLECT_MEMBER2("usr", value.usr);
|
||||||
|
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
||||||
|
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
|
||||||
|
ReflectShortName(visitor, value.def);
|
||||||
|
ReflectHoverAndComments(visitor, value.def);
|
||||||
REFLECT_MEMBER2("spell", value.def.spell);
|
REFLECT_MEMBER2("spell", value.def.spell);
|
||||||
REFLECT_MEMBER2("extent", value.def.extent);
|
REFLECT_MEMBER2("extent", value.def.extent);
|
||||||
REFLECT_MEMBER2("bases", value.def.bases);
|
REFLECT_MEMBER2("bases", value.def.bases);
|
||||||
REFLECT_MEMBER2("derived", value.derived);
|
REFLECT_MEMBER2("funcs", value.def.funcs);
|
||||||
|
REFLECT_MEMBER2("types", value.def.types);
|
||||||
REFLECT_MEMBER2("vars", value.def.vars);
|
REFLECT_MEMBER2("vars", value.def.vars);
|
||||||
|
REFLECT_MEMBER2("alias_of", value.def.alias_of);
|
||||||
|
REFLECT_MEMBER2("kind", value.def.kind);
|
||||||
|
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
|
||||||
|
|
||||||
|
REFLECT_MEMBER2("declarations", value.declarations);
|
||||||
|
REFLECT_MEMBER2("derived", value.derived);
|
||||||
|
REFLECT_MEMBER2("instances", value.instances);
|
||||||
REFLECT_MEMBER2("uses", value.uses);
|
REFLECT_MEMBER2("uses", value.uses);
|
||||||
REFLECT_MEMBER2("callees", value.def.callees);
|
|
||||||
REFLECT_MEMBER_END();
|
REFLECT_MEMBER_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,13 +308,15 @@ template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) {
|
|||||||
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
|
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
|
||||||
ReflectShortName(visitor, value.def);
|
ReflectShortName(visitor, value.def);
|
||||||
ReflectHoverAndComments(visitor, value.def);
|
ReflectHoverAndComments(visitor, value.def);
|
||||||
REFLECT_MEMBER2("declarations", value.declarations);
|
|
||||||
REFLECT_MEMBER2("spell", value.def.spell);
|
REFLECT_MEMBER2("spell", value.def.spell);
|
||||||
REFLECT_MEMBER2("extent", value.def.extent);
|
REFLECT_MEMBER2("extent", value.def.extent);
|
||||||
REFLECT_MEMBER2("type", value.def.type);
|
REFLECT_MEMBER2("type", value.def.type);
|
||||||
REFLECT_MEMBER2("uses", value.uses);
|
|
||||||
REFLECT_MEMBER2("kind", value.def.kind);
|
REFLECT_MEMBER2("kind", value.def.kind);
|
||||||
|
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
|
||||||
REFLECT_MEMBER2("storage", value.def.storage);
|
REFLECT_MEMBER2("storage", value.def.storage);
|
||||||
|
|
||||||
|
REFLECT_MEMBER2("declarations", value.declarations);
|
||||||
|
REFLECT_MEMBER2("uses", value.uses);
|
||||||
REFLECT_MEMBER_END();
|
REFLECT_MEMBER_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user