mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-30 11:27:07 +00:00
Remove ls
prefix from many LSP interfaces
Rename SymbolKind to Kind & lsSymbolKind to SymbolKind Use textDocumentSync: TextDocumentSyncOptions
This commit is contained in:
parent
6517f9f143
commit
50736827ca
@ -60,10 +60,9 @@ struct ProxyFileSystem : FileSystem {
|
||||
|
||||
namespace ccls {
|
||||
|
||||
lsTextEdit ToTextEdit(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &L,
|
||||
const clang::FixItHint &FixIt) {
|
||||
lsTextEdit edit;
|
||||
TextEdit ToTextEdit(const clang::SourceManager &SM, const clang::LangOptions &L,
|
||||
const clang::FixItHint &FixIt) {
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
bool use_angle_brackets) {
|
||||
lsCompletionItem item;
|
||||
CompletionItem BuildCompletionItem(const std::string &path,
|
||||
bool use_angle_brackets) {
|
||||
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);
|
||||
|
@ -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.
|
||||
|
170
src/indexer.cc
170
src/indexer.cc
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
37
src/lsp.cc
37
src/lsp.cc
@ -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
|
||||
|
126
src/lsp.hh
126
src/lsp.hh
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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 &);
|
||||
|
@ -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;
|
||||
|
@ -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 ¶m, 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 ¶m, 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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -26,105 +26,37 @@ 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;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsCodeLensOptions, resolveProvider);
|
||||
|
||||
// Completion options.
|
||||
struct lsCompletionOptions {
|
||||
// The server provides support to resolve additional
|
||||
// information for a completion item.
|
||||
bool resolveProvider = false;
|
||||
|
||||
// The characters that trigger completion automatically.
|
||||
// vscode doesn't support trigger character sequences, so we use ':'
|
||||
// for
|
||||
// '::' and '>' for '->'. See
|
||||
// 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.
|
||||
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;
|
||||
struct ServerCap {
|
||||
struct SaveOptions {
|
||||
bool includeText = false;
|
||||
};
|
||||
struct TextDocumentSyncOptions {
|
||||
bool openClose = true;
|
||||
TextDocumentSyncKind change = TextDocumentSyncKind::Incremental;
|
||||
bool willSave = false;
|
||||
bool willSaveWaitUntil = false;
|
||||
SaveOptions save;
|
||||
} textDocumentSync;
|
||||
|
||||
// The server provides hover support.
|
||||
bool hoverProvider = true;
|
||||
// The server provides completion support.
|
||||
lsCompletionOptions completionProvider;
|
||||
// The server provides signature help support.
|
||||
lsSignatureHelpOptions signatureHelpProvider;
|
||||
struct CompletionOptions {
|
||||
bool resolveProvider = false;
|
||||
|
||||
// The characters that trigger completion automatically.
|
||||
// vscode doesn't support trigger character sequences, so we use ':'
|
||||
// for
|
||||
// '::' and '>' for '->'. See
|
||||
// https://github.com/Microsoft/language-server-protocol/issues/138.
|
||||
std::vector<std::string> triggerCharacters = {".", ":", ">", "#",
|
||||
"<", "\"", "/"};
|
||||
} completionProvider;
|
||||
struct SignatureHelpOptions {
|
||||
std::vector<std::string> triggerCharacters = {"(", ","};
|
||||
} 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;
|
||||
};
|
||||
|
||||
// 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;
|
||||
std::optional<WorkspaceEdit> workspaceEdit;
|
||||
DynamicReg didChangeConfiguration;
|
||||
DynamicReg didChangeWatchedFiles;
|
||||
DynamicReg symbol;
|
||||
DynamicReg 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,
|
||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
|
||||
snippetSupport);
|
||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem);
|
||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
|
||||
hierarchicalDocumentSymbolSupport);
|
||||
MAKE_REFLECT_STRUCT(
|
||||
lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem,
|
||||
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, 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 ¶m, ReplyOnce &reply) {
|
||||
void Initialize(MessageHandler *m, InitializeParam ¶m, 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 ¶m, 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 ¶m, 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);
|
||||
}
|
||||
|
@ -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 ¶m,
|
||||
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 ¶m,
|
||||
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 ¶m,
|
||||
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 ¶m,
|
||||
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 ¶m,
|
||||
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 ¶m,
|
||||
|
||||
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);
|
||||
|
@ -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 ¶m,
|
||||
void MessageHandler::textDocument_completion(CompletionParam ¶m,
|
||||
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 ¶m,
|
||||
|
||||
// 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 ¶m,
|
||||
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 ¶m,
|
||||
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,
|
||||
|
@ -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 ¶m,
|
||||
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 ¶m,
|
||||
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 ¶m,
|
||||
// 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 ¶m,
|
||||
}
|
||||
};
|
||||
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));
|
||||
|
@ -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 ¶m,
|
||||
@ -81,10 +81,10 @@ void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m,
|
||||
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;
|
||||
|
@ -42,7 +42,7 @@ void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m,
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -6,32 +6,32 @@
|
||||
|
||||
namespace ccls {
|
||||
namespace {
|
||||
lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
|
||||
const std::string &new_text) {
|
||||
std::unordered_map<int, lsTextDocumentEdit> path_to_edit;
|
||||
WorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
|
||||
const std::string &new_text) {
|
||||
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 ¶m, 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;
|
||||
|
@ -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 ¶m, ReplyOnce &reply) {
|
||||
static CompleteConsumerCache<lsSignatureHelp> cache;
|
||||
static CompleteConsumerCache<SignatureHelp> cache;
|
||||
|
||||
std::string path = param.textDocument.uri.GetPath();
|
||||
lsPosition begin_pos = param.position;
|
||||
|
@ -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 ¶m,
|
||||
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 ¶m,
|
||||
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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
62
src/query.cc
62
src/query.cc
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
SymbolRef sym, int file_id) {
|
||||
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,
|
||||
const std::vector<Use> &uses) {
|
||||
std::vector<lsLocation> ret;
|
||||
std::vector<Location> GetLsLocations(DB *db, WorkingFiles *wfiles,
|
||||
const std::vector<Use> &uses) {
|
||||
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,
|
||||
bool detailed) {
|
||||
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.
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user