Remove ls prefix from many LSP interfaces

Rename SymbolKind to Kind & lsSymbolKind to SymbolKind
Use textDocumentSync: TextDocumentSyncOptions
This commit is contained in:
Fangrui Song 2018-11-03 13:52:43 -07:00
parent 6517f9f143
commit 50736827ca
41 changed files with 681 additions and 833 deletions

View File

@ -60,10 +60,9 @@ struct ProxyFileSystem : FileSystem {
namespace ccls {
lsTextEdit ToTextEdit(const clang::SourceManager &SM,
const clang::LangOptions &L,
TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L,
const clang::FixItHint &FixIt) {
lsTextEdit edit;
TextEdit edit;
edit.newText = FixIt.CodeToInsert;
auto r = FromCharSourceRange(SM, L, FixIt.RemoveRange);
edit.range =
@ -211,7 +210,7 @@ public:
Flush();
}
void HandleDiagnostic(DiagnosticsEngine::Level Level,
const Diagnostic &Info) override {
const clang::Diagnostic &Info) override {
DiagnosticConsumer::HandleDiagnostic(Level, Info);
SourceLocation L = Info.getLocation();
if (!L.isValid()) return;
@ -360,8 +359,8 @@ void *CompletionPreloadMain(void *manager_) {
int debounce =
is_open ? g_config->diagnostics.onOpen : g_config->diagnostics.onSave;
if (debounce >= 0) {
lsTextDocumentIdentifier document;
document.uri = lsDocumentUri::FromPath(request.path);
TextDocumentIdentifier document;
document.uri = DocumentUri::FromPath(request.path);
manager->DiagnosticsUpdate(request.path, debounce);
}
}
@ -491,24 +490,24 @@ void *DiagnosticMain(void *manager_) {
for (auto &Buf : Bufs)
Buf.release();
auto Fill = [](const DiagBase &d, lsDiagnostic &ret) {
auto Fill = [](const DiagBase &d, Diagnostic &ret) {
ret.range = lsRange{{d.range.start.line, d.range.start.column},
{d.range.end.line, d.range.end.column}};
switch (d.level) {
case DiagnosticsEngine::Ignored:
// llvm_unreachable
case DiagnosticsEngine::Remark:
ret.severity = lsDiagnosticSeverity::Hint;
ret.severity = DiagnosticSeverity::Hint;
break;
case DiagnosticsEngine::Note:
ret.severity = lsDiagnosticSeverity::Information;
ret.severity = DiagnosticSeverity::Information;
break;
case DiagnosticsEngine::Warning:
ret.severity = lsDiagnosticSeverity::Warning;
ret.severity = DiagnosticSeverity::Warning;
break;
case DiagnosticsEngine::Error:
case DiagnosticsEngine::Fatal:
ret.severity = lsDiagnosticSeverity::Error;
ret.severity = DiagnosticSeverity::Error;
break;
}
ret.code = d.category;
@ -518,13 +517,13 @@ void *DiagnosticMain(void *manager_) {
std::vector<Diag> diags = DC.Take();
if (std::shared_ptr<PreambleData> preamble = session->GetPreamble())
diags.insert(diags.end(), preamble->diags.begin(), preamble->diags.end());
std::vector<lsDiagnostic> ls_diags;
std::vector<Diagnostic> ls_diags;
for (auto &d : diags) {
if (!d.concerned)
continue;
std::string buf;
llvm::raw_string_ostream OS(buf);
lsDiagnostic &ls_diag = ls_diags.emplace_back();
Diagnostic &ls_diag = ls_diags.emplace_back();
Fill(d, ls_diag);
ls_diag.fixits_ = d.edits;
OS << d.message;
@ -537,7 +536,7 @@ void *DiagnosticMain(void *manager_) {
for (auto &n : d.notes) {
if (!n.concerned)
continue;
lsDiagnostic &ls_diag1 = ls_diags.emplace_back();
Diagnostic &ls_diag1 = ls_diags.emplace_back();
Fill(n, ls_diag1);
OS << n.message << "\n\n";
printDiag(OS, d);

View File

@ -33,10 +33,10 @@ struct DiagBase {
struct Note : DiagBase {};
struct Diag : DiagBase {
std::vector<Note> notes;
std::vector<lsTextEdit> edits;
std::vector<TextEdit> edits;
};
lsTextEdit ToTextEdit(const clang::SourceManager &SM,
TextEdit ToTextEdit(const clang::SourceManager &SM,
const clang::LangOptions &L,
const clang::FixItHint &FixIt);
@ -63,18 +63,18 @@ struct CompletionSession
struct CompletionManager {
using OnDiagnostic = std::function<void(
std::string path, std::vector<lsDiagnostic> diagnostics)>;
std::string path, std::vector<Diagnostic> diagnostics)>;
// If OptConsumer is nullptr, the request has been cancelled.
using OnComplete =
std::function<void(clang::CodeCompleteConsumer *OptConsumer)>;
using OnDropped = std::function<void(lsRequestId request_id)>;
using OnDropped = std::function<void(RequestId request_id)>;
struct PreloadRequest {
std::string path;
};
struct CompletionRequest {
CompletionRequest(const lsRequestId &id,
const lsTextDocumentIdentifier &document,
CompletionRequest(const RequestId &id,
const TextDocumentIdentifier &document,
const lsPosition &position,
std::unique_ptr<clang::CodeCompleteConsumer> Consumer,
clang::CodeCompleteOptions CCOpts,
@ -83,8 +83,8 @@ struct CompletionManager {
Consumer(std::move(Consumer)), CCOpts(CCOpts),
on_complete(on_complete) {}
lsRequestId id;
lsTextDocumentIdentifier document;
RequestId id;
TextDocumentIdentifier document;
lsPosition position;
std::unique_ptr<clang::CodeCompleteConsumer> Consumer;
clang::CodeCompleteOptions CCOpts;

View File

@ -10,10 +10,10 @@
namespace ccls {
template <typename Node>
std::vector<lsLocation> FlattenHierarchy(const std::optional<Node> &root) {
std::vector<Location> FlattenHierarchy(const std::optional<Node> &root) {
if (!root)
return {};
std::vector<lsLocation> ret;
std::vector<Location> ret;
std::queue<const Node *> q;
for (auto &entry : root->children)
q.push(&entry);

View File

@ -22,7 +22,7 @@ namespace {
struct CompletionCandidate {
std::string absolute_path;
lsCompletionItem completion_item;
CompletionItem completion_item;
};
std::string ElideLongPath(const std::string &path) {
@ -74,15 +74,15 @@ bool TrimPath(Project *project, std::string &path) {
return angle;
}
lsCompletionItem BuildCompletionItem(const std::string &path,
CompletionItem BuildCompletionItem(const std::string &path,
bool use_angle_brackets) {
lsCompletionItem item;
CompletionItem item;
item.label = ElideLongPath(path);
item.detail = path; // the include path, used in de-duplicating
item.textEdit.newText = path;
item.insertTextFormat = lsInsertTextFormat::PlainText;
item.insertTextFormat = InsertTextFormat::PlainText;
item.use_angle_brackets_ = use_angle_brackets;
item.kind = lsCompletionItemKind::File;
item.kind = CompletionItemKind::File;
item.priority_ = 0;
return item;
}
@ -124,7 +124,7 @@ void IncludeComplete::Rescan() {
}
void IncludeComplete::InsertCompletionItem(const std::string &absolute_path,
lsCompletionItem &&item) {
CompletionItem &&item) {
if (inserted_paths.insert({item.detail, inserted_paths.size()}).second) {
completion_items.push_back(item);
// insert if not found or with shorter include path
@ -135,7 +135,7 @@ void IncludeComplete::InsertCompletionItem(const std::string &absolute_path,
completion_items.size() - 1;
}
} else {
lsCompletionItem &inserted_item =
CompletionItem &inserted_item =
completion_items[inserted_paths[item.detail]];
// Update |use_angle_brackets_|, prefer quotes.
if (!item.use_angle_brackets_)
@ -151,7 +151,7 @@ void IncludeComplete::AddFile(const std::string &path) {
std::string trimmed_path = path;
bool use_angle_brackets = TrimPath(project_, trimmed_path);
lsCompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets);
CompletionItem item = BuildCompletionItem(trimmed_path, use_angle_brackets);
std::unique_lock<std::mutex> lock(completion_items_mutex, std::defer_lock);
if (is_scanning)
@ -190,7 +190,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
std::move(result.completion_item));
}
std::optional<lsCompletionItem>
std::optional<CompletionItem>
IncludeComplete::FindCompletionItemForAbsolutePath(
const std::string &absolute_path) {
std::lock_guard<std::mutex> lock(completion_items_mutex);

View File

@ -26,18 +26,18 @@ struct IncludeComplete {
void InsertIncludesFromDirectory(std::string directory,
bool use_angle_brackets);
std::optional<ccls::lsCompletionItem>
std::optional<ccls::CompletionItem>
FindCompletionItemForAbsolutePath(const std::string &absolute_path);
// Insert item to |completion_items|.
// Update |absolute_path_to_completion_item| and |inserted_paths|.
void InsertCompletionItem(const std::string &absolute_path,
ccls::lsCompletionItem &&item);
ccls::CompletionItem &&item);
// Guards |completion_items| when |is_scanning| is true.
std::mutex completion_items_mutex;
std::atomic<bool> is_scanning;
std::vector<ccls::lsCompletionItem> completion_items;
std::vector<ccls::CompletionItem> completion_items;
// Absolute file path to the completion item in |completion_items|.
// Keep the one with shortest include path.

View File

@ -105,110 +105,110 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts,
BInfo.second);
}
SymbolKind GetSymbolKind(const Decl *D, lsSymbolKind &kind) {
Kind GetKind(const Decl *D, SymbolKind &kind) {
switch (D->getKind()) {
case Decl::LinkageSpec:
return SymbolKind::Invalid;
return Kind::Invalid;
case Decl::Namespace:
kind = lsSymbolKind::Namespace;
return SymbolKind::Type;
kind = SymbolKind::Namespace;
return Kind::Type;
case Decl::NamespaceAlias:
kind = lsSymbolKind::TypeAlias;
return SymbolKind::Type;
kind = SymbolKind::TypeAlias;
return Kind::Type;
case Decl::ObjCCategory:
case Decl::ObjCImplementation:
case Decl::ObjCInterface:
case Decl::ObjCProtocol:
kind = lsSymbolKind::Interface;
return SymbolKind::Type;
kind = SymbolKind::Interface;
return Kind::Type;
case Decl::ObjCMethod:
kind = lsSymbolKind::Method;
return SymbolKind::Func;
kind = SymbolKind::Method;
return Kind::Func;
case Decl::ObjCProperty:
kind = lsSymbolKind::Property;
return SymbolKind::Type;
kind = SymbolKind::Property;
return Kind::Type;
case Decl::ClassTemplate:
kind = lsSymbolKind::Class;
return SymbolKind::Type;
kind = SymbolKind::Class;
return Kind::Type;
case Decl::FunctionTemplate:
kind = lsSymbolKind::Function;
return SymbolKind::Func;
kind = SymbolKind::Function;
return Kind::Func;
case Decl::TypeAliasTemplate:
kind = lsSymbolKind::TypeAlias;
return SymbolKind::Type;
kind = SymbolKind::TypeAlias;
return Kind::Type;
case Decl::VarTemplate:
kind = lsSymbolKind::Variable;
return SymbolKind::Var;
kind = SymbolKind::Variable;
return Kind::Var;
case Decl::TemplateTemplateParm:
kind = lsSymbolKind::TypeParameter;
return SymbolKind::Type;
kind = SymbolKind::TypeParameter;
return Kind::Type;
case Decl::Enum:
kind = lsSymbolKind::Enum;
return SymbolKind::Type;
kind = SymbolKind::Enum;
return Kind::Type;
case Decl::CXXRecord:
case Decl::Record:
kind = lsSymbolKind::Class;
kind = SymbolKind::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;
kind = SymbolKind::Struct;
return Kind::Type;
case Decl::ClassTemplateSpecialization:
case Decl::ClassTemplatePartialSpecialization:
kind = lsSymbolKind::Class;
return SymbolKind::Type;
kind = SymbolKind::Class;
return Kind::Type;
case Decl::TypeAlias:
case Decl::Typedef:
case Decl::UnresolvedUsingTypename:
kind = lsSymbolKind::TypeAlias;
return SymbolKind::Type;
kind = SymbolKind::TypeAlias;
return Kind::Type;
case Decl::Binding:
kind = lsSymbolKind::Variable;
return SymbolKind::Var;
kind = SymbolKind::Variable;
return Kind::Var;
case Decl::Field:
case Decl::ObjCIvar:
kind = lsSymbolKind::Field;
return SymbolKind::Var;
kind = SymbolKind::Field;
return Kind::Var;
case Decl::Function:
kind = lsSymbolKind::Function;
return SymbolKind::Func;
kind = SymbolKind::Function;
return Kind::Func;
case Decl::CXXMethod: {
const auto *MD = cast<CXXMethodDecl>(D);
kind = MD->isStatic() ? lsSymbolKind::StaticMethod : lsSymbolKind::Method;
return SymbolKind::Func;
kind = MD->isStatic() ? SymbolKind::StaticMethod : SymbolKind::Method;
return Kind::Func;
}
case Decl::CXXConstructor:
kind = lsSymbolKind::Constructor;
return SymbolKind::Func;
kind = SymbolKind::Constructor;
return Kind::Func;
case Decl::CXXConversion:
case Decl::CXXDestructor:
kind = lsSymbolKind::Method;
return SymbolKind::Func;
kind = SymbolKind::Method;
return Kind::Func;
case Decl::Var:
case Decl::Decomposition:
kind = lsSymbolKind::Variable;
return SymbolKind::Var;
kind = SymbolKind::Variable;
return Kind::Var;
case Decl::ImplicitParam:
case Decl::ParmVar:
// ccls extension
kind = lsSymbolKind::Parameter;
return SymbolKind::Var;
kind = SymbolKind::Parameter;
return Kind::Var;
case Decl::VarTemplateSpecialization:
case Decl::VarTemplatePartialSpecialization:
kind = lsSymbolKind::Variable;
return SymbolKind::Var;
kind = SymbolKind::Variable;
return Kind::Var;
case Decl::EnumConstant:
kind = lsSymbolKind::EnumMember;
return SymbolKind::Var;
kind = SymbolKind::EnumMember;
return Kind::Var;
case Decl::UnresolvedUsingValue:
kind = lsSymbolKind::Variable;
return SymbolKind::Var;
kind = SymbolKind::Variable;
return Kind::Var;
case Decl::TranslationUnit:
return SymbolKind::Invalid;
return Kind::Invalid;
default:
LOG_S(INFO) << "unhandled " << int(D->getKind());
return SymbolKind::Invalid;
return Kind::Invalid;
}
}
@ -605,7 +605,7 @@ public:
return it->second.first;
}
void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind,
void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, Kind kind,
SourceLocation Spell) const {
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell));
if (!FE)
@ -617,13 +617,13 @@ public:
FromTokenRange(SM, Ctx->getLangOpts(), SourceRange(Spell, Spell));
Use use{{spell, Role::Dynamic}, lid};
switch (kind) {
case SymbolKind::Func:
case Kind::Func:
db->ToFunc(usr).uses.push_back(use);
break;
case SymbolKind::Type:
case Kind::Type:
db->ToType(usr).uses.push_back(use);
break;
case SymbolKind::Var:
case Kind::Var:
db->ToVar(usr).uses.push_back(use);
break;
default:
@ -738,8 +738,8 @@ public:
IndexFunc *func = nullptr;
IndexType *type = nullptr;
IndexVar *var = nullptr;
lsSymbolKind ls_kind;
SymbolKind kind = GetSymbolKind(D, ls_kind);
SymbolKind ls_kind;
Kind kind = GetKind(D, ls_kind);
if (is_def)
switch (D->getKind()) {
@ -773,8 +773,8 @@ public:
SourceRange R = OrigD->getSourceRange();
entity->def.spell = {use,
FromTokenRangeDefaulted(SM, Lang, R, FE, loc)};
entity->def.parent_kind = lsSymbolKind::File;
GetSymbolKind(cast<Decl>(SemDC), entity->def.parent_kind);
entity->def.parent_kind = SymbolKind::File;
GetKind(cast<Decl>(SemDC), entity->def.parent_kind);
} else if (is_decl) {
SourceRange R = OrigD->getSourceRange();
entity->declarations.push_back(
@ -787,13 +787,13 @@ public:
entity->def.comments = Intern(GetComment(OrigD));
};
switch (kind) {
case SymbolKind::Invalid:
case Kind::Invalid:
LOG_S(INFO) << "Unhandled " << int(D->getKind()) << " " << info->qualified
<< " in " << db->path << ":" << loc.start.line + 1;
return true;
case SymbolKind::File:
case Kind::File:
return true;
case SymbolKind::Func:
case Kind::Func:
func = &db->ToFunc(usr);
func->def.kind = ls_kind;
// Mark as Role::Implicit to span one more column to the left/right.
@ -803,40 +803,40 @@ public:
role = Role(role | Role::Implicit);
do_def_decl(func);
if (Spell != Loc)
AddMacroUse(db, SM, usr, SymbolKind::Func, Spell);
AddMacroUse(db, SM, usr, Kind::Func, Spell);
if (func->def.detailed_name[0] == '\0')
SetName(D, info->short_name, info->qualified, func->def);
if (is_def || is_decl) {
const Decl *DC = cast<Decl>(SemDC);
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type)
if (GetKind(DC, ls_kind) == Kind::Type)
db->ToType(GetUsr(DC)).def.funcs.push_back(usr);
} else {
const Decl *DC = cast<Decl>(LexDC);
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Func)
if (GetKind(DC, ls_kind) == Kind::Func)
db->ToFunc(GetUsr(DC))
.def.callees.push_back({loc, usr, SymbolKind::Func, role});
.def.callees.push_back({loc, usr, Kind::Func, role});
}
break;
case SymbolKind::Type:
case Kind::Type:
type = &db->ToType(usr);
type->def.kind = ls_kind;
do_def_decl(type);
if (Spell != Loc)
AddMacroUse(db, SM, usr, SymbolKind::Type, Spell);
AddMacroUse(db, SM, usr, Kind::Type, Spell);
if (type->def.detailed_name[0] == '\0' && info->short_name.size())
SetName(D, info->short_name, info->qualified, type->def);
if (is_def || is_decl) {
const Decl *DC = cast<Decl>(SemDC);
if (GetSymbolKind(DC, ls_kind) == SymbolKind::Type)
if (GetKind(DC, ls_kind) == Kind::Type)
db->ToType(GetUsr(DC)).def.types.push_back(usr);
}
break;
case SymbolKind::Var:
case Kind::Var:
var = &db->ToVar(usr);
var->def.kind = ls_kind;
do_def_decl(var);
if (Spell != Loc)
AddMacroUse(db, SM, usr, SymbolKind::Var, Spell);
AddMacroUse(db, SM, usr, Kind::Var, Spell);
if (var->def.detailed_name[0] == '\0')
SetVarName(D, info->short_name, info->qualified, var->def);
QualType T;
@ -844,10 +844,10 @@ public:
T = VD->getType();
if (is_def || is_decl) {
const Decl *DC = cast<Decl>(SemDC);
SymbolKind kind = GetSymbolKind(DC, var->def.parent_kind);
if (kind == SymbolKind::Func)
Kind kind = GetKind(DC, var->def.parent_kind);
if (kind == Kind::Func)
db->ToFunc(GetUsr(DC)).def.vars.push_back(usr);
else if (kind == SymbolKind::Type && !isa<RecordDecl>(SemDC))
else if (kind == Kind::Type && !isa<RecordDecl>(SemDC))
db->ToType(GetUsr(DC)).def.vars.emplace_back(usr, -1);
if (!T.isNull()) {
if (auto *BT = T->getAs<BuiltinType>()) {
@ -871,8 +871,8 @@ public:
FromTokenRange(SM, Lang, R1)};
type1.def.detailed_name = Intern(info1->short_name);
type1.def.short_name_size = int16_t(info1->short_name.size());
type1.def.kind = lsSymbolKind::TypeParameter;
type1.def.parent_kind = lsSymbolKind::Class;
type1.def.kind = SymbolKind::TypeParameter;
type1.def.parent_kind = SymbolKind::Class;
var->def.type = usr1;
type1.instances.push_back(usr);
break;
@ -893,7 +893,7 @@ public:
var->def.spell = {
Use{{FromTokenRange(SM, Lang, {L, L}), Role::Definition}, lid},
FromTokenRange(SM, Lang, D->getSourceRange())};
var->def.parent_kind = lsSymbolKind::Method;
var->def.parent_kind = SymbolKind::Method;
}
}
break;
@ -962,7 +962,7 @@ public:
break;
case Decl::ClassTemplateSpecialization:
case Decl::ClassTemplatePartialSpecialization:
type->def.kind = lsSymbolKind::Class;
type->def.kind = SymbolKind::Class;
if (is_def) {
if (auto *ORD = dyn_cast<RecordDecl>(OrigD))
CollectRecordMembers(*type, ORD);
@ -1090,8 +1090,8 @@ public:
auto [Name, usr] = GetMacro(Tok);
IndexVar &var = db->ToVar(usr);
Range range = FromTokenRange(SM, Lang, {L, L}, &UniqueID);
var.def.kind = lsSymbolKind::Macro;
var.def.parent_kind = lsSymbolKind::File;
var.def.kind = SymbolKind::Macro;
var.def.parent_kind = SymbolKind::File;
if (var.def.spell)
var.declarations.push_back(*var.def.spell);
const MacroInfo *MI = MD->getMacroInfo();
@ -1344,7 +1344,7 @@ void Reflect(Reader &vis, SymbolRef &v) {
v.range = Range::FromString(s);
s = strchr(s, '|');
v.usr = strtoull(s + 1, &s, 10);
v.kind = static_cast<SymbolKind>(strtol(s + 1, &s, 10));
v.kind = static_cast<Kind>(strtol(s + 1, &s, 10));
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
} else {
Reflect(vis, v.range);

View File

@ -35,7 +35,7 @@ enum class LanguageId;
struct SymbolIdx {
Usr usr;
SymbolKind kind;
Kind kind;
bool operator==(const SymbolIdx &o) const {
return usr == o.usr && kind == o.kind;
@ -50,10 +50,10 @@ MAKE_REFLECT_STRUCT(SymbolIdx, usr, kind);
struct SymbolRef {
Range range;
Usr usr;
SymbolKind kind;
Kind kind;
Role role;
operator SymbolIdx() const { return {usr, kind}; }
std::tuple<Range, Usr, SymbolKind, Role> ToTuple() const {
std::tuple<Range, Usr, Kind, Role> ToTuple() const {
return std::make_tuple(range, usr, kind, role);
}
bool operator==(const SymbolRef &o) const { return ToTuple() == o.ToTuple(); }
@ -62,7 +62,7 @@ struct SymbolRef {
struct ExtentRef : SymbolRef {
Range extent;
std::tuple<Range, Usr, SymbolKind, Role, Range> ToTuple() const {
std::tuple<Range, Usr, Kind, Role, Range> ToTuple() const {
return std::make_tuple(range, usr, kind, role, extent);
}
bool operator==(const ExtentRef &o) const { return ToTuple() == o.ToTuple(); }
@ -133,8 +133,8 @@ struct FuncDef : NameMixin<FuncDef> {
int16_t qual_name_offset = 0;
int16_t short_name_offset = 0;
int16_t short_name_size = 0;
lsSymbolKind kind = lsSymbolKind::Unknown;
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
SymbolKind kind = SymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
uint8_t storage = clang::SC_None;
std::vector<Usr> GetBases() const { return bases; }
@ -171,8 +171,8 @@ struct TypeDef : NameMixin<TypeDef> {
int16_t qual_name_offset = 0;
int16_t short_name_offset = 0;
int16_t short_name_size = 0;
lsSymbolKind kind = lsSymbolKind::Unknown;
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
SymbolKind kind = SymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
std::vector<Usr> GetBases() const { return bases; }
};
@ -203,18 +203,18 @@ struct VarDef : NameMixin<VarDef> {
int16_t qual_name_offset = 0;
int16_t short_name_offset = 0;
int16_t short_name_size = 0;
lsSymbolKind kind = lsSymbolKind::Unknown;
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
SymbolKind kind = SymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
// Note a variable may have instances of both |None| and |Extern|
// (declaration).
uint8_t storage = clang::SC_None;
bool is_local() const {
return spell &&
(parent_kind == lsSymbolKind::Function ||
parent_kind == lsSymbolKind::Method ||
parent_kind == lsSymbolKind::StaticMethod ||
parent_kind == lsSymbolKind::Constructor) &&
(parent_kind == SymbolKind::Function ||
parent_kind == SymbolKind::Method ||
parent_kind == SymbolKind::StaticMethod ||
parent_kind == SymbolKind::Constructor) &&
storage == clang::SC_None;
}

View File

@ -10,55 +10,48 @@
#include <stdio.h>
namespace ccls {
void Reflect(Reader &visitor, lsRequestId &value) {
void Reflect(Reader &visitor, RequestId &value) {
if (visitor.IsInt64()) {
value.type = lsRequestId::kInt;
value.type = RequestId::kInt;
value.value = int(visitor.GetInt64());
} else if (visitor.IsInt()) {
value.type = lsRequestId::kInt;
value.type = RequestId::kInt;
value.value = visitor.GetInt();
} else if (visitor.IsString()) {
value.type = lsRequestId::kString;
value.type = RequestId::kString;
value.value = atoll(visitor.GetString());
} else {
value.type = lsRequestId::kNone;
value.type = RequestId::kNone;
value.value = -1;
}
}
void Reflect(Writer &visitor, lsRequestId &value) {
void Reflect(Writer &visitor, RequestId &value) {
switch (value.type) {
case lsRequestId::kNone:
case RequestId::kNone:
visitor.Null();
break;
case lsRequestId::kInt:
case RequestId::kInt:
visitor.Int(value.value);
break;
case lsRequestId::kString:
case RequestId::kString:
auto s = std::to_string(value.value);
visitor.String(s.c_str(), s.length());
break;
}
}
lsTextDocumentIdentifier
lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const {
lsTextDocumentIdentifier result;
result.uri = uri;
return result;
}
lsDocumentUri lsDocumentUri::FromPath(const std::string &path) {
lsDocumentUri result;
DocumentUri DocumentUri::FromPath(const std::string &path) {
DocumentUri result;
result.SetPath(path);
return result;
}
bool lsDocumentUri::operator==(const lsDocumentUri &other) const {
bool DocumentUri::operator==(const DocumentUri &other) const {
return raw_uri == other.raw_uri;
}
void lsDocumentUri::SetPath(const std::string &path) {
void DocumentUri::SetPath(const std::string &path) {
// file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests
raw_uri = path;
@ -99,7 +92,7 @@ void lsDocumentUri::SetPath(const std::string &path) {
raw_uri = std::move(t);
}
std::string lsDocumentUri::GetPath() const {
std::string DocumentUri::GetPath() const {
if (raw_uri.compare(0, 7, "file://")) {
LOG_S(WARNING)
<< "Received potentially bad URI (not starting with file://): "
@ -136,7 +129,7 @@ std::string lsPosition::ToString() const {
return std::to_string(line) + ":" + std::to_string(character);
}
bool lsTextEdit::operator==(const lsTextEdit &that) {
bool TextEdit::operator==(const TextEdit &that) {
return range == that.range && newText == that.newText;
}
} // namespace ccls

View File

@ -13,7 +13,7 @@
#include <unordered_map>
namespace ccls {
struct lsRequestId {
struct RequestId {
// The client can send the request id as an int or a string. We should output
// the same format we received.
enum Type { kNone, kInt, kString };
@ -23,17 +23,17 @@ struct lsRequestId {
bool Valid() const { return type != kNone; }
};
void Reflect(Reader &visitor, lsRequestId &value);
void Reflect(Writer &visitor, lsRequestId &value);
void Reflect(Reader &visitor, RequestId &value);
void Reflect(Writer &visitor, RequestId &value);
struct InMessage {
lsRequestId id;
RequestId id;
std::string method;
std::unique_ptr<char[]> message;
std::unique_ptr<rapidjson::Document> document;
};
enum class lsErrorCodes {
enum class ErrorCode {
// Defined by JSON RPC
ParseError = -32700,
InvalidRequest = -32600,
@ -48,11 +48,11 @@ enum class lsErrorCodes {
// Defined by the protocol.
RequestCancelled = -32800,
};
MAKE_REFLECT_TYPE_PROXY(lsErrorCodes);
MAKE_REFLECT_TYPE_PROXY(ErrorCode);
struct lsResponseError {
struct ResponseError {
// A number indicating the error type that occurred.
lsErrorCodes code;
ErrorCode code;
// A string providing a short description of the error.
std::string message;
@ -61,7 +61,7 @@ struct lsResponseError {
// information about the error. Can be omitted.
// std::optional<D> data;
};
MAKE_REFLECT_STRUCT(lsResponseError, code, message);
MAKE_REFLECT_STRUCT(ResponseError, code, message);
constexpr char ccls_xref[] = "ccls.xref";
constexpr char window_showMessage[] = "window/showMessage";
@ -74,10 +74,10 @@ constexpr char window_showMessage[] = "window/showMessage";
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
struct lsDocumentUri {
static lsDocumentUri FromPath(const std::string &path);
struct DocumentUri {
static DocumentUri FromPath(const std::string &path);
bool operator==(const lsDocumentUri &other) const;
bool operator==(const DocumentUri &other) const;
void SetPath(const std::string &path);
std::string GetPath() const;
@ -86,7 +86,7 @@ struct lsDocumentUri {
};
template <typename TVisitor>
void Reflect(TVisitor &visitor, lsDocumentUri &value) {
void Reflect(TVisitor &visitor, DocumentUri &value) {
Reflect(visitor, value.raw_uri);
}
@ -115,20 +115,20 @@ struct lsRange {
};
MAKE_REFLECT_STRUCT(lsRange, start, end);
struct lsLocation {
lsDocumentUri uri;
struct Location {
DocumentUri uri;
lsRange range;
bool operator==(const lsLocation &o) const {
bool operator==(const Location &o) const {
return uri == o.uri && range == o.range;
}
bool operator<(const lsLocation &o) const {
bool operator<(const Location &o) const {
return !(uri.raw_uri == o.uri.raw_uri) ? uri.raw_uri < o.uri.raw_uri
: range < o.range;
}
};
MAKE_REFLECT_STRUCT(lsLocation, uri, range);
MAKE_REFLECT_STRUCT(Location, uri, range);
enum class lsSymbolKind : uint8_t {
enum class SymbolKind : uint8_t {
Unknown = 0,
File = 1,
@ -169,30 +169,28 @@ enum class lsSymbolKind : uint8_t {
StaticMethod = 254,
Macro = 255,
};
MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);
MAKE_REFLECT_TYPE_PROXY(SymbolKind);
struct lsSymbolInformation {
struct SymbolInformation {
std::string_view name;
lsSymbolKind kind;
lsLocation location;
SymbolKind kind;
Location location;
std::optional<std::string_view> containerName;
};
struct lsTextDocumentIdentifier {
lsDocumentUri uri;
struct TextDocumentIdentifier {
DocumentUri uri;
};
MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri);
MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri);
struct lsVersionedTextDocumentIdentifier {
lsDocumentUri uri;
struct VersionedTextDocumentIdentifier {
DocumentUri uri;
// The version number of this document. number | null
std::optional<int> version;
lsTextDocumentIdentifier AsTextDocumentIdentifier() const;
};
MAKE_REFLECT_STRUCT(lsVersionedTextDocumentIdentifier, uri, version);
MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version);
struct lsTextEdit {
struct TextEdit {
// The range of the text document to be manipulated. To insert
// text into a document create a range where start === end.
lsRange range;
@ -201,13 +199,13 @@ struct lsTextEdit {
// empty string.
std::string newText;
bool operator==(const lsTextEdit &that);
bool operator==(const TextEdit &that);
};
MAKE_REFLECT_STRUCT(lsTextEdit, range, newText);
MAKE_REFLECT_STRUCT(TextEdit, range, newText);
struct lsTextDocumentItem {
struct TextDocumentItem {
// The text document's URI.
lsDocumentUri uri;
DocumentUri uri;
// The text document's language identifier.
std::string languageId;
@ -219,28 +217,21 @@ struct lsTextDocumentItem {
// The content of the opened text document.
std::string text;
};
MAKE_REFLECT_STRUCT(lsTextDocumentItem, uri, languageId, version, text);
MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
struct lsTextDocumentEdit {
struct TextDocumentEdit {
// The text document to change.
lsVersionedTextDocumentIdentifier textDocument;
VersionedTextDocumentIdentifier textDocument;
// The edits to be applied.
std::vector<lsTextEdit> edits;
std::vector<TextEdit> edits;
};
MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits);
MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits);
struct lsWorkspaceEdit {
// Holds changes to existing resources.
// changes ? : { [uri:string]: TextEdit[]; };
// std::unordered_map<lsDocumentUri, std::vector<lsTextEdit>> changes;
// An array of `TextDocumentEdit`s to express changes to specific a specific
// version of a text document. Whether a client supports versioned document
// edits is expressed via `WorkspaceClientCapabilites.versionedWorkspaceEdit`.
std::vector<lsTextDocumentEdit> documentChanges;
struct WorkspaceEdit {
std::vector<TextDocumentEdit> documentChanges;
};
MAKE_REFLECT_STRUCT(lsWorkspaceEdit, documentChanges);
MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges);
struct TextDocumentContentChangeEvent {
// The range of the document that changed.
@ -252,12 +243,12 @@ struct TextDocumentContentChangeEvent {
};
struct TextDocumentDidChangeParam {
lsVersionedTextDocumentIdentifier textDocument;
VersionedTextDocumentIdentifier textDocument;
std::vector<TextDocumentContentChangeEvent> contentChanges;
};
struct WorkspaceFolder {
lsDocumentUri uri;
DocumentUri uri;
std::string name;
};
MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name);
@ -266,7 +257,7 @@ MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name);
enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
MAKE_REFLECT_TYPE_PROXY(MessageType)
enum class lsDiagnosticSeverity {
enum class DiagnosticSeverity {
// Reports an error.
Error = 1,
// Reports a warning.
@ -276,15 +267,15 @@ enum class lsDiagnosticSeverity {
// Reports a hint.
Hint = 4
};
MAKE_REFLECT_TYPE_PROXY(lsDiagnosticSeverity);
MAKE_REFLECT_TYPE_PROXY(DiagnosticSeverity);
struct lsDiagnostic {
struct Diagnostic {
// The range at which the message applies.
lsRange range;
// The diagnostic's severity. Can be omitted. If omitted it is up to the
// client to interpret diagnostics as error, warning, info or hint.
std::optional<lsDiagnosticSeverity> severity;
std::optional<DiagnosticSeverity> severity;
// The diagnostic's code. Can be omitted.
int code = 0;
@ -297,24 +288,15 @@ struct lsDiagnostic {
std::string message;
// Non-serialized set of fixits.
std::vector<lsTextEdit> fixits_;
std::vector<TextEdit> fixits_;
};
MAKE_REFLECT_STRUCT(lsDiagnostic, range, severity, source, message);
MAKE_REFLECT_STRUCT(Diagnostic, range, severity, source, message);
struct lsPublishDiagnosticsParams {
// The URI for which diagnostic information is reported.
lsDocumentUri uri;
// An array of diagnostic information items.
std::vector<lsDiagnostic> diagnostics;
};
MAKE_REFLECT_STRUCT(lsPublishDiagnosticsParams, uri, diagnostics);
struct lsShowMessageParams {
struct ShowMessageParam {
MessageType type = MessageType::Error;
std::string message;
};
MAKE_REFLECT_STRUCT(lsShowMessageParams, type, message);
MAKE_REFLECT_STRUCT(ShowMessageParam, type, message);
// Used to identify the language at a file level. The ordering is important, as
// a file previously identified as `C`, will be changed to `Cpp` if it
@ -324,8 +306,8 @@ MAKE_REFLECT_TYPE_PROXY(LanguageId);
// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in
// front of others.
enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var };
MAKE_REFLECT_TYPE_PROXY(SymbolKind);
enum class Kind : uint8_t { Invalid, File, Type, Func, Var };
MAKE_REFLECT_TYPE_PROXY(Kind);
enum class Role : uint16_t {
None = 0,

View File

@ -18,7 +18,7 @@ std::optional<Matcher> Matcher::Create(const std::string &search) {
);
return m;
} catch (const std::exception &e) {
lsShowMessageParams params;
ShowMessageParam params;
params.type = MessageType::Error;
params.message =
"failed to parse EMCAScript regex " + search + " : " + e.what();

View File

@ -31,9 +31,9 @@ MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics);
MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context);
// completion
MAKE_REFLECT_TYPE_PROXY(lsCompletionTriggerKind);
MAKE_REFLECT_STRUCT(lsCompletionContext, triggerKind, triggerCharacter);
MAKE_REFLECT_STRUCT(lsCompletionParams, textDocument, position, context);
MAKE_REFLECT_TYPE_PROXY(CompletionTriggerKind);
MAKE_REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter);
MAKE_REFLECT_STRUCT(CompletionParam, textDocument, position, context);
// formatting
MAKE_REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces);
@ -53,8 +53,8 @@ MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query, folders);
namespace {
struct CclsSemanticHighlightSymbol {
int id = 0;
lsSymbolKind parentKind;
lsSymbolKind kind;
SymbolKind parentKind;
SymbolKind kind;
uint8_t storage;
std::vector<std::pair<int, int>> ranges;
@ -63,7 +63,7 @@ struct CclsSemanticHighlightSymbol {
};
struct CclsSemanticHighlightParams {
lsDocumentUri uri;
DocumentUri uri;
std::vector<CclsSemanticHighlightSymbol> symbols;
};
MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage,
@ -71,7 +71,7 @@ MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage,
MAKE_REFLECT_STRUCT(CclsSemanticHighlightParams, uri, symbols);
struct CclsSetSkippedRangesParams {
lsDocumentUri uri;
DocumentUri uri;
std::vector<lsRange> skippedRanges;
};
MAKE_REFLECT_STRUCT(CclsSetSkippedRangesParams, uri, skippedRanges);
@ -194,19 +194,19 @@ void MessageHandler::Run(InMessage &msg) {
try {
it->second(reader, reply);
} catch (std::invalid_argument &ex) {
lsResponseError err;
err.code = lsErrorCodes::InvalidParams;
ResponseError err;
err.code = ErrorCode::InvalidParams;
err.message = "invalid params of " + msg.method + ": " + ex.what();
reply.Error(err);
} catch (...) {
lsResponseError err;
err.code = lsErrorCodes::InternalError;
ResponseError err;
err.code = ErrorCode::InternalError;
err.message = "failed to process " + msg.method;
reply.Error(err);
}
} else {
lsResponseError err;
err.code = lsErrorCodes::MethodNotFound;
ResponseError err;
err.code = ErrorCode::MethodNotFound;
err.message = "unknown request " + msg.method;
reply.Error(err);
}
@ -246,12 +246,12 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply,
for (auto &[root, folder] : project->root2folder)
has_entry |= folder.path2entry_index.count(path);
}
lsResponseError err;
ResponseError err;
if (has_entry) {
err.code = lsErrorCodes::ServerNotInitialized;
err.code = ErrorCode::ServerNotInitialized;
err.message = path + " is being indexed";
} else {
err.code = lsErrorCodes::InternalError;
err.code = ErrorCode::InternalError;
err.message = "unable to find " + path;
}
reply.Error(err);
@ -262,7 +262,7 @@ QueryFile *MessageHandler::FindFile(ReplyOnce &reply,
void EmitSkippedRanges(WorkingFile *wfile, QueryFile &file) {
CclsSetSkippedRangesParams params;
params.uri = lsDocumentUri::FromPath(wfile->filename);
params.uri = DocumentUri::FromPath(wfile->filename);
for (Range skipped : file.def->skipped_ranges)
if (auto ls_skipped = GetLsRange(wfile, skipped))
params.skippedRanges.push_back(*ls_skipped);
@ -282,13 +282,13 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) {
for (auto [sym, refcnt] : file.symbol2refcnt) {
if (refcnt <= 0) continue;
std::string_view detailed_name;
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
lsSymbolKind kind = lsSymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
SymbolKind kind = SymbolKind::Unknown;
uint8_t storage = SC_None;
int idx;
// This switch statement also filters out symbols that are not highlighted.
switch (sym.kind) {
case SymbolKind::Func: {
case Kind::Func: {
idx = db->func_usr[sym.usr];
const QueryFunc &func = db->funcs[idx];
const QueryFunc::Def *def = func.AnyDef();
@ -322,7 +322,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) {
sym.range.end.column = start_col + concise_name.size();
break;
}
case SymbolKind::Type: {
case Kind::Type: {
idx = db->type_usr[sym.usr];
const QueryType &type = db->types[idx];
for (auto &def : type.def) {
@ -335,7 +335,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) {
}
break;
}
case SymbolKind::Var: {
case Kind::Var: {
idx = db->var_usr[sym.usr];
const QueryVar &var = db->vars[idx];
for (auto &def : var.def) {
@ -410,7 +410,7 @@ void EmitSemanticHighlight(DB *db, WorkingFile *wfile, QueryFile &file) {
}
CclsSemanticHighlightParams params;
params.uri = lsDocumentUri::FromPath(wfile->filename);
params.uri = DocumentUri::FromPath(wfile->filename);
// Transform lsRange into pair<int, int> (offset pairs)
if (!g_config->highlight.lsRanges) {
std::vector<std::pair<lsRange, CclsSemanticHighlightSymbol *>> scratch;

View File

@ -32,54 +32,54 @@ struct WorkingFile;
struct WorkingFiles;
namespace pipeline {
void Reply(lsRequestId id, const std::function<void(Writer &)> &fn);
void ReplyError(lsRequestId id, const std::function<void(Writer &)> &fn);
void Reply(RequestId id, const std::function<void(Writer &)> &fn);
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn);
}
struct EmptyParam {
bool placeholder;
};
struct TextDocumentParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
};
struct DidOpenTextDocumentParam {
lsTextDocumentItem textDocument;
TextDocumentItem textDocument;
};
struct TextDocumentPositionParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
lsPosition position;
};
struct RenameParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
lsPosition position;
std::string newName;
};
// code*
struct CodeActionParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
lsRange range;
struct Context {
std::vector<lsDiagnostic> diagnostics;
std::vector<Diagnostic> diagnostics;
} context;
};
// completion
enum class lsCompletionTriggerKind {
enum class CompletionTriggerKind {
Invoked = 1,
TriggerCharacter = 2,
TriggerForIncompleteCompletions = 3,
};
struct lsCompletionContext {
lsCompletionTriggerKind triggerKind = lsCompletionTriggerKind::Invoked;
struct CompletionContext {
CompletionTriggerKind triggerKind = CompletionTriggerKind::Invoked;
std::optional<std::string> triggerCharacter;
};
struct lsCompletionParams : TextDocumentPositionParam {
lsCompletionContext context;
struct CompletionParam : TextDocumentPositionParam {
CompletionContext context;
};
enum class lsCompletionItemKind {
enum class CompletionItemKind {
Text = 1,
Method = 2,
Function = 3,
@ -106,21 +106,21 @@ enum class lsCompletionItemKind {
Operator = 24,
TypeParameter = 25,
};
enum class lsInsertTextFormat {
enum class InsertTextFormat {
PlainText = 1,
Snippet = 2
};
struct lsCompletionItem {
struct CompletionItem {
std::string label;
lsCompletionItemKind kind = lsCompletionItemKind::Text;
CompletionItemKind kind = CompletionItemKind::Text;
std::string detail;
std::optional<std::string> documentation;
std::string sortText;
std::optional<std::string> filterText;
std::string insertText;
lsInsertTextFormat insertTextFormat = lsInsertTextFormat::PlainText;
lsTextEdit textEdit;
std::vector<lsTextEdit> additionalTextEdits;
InsertTextFormat insertTextFormat = InsertTextFormat::PlainText;
TextEdit textEdit;
std::vector<TextEdit> additionalTextEdits;
std::vector<std::string> parameters_;
int score_;
@ -134,17 +134,17 @@ struct FormattingOptions {
bool insertSpaces;
};
struct DocumentFormattingParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
FormattingOptions options;
};
struct DocumentOnTypeFormattingParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
lsPosition position;
std::string ch;
FormattingOptions options;
};
struct DocumentRangeFormattingParam {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
lsRange range;
FormattingOptions options;
};
@ -157,7 +157,7 @@ enum class FileChangeType {
};
struct DidChangeWatchedFilesParam {
struct Event {
lsDocumentUri uri;
DocumentUri uri;
FileChangeType type;
};
std::vector<Event> changes;
@ -179,7 +179,7 @@ template <typename Res>
using Callback = std::function<void(Res*)>;
struct ReplyOnce {
lsRequestId id;
RequestId id;
template <typename Res> void operator()(Res &result) const {
if (id.Valid())
pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); });
@ -229,7 +229,7 @@ private:
void shutdown(EmptyParam &, ReplyOnce &);
void textDocument_codeAction(CodeActionParam &, ReplyOnce &);
void textDocument_codeLens(TextDocumentParam &, ReplyOnce &);
void textDocument_completion(lsCompletionParams &, ReplyOnce &);
void textDocument_completion(CompletionParam &, ReplyOnce &);
void textDocument_definition(TextDocumentPositionParam &, ReplyOnce &);
void textDocument_didChange(TextDocumentDidChangeParam &);
void textDocument_didClose(TextDocumentParam &);

View File

@ -47,7 +47,7 @@ struct Out_cclsCall {
Usr usr;
std::string id;
std::string_view name;
lsLocation location;
Location location;
CallType callType = CallType::Direct;
int numChildren;
// Empty if the |levels| limit is reached.
@ -85,15 +85,14 @@ bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee,
if (callee) {
if (const auto *def = func.AnyDef())
for (SymbolRef sym : def->callees)
if (sym.kind == SymbolKind::Func)
if (sym.kind == Kind::Func)
handle(sym, def->file_id, call_type);
} else {
for (Use use : func.uses) {
const QueryFile &file1 = m->db->files[use.file_id];
Maybe<ExtentRef> best;
for (auto [sym, refcnt] : file1.symbol2refcnt)
if (refcnt > 0 && sym.extent.Valid() &&
sym.kind == SymbolKind::Func &&
if (refcnt > 0 && sym.extent.Valid() && sym.kind == Kind::Func &&
sym.extent.start <= use.range.start &&
use.range.end <= sym.extent.end &&
(!best || best->extent.start < sym.extent.start))
@ -195,7 +194,7 @@ void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) {
WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path);
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, param.position)) {
if (sym.kind == SymbolKind::Func) {
if (sym.kind == Kind::Func) {
result = BuildInitial(this, sym.usr, param.callee, param.callType,
param.qualified, param.levels);
break;

View File

@ -15,7 +15,7 @@ struct Param : TextDocumentPositionParam {
// should be specified for building the root and |levels| of nodes below.
Usr usr;
std::string id;
SymbolKind kind = SymbolKind::Invalid;
Kind kind = Kind::Invalid;
// true: derived classes/functions; false: base classes/functions
bool derived = false;
@ -30,9 +30,9 @@ MAKE_REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified,
struct Out_cclsInheritance {
Usr usr;
std::string id;
SymbolKind kind;
Kind kind;
std::string_view name;
lsLocation location;
Location location;
// For unexpanded nodes, this is an upper bound because some entities may be
// undefined. If it is 0, there are no members.
int numChildren;
@ -99,7 +99,7 @@ bool ExpandHelper(MessageHandler *m, Out_cclsInheritance *entry, bool derived,
bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived,
bool qualified, int levels) {
if (entry->kind == SymbolKind::Func)
if (entry->kind == Kind::Func)
return ExpandHelper(m, entry, derived, qualified, levels,
m->db->Func(entry->usr));
else
@ -129,10 +129,9 @@ void Inheritance(MessageHandler *m, Param &param, ReplyOnce &reply) {
result->id = std::to_string(param.usr);
result->usr = param.usr;
result->kind = param.kind;
if (!(((param.kind == SymbolKind::Func && m->db->HasFunc(param.usr)) ||
(param.kind == SymbolKind::Type && m->db->HasType(param.usr))) &&
Expand(m, &*result, param.derived, param.qualified,
param.levels)))
if (!(((param.kind == Kind::Func && m->db->HasFunc(param.usr)) ||
(param.kind == Kind::Type && m->db->HasType(param.usr))) &&
Expand(m, &*result, param.derived, param.qualified, param.levels)))
result.reset();
} else {
QueryFile *file = m->FindFile(reply, param.textDocument.uri.GetPath());
@ -141,7 +140,7 @@ void Inheritance(MessageHandler *m, Param &param, ReplyOnce &reply) {
WorkingFile *wfile = m->wfiles->GetFileByFilename(file->def->path);
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position))
if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) {
if (sym.kind == Kind::Func || sym.kind == Kind::Type) {
result = BuildInitial(m, sym, param.derived, param.qualified,
param.levels);
break;

View File

@ -24,9 +24,9 @@ struct Param : TextDocumentPositionParam {
bool qualified = false;
int levels = 1;
// If SymbolKind::Func and the point is at a type, list member functions
// instead of member variables.
SymbolKind kind = SymbolKind::Var;
// If Kind::Func and the point is at a type, list member functions instead of
// member variables.
Kind kind = Kind::Var;
bool hierarchy = false;
};
@ -38,7 +38,7 @@ struct Out_cclsMember {
std::string id;
std::string_view name;
std::string fieldName;
lsLocation location;
Location location;
// For unexpanded nodes, this is an upper bound because some entities may be
// undefined. If it is 0, there are no members.
int numChildren = 0;
@ -49,7 +49,7 @@ MAKE_REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren,
children);
bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
int levels, SymbolKind memberKind);
int levels, Kind memberKind);
// Add a field to |entry| which is a Func/Type.
void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var,
@ -77,14 +77,14 @@ void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var,
entry1.fieldName += def1->Name(false);
}
if (def1->spell) {
if (std::optional<lsLocation> loc =
if (std::optional<Location> loc =
GetLsLocation(m->db, m->wfiles, *def1->spell))
entry1.location = *loc;
}
if (def1->type) {
entry1.id = std::to_string(def1->type);
entry1.usr = def1->type;
if (Expand(m, &entry1, qualified, levels, SymbolKind::Var))
if (Expand(m, &entry1, qualified, levels, Kind::Var))
entry->children.push_back(std::move(entry1));
} else {
entry1.id = "0";
@ -95,7 +95,7 @@ void DoField(MessageHandler *m, Out_cclsMember *entry, const QueryVar &var,
// Expand a type node by adding members recursively to it.
bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
int levels, SymbolKind memberKind) {
int levels, Kind memberKind) {
if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) {
entry->name = ClangBuiltinTypeName(int(entry->usr));
return true;
@ -117,7 +117,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
const auto *def = type->AnyDef();
if (!def)
continue;
if (def->kind != lsSymbolKind::Namespace)
if (def->kind != SymbolKind::Namespace)
for (Usr usr : def->bases) {
auto &type1 = m->db->Type(usr);
if (type1.def.size()) {
@ -132,13 +132,13 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
entry1.usr = def->alias_of;
if (def1 && def1->spell) {
// The declaration of target type.
if (std::optional<lsLocation> loc =
if (std::optional<Location> loc =
GetLsLocation(m->db, m->wfiles, *def1->spell))
entry1.location = *loc;
} else if (def->spell) {
// Builtin types have no declaration but the typedef declaration
// itself is useful.
if (std::optional<lsLocation> loc =
if (std::optional<Location> loc =
GetLsLocation(m->db, m->wfiles, *def->spell))
entry1.location = *loc;
}
@ -150,7 +150,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
entry1.fieldName = std::string(entry1.name);
entry->children.push_back(std::move(entry1));
}
} else if (memberKind == SymbolKind::Func) {
} else if (memberKind == Kind::Func) {
llvm::DenseSet<Usr, DenseMapInfoForUsr> seen1;
for (auto &def : type->def)
for (Usr usr : def.funcs)
@ -170,7 +170,7 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
entry->children.push_back(std::move(entry1));
}
}
} else if (memberKind == SymbolKind::Type) {
} else if (memberKind == Kind::Type) {
llvm::DenseSet<Usr, DenseMapInfoForUsr> seen1;
for (auto &def : type->def)
for (Usr usr : def.types)
@ -207,13 +207,13 @@ bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
return true;
}
std::optional<Out_cclsMember> BuildInitial(MessageHandler *m, SymbolKind kind,
std::optional<Out_cclsMember> BuildInitial(MessageHandler *m, Kind kind,
Usr root_usr, bool qualified,
int levels, SymbolKind memberKind) {
int levels, Kind memberKind) {
switch (kind) {
default:
return {};
case SymbolKind::Func: {
case Kind::Func: {
const auto *def = m->db->Func(root_usr).AnyDef();
if (!def)
return {};
@ -232,7 +232,7 @@ std::optional<Out_cclsMember> BuildInitial(MessageHandler *m, SymbolKind kind,
}
return entry;
}
case SymbolKind::Type: {
case Kind::Type: {
const auto *def = m->db->Type(root_usr).AnyDef();
if (!def)
return {};
@ -276,15 +276,15 @@ void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) {
for (SymbolRef sym :
FindSymbolsAtLocation(wfile, file, param.position)) {
switch (sym.kind) {
case SymbolKind::Func:
case SymbolKind::Type:
case Kind::Func:
case Kind::Type:
result = BuildInitial(this, sym.kind, sym.usr, param.qualified,
param.levels, param.kind);
break;
case SymbolKind::Var: {
case Kind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef();
if (def && def->type)
result = BuildInitial(this, SymbolKind::Type, def->type, param.qualified,
result = BuildInitial(this, Kind::Type, def->type, param.qualified,
param.levels, param.kind);
break;
}

View File

@ -19,7 +19,7 @@ limitations under the License.
namespace ccls {
namespace {
struct Param {
lsTextDocumentIdentifier textDocument;
TextDocumentIdentifier textDocument;
lsPosition position;
std::string direction;
};
@ -95,10 +95,10 @@ void MessageHandler::ccls_navigate(Reader &reader,
res = sym.extent;
break;
}
std::vector<lsLocation> result;
std::vector<Location> result;
if (res)
if (auto ls_range = GetLsRange(wfile, *res)) {
lsLocation &ls_loc = result.emplace_back();
Location &ls_loc = result.emplace_back();
ls_loc.uri = param.textDocument.uri;
ls_loc.range = *ls_range;
}

View File

@ -28,7 +28,7 @@ void MessageHandler::ccls_reload(Reader &reader) {
if (param.whitelist.empty() && param.blacklist.empty()) {
vfs->Clear();
db->clear();
project->Index(wfiles, lsRequestId());
project->Index(wfiles, RequestId());
clang_complete->FlushAllSessions();
return;
}

View File

@ -24,21 +24,21 @@ void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) {
return;
WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path);
std::vector<lsLocation> result;
std::vector<Location> result;
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, param.position)) {
Usr usr = sym.usr;
switch (sym.kind) {
default:
break;
case SymbolKind::Var: {
case Kind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef();
if (!def || !def->type)
continue;
usr = def->type;
[[fallthrough]];
}
case SymbolKind::Type:
case Kind::Type:
result = GetLsLocations(
db, wfiles,
GetVarDeclarations(db, db->Type(usr).instances, param.kind));

View File

@ -26,18 +26,24 @@ using namespace llvm;
extern std::string g_init_options;
namespace {
enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 };
MAKE_REFLECT_TYPE_PROXY(TextDocumentSyncKind)
// Code Lens options.
struct lsCodeLensOptions {
// Code lens has a resolve provider as well.
bool resolveProvider = false;
struct ServerCap {
struct SaveOptions {
bool includeText = false;
};
MAKE_REFLECT_STRUCT(lsCodeLensOptions, resolveProvider);
struct TextDocumentSyncOptions {
bool openClose = true;
TextDocumentSyncKind change = TextDocumentSyncKind::Incremental;
bool willSave = false;
bool willSaveWaitUntil = false;
SaveOptions save;
} textDocumentSync;
// Completion options.
struct lsCompletionOptions {
// The server provides support to resolve additional
// information for a completion item.
// The server provides hover support.
bool hoverProvider = true;
struct CompletionOptions {
bool resolveProvider = false;
// The characters that trigger completion automatically.
@ -47,84 +53,10 @@ struct lsCompletionOptions {
// https://github.com/Microsoft/language-server-protocol/issues/138.
std::vector<std::string> triggerCharacters = {".", ":", ">", "#",
"<", "\"", "/"};
};
MAKE_REFLECT_STRUCT(lsCompletionOptions, resolveProvider, triggerCharacters);
// Format document on type options
struct lsDocumentOnTypeFormattingOptions {
// A character on which formatting should be triggered, like `}`.
std::string firstTriggerCharacter = "}";
// More trigger characters.
std::vector<std::string> moreTriggerCharacter;
};
MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter,
moreTriggerCharacter);
// Save options.
struct lsSaveOptions {
// The client is supposed to include the content on save.
bool includeText = false;
};
MAKE_REFLECT_STRUCT(lsSaveOptions, includeText);
// Signature help options.
struct lsSignatureHelpOptions {
// The characters that trigger signature help automatically.
// NOTE: If updating signature help tokens make sure to also update
// WorkingFile::FindClosestCallNameInBuffer.
} completionProvider;
struct SignatureHelpOptions {
std::vector<std::string> triggerCharacters = {"(", ","};
};
MAKE_REFLECT_STRUCT(lsSignatureHelpOptions, triggerCharacters);
// Defines how the host (editor) should sync document changes to the language
// server.
enum class lsTextDocumentSyncKind {
// Documents should not be synced at all.
None = 0,
// Documents are synced by always sending the full content
// of the document.
Full = 1,
// Documents are synced by sending the full content on open.
// After that only incremental updates to the document are
// send.
Incremental = 2
};
MAKE_REFLECT_TYPE_PROXY(lsTextDocumentSyncKind)
struct lsTextDocumentSyncOptions {
// Open and close notifications are sent to the server.
bool openClose = false;
// Change notificatins are sent to the server. See TextDocumentSyncKind.None,
// TextDocumentSyncKind.Full and TextDocumentSyncKindIncremental.
lsTextDocumentSyncKind change = lsTextDocumentSyncKind::Incremental;
// Will save notifications are sent to the server.
std::optional<bool> willSave;
// Will save wait until requests are sent to the server.
std::optional<bool> willSaveWaitUntil;
// Save notifications are sent to the server.
std::optional<lsSaveOptions> save;
};
MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, change, willSave,
willSaveWaitUntil, save);
struct lsServerCapabilities {
// Defines how text documents are synced. Is either a detailed structure
// defining each notification or for backwards compatibility the
// TextDocumentSyncKind number.
// TODO: It seems like the new API is broken and doesn't work.
// std::optional<lsTextDocumentSyncOptions> textDocumentSync;
lsTextDocumentSyncKind textDocumentSync = lsTextDocumentSyncKind::Incremental;
// The server provides hover support.
bool hoverProvider = true;
// The server provides completion support.
lsCompletionOptions completionProvider;
// The server provides signature help support.
lsSignatureHelpOptions signatureHelpProvider;
} signatureHelpProvider;
bool definitionProvider = true;
bool typeDefinitionProvider = true;
bool implementationProvider = true;
@ -133,10 +65,15 @@ struct lsServerCapabilities {
bool documentSymbolProvider = true;
bool workspaceSymbolProvider = true;
bool codeActionProvider = true;
lsCodeLensOptions codeLensProvider;
struct CodeLensOptions {
bool resolveProvider = false;
} codeLensProvider;
bool documentFormattingProvider = true;
bool documentRangeFormattingProvider = true;
lsDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
struct DocumentOnTypeFormattingOptions {
std::string firstTriggerCharacter = "}";
std::vector<std::string> moreTriggerCharacter;
} documentOnTypeFormattingProvider;
bool renameProvider = true;
struct DocumentLinkOptions {
bool resolveProvider = true;
@ -153,12 +90,21 @@ struct lsServerCapabilities {
} workspaceFolders;
} workspace;
};
MAKE_REFLECT_STRUCT(lsServerCapabilities::DocumentLinkOptions, resolveProvider);
MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands);
MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace::WorkspaceFolders,
supported, changeNotifications);
MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace, workspaceFolders);
MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider,
MAKE_REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider,
triggerCharacters);
MAKE_REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider);
MAKE_REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider);
MAKE_REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions,
firstTriggerCharacter, moreTriggerCharacter);
MAKE_REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands);
MAKE_REFLECT_STRUCT(ServerCap::SaveOptions, includeText);
MAKE_REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters);
MAKE_REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change,
willSave, willSaveWaitUntil, save);
MAKE_REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported,
changeNotifications);
MAKE_REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders);
MAKE_REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider,
completionProvider, signatureHelpProvider,
definitionProvider, implementationProvider,
typeDefinitionProvider, referencesProvider,
@ -170,72 +116,38 @@ MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider,
documentLinkProvider, foldingRangeProvider,
executeCommandProvider, workspace);
struct DynamicReg {
bool dynamicRegistration = false;
};
MAKE_REFLECT_STRUCT(DynamicReg, dynamicRegistration);
// Workspace specific client capabilities.
struct lsWorkspaceClientCapabilites {
struct WorkspaceClientCap {
// The client supports applying batch edits to the workspace.
std::optional<bool> applyEdit;
struct lsWorkspaceEdit {
struct WorkspaceEdit {
// The client supports versioned document changes in `WorkspaceEdit`s
std::optional<bool> documentChanges;
};
// Capabilities specific to `WorkspaceEdit`s
std::optional<lsWorkspaceEdit> workspaceEdit;
struct lsGenericDynamicReg {
// Did foo notification supports dynamic registration.
std::optional<bool> dynamicRegistration;
std::optional<WorkspaceEdit> workspaceEdit;
DynamicReg didChangeConfiguration;
DynamicReg didChangeWatchedFiles;
DynamicReg symbol;
DynamicReg executeCommand;
};
// Capabilities specific to the `workspace/didChangeConfiguration`
// notification.
std::optional<lsGenericDynamicReg> didChangeConfiguration;
// Capabilities specific to the `workspace/didChangeWatchedFiles`
// notification.
std::optional<lsGenericDynamicReg> didChangeWatchedFiles;
// Capabilities specific to the `workspace/symbol` request.
std::optional<lsGenericDynamicReg> symbol;
// Capabilities specific to the `workspace/executeCommand` request.
std::optional<lsGenericDynamicReg> executeCommand;
};
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit,
documentChanges);
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg,
dynamicRegistration);
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, applyEdit, workspaceEdit,
MAKE_REFLECT_STRUCT(WorkspaceClientCap::WorkspaceEdit, documentChanges);
MAKE_REFLECT_STRUCT(WorkspaceClientCap, applyEdit, workspaceEdit,
didChangeConfiguration, didChangeWatchedFiles, symbol,
executeCommand);
// Text document specific client capabilities.
struct lsTextDocumentClientCapabilities {
struct lsSynchronization {
// Whether text document synchronization supports dynamic registration.
std::optional<bool> dynamicRegistration;
// The client supports sending will save notifications.
std::optional<bool> willSave;
// The client supports sending a will save request and
// waits for a response providing text edits which will
// be applied to the document before it is saved.
std::optional<bool> willSaveWaitUntil;
// The client supports did save notifications.
std::optional<bool> didSave;
};
lsSynchronization synchronization;
struct lsCompletion {
// Whether completion supports dynamic registration.
std::optional<bool> dynamicRegistration;
struct lsCompletionItem {
struct TextDocumentClientCap {
struct Completion {
struct CompletionItem {
// Client supports snippets as insert text.
//
// A snippet can define tab stops and placeholders with `$1`, `$2`
@ -246,99 +158,65 @@ struct lsTextDocumentClientCapabilities {
} completionItem;
} completion;
struct lsDocumentSymbol {
struct DocumentSymbol {
bool hierarchicalDocumentSymbolSupport = false;
} documentSymbol;
struct lsGenericDynamicReg {
// Whether foo supports dynamic registration.
std::optional<bool> dynamicRegistration;
};
struct CodeLensRegistrationOptions : public lsGenericDynamicReg {
// Code lens has a resolve provider as well.
bool resolveProvider;
};
// Capabilities specific to the `textDocument/codeLens`
std::optional<CodeLensRegistrationOptions> codeLens;
// Capabilities specific to the `textDocument/rename`
std::optional<lsGenericDynamicReg> rename;
};
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization,
dynamicRegistration, willSave, willSaveWaitUntil, didSave);
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion,
dynamicRegistration, completionItem);
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsDocumentSymbol,
hierarchicalDocumentSymbolSupport);
MAKE_REFLECT_STRUCT(
lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem,
MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
snippetSupport);
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg,
dynamicRegistration);
MAKE_REFLECT_STRUCT(
lsTextDocumentClientCapabilities::CodeLensRegistrationOptions,
dynamicRegistration, resolveProvider);
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, completion,
documentSymbol, rename, synchronization);
MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem);
MAKE_REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
hierarchicalDocumentSymbolSupport);
MAKE_REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol);
struct lsClientCapabilities {
// Workspace specific client capabilities.
lsWorkspaceClientCapabilites workspace;
// Text document specific client capabilities.
lsTextDocumentClientCapabilities textDocument;
struct ClientCap {
WorkspaceClientCap workspace;
TextDocumentClientCap textDocument;
};
MAKE_REFLECT_STRUCT(lsClientCapabilities, workspace, textDocument);
MAKE_REFLECT_STRUCT(ClientCap, workspace, textDocument);
struct lsInitializeParams {
struct InitializeParam {
// The rootUri of the workspace. Is null if no
// folder is open. If both `rootPath` and `rootUri` are set
// `rootUri` wins.
std::optional<lsDocumentUri> rootUri;
std::optional<DocumentUri> rootUri;
// User provided initialization options.
Config initializationOptions;
ClientCap capabilities;
// The capabilities provided by the client (editor or tool)
lsClientCapabilities capabilities;
enum class lsTrace {
enum class Trace {
// NOTE: serialized as a string, one of 'off' | 'messages' | 'verbose';
Off, // off
Messages, // messages
Verbose // verbose
};
// The initial trace setting. If omitted trace is disabled ('off').
lsTrace trace = lsTrace::Off;
Trace trace = Trace::Off;
std::vector<WorkspaceFolder> workspaceFolders;
};
void Reflect(Reader &reader, lsInitializeParams::lsTrace &value) {
void Reflect(Reader &reader, InitializeParam::Trace &value) {
if (!reader.IsString()) {
value = lsInitializeParams::lsTrace::Off;
value = InitializeParam::Trace::Off;
return;
}
std::string v = reader.GetString();
if (v == "off")
value = lsInitializeParams::lsTrace::Off;
value = InitializeParam::Trace::Off;
else if (v == "messages")
value = lsInitializeParams::lsTrace::Messages;
value = InitializeParam::Trace::Messages;
else if (v == "verbose")
value = lsInitializeParams::lsTrace::Verbose;
value = InitializeParam::Trace::Verbose;
}
MAKE_REFLECT_STRUCT(lsInitializeParams, rootUri, initializationOptions,
MAKE_REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions,
capabilities, trace, workspaceFolders);
struct lsInitializeResult {
lsServerCapabilities capabilities;
struct InitializeResult {
ServerCap capabilities;
};
MAKE_REFLECT_STRUCT(lsInitializeResult, capabilities);
MAKE_REFLECT_STRUCT(InitializeResult, capabilities);
void *Indexer(void *arg_) {
MessageHandler *h;
@ -353,7 +231,7 @@ void *Indexer(void *arg_) {
}
} // namespace
void Initialize(MessageHandler *m, lsInitializeParams &param, ReplyOnce &reply) {
void Initialize(MessageHandler *m, InitializeParam &param, ReplyOnce &reply) {
std::string project_path = NormalizePath(param.rootUri->GetPath());
LOG_S(INFO) << "initialize in directory " << project_path << " with uri "
<< param.rootUri->raw_uri;
@ -401,7 +279,7 @@ void Initialize(MessageHandler *m, lsInitializeParams &param, ReplyOnce &reply)
// Send initialization before starting indexers, so we don't send a
// status update too early.
{
lsInitializeResult result;
InitializeResult result;
reply(result);
}
@ -448,7 +326,7 @@ void Initialize(MessageHandler *m, lsInitializeParams &param, ReplyOnce &reply)
}
void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) {
lsInitializeParams param;
InitializeParam param;
Reflect(reader, param);
if (!param.rootUri)
return;
@ -456,8 +334,8 @@ void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) {
}
void StandaloneInitialize(MessageHandler &handler, const std::string &root) {
lsInitializeParams param;
param.rootUri = lsDocumentUri::FromPath(root);
InitializeParam param;
param.rootUri = DocumentUri::FromPath(root);
ReplyOnce reply;
Initialize(&handler, param, reply);
}

View File

@ -27,7 +27,7 @@ namespace {
struct CodeAction {
std::string title;
const char *kind = "quickfix";
lsWorkspaceEdit edit;
WorkspaceEdit edit;
};
MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit);
}
@ -39,9 +39,9 @@ void MessageHandler::textDocument_codeAction(CodeActionParam &param,
return;
}
std::vector<CodeAction> result;
std::vector<lsDiagnostic> diagnostics;
std::vector<Diagnostic> diagnostics;
wfiles->DoAction([&]() { diagnostics = wfile->diagnostics_; });
for (lsDiagnostic &diag : diagnostics)
for (Diagnostic &diag : diagnostics)
if (diag.fixits_.size()) {
CodeAction &cmd = result.emplace_back();
cmd.title = "FixIt: " + diag.message;
@ -56,21 +56,21 @@ void MessageHandler::textDocument_codeAction(CodeActionParam &param,
namespace {
struct Cmd_xref {
Usr usr;
SymbolKind kind;
Kind kind;
std::string field;
};
struct lsCommand {
struct Command {
std::string title;
std::string command;
std::vector<std::string> arguments;
};
struct lsCodeLens {
struct CodeLens {
lsRange range;
std::optional<lsCommand> command;
std::optional<Command> command;
};
MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field);
MAKE_REFLECT_STRUCT(lsCommand, title, command, arguments);
MAKE_REFLECT_STRUCT(lsCodeLens, range, command);
MAKE_REFLECT_STRUCT(Command, title, command, arguments);
MAKE_REFLECT_STRUCT(CodeLens, range, command);
template <typename T>
std::string ToString(T &v) {
@ -82,7 +82,7 @@ std::string ToString(T &v) {
}
struct CommonCodeLensParams {
std::vector<lsCodeLens> *result;
std::vector<CodeLens> *result;
DB *db;
WorkingFile *wfile;
};
@ -90,7 +90,7 @@ struct CommonCodeLensParams {
void MessageHandler::textDocument_codeLens(TextDocumentParam &param,
ReplyOnce &reply) {
std::vector<lsCodeLens> result;
std::vector<CodeLens> result;
std::string path = param.textDocument.uri.GetPath();
QueryFile *file = FindFile(reply, path);
@ -107,9 +107,9 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam &param,
std::optional<lsRange> ls_range = GetLsRange(wfile, range);
if (!ls_range)
return;
lsCodeLens &code_lens = result.emplace_back();
CodeLens &code_lens = result.emplace_back();
code_lens.range = *ls_range;
code_lens.command = lsCommand();
code_lens.command = Command();
code_lens.command->command = std::string(ccls_xref);
bool plural = num > 1 && singular[strlen(singular) - 1] != 'd';
code_lens.command->title =
@ -122,49 +122,49 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam &param,
if (refcnt <= 0 || !sym.extent.Valid() || !seen.insert(sym.range).second)
continue;
switch (sym.kind) {
case SymbolKind::Func: {
case Kind::Func: {
QueryFunc &func = db->GetFunc(sym);
const QueryFunc::Def *def = func.AnyDef();
if (!def)
continue;
std::vector<Use> base_uses = GetUsesForAllBases(db, func);
std::vector<Use> derived_uses = GetUsesForAllDerived(db, func);
Add("ref", {sym.usr, SymbolKind::Func, "uses"}, sym.range,
func.uses.size(), base_uses.empty());
Add("ref", {sym.usr, Kind::Func, "uses"}, sym.range, func.uses.size(),
base_uses.empty());
if (base_uses.size())
Add("b.ref", {sym.usr, SymbolKind::Func, "bases uses"}, sym.range,
Add("b.ref", {sym.usr, Kind::Func, "bases uses"}, sym.range,
base_uses.size());
if (derived_uses.size())
Add("d.ref", {sym.usr, SymbolKind::Func, "derived uses"}, sym.range,
Add("d.ref", {sym.usr, Kind::Func, "derived uses"}, sym.range,
derived_uses.size());
if (base_uses.empty())
Add("base", {sym.usr, SymbolKind::Func, "bases"}, sym.range,
Add("base", {sym.usr, Kind::Func, "bases"}, sym.range,
def->bases.size());
Add("derived", {sym.usr, SymbolKind::Func, "derived"}, sym.range,
Add("derived", {sym.usr, Kind::Func, "derived"}, sym.range,
func.derived.size());
break;
}
case SymbolKind::Type: {
case Kind::Type: {
QueryType &type = db->GetType(sym);
Add("ref", {sym.usr, SymbolKind::Type, "uses"}, sym.range,
type.uses.size(), true);
Add("derived", {sym.usr, SymbolKind::Type, "derived"}, sym.range,
Add("ref", {sym.usr, Kind::Type, "uses"}, sym.range, type.uses.size(),
true);
Add("derived", {sym.usr, Kind::Type, "derived"}, sym.range,
type.derived.size());
Add("var", {sym.usr, SymbolKind::Type, "instances"}, sym.range,
Add("var", {sym.usr, Kind::Type, "instances"}, sym.range,
type.instances.size());
break;
}
case SymbolKind::Var: {
case Kind::Var: {
QueryVar &var = db->GetVar(sym);
const QueryVar::Def *def = var.AnyDef();
if (!def || (def->is_local() && !g_config->codeLens.localVariables))
continue;
Add("ref", {sym.usr, SymbolKind::Var, "uses"}, sym.range, var.uses.size(),
def->kind != lsSymbolKind::Macro);
Add("ref", {sym.usr, Kind::Var, "uses"}, sym.range, var.uses.size(),
def->kind != SymbolKind::Macro);
break;
}
case SymbolKind::File:
case SymbolKind::Invalid:
case Kind::File:
case Kind::Invalid:
llvm_unreachable("");
};
}
@ -174,7 +174,7 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam &param,
void MessageHandler::workspace_executeCommand(Reader &reader,
ReplyOnce &reply) {
lsCommand param;
Command param;
Reflect(reader, param);
if (param.arguments.empty()) {
return;
@ -185,14 +185,14 @@ void MessageHandler::workspace_executeCommand(Reader &reader,
if (param.command == ccls_xref) {
Cmd_xref cmd;
Reflect(json_reader, cmd);
std::vector<lsLocation> result;
std::vector<Location> result;
auto Map = [&](auto &&uses) {
for (auto &use : uses)
if (auto loc = GetLsLocation(db, wfiles, use))
result.push_back(std::move(*loc));
};
switch (cmd.kind) {
case SymbolKind::Func: {
case Kind::Func: {
QueryFunc &func = db->Func(cmd.usr);
if (cmd.field == "bases") {
if (auto *def = func.AnyDef())
@ -208,7 +208,7 @@ void MessageHandler::workspace_executeCommand(Reader &reader,
}
break;
}
case SymbolKind::Type: {
case Kind::Type: {
QueryType &type = db->Type(cmd.usr);
if (cmd.field == "derived") {
Map(GetTypeDeclarations(db, type.derived));
@ -219,7 +219,7 @@ void MessageHandler::workspace_executeCommand(Reader &reader,
}
break;
}
case SymbolKind::Var: {
case Kind::Var: {
QueryVar &var = db->Var(cmd.usr);
if (cmd.field == "uses")
Map(var.uses);

View File

@ -18,21 +18,21 @@ namespace ccls {
using namespace clang;
using namespace llvm;
struct lsCompletionList {
bool isIncomplete = false;
std::vector<lsCompletionItem> items;
};
MAKE_REFLECT_TYPE_PROXY(lsInsertTextFormat);
MAKE_REFLECT_TYPE_PROXY(lsCompletionItemKind);
MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation,
MAKE_REFLECT_TYPE_PROXY(InsertTextFormat);
MAKE_REFLECT_TYPE_PROXY(CompletionItemKind);
MAKE_REFLECT_STRUCT(CompletionItem, label, kind, detail, documentation,
sortText, filterText, insertText, insertTextFormat,
textEdit, additionalTextEdits);
MAKE_REFLECT_STRUCT(lsCompletionList, isIncomplete, items);
namespace {
struct CompletionList {
bool isIncomplete = false;
std::vector<CompletionItem> items;
};
MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items);
void DecorateIncludePaths(const std::smatch &match,
std::vector<lsCompletionItem> *items) {
std::vector<CompletionItem> *items) {
std::string spaces_after_include = " ";
if (match[3].compare("include") == 0 && match[5].length())
spaces_after_include = match[4].str();
@ -41,7 +41,7 @@ void DecorateIncludePaths(const std::smatch &match,
match[1].str() + '#' + match[2].str() + "include" + spaces_after_include;
std::string suffix = match[7].str();
for (lsCompletionItem &item : *items) {
for (CompletionItem &item : *items) {
char quote0, quote1;
if (match[5].compare("<") == 0 ||
(match[5].length() == 0 && item.use_angle_brackets_))
@ -82,9 +82,9 @@ ParseIncludeLineResult ParseIncludeLine(const std::string &line) {
// Pre-filters completion responses before sending to vscode. This results in a
// significantly snappier completion experience as vscode is easily overloaded
// when given 1000+ completion items.
void FilterCandidates(lsCompletionList &result,
const std::string &complete_text, lsPosition begin_pos,
lsPosition end_pos, const std::string &buffer_line) {
void FilterCandidates(CompletionList &result, const std::string &complete_text,
lsPosition begin_pos, lsPosition end_pos,
const std::string &buffer_line) {
assert(begin_pos.line == end_pos.line);
auto &items = result.items;
@ -155,12 +155,12 @@ void FilterCandidates(lsCompletionList &result,
: FuzzyMatcher::kMinScore;
}
items.erase(std::remove_if(items.begin(), items.end(),
[](const lsCompletionItem &item) {
[](const CompletionItem &item) {
return item.score_ <= FuzzyMatcher::kMinScore;
}),
items.end());
std::sort(items.begin(), items.end(),
[](const lsCompletionItem &lhs, const lsCompletionItem &rhs) {
[](const CompletionItem &lhs, const CompletionItem &rhs) {
int t = int(lhs.additionalTextEdits.size() -
rhs.additionalTextEdits.size());
if (t)
@ -178,45 +178,45 @@ void FilterCandidates(lsCompletionList &result,
finalize();
}
lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) {
CompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) {
switch (cursor_kind) {
case CXCursor_UnexposedDecl:
return lsCompletionItemKind::Text;
return CompletionItemKind::Text;
case CXCursor_StructDecl:
case CXCursor_UnionDecl:
return lsCompletionItemKind::Struct;
return CompletionItemKind::Struct;
case CXCursor_ClassDecl:
return lsCompletionItemKind::Class;
return CompletionItemKind::Class;
case CXCursor_EnumDecl:
return lsCompletionItemKind::Enum;
return CompletionItemKind::Enum;
case CXCursor_FieldDecl:
return lsCompletionItemKind::Field;
return CompletionItemKind::Field;
case CXCursor_EnumConstantDecl:
return lsCompletionItemKind::EnumMember;
return CompletionItemKind::EnumMember;
case CXCursor_FunctionDecl:
return lsCompletionItemKind::Function;
return CompletionItemKind::Function;
case CXCursor_VarDecl:
case CXCursor_ParmDecl:
return lsCompletionItemKind::Variable;
return CompletionItemKind::Variable;
case CXCursor_ObjCInterfaceDecl:
return lsCompletionItemKind::Interface;
return CompletionItemKind::Interface;
case CXCursor_ObjCInstanceMethodDecl:
case CXCursor_CXXMethod:
case CXCursor_ObjCClassMethodDecl:
return lsCompletionItemKind::Method;
return CompletionItemKind::Method;
case CXCursor_FunctionTemplate:
return lsCompletionItemKind::Function;
return CompletionItemKind::Function;
case CXCursor_Constructor:
case CXCursor_Destructor:
case CXCursor_ConversionFunction:
return lsCompletionItemKind::Constructor;
return CompletionItemKind::Constructor;
case CXCursor_ObjCIvarDecl:
return lsCompletionItemKind::Variable;
return CompletionItemKind::Variable;
case CXCursor_ClassTemplate:
case CXCursor_ClassTemplatePartialSpecialization:
@ -228,50 +228,43 @@ lsCompletionItemKind GetCompletionKind(CXCursorKind cursor_kind) {
case CXCursor_ObjCProtocolDecl:
case CXCursor_ObjCImplementationDecl:
case CXCursor_ObjCCategoryImplDecl:
return lsCompletionItemKind::Class;
return CompletionItemKind::Class;
case CXCursor_ObjCPropertyDecl:
return lsCompletionItemKind::Property;
return CompletionItemKind::Property;
case CXCursor_MacroInstantiation:
case CXCursor_MacroDefinition:
return lsCompletionItemKind::Interface;
return CompletionItemKind::Interface;
case CXCursor_Namespace:
case CXCursor_NamespaceAlias:
case CXCursor_NamespaceRef:
return lsCompletionItemKind::Module;
return CompletionItemKind::Module;
case CXCursor_MemberRef:
case CXCursor_TypeRef:
case CXCursor_ObjCSuperClassRef:
case CXCursor_ObjCProtocolRef:
case CXCursor_ObjCClassRef:
return lsCompletionItemKind::Reference;
// return lsCompletionItemKind::Unit;
// return lsCompletionItemKind::Value;
// return lsCompletionItemKind::Keyword;
// return lsCompletionItemKind::Snippet;
// return lsCompletionItemKind::Color;
// return lsCompletionItemKind::File;
return CompletionItemKind::Reference;
case CXCursor_NotImplemented:
case CXCursor_OverloadCandidate:
return lsCompletionItemKind::Text;
return CompletionItemKind::Text;
case CXCursor_TemplateTypeParameter:
case CXCursor_TemplateTemplateParameter:
return lsCompletionItemKind::TypeParameter;
return CompletionItemKind::TypeParameter;
default:
LOG_S(WARNING) << "Unhandled completion kind " << cursor_kind;
return lsCompletionItemKind::Text;
return CompletionItemKind::Text;
}
}
void BuildItem(const CodeCompletionResult &R, const CodeCompletionString &CCS,
std::vector<lsCompletionItem> &out) {
std::vector<CompletionItem> &out) {
assert(!out.empty());
auto first = out.size() - 1;
bool ignore = false;
@ -330,7 +323,7 @@ void BuildItem(const CodeCompletionResult &R, const CodeCompletionString &CCS,
}
out[i].textEdit.newText +=
"${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}";
out[i].insertTextFormat = lsInsertTextFormat::Snippet;
out[i].insertTextFormat = InsertTextFormat::Snippet;
} else if (Kind != CodeCompletionString::CK_Informative) {
out[i].textEdit.newText += text;
}
@ -352,7 +345,7 @@ class CompletionConsumer : public CodeCompleteConsumer {
public:
bool from_cache;
std::vector<lsCompletionItem> ls_items;
std::vector<CompletionItem> ls_items;
CompletionConsumer(const CodeCompleteOptions &Opts, bool from_cache)
: CodeCompleteConsumer(Opts, false),
@ -384,7 +377,7 @@ public:
CodeCompletionString *CCS = R.CreateCodeCompletionString(
S, Context, getAllocator(), getCodeCompletionTUInfo(),
includeBriefComments());
lsCompletionItem ls_item;
CompletionItem ls_item;
ls_item.kind = GetCompletionKind(R.CursorKind);
if (const char *brief = CCS->getBriefComment())
ls_item.documentation = brief;
@ -396,7 +389,7 @@ public:
for (size_t j = first_idx; j < ls_items.size(); j++) {
if (g_config->client.snippetSupport &&
ls_items[j].insertTextFormat == lsInsertTextFormat::Snippet)
ls_items[j].insertTextFormat == InsertTextFormat::Snippet)
ls_items[j].textEdit.newText += "$0";
ls_items[j].priority_ = CCS->getPriority();
if (!g_config->completion.detailedLabel) {
@ -407,7 +400,7 @@ public:
#if LLVM_VERSION_MAJOR >= 7
for (const FixItHint &FixIt : R.FixIts) {
auto &AST = S.getASTContext();
lsTextEdit ls_edit =
TextEdit ls_edit =
ccls::ToTextEdit(AST.getSourceManager(), AST.getLangOpts(), FixIt);
for (size_t j = first_idx; j < ls_items.size(); j++)
ls_items[j].additionalTextEdits.push_back(ls_edit);
@ -421,10 +414,10 @@ public:
};
} // namespace
void MessageHandler::textDocument_completion(lsCompletionParams &param,
void MessageHandler::textDocument_completion(CompletionParam &param,
ReplyOnce &reply) {
static CompleteConsumerCache<std::vector<lsCompletionItem>> cache;
lsCompletionList result;
static CompleteConsumerCache<std::vector<CompletionItem>> cache;
CompletionList result;
std::string path = param.textDocument.uri.GetPath();
WorkingFile *file = wfiles->GetFileByFilename(path);
if (!file) {
@ -440,7 +433,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams &param,
// Check for - and : before completing -> or ::, since vscode does not
// support multi-character trigger characters.
if (param.context.triggerKind == lsCompletionTriggerKind::TriggerCharacter &&
if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter &&
param.context.triggerCharacter) {
bool did_fail_check = false;
@ -484,7 +477,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams &param,
ParseIncludeLineResult preprocess = ParseIncludeLine(buffer_line);
if (preprocess.ok && preprocess.keyword.compare("include") == 0) {
lsCompletionList result;
CompletionList result;
{
std::unique_lock<std::mutex> lock(
include_complete->completion_items_mutex, std::defer_lock);
@ -509,7 +502,7 @@ void MessageHandler::textDocument_completion(lsCompletionParams &param,
if (!OptConsumer)
return;
auto *Consumer = static_cast<CompletionConsumer *>(OptConsumer);
lsCompletionList result;
CompletionList result;
result.items = Consumer->ls_items;
FilterCandidates(result, completion_text, begin_pos, end_pos,

View File

@ -12,14 +12,14 @@ namespace ccls {
namespace {
std::vector<DeclRef> GetNonDefDeclarationTargets(DB *db, SymbolRef sym) {
switch (sym.kind) {
case SymbolKind::Var: {
case Kind::Var: {
std::vector<DeclRef> ret = GetNonDefDeclarations(db, sym);
// If there is no declaration, jump to its type.
if (ret.empty()) {
for (auto &def : db->GetVar(sym).def)
if (def.type) {
if (Maybe<DeclRef> use = GetDefinitionSpell(
db, SymbolIdx{def.type, SymbolKind::Type})) {
if (Maybe<DeclRef> use =
GetDefinitionSpell(db, SymbolIdx{def.type, Kind::Type})) {
ret.push_back(*use);
break;
}
@ -40,7 +40,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam &param,
if (!file)
return;
std::vector<lsLocation> result;
std::vector<Location> result;
Maybe<Use> on_def;
WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path);
lsPosition &ls_pos = param.position;
@ -88,7 +88,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam &param,
for (const IndexInclude &include : file->def->includes) {
if (include.line == ls_pos.line) {
result.push_back(
lsLocation{lsDocumentUri::FromPath(include.resolved_path)});
Location{DocumentUri::FromPath(include.resolved_path)});
range = {{0, 0}, {0, 0}};
break;
}
@ -110,7 +110,7 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam &param,
// not in the same file, line distance> to find the best match.
std::tuple<int, int, bool, int> best_score{INT_MAX, 0, true, 0};
SymbolIdx best_sym;
best_sym.kind = SymbolKind::Invalid;
best_sym.kind = Kind::Invalid;
auto fn = [&](SymbolIdx sym) {
std::string_view short_name = db->GetSymbolName(sym, false),
name = short_query.size() < query.size()
@ -136,14 +136,14 @@ void MessageHandler::textDocument_definition(TextDocumentPositionParam &param,
}
};
for (auto &func : db->funcs)
fn({func.usr, SymbolKind::Func});
fn({func.usr, Kind::Func});
for (auto &type : db->types)
fn({type.usr, SymbolKind::Type});
fn({type.usr, Kind::Type});
for (auto &var : db->vars)
if (var.def.size() && !var.def[0].is_local())
fn({var.usr, SymbolKind::Var});
fn({var.usr, Kind::Var});
if (best_sym.kind != SymbolKind::Invalid) {
if (best_sym.kind != Kind::Invalid) {
Maybe<DeclRef> dr = GetDefinitionSpell(db, best_sym);
assert(dr);
if (auto loc = GetLsLocation(db, wfiles, *dr))
@ -162,7 +162,7 @@ void MessageHandler::textDocument_typeDefinition(
return;
WorkingFile *working_file = wfiles->GetFileByFilename(file->def->path);
std::vector<lsLocation> result;
std::vector<Location> result;
auto Add = [&](const QueryType &type) {
for (const auto &def : type.def)
if (def.spell) {
@ -177,13 +177,13 @@ void MessageHandler::textDocument_typeDefinition(
for (SymbolRef sym :
FindSymbolsAtLocation(working_file, file, param.position)) {
switch (sym.kind) {
case SymbolKind::Var: {
case Kind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef();
if (def && def->type)
Add(db->Type(def->type));
break;
}
case SymbolKind::Type: {
case Kind::Type: {
for (auto &def : db->GetType(sym).def)
if (def.alias_of) {
Add(db->Type(def.alias_of));

View File

@ -10,7 +10,7 @@
MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind);
namespace ccls {
MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName);
MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName);
namespace {
struct DocumentHighlight {
@ -45,7 +45,7 @@ void MessageHandler::textDocument_documentHighlight(
if (refcnt <= 0)
continue;
Usr usr = sym.usr;
SymbolKind kind = sym.kind;
Kind kind = sym.kind;
if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) {
return usr == sym1.usr && kind == sym1.kind;
}))
@ -68,11 +68,11 @@ void MessageHandler::textDocument_documentHighlight(
}
namespace {
struct lsDocumentLink {
struct DocumentLink {
lsRange range;
lsDocumentUri target;
DocumentUri target;
};
MAKE_REFLECT_STRUCT(lsDocumentLink, range, target);
MAKE_REFLECT_STRUCT(DocumentLink, range, target);
} // namespace
void MessageHandler::textDocument_documentLink(TextDocumentParam &param,
@ -81,10 +81,10 @@ void MessageHandler::textDocument_documentLink(TextDocumentParam &param,
if (!file)
return;
std::vector<lsDocumentLink> result;
std::vector<DocumentLink> result;
for (const IndexInclude &include : file->def->includes)
result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}},
lsDocumentUri::FromPath(include.resolved_path)});
DocumentUri::FromPath(include.resolved_path)});
reply(result);
} // namespace ccls
@ -98,18 +98,18 @@ struct DocumentSymbolParam : TextDocumentParam {
};
MAKE_REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine);
struct lsDocumentSymbol {
struct DocumentSymbol {
std::string name;
std::string detail;
lsSymbolKind kind;
SymbolKind kind;
lsRange range;
lsRange selectionRange;
std::vector<std::unique_ptr<lsDocumentSymbol>> children;
std::vector<std::unique_ptr<DocumentSymbol>> children;
};
void Reflect(Writer &vis, std::unique_ptr<lsDocumentSymbol> &v);
MAKE_REFLECT_STRUCT(lsDocumentSymbol, name, detail, kind, range, selectionRange,
void Reflect(Writer &vis, std::unique_ptr<DocumentSymbol> &v);
MAKE_REFLECT_STRUCT(DocumentSymbol, name, detail, kind, range, selectionRange,
children);
void Reflect(Writer &vis, std::unique_ptr<lsDocumentSymbol> &v) {
void Reflect(Writer &vis, std::unique_ptr<DocumentSymbol> &v) {
Reflect(vis, *v);
}
@ -119,7 +119,7 @@ bool Ignore(const Def *def) {
}
template <>
bool Ignore(const QueryType::Def *def) {
return !def || def->kind == lsSymbolKind::TypeParameter;
return !def || def->kind == SymbolKind::TypeParameter;
}
template<>
bool Ignore(const QueryVar::Def *def) {
@ -151,8 +151,8 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
std::sort(result.begin(), result.end());
reply(result);
} else if (g_config->client.hierarchicalDocumentSymbolSupport) {
std::unordered_map<SymbolIdx, std::unique_ptr<lsDocumentSymbol>> sym2ds;
std::vector<std::pair<std::vector<const void *>, lsDocumentSymbol *>> funcs,
std::unordered_map<SymbolIdx, std::unique_ptr<DocumentSymbol>> sym2ds;
std::vector<std::pair<std::vector<const void *>, DocumentSymbol *>> funcs,
types;
for (auto [sym, refcnt] : file->symbol2refcnt) {
if (refcnt <= 0 || !sym.extent.Valid())
@ -161,7 +161,7 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
if (!r.second)
continue;
auto &ds = r.first->second;
ds = std::make_unique<lsDocumentSymbol>();
ds = std::make_unique<DocumentSymbol>();
std::vector<const void *> def_ptrs;
WithEntity(db, sym, [&, sym = sym](const auto &entity) {
auto *def = entity.AnyDef();
@ -180,25 +180,25 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
for (auto &def : entity.def)
if (def.file_id == file_id && !Ignore(&def)) {
ds->kind = def.kind;
if (def.spell || def.kind == lsSymbolKind::Namespace)
if (def.spell || def.kind == SymbolKind::Namespace)
def_ptrs.push_back(&def);
}
});
if (def_ptrs.empty() || !(param.all || sym.role & Role::Definition ||
ds->kind == lsSymbolKind::Namespace)) {
ds->kind == SymbolKind::Namespace)) {
ds.reset();
continue;
}
if (sym.kind == SymbolKind::Func)
if (sym.kind == Kind::Func)
funcs.emplace_back(std::move(def_ptrs), ds.get());
else if (sym.kind == SymbolKind::Type)
else if (sym.kind == Kind::Type)
types.emplace_back(std::move(def_ptrs), ds.get());
}
for (auto &[def_ptrs, ds] : funcs)
for (const void *def_ptr : def_ptrs)
for (Usr usr1 : ((const QueryFunc::Def *)def_ptr)->vars) {
auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var});
auto it = sym2ds.find(SymbolIdx{usr1, Kind::Var});
if (it != sym2ds.end() && it->second)
ds->children.push_back(std::move(it->second));
}
@ -206,37 +206,36 @@ void MessageHandler::textDocument_documentSymbol(Reader &reader,
for (const void *def_ptr : def_ptrs) {
auto *def = (const QueryType::Def *)def_ptr;
for (Usr usr1 : def->funcs) {
auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Func});
auto it = sym2ds.find(SymbolIdx{usr1, Kind::Func});
if (it != sym2ds.end() && it->second)
ds->children.push_back(std::move(it->second));
}
for (Usr usr1 : def->types) {
auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Type});
auto it = sym2ds.find(SymbolIdx{usr1, Kind::Type});
if (it != sym2ds.end() && it->second)
ds->children.push_back(std::move(it->second));
}
for (auto [usr1, _] : def->vars) {
auto it = sym2ds.find(SymbolIdx{usr1, SymbolKind::Var});
auto it = sym2ds.find(SymbolIdx{usr1, Kind::Var});
if (it != sym2ds.end() && it->second)
ds->children.push_back(std::move(it->second));
}
}
std::vector<std::unique_ptr<lsDocumentSymbol>> result;
std::vector<std::unique_ptr<DocumentSymbol>> result;
for (auto &[_, ds] : sym2ds)
if (ds)
result.push_back(std::move(ds));
reply(result);
} else {
std::vector<lsSymbolInformation> result;
std::vector<SymbolInformation> result;
for (auto [sym, refcnt] : file->symbol2refcnt) {
if (refcnt <= 0 || !sym.extent.Valid() ||
!(param.all || sym.role & Role::Definition))
continue;
if (std::optional<lsSymbolInformation> info =
if (std::optional<SymbolInformation> info =
GetSymbolInfo(db, sym, false)) {
if ((sym.kind == SymbolKind::Type &&
Ignore(db->GetType(sym).AnyDef())) ||
(sym.kind == SymbolKind::Var && Ignore(db->GetVar(sym).AnyDef())))
if ((sym.kind == Kind::Type && Ignore(db->GetType(sym).AnyDef())) ||
(sym.kind == Kind::Var && Ignore(db->GetVar(sym).AnyDef())))
continue;
if (auto loc = GetLsLocation(db, wfiles, sym, file_id)) {
info->location = *loc;

View File

@ -42,7 +42,7 @@ void MessageHandler::textDocument_foldingRange(TextDocumentParam &param,
for (auto [sym, refcnt] : file->symbol2refcnt)
if (refcnt > 0 && sym.extent.Valid() &&
(sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) &&
(sym.kind == Kind::Func || sym.kind == Kind::Type) &&
(ls_range = GetLsRange(wfile, sym.extent))) {
FoldingRange &fold = result.emplace_back();
fold.startLine = ls_range->start.line;

View File

@ -41,9 +41,9 @@ FormatCode(std::string_view code, std::string_view file, tooling::Range Range) {
File));
}
std::vector<lsTextEdit>
ReplacementsToEdits(std::string_view code, const tooling::Replacements &Repls) {
std::vector<lsTextEdit> ret;
std::vector<TextEdit> ReplacementsToEdits(std::string_view code,
const tooling::Replacements &Repls) {
std::vector<TextEdit> ret;
int i = 0, line = 0, col = 0;
auto move = [&](int p) {
for (; i < p; i++)
@ -74,8 +74,8 @@ void Format(ReplyOnce &reply, WorkingFile *wfile, tooling::Range range) {
auto result = ReplacementsToEdits(code, *ReplsOrErr);
reply(result);
} else {
lsResponseError err;
err.code = lsErrorCodes::UnknownErrorCode;
ResponseError err;
err.code = ErrorCode::UnknownErrorCode;
err.message = llvm::toString(ReplsOrErr.takeError());
reply.Error(err);
}

View File

@ -6,16 +6,16 @@
namespace ccls {
namespace {
struct lsMarkedString {
struct MarkedString {
std::optional<std::string> language;
std::string value;
};
struct Hover {
std::vector<lsMarkedString> contents;
std::vector<MarkedString> contents;
std::optional<lsRange> range;
};
void Reflect(Writer &visitor, lsMarkedString &value) {
void Reflect(Writer &visitor, MarkedString &value) {
// If there is a language, emit a `{language:string, value:string}` object. If
// not, emit a string.
if (value.language) {
@ -42,10 +42,10 @@ const char *LanguageIdentifier(LanguageId lang) {
}
// Returns the hover or detailed name for `sym`, if any.
std::pair<std::optional<lsMarkedString>, std::optional<lsMarkedString>>
std::pair<std::optional<MarkedString>, std::optional<MarkedString>>
GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) {
const char *comments = nullptr;
std::optional<lsMarkedString> ls_comments, hover;
std::optional<MarkedString> ls_comments, hover;
WithEntity(db, sym, [&](const auto &entity) {
std::remove_reference_t<decltype(entity.def[0])> *def = nullptr;
for (auto &d : entity.def) {
@ -62,7 +62,7 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) {
comments = def->comments;
}
if (def) {
lsMarkedString m;
MarkedString m;
m.language = LanguageIdentifier(lang);
if (def->hover[0]) {
m.value = def->hover;
@ -72,7 +72,7 @@ GetHover(DB *db, LanguageId lang, SymbolRef sym, int file_id) {
hover = m;
}
if (comments)
ls_comments = lsMarkedString{std::nullopt, comments};
ls_comments = MarkedString{std::nullopt, comments};
}
});
return {hover, ls_comments};

View File

@ -41,7 +41,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) {
for (auto &folder : param.folders)
EnsureEndsInSlash(folder);
std::vector<uint8_t> file_set = db->GetFileSet(param.folders);
std::vector<lsLocation> result;
std::vector<Location> result;
std::unordered_set<Use> seen_uses;
int line = param.position.line;
@ -51,12 +51,12 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) {
std::unordered_set<Usr> seen;
seen.insert(sym.usr);
std::vector<Usr> stack{sym.usr};
if (sym.kind != SymbolKind::Func)
if (sym.kind != Kind::Func)
param.base = false;
while (stack.size()) {
sym.usr = stack.back();
stack.pop_back();
auto fn = [&](Use use, lsSymbolKind parent_kind) {
auto fn = [&](Use use, SymbolKind parent_kind) {
if (file_set[use.file_id] &&
Role(use.role & param.role) == param.role &&
!(use.role & param.excludeRole) && seen_uses.insert(use).second)
@ -64,7 +64,7 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) {
result.push_back(*loc);
};
WithEntity(db, sym, [&](const auto &entity) {
lsSymbolKind parent_kind = lsSymbolKind::Unknown;
SymbolKind parent_kind = SymbolKind::Unknown;
for (auto &def : entity.def)
if (def.spell) {
parent_kind = GetSymbolKind(db, sym);
@ -108,8 +108,8 @@ void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) {
for (const IndexInclude &include : file1.def->includes)
if (include.resolved_path == path) {
// Another file |file1| has the same include line.
lsLocation &loc = result.emplace_back();
loc.uri = lsDocumentUri::FromPath(file1.def->path);
Location &loc = result.emplace_back();
loc.uri = DocumentUri::FromPath(file1.def->path);
loc.range.start.line = loc.range.end.line = include.line;
break;
}

View File

@ -6,32 +6,32 @@
namespace ccls {
namespace {
lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
const std::string &new_text) {
std::unordered_map<int, lsTextDocumentEdit> path_to_edit;
std::unordered_map<int, TextDocumentEdit> path_to_edit;
EachOccurrence(db, sym, true, [&](Use use) {
std::optional<lsLocation> ls_location = GetLsLocation(db, wfiles, use);
std::optional<Location> ls_location = GetLsLocation(db, wfiles, use);
if (!ls_location)
return;
int file_id = use.file_id;
if (path_to_edit.find(file_id) == path_to_edit.end()) {
path_to_edit[file_id] = lsTextDocumentEdit();
path_to_edit[file_id] = TextDocumentEdit();
QueryFile &file = db->files[file_id];
if (!file.def)
return;
const std::string &path = file.def->path;
path_to_edit[file_id].textDocument.uri = lsDocumentUri::FromPath(path);
path_to_edit[file_id].textDocument.uri = DocumentUri::FromPath(path);
WorkingFile *working_file = wfiles->GetFileByFilename(path);
if (working_file)
path_to_edit[file_id].textDocument.version = working_file->version;
}
lsTextEdit edit;
TextEdit edit;
edit.range = ls_location->range;
edit.newText = new_text;
@ -41,7 +41,7 @@ lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
edits.push_back(edit);
});
lsWorkspaceEdit edit;
WorkspaceEdit edit;
for (const auto &changes : path_to_edit)
edit.documentChanges.push_back(changes.second);
return edit;
@ -55,7 +55,7 @@ void MessageHandler::textDocument_rename(RenameParam &param, ReplyOnce &reply) {
return;
WorkingFile *wfile = wfiles->GetFileByFilename(file->def->path);
lsWorkspaceEdit result;
WorkspaceEdit result;
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, param.position)) {
result = BuildWorkspaceEdit(db, wfiles, sym, param.newName);
break;

View File

@ -19,14 +19,14 @@ struct SignatureInformation {
std::optional<std::string> documentation;
std::vector<ParameterInformation> parameters;
};
struct lsSignatureHelp {
struct SignatureHelp {
std::vector<SignatureInformation> signatures;
int activeSignature = 0;
int activeParameter = 0;
};
MAKE_REFLECT_STRUCT(ParameterInformation, label);
MAKE_REFLECT_STRUCT(SignatureInformation, label, documentation, parameters);
MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature,
MAKE_REFLECT_STRUCT(SignatureHelp, signatures, activeSignature,
activeParameter);
std::string BuildOptional(const CodeCompletionString &CCS,
@ -64,7 +64,7 @@ class SignatureHelpConsumer : public CodeCompleteConsumer {
CodeCompletionTUInfo CCTUInfo;
public:
bool from_cache;
lsSignatureHelp ls_sighelp;
SignatureHelp ls_sighelp;
SignatureHelpConsumer(const clang::CodeCompleteOptions &CCOpts,
bool from_cache)
: CodeCompleteConsumer(CCOpts, false),
@ -140,7 +140,7 @@ public:
void MessageHandler::textDocument_signatureHelp(
TextDocumentPositionParam &param, ReplyOnce &reply) {
static CompleteConsumerCache<lsSignatureHelp> cache;
static CompleteConsumerCache<SignatureHelp> cache;
std::string path = param.textDocument.uri.GetPath();
lsPosition begin_pos = param.position;

View File

@ -30,12 +30,12 @@ limitations under the License.
#include <limits.h>
namespace ccls {
MAKE_REFLECT_STRUCT(lsSymbolInformation, name, kind, location, containerName);
MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName);
void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) {
for (const std::string &folder : g_config->workspaceFolders)
project->Load(folder);
project->Index(wfiles, lsRequestId());
project->Index(wfiles, RequestId());
clang_complete->FlushAllSessions();
};
@ -89,7 +89,7 @@ void MessageHandler::workspace_didChangeWorkspaceFolders(
project->Load(root);
}
project->Index(wfiles, lsRequestId());
project->Index(wfiles, RequestId());
clang_complete->FlushAllSessions();
}
@ -99,8 +99,8 @@ namespace {
bool AddSymbol(
DB *db, WorkingFiles *wfiles, const std::vector<uint8_t> &file_set,
SymbolIdx sym, bool use_detailed,
std::vector<std::tuple<lsSymbolInformation, int, SymbolIdx>> *result) {
std::optional<lsSymbolInformation> info = GetSymbolInfo(db, sym, true);
std::vector<std::tuple<SymbolInformation, int, SymbolIdx>> *result) {
std::optional<SymbolInformation> info = GetSymbolInfo(db, sym, true);
if (!info)
return false;
@ -125,7 +125,7 @@ bool AddSymbol(
if (!in_folder)
return false;
std::optional<lsLocation> ls_location = GetLsLocation(db, wfiles, *dr);
std::optional<Location> ls_location = GetLsLocation(db, wfiles, *dr);
if (!ls_location)
return false;
info->location = *ls_location;
@ -136,14 +136,14 @@ bool AddSymbol(
void MessageHandler::workspace_symbol(WorkspaceSymbolParam &param,
ReplyOnce &reply) {
std::vector<lsSymbolInformation> result;
std::vector<SymbolInformation> result;
const std::string &query = param.query;
for (auto &folder : param.folders)
EnsureEndsInSlash(folder);
std::vector<uint8_t> file_set = db->GetFileSet(param.folders);
// {symbol info, matching detailed_name or short_name, index}
std::vector<std::tuple<lsSymbolInformation, int, SymbolIdx>> cands;
std::vector<std::tuple<SymbolInformation, int, SymbolIdx>> cands;
bool sensitive = g_config->workspaceSymbol.caseSensitivity;
// Find subsequence matches.
@ -163,14 +163,13 @@ void MessageHandler::workspace_symbol(WorkspaceSymbolParam &param,
cands.size() >= g_config->workspaceSymbol.maxNum;
};
for (auto &func : db->funcs)
if (Add({func.usr, SymbolKind::Func}))
if (Add({func.usr, Kind::Func}))
goto done_add;
for (auto &type : db->types)
if (Add({type.usr, SymbolKind::Type}))
if (Add({type.usr, Kind::Type}))
goto done_add;
for (auto &var : db->vars)
if (var.def.size() && !var.def[0].is_local() &&
Add({var.usr, SymbolKind::Var}))
if (var.def.size() && !var.def[0].is_local() && Add({var.usr, Kind::Var}))
goto done_add;
done_add:

View File

@ -33,6 +33,14 @@ using namespace llvm;
#endif
namespace ccls {
namespace {
struct PublishDiagnosticParam {
DocumentUri uri;
std::vector<Diagnostic> diagnostics;
};
MAKE_REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics);
} // namespace
void VFS::Clear() {
std::lock_guard lock(mutex);
state.clear();
@ -69,7 +77,7 @@ struct Index_Request {
std::string path;
std::vector<const char *> args;
IndexMode mode;
lsRequestId id;
RequestId id;
int64_t ts = tick++;
};
@ -291,8 +299,8 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
if (!ok) {
if (request.id.Valid()) {
lsResponseError err;
err.code = lsErrorCodes::InternalError;
ResponseError err;
err.code = ErrorCode::InternalError;
err.message = "failed to index " + path_to_index;
pipeline::ReplyError(request.id, err);
}
@ -441,7 +449,7 @@ void LaunchStdin() {
if (!reader.HasMember("jsonrpc") ||
std::string(reader["jsonrpc"]->GetString()) != "2.0")
return;
lsRequestId id;
RequestId id;
std::string method;
ReflectMember(reader, "id", id);
ReflectMember(reader, "method", method);
@ -479,16 +487,16 @@ void MainLoop() {
CompletionManager clang_complete(
&project, &wfiles,
[&](std::string path, std::vector<lsDiagnostic> diagnostics) {
lsPublishDiagnosticsParams params;
params.uri = lsDocumentUri::FromPath(path);
[&](std::string path, std::vector<Diagnostic> diagnostics) {
PublishDiagnosticParam params;
params.uri = DocumentUri::FromPath(path);
params.diagnostics = diagnostics;
Notify("textDocument/publishDiagnostics", params);
},
[](lsRequestId id) {
[](RequestId id) {
if (id.Valid()) {
lsResponseError err;
err.code = lsErrorCodes::InternalError;
ResponseError err;
err.code = ErrorCode::InternalError;
err.message = "drop older completion request";
ReplyError(id, err);
}
@ -572,7 +580,7 @@ void Standalone(const std::string &root) {
}
void Index(const std::string &path, const std::vector<const char *> &args,
IndexMode mode, lsRequestId id) {
IndexMode mode, RequestId id) {
pending_index_requests++;
index_request->PushBack({path, args, mode, id}, mode != IndexMode::NonInteractive);
}
@ -603,7 +611,7 @@ void Notify(const char *method, const std::function<void(Writer &)> &fn) {
for_stdout->PushBack(output.GetString());
}
static void Reply(lsRequestId id, const char *key,
static void Reply(RequestId id, const char *key,
const std::function<void(Writer &)> &fn) {
rapidjson::StringBuffer output;
rapidjson::Writer<rapidjson::StringBuffer> w(output);
@ -612,13 +620,13 @@ static void Reply(lsRequestId id, const char *key,
w.String("2.0");
w.Key("id");
switch (id.type) {
case lsRequestId::kNone:
case RequestId::kNone:
w.Null();
break;
case lsRequestId::kInt:
case RequestId::kInt:
w.Int(id.value);
break;
case lsRequestId::kString:
case RequestId::kString:
auto s = std::to_string(id.value);
w.String(s.c_str(), s.length());
break;
@ -630,11 +638,11 @@ static void Reply(lsRequestId id, const char *key,
for_stdout->PushBack(output.GetString());
}
void Reply(lsRequestId id, const std::function<void(Writer &)> &fn) {
void Reply(RequestId id, const std::function<void(Writer &)> &fn) {
Reply(id, "result", fn);
}
void ReplyError(lsRequestId id, const std::function<void(Writer &)> &fn) {
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn) {
Reply(id, "error", fn);
}
} // namespace pipeline

View File

@ -50,7 +50,7 @@ void MainLoop();
void Standalone(const std::string &root);
void Index(const std::string &path, const std::vector<const char *> &args,
IndexMode mode, lsRequestId id = {});
IndexMode mode, RequestId id = {});
std::optional<std::string> LoadIndexedContent(const std::string& path);
@ -59,10 +59,10 @@ template <typename T> void Notify(const char *method, T &result) {
Notify(method, [&](Writer &w) { Reflect(w, result); });
}
void Reply(lsRequestId id, const std::function<void(Writer &)> &fn);
void Reply(RequestId id, const std::function<void(Writer &)> &fn);
void ReplyError(lsRequestId id, const std::function<void(Writer &)> &fn);
template <typename T> void ReplyError(lsRequestId id, T &result) {
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn);
template <typename T> void ReplyError(RequestId id, T &result) {
ReplyError(id, [&](Writer &w) { Reflect(w, result); });
}
} // namespace pipeline

View File

@ -451,7 +451,7 @@ Project::Entry Project::FindEntry(const std::string &path,
return result;
}
void Project::Index(WorkingFiles *wfiles, lsRequestId id) {
void Project::Index(WorkingFiles *wfiles, RequestId id) {
auto &gi = g_config->index;
GroupMatch match(gi.whitelist, gi.blacklist),
match_i(gi.initialWhitelist, gi.initialBlacklist);

View File

@ -63,6 +63,6 @@ struct Project {
void SetArgsForFile(const std::vector<const char *> &args,
const std::string &path);
void Index(WorkingFiles *wfiles, lsRequestId id);
void Index(WorkingFiles *wfiles, RequestId id);
};
} // namespace ccls

View File

@ -146,10 +146,10 @@ void DB::clear() {
}
template <typename Def>
void DB::RemoveUsrs(SymbolKind kind, int file_id,
void DB::RemoveUsrs(Kind kind, int file_id,
const std::vector<std::pair<Usr, Def>> &to_remove) {
switch (kind) {
case SymbolKind::Func: {
case Kind::Func: {
for (auto &[usr, _] : to_remove) {
// FIXME
if (!HasFunc(usr))
@ -163,7 +163,7 @@ void DB::RemoveUsrs(SymbolKind kind, int file_id,
}
break;
}
case SymbolKind::Type: {
case Kind::Type: {
for (auto &[usr, _] : to_remove) {
// FIXME
if (!HasType(usr))
@ -177,7 +177,7 @@ void DB::RemoveUsrs(SymbolKind kind, int file_id,
}
break;
}
case SymbolKind::Var: {
case Kind::Var: {
for (auto &[usr, _] : to_remove) {
// FIXME
if (!HasVar(usr))
@ -220,8 +220,8 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
}
// References (Use &use) in this function are important to update file_id.
auto Ref = [&](std::unordered_map<int, int> &lid2fid, Usr usr,
SymbolKind kind, Use &use, int delta) {
auto Ref = [&](std::unordered_map<int, int> &lid2fid, Usr usr, Kind kind,
Use &use, int delta) {
use.file_id =
use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second;
ExtentRef sym{{use.range, usr, kind, use.role}};
@ -231,8 +231,8 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
if (!v)
files[use.file_id].symbol2refcnt.erase(sym);
};
auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr,
SymbolKind kind, DeclRef &dr, int delta) {
auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr, Kind kind,
DeclRef &dr, int delta) {
dr.file_id =
dr.file_id == -1 ? u->file_id : lid2fid.find(dr.file_id)->second;
ExtentRef sym{{dr.range, usr, kind, dr.role}, dr.extent};
@ -244,7 +244,7 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
};
auto UpdateUses =
[&](Usr usr, SymbolKind kind,
[&](Usr usr, Kind kind,
llvm::DenseMap<Usr, int, DenseMapInfoForUsr> &entity_usr,
auto &entities, auto &p, bool hint_implicit) {
auto R = entity_usr.try_emplace(usr, entity_usr.size());
@ -291,19 +291,19 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
}
for (auto &[usr, def] : u->funcs_removed)
if (def.spell)
RefDecl(prev_lid2file_id, usr, SymbolKind::Func, *def.spell, -1);
RemoveUsrs(SymbolKind::Func, u->file_id, u->funcs_removed);
RefDecl(prev_lid2file_id, usr, Kind::Func, *def.spell, -1);
RemoveUsrs(Kind::Func, u->file_id, u->funcs_removed);
Update(lid2file_id, u->file_id, std::move(u->funcs_def_update));
for (auto &[usr, del_add]: u->funcs_declarations) {
for (DeclRef &dr : del_add.first)
RefDecl(prev_lid2file_id, usr, SymbolKind::Func, dr, -1);
RefDecl(prev_lid2file_id, usr, Kind::Func, dr, -1);
for (DeclRef &dr : del_add.second)
RefDecl(lid2file_id, usr, SymbolKind::Func, dr, 1);
RefDecl(lid2file_id, usr, Kind::Func, dr, 1);
}
REMOVE_ADD(func, declarations);
REMOVE_ADD(func, derived);
for (auto &[usr, p] : u->funcs_uses)
UpdateUses(usr, SymbolKind::Func, func_usr, funcs, p, true);
UpdateUses(usr, Kind::Func, func_usr, funcs, p, true);
if ((t = types.size() + u->types_hint) > types.capacity()) {
t = size_t(t * grow);
@ -312,20 +312,20 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
}
for (auto &[usr, def] : u->types_removed)
if (def.spell)
RefDecl(prev_lid2file_id, usr, SymbolKind::Type, *def.spell, -1);
RemoveUsrs(SymbolKind::Type, u->file_id, u->types_removed);
RefDecl(prev_lid2file_id, usr, Kind::Type, *def.spell, -1);
RemoveUsrs(Kind::Type, u->file_id, u->types_removed);
Update(lid2file_id, u->file_id, std::move(u->types_def_update));
for (auto &[usr, del_add]: u->types_declarations) {
for (DeclRef &dr : del_add.first)
RefDecl(prev_lid2file_id, usr, SymbolKind::Type, dr, -1);
RefDecl(prev_lid2file_id, usr, Kind::Type, dr, -1);
for (DeclRef &dr : del_add.second)
RefDecl(lid2file_id, usr, SymbolKind::Type, dr, 1);
RefDecl(lid2file_id, usr, Kind::Type, dr, 1);
}
REMOVE_ADD(type, declarations);
REMOVE_ADD(type, derived);
REMOVE_ADD(type, instances);
for (auto &[usr, p] : u->types_uses)
UpdateUses(usr, SymbolKind::Type, type_usr, types, p, false);
UpdateUses(usr, Kind::Type, type_usr, types, p, false);
if ((t = vars.size() + u->vars_hint) > vars.capacity()) {
t = size_t(t * grow);
@ -334,18 +334,18 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
}
for (auto &[usr, def] : u->vars_removed)
if (def.spell)
RefDecl(prev_lid2file_id, usr, SymbolKind::Var, *def.spell, -1);
RemoveUsrs(SymbolKind::Var, u->file_id, u->vars_removed);
RefDecl(prev_lid2file_id, usr, Kind::Var, *def.spell, -1);
RemoveUsrs(Kind::Var, u->file_id, u->vars_removed);
Update(lid2file_id, u->file_id, std::move(u->vars_def_update));
for (auto &[usr, del_add]: u->vars_declarations) {
for (DeclRef &dr : del_add.first)
RefDecl(prev_lid2file_id, usr, SymbolKind::Var, dr, -1);
RefDecl(prev_lid2file_id, usr, Kind::Var, dr, -1);
for (DeclRef &dr : del_add.second)
RefDecl(lid2file_id, usr, SymbolKind::Var, dr, 1);
RefDecl(lid2file_id, usr, Kind::Var, dr, 1);
}
REMOVE_ADD(var, declarations);
for (auto &[usr, p] : u->vars_uses)
UpdateUses(usr, SymbolKind::Var, var_usr, vars, p, false);
UpdateUses(usr, Kind::Var, var_usr, vars, p, false);
#undef REMOVE_ADD
}
@ -374,7 +374,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
if (def.spell) {
AssignFileId(lid2file_id, file_id, *def.spell);
files[def.spell->file_id].symbol2refcnt[{
{def.spell->range, u.first, SymbolKind::Func, def.spell->role},
{def.spell->range, u.first, Kind::Func, def.spell->role},
def.spell->extent}]++;
}
@ -397,7 +397,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
if (def.spell) {
AssignFileId(lid2file_id, file_id, *def.spell);
files[def.spell->file_id].symbol2refcnt[{
{def.spell->range, u.first, SymbolKind::Type, def.spell->role},
{def.spell->range, u.first, Kind::Type, def.spell->role},
def.spell->extent}]++;
}
auto R = type_usr.try_emplace({u.first}, type_usr.size());
@ -419,7 +419,7 @@ void DB::Update(const Lid2file_id &lid2file_id, int file_id,
if (def.spell) {
AssignFileId(lid2file_id, file_id, *def.spell);
files[def.spell->file_id].symbol2refcnt[{
{def.spell->range, u.first, SymbolKind::Var, def.spell->role},
{def.spell->range, u.first, Kind::Var, def.spell->role},
def.spell->extent}]++;
}
auto R = var_usr.try_emplace({u.first}, var_usr.size());
@ -437,19 +437,19 @@ std::string_view DB::GetSymbolName(SymbolIdx sym, bool qualified) {
switch (sym.kind) {
default:
break;
case SymbolKind::File:
case Kind::File:
if (files[usr].def)
return files[usr].def->path;
break;
case SymbolKind::Func:
case Kind::Func:
if (const auto *def = Func(usr).AnyDef())
return def->Name(qualified);
break;
case SymbolKind::Type:
case Kind::Type:
if (const auto *def = Type(usr).AnyDef())
return def->Name(qualified);
break;
case SymbolKind::Var:
case Kind::Var:
if (const auto *def = Var(usr).AnyDef())
return def->Name(qualified);
break;

View File

@ -157,7 +157,7 @@ struct DB {
void clear();
template <typename Def>
void RemoveUsrs(SymbolKind kind, int file_id,
void RemoveUsrs(Kind kind, int file_id,
const std::vector<std::pair<Usr, Def>> &to_remove);
// Insert the contents of |update| into |db|.
void ApplyIndexUpdate(IndexUpdate *update);

View File

@ -64,13 +64,13 @@ std::vector<Use> GetVarDeclarations(DB *db, const std::vector<Usr> &usrs,
if (def.spell) {
has_def = true;
// See messages/ccls_vars.cc
if (def.kind == lsSymbolKind::Field) {
if (def.kind == SymbolKind::Field) {
if (!(kind & 1))
break;
} else if (def.kind == lsSymbolKind::Variable) {
} else if (def.kind == SymbolKind::Variable) {
if (!(kind & 2))
break;
} else if (def.kind == lsSymbolKind::Parameter) {
} else if (def.kind == SymbolKind::Parameter) {
if (!(kind & 4))
break;
}
@ -86,11 +86,11 @@ std::vector<Use> GetVarDeclarations(DB *db, const std::vector<Usr> &usrs,
std::vector<DeclRef> &GetNonDefDeclarations(DB *db, SymbolIdx sym) {
static std::vector<DeclRef> empty;
switch (sym.kind) {
case SymbolKind::Func:
case Kind::Func:
return db->GetFunc(sym).declarations;
case SymbolKind::Type:
case Kind::Type:
return db->GetType(sym).declarations;
case SymbolKind::Var:
case Kind::Var:
return db->GetVar(sym).declarations;
default:
break;
@ -169,45 +169,44 @@ std::optional<lsRange> GetLsRange(WorkingFile *wfile,
lsPosition{*end, end_column}};
}
lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) {
DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path) {
QueryFile &file = db->files[file_id];
if (file.def) {
*path = file.def->path;
return lsDocumentUri::FromPath(*path);
return DocumentUri::FromPath(*path);
} else {
*path = "";
return lsDocumentUri::FromPath("");
return DocumentUri::FromPath("");
}
}
lsDocumentUri GetLsDocumentUri(DB *db, int file_id) {
DocumentUri GetLsDocumentUri(DB *db, int file_id) {
QueryFile &file = db->files[file_id];
if (file.def) {
return lsDocumentUri::FromPath(file.def->path);
return DocumentUri::FromPath(file.def->path);
} else {
return lsDocumentUri::FromPath("");
return DocumentUri::FromPath("");
}
}
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles,
Use use) {
std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles, Use use) {
std::string path;
lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path);
DocumentUri uri = GetLsDocumentUri(db, use.file_id, &path);
std::optional<lsRange> range =
GetLsRange(wfiles->GetFileByFilename(path), use.range);
if (!range)
return std::nullopt;
return lsLocation{uri, *range};
return Location{uri, *range};
}
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles,
std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles,
SymbolRef sym, int file_id) {
return GetLsLocation(db, wfiles, Use{{sym.range, sym.role}, file_id});
}
std::vector<lsLocation> GetLsLocations(DB *db, WorkingFiles *wfiles,
std::vector<Location> GetLsLocations(DB *db, WorkingFiles *wfiles,
const std::vector<Use> &uses) {
std::vector<lsLocation> ret;
std::vector<Location> ret;
for (Use use : uses)
if (auto loc = GetLsLocation(db, wfiles, use))
ret.push_back(*loc);
@ -218,12 +217,12 @@ std::vector<lsLocation> GetLsLocations(DB *db, WorkingFiles *wfiles,
return ret;
}
lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym) {
lsSymbolKind ret;
if (sym.kind == SymbolKind::File)
ret = lsSymbolKind::File;
SymbolKind GetSymbolKind(DB *db, SymbolIdx sym) {
SymbolKind ret;
if (sym.kind == Kind::File)
ret = SymbolKind::File;
else {
ret = lsSymbolKind::Unknown;
ret = SymbolKind::Unknown;
WithEntity(db, sym, [&](const auto &entity) {
for (auto &def : entity.def) {
ret = def.kind;
@ -234,23 +233,23 @@ lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym) {
return ret;
}
std::optional<lsSymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
std::optional<SymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
bool detailed) {
switch (sym.kind) {
case SymbolKind::Invalid:
case Kind::Invalid:
break;
case SymbolKind::File: {
case Kind::File: {
QueryFile &file = db->GetFile(sym);
if (!file.def)
break;
lsSymbolInformation info;
SymbolInformation info;
info.name = file.def->path;
info.kind = lsSymbolKind::File;
info.kind = SymbolKind::File;
return info;
}
default: {
lsSymbolInformation info;
SymbolInformation info;
EachEntityDef(db, sym, [&](const auto &def) {
if (detailed)
info.name = def.detailed_name;
@ -290,10 +289,10 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile *wfile,
// important for macros which generate code so that we can resolving the
// macro argument takes priority over the entire macro body.
//
// Order SymbolKind::Var before SymbolKind::Type. Macro calls are treated as
// Var currently. If a macro expands to tokens led by a SymbolKind::Type, the
// macro and the Type have the same range. We want to find the macro
// definition instead of the Type definition.
// Order Kind::Var before Kind::Type. Macro calls are treated as Var
// currently. If a macro expands to tokens led by a Kind::Type, the macro and
// the Type have the same range. We want to find the macro definition instead
// of the Type definition.
//
// Then order functions before other types, which makes goto definition work
// better on constructors.

View File

@ -24,16 +24,16 @@ std::vector<Use> GetUsesForAllBases(DB *db, QueryFunc &root);
std::vector<Use> GetUsesForAllDerived(DB *db, QueryFunc &root);
std::optional<lsRange> GetLsRange(WorkingFile *working_file,
const Range &location);
lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path);
lsDocumentUri GetLsDocumentUri(DB *db, int file_id);
DocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path);
DocumentUri GetLsDocumentUri(DB *db, int file_id);
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles, Use use);
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *wfiles,
std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles, Use use);
std::optional<Location> GetLsLocation(DB *db, WorkingFiles *wfiles,
SymbolRef sym, int file_id);
std::vector<lsLocation> GetLsLocations(DB *db, WorkingFiles *wfiles,
std::vector<Location> GetLsLocations(DB *db, WorkingFiles *wfiles,
const std::vector<Use> &uses);
// Returns a symbol. The symbol will *NOT* have a location assigned.
std::optional<lsSymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
std::optional<SymbolInformation> GetSymbolInfo(DB *db, SymbolIdx sym,
bool detailed);
std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile *working_file,
@ -43,16 +43,16 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile *working_file,
template <typename Fn> void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) {
switch (sym.kind) {
case SymbolKind::Invalid:
case SymbolKind::File:
case Kind::Invalid:
case Kind::File:
break;
case SymbolKind::Func:
case Kind::Func:
fn(db->GetFunc(sym));
break;
case SymbolKind::Type:
case Kind::Type:
fn(db->GetType(sym));
break;
case SymbolKind::Var:
case Kind::Var:
fn(db->GetVar(sym));
break;
}
@ -81,7 +81,7 @@ void EachOccurrence(DB *db, SymbolIdx sym, bool include_decl, Fn &&fn) {
});
}
lsSymbolKind GetSymbolKind(DB *db, SymbolIdx sym);
SymbolKind GetSymbolKind(DB *db, SymbolIdx sym);
template <typename Fn>
void EachDefinedFunc(DB *db, const std::vector<Usr> &usrs, Fn &&fn) {

View File

@ -255,10 +255,10 @@ bool RunIndexTests(const std::string &filter_path, bool enable_update) {
bool success = true;
bool update_all = false;
// FIXME: show diagnostics in STL/headers when running tests. At the moment
// this can be done by constructing ClangIndex index(1, 1);
CompletionManager completion(
nullptr, nullptr, [&](std::string, std::vector<lsDiagnostic>) {},
[](lsRequestId id) {});
// this can be done by conRequestIdex index(1, 1);
CompletionManager completion(nullptr, nullptr,
[&](std::string, std::vector<Diagnostic>) {},
[](RequestId id) {});
GetFilesInFolder(
"index_tests", true /*recursive*/, true /*add_folder_to_path*/,
[&](const std::string &path) {

View File

@ -439,7 +439,7 @@ void WorkingFiles::DoActionOnFile(
action(file);
}
WorkingFile *WorkingFiles::OnOpen(const lsTextDocumentItem &open) {
WorkingFile *WorkingFiles::OnOpen(const TextDocumentItem &open) {
std::lock_guard<std::mutex> lock(files_mutex);
std::string filename = open.uri.GetPath();
@ -493,7 +493,7 @@ void WorkingFiles::OnChange(const TextDocumentDidChangeParam &change) {
}
}
void WorkingFiles::OnClose(const lsTextDocumentIdentifier &close) {
void WorkingFiles::OnClose(const TextDocumentIdentifier &close) {
std::lock_guard<std::mutex> lock(files_mutex);
std::string filename = close.uri.GetPath();

View File

@ -31,7 +31,7 @@ struct WorkingFile {
// A set of diagnostics that have been reported for this file.
// NOTE: _ is appended because it must be accessed under the WorkingFiles
// lock!
std::vector<lsDiagnostic> diagnostics_;
std::vector<Diagnostic> diagnostics_;
WorkingFile(const std::string &filename, const std::string &buffer_content);
@ -105,9 +105,9 @@ struct WorkingFiles {
void DoActionOnFile(const std::string &filename,
const std::function<void(WorkingFile *file)> &action);
WorkingFile *OnOpen(const lsTextDocumentItem &open);
WorkingFile *OnOpen(const TextDocumentItem &open);
void OnChange(const TextDocumentDidChangeParam &change);
void OnClose(const lsTextDocumentIdentifier &close);
void OnClose(const TextDocumentIdentifier &close);
// If |filter_paths| is non-empty, only files which contain any of the given
// strings. For example, {"foo", "bar"} means that every result has either the