clang-format

DEF CON 26 CTF
This commit is contained in:
Fangrui Song 2018-08-09 10:08:14 -07:00
parent 87f36a4a96
commit 39787d2851
87 changed files with 2058 additions and 2372 deletions

View File

@ -197,8 +197,9 @@ void BuildCompletionItemTexts(std::vector<lsCompletionItem> &out,
continue; continue;
if (Kind == CodeCompletionString::CK_Placeholder) { if (Kind == CodeCompletionString::CK_Placeholder) {
out[i].insertText += out[i].insertText += "${" +
"${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}"; std::to_string(out[i].parameters_.size()) + ":" +
text + "}";
out[i].insertTextFormat = lsInsertTextFormat::Snippet; out[i].insertTextFormat = lsInsertTextFormat::Snippet;
} else { } else {
out[i].insertText += text; out[i].insertText += text;
@ -238,7 +239,8 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item,
item.detail += Chunk.Text; item.detail += Chunk.Text;
// Add parameter declarations as snippets if enabled // Add parameter declarations as snippets if enabled
if (include_snippets) { if (include_snippets) {
item.insertText += "${" + std::to_string(parameters->size()) + ":" + Chunk.Text + "}"; item.insertText +=
"${" + std::to_string(parameters->size()) + ":" + Chunk.Text + "}";
item.insertTextFormat = lsInsertTextFormat::Snippet; item.insertTextFormat = lsInsertTextFormat::Snippet;
} else } else
do_insert = false; do_insert = false;
@ -250,8 +252,8 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item,
case CodeCompletionString::CK_Optional: { case CodeCompletionString::CK_Optional: {
// Do not add text to insert string if we're in angle brackets. // Do not add text to insert string if we're in angle brackets.
bool should_insert = do_insert && angle_stack == 0; bool should_insert = do_insert && angle_stack == 0;
BuildDetailString(*Chunk.Optional, item, should_insert, BuildDetailString(*Chunk.Optional, item, should_insert, parameters,
parameters, include_snippets, angle_stack); include_snippets, angle_stack);
break; break;
} }
case CodeCompletionString::CK_ResultType: case CodeCompletionString::CK_ResultType:
@ -298,8 +300,7 @@ public:
Alloc(std::make_shared<clang::GlobalCodeCompletionAllocator>()), Alloc(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
CCTUInfo(Alloc) {} CCTUInfo(Alloc) {}
void ProcessCodeCompleteResults(Sema &S, void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
CodeCompletionContext Context,
CodeCompletionResult *Results, CodeCompletionResult *Results,
unsigned NumResults) override { unsigned NumResults) override {
ls_items.reserve(NumResults); ls_items.reserve(NumResults);
@ -334,8 +335,7 @@ public:
} else { } else {
bool do_insert = true; bool do_insert = true;
int angle_stack = 0; int angle_stack = 0;
BuildDetailString(*CCS, ls_item, do_insert, BuildDetailString(*CCS, ls_item, do_insert, &ls_item.parameters_,
&ls_item.parameters_,
g_config->client.snippetSupport, angle_stack); g_config->client.snippetSupport, angle_stack);
if (g_config->client.snippetSupport && if (g_config->client.snippetSupport &&
ls_item.insertTextFormat == lsInsertTextFormat::Snippet) ls_item.insertTextFormat == lsInsertTextFormat::Snippet)
@ -427,7 +427,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
true /*create_if_needed*/); true /*create_if_needed*/);
std::lock_guard<std::mutex> lock(session->completion.lock); std::lock_guard<std::mutex> lock(session->completion.lock);
TryEnsureDocumentParsed(completion_manager, session, &session->completion.tu, false); TryEnsureDocumentParsed(completion_manager, session,
&session->completion.tu, false);
// It is possible we failed to create the document despite // It is possible we failed to create the document despite
// |TryEnsureDocumentParsed|. // |TryEnsureDocumentParsed|.
@ -464,7 +465,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr, capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr,
*FileMgr, Diagnostics, TemporaryBuffers); *FileMgr, Diagnostics, TemporaryBuffers);
request->on_complete(capture.ls_items, false /*is_cached_result*/); request->on_complete(capture.ls_items, false /*is_cached_result*/);
// completion_manager->on_diagnostic_(session->file.filename, Diags.take()); // completion_manager->on_diagnostic_(session->file.filename,
// Diags.take());
} }
} }
} }
@ -509,7 +511,8 @@ void DiagnosticQueryMain(ClangCompleteManager *manager) {
if (!FLoc.isValid()) // why? if (!FLoc.isValid()) // why?
continue; continue;
const FileEntry *FE = FLoc.getFileEntry(); const FileEntry *FE = FLoc.getFileEntry();
if (!FE || FileName(*FE) != path) continue; if (!FE || FileName(*FE) != path)
continue;
const auto &SM = FLoc.getManager(); const auto &SM = FLoc.getManager();
SourceRange R; SourceRange R;
for (const auto &CR : I->getRanges()) { for (const auto &CR : I->getRanges()) {
@ -559,24 +562,25 @@ ClangCompleteManager::ClangCompleteManager(Project* project,
WorkingFiles *working_files, WorkingFiles *working_files,
OnDiagnostic on_diagnostic, OnDiagnostic on_diagnostic,
OnDropped on_dropped) OnDropped on_dropped)
: project_(project), : project_(project), working_files_(working_files),
working_files_(working_files), on_diagnostic_(on_diagnostic), on_dropped_(on_dropped),
on_diagnostic_(on_diagnostic),
on_dropped_(on_dropped),
preloaded_sessions_(kMaxPreloadedSessions), preloaded_sessions_(kMaxPreloadedSessions),
completion_sessions_(kMaxCompletionSessions) { completion_sessions_(kMaxCompletionSessions) {
std::thread([&]() { std::thread([&]() {
set_thread_name("comp-query"); set_thread_name("comp-query");
CompletionQueryMain(this); CompletionQueryMain(this);
}).detach(); })
.detach();
std::thread([&]() { std::thread([&]() {
set_thread_name("comp-preload"); set_thread_name("comp-preload");
CompletionPreloadMain(this); CompletionPreloadMain(this);
}).detach(); })
.detach();
std::thread([&]() { std::thread([&]() {
set_thread_name("diag-query"); set_thread_name("diag-query");
DiagnosticQueryMain(this); DiagnosticQueryMain(this);
}).detach(); })
.detach();
} }
void ClangCompleteManager::CodeComplete( void ClangCompleteManager::CodeComplete(
@ -668,8 +672,8 @@ bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession(
return true; return true;
} }
std::shared_ptr<CompletionSession> ClangCompleteManager::TryGetSession( std::shared_ptr<CompletionSession>
const std::string& filename, ClangCompleteManager::TryGetSession(const std::string &filename,
bool mark_as_completion, bool mark_as_completion,
bool create_if_needed) { bool create_if_needed) {
std::lock_guard<std::mutex> lock(sessions_lock_); std::lock_guard<std::mutex> lock(sessions_lock_);

View File

@ -36,12 +36,10 @@ struct CompletionSession
}; };
struct ClangCompleteManager { struct ClangCompleteManager {
using OnDiagnostic = using OnDiagnostic = std::function<void(
std::function<void(std::string path, std::string path, std::vector<lsDiagnostic> diagnostics)>;
std::vector<lsDiagnostic> diagnostics)>; using OnComplete = std::function<void(
using OnComplete = const std::vector<lsCompletionItem> &results, bool is_cached_result)>;
std::function<void(const std::vector<lsCompletionItem>& results,
bool is_cached_result)>;
using OnDropped = std::function<void(lsRequestId request_id)>; using OnDropped = std::function<void(lsRequestId request_id)>;
struct PreloadRequest { struct PreloadRequest {
@ -54,11 +52,8 @@ struct ClangCompleteManager {
struct CompletionRequest { struct CompletionRequest {
CompletionRequest(const lsRequestId &id, CompletionRequest(const lsRequestId &id,
const lsTextDocumentIdentifier &document, const lsTextDocumentIdentifier &document,
const lsPosition& position, const lsPosition &position, const OnComplete &on_complete)
const OnComplete& on_complete) : id(id), document(document), position(position),
: id(id),
document(document),
position(position),
on_complete(on_complete) {} on_complete(on_complete) {}
lsRequestId id; lsRequestId id;
@ -70,10 +65,8 @@ struct ClangCompleteManager {
lsTextDocumentIdentifier document; lsTextDocumentIdentifier document;
}; };
ClangCompleteManager(Project* project, ClangCompleteManager(Project *project, WorkingFiles *working_files,
WorkingFiles* working_files, OnDiagnostic on_diagnostic, OnDropped on_dropped);
OnDiagnostic on_diagnostic,
OnDropped on_dropped);
// Start a code completion at the given location. |on_complete| will run when // Start a code completion at the given location. |on_complete| will run when
// completion results are available. |on_complete| may run on any thread. // completion results are available. |on_complete| may run on any thread.

View File

@ -103,8 +103,7 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
ret->PCHCO->getRawReader().getFormat(), &ErrUnit)); ret->PCHCO->getRawReader().getFormat(), &ErrUnit));
}; };
if (!CRC.RunSafely(parse)) { if (!CRC.RunSafely(parse)) {
LOG_S(ERROR) LOG_S(ERROR) << "clang crashed for " << filepath << "\n"
<< "clang crashed for " << filepath << "\n"
<< StringJoin(args, " ") + " -fsyntax-only"; << StringJoin(args, " ") + " -fsyntax-only";
return {}; return {};
} }

View File

@ -7,9 +7,9 @@
#include <llvm/Support/CrashRecoveryContext.h> #include <llvm/Support/CrashRecoveryContext.h>
#include <memory> #include <memory>
#include <stdlib.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdlib.h>
std::vector<clang::ASTUnit::RemappedFile> std::vector<clang::ASTUnit::RemappedFile>
GetRemapped(const WorkingFiles::Snapshot &snapshot); GetRemapped(const WorkingFiles::Snapshot &snapshot);
@ -19,12 +19,12 @@ Range FromCharSourceRange(const clang::SourceManager &SM,
clang::CharSourceRange R, clang::CharSourceRange R,
llvm::sys::fs::UniqueID *UniqueID = nullptr); llvm::sys::fs::UniqueID *UniqueID = nullptr);
Range FromCharRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, Range FromCharRange(const clang::SourceManager &SM,
clang::SourceRange R, const clang::LangOptions &LangOpts, clang::SourceRange R,
llvm::sys::fs::UniqueID *UniqueID = nullptr); llvm::sys::fs::UniqueID *UniqueID = nullptr);
Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts, Range FromTokenRange(const clang::SourceManager &SM,
clang::SourceRange R, const clang::LangOptions &LangOpts, clang::SourceRange R,
llvm::sys::fs::UniqueID *UniqueID = nullptr); llvm::sys::fs::UniqueID *UniqueID = nullptr);
struct ClangTranslationUnit { struct ClangTranslationUnit {

View File

@ -218,49 +218,23 @@ struct Config {
MAKE_REFLECT_STRUCT(Config::Clang, extraArgs, resourceDir); MAKE_REFLECT_STRUCT(Config::Clang, extraArgs, resourceDir);
MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport); MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport);
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables); MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
MAKE_REFLECT_STRUCT(Config::Completion, MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests,
caseSensitivity, detailedLabel, filterAndSort, includeBlacklist,
dropOldRequests, includeMaxPathSize, includeSuffixWhitelist,
detailedLabel,
filterAndSort,
includeBlacklist,
includeMaxPathSize,
includeSuffixWhitelist,
includeWhitelist); includeWhitelist);
MAKE_REFLECT_STRUCT(Config::Diagnostics, MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onParse,
blacklist, onType, whitelist)
frequencyMs,
onParse,
onType,
whitelist)
MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist) MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist)
MAKE_REFLECT_STRUCT(Config::Index, MAKE_REFLECT_STRUCT(Config::Index, attributeMakeCallsToCtor, blacklist,
attributeMakeCallsToCtor, comments, enabled, onDidChange, reparseForDependency,
blacklist, threads, whitelist);
comments,
enabled,
onDidChange,
reparseForDependency,
threads,
whitelist);
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum); MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
MAKE_REFLECT_STRUCT(Config, MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
compilationDatabaseCommand, compilationDatabaseDirectory, cacheDirectory, cacheFormat,
compilationDatabaseDirectory,
cacheDirectory,
cacheFormat,
clang, clang, client, codeLens, completion, diagnostics, highlight,
client, index, largeFileSize, workspaceSymbol, xref);
codeLens,
completion,
diagnostics,
highlight,
index,
largeFileSize,
workspaceSymbol,
xref);
extern Config *g_config; extern Config *g_config;
thread_local extern int g_thread_id; thread_local extern int g_thread_id;

View File

@ -8,8 +8,8 @@
namespace { namespace {
std::optional<std::string> GetFileContents( std::optional<std::string>
const std::string& path, GetFileContents(const std::string &path,
std::unordered_map<std::string, FileContents> *file_contents) { std::unordered_map<std::string, FileContents> *file_contents) {
auto it = file_contents->find(path); auto it = file_contents->find(path);
if (it == file_contents->end()) { if (it == file_contents->end()) {
@ -115,7 +115,8 @@ IndexFile* FileConsumer::TryConsumeFile(
return nullptr; return nullptr;
// Build IndexFile instance. // Build IndexFile instance.
local_[UniqueID] = std::make_unique<IndexFile>(UniqueID, file_name, *contents); local_[UniqueID] =
std::make_unique<IndexFile>(UniqueID, file_name, *contents);
return local_[UniqueID].get(); return local_[UniqueID].get();
} }

View File

@ -42,15 +42,14 @@ struct VFS {
}; };
namespace std { namespace std {
template <> template <> struct hash<llvm::sys::fs::UniqueID> {
struct hash<llvm::sys::fs::UniqueID> {
std::size_t operator()(llvm::sys::fs::UniqueID ID) const { std::size_t operator()(llvm::sys::fs::UniqueID ID) const {
size_t ret = ID.getDevice(); size_t ret = ID.getDevice();
hash_combine(ret, ID.getFile()); hash_combine(ret, ID.getFile());
return ret; return ret;
} }
}; };
} } // namespace std
// FileConsumer is used by the indexer. When it encouters a file, it tries to // FileConsumer is used by the indexer. When it encouters a file, it tries to
// take ownership over it. If the indexer has ownership over a file, it will // take ownership over it. If the indexer has ownership over a file, it will
@ -68,14 +67,16 @@ struct FileConsumer {
// //
// note: file_contents is passed as a parameter instead of as a member // note: file_contents is passed as a parameter instead of as a member
// variable since it is large and we do not want to copy it. // variable since it is large and we do not want to copy it.
IndexFile* TryConsumeFile(const clang::FileEntry& file, IndexFile *
TryConsumeFile(const clang::FileEntry &file,
std::unordered_map<std::string, FileContents> *file_contents); std::unordered_map<std::string, FileContents> *file_contents);
// Returns and passes ownership of all local state. // Returns and passes ownership of all local state.
std::vector<std::unique_ptr<IndexFile>> TakeLocalState(); std::vector<std::unique_ptr<IndexFile>> TakeLocalState();
private: private:
std::unordered_map<llvm::sys::fs::UniqueID, std::unique_ptr<IndexFile>> local_; std::unordered_map<llvm::sys::fs::UniqueID, std::unique_ptr<IndexFile>>
local_;
VFS *vfs_; VFS *vfs_;
std::string parse_file_; std::string parse_file_;
int thread_id_; int thread_id_;

View File

@ -6,9 +6,7 @@ using namespace llvm;
#include <set> #include <set>
#include <vector> #include <vector>
void GetFilesInFolder(std::string folder, void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix,
bool recursive,
bool dir_prefix,
const std::function<void(const std::string &)> &handler) { const std::function<void(const std::string &)> &handler) {
EnsureEndsInSlash(folder); EnsureEndsInSlash(folder);
sys::fs::file_status Status; sys::fs::file_status Status;

View File

@ -1,8 +1,8 @@
#include "fuzzy_match.h" #include "fuzzy_match.h"
#include <algorithm>
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <algorithm>
#include <vector> #include <vector>
enum CharClass { Other, Lower, Upper }; enum CharClass { Other, Lower, Upper };

View File

@ -46,8 +46,7 @@ size_t TrimCommonPathPrefix(const std::string& result,
} }
// Returns true iff angle brackets should be used. // Returns true iff angle brackets should be used.
bool TrimPath(Project* project, bool TrimPath(Project *project, const std::string &project_root,
const std::string& project_root,
std::string *insert_path) { std::string *insert_path) {
size_t start = TrimCommonPathPrefix(*insert_path, project_root); size_t start = TrimCommonPathPrefix(*insert_path, project_root);
bool angle = false; bool angle = false;
@ -68,8 +67,7 @@ bool TrimPath(Project* project,
} }
lsCompletionItem BuildCompletionItem(const std::string &path, lsCompletionItem BuildCompletionItem(const std::string &path,
bool use_angle_brackets, bool use_angle_brackets, bool is_stl) {
bool is_stl) {
lsCompletionItem item; lsCompletionItem item;
item.label = ElideLongPath(path); item.label = ElideLongPath(path);
item.detail = path; // the include path, used in de-duplicating item.detail = path; // the include path, used in de-duplicating
@ -102,7 +100,8 @@ void IncludeComplete::Rescan() {
if (!match_ && (g_config->completion.includeWhitelist.size() || if (!match_ && (g_config->completion.includeWhitelist.size() ||
g_config->completion.includeBlacklist.size())) g_config->completion.includeBlacklist.size()))
match_ = std::make_unique<GroupMatch>(g_config->completion.includeWhitelist, match_ =
std::make_unique<GroupMatch>(g_config->completion.includeWhitelist,
g_config->completion.includeBlacklist); g_config->completion.includeBlacklist);
is_scanning = true; is_scanning = true;
@ -117,7 +116,8 @@ void IncludeComplete::Rescan() {
InsertIncludesFromDirectory(dir, true /*use_angle_brackets*/); InsertIncludesFromDirectory(dir, true /*use_angle_brackets*/);
is_scanning = false; is_scanning = false;
}).detach(); })
.detach();
} }
void IncludeComplete::InsertCompletionItem(const std::string &absolute_path, void IncludeComplete::InsertCompletionItem(const std::string &absolute_path,
@ -189,7 +189,8 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
std::move(result.completion_item)); std::move(result.completion_item));
} }
std::optional<lsCompletionItem> IncludeComplete::FindCompletionItemForAbsolutePath( std::optional<lsCompletionItem>
IncludeComplete::FindCompletionItemForAbsolutePath(
const std::string &absolute_path) { const std::string &absolute_path) {
std::lock_guard<std::mutex> lock(completion_items_mutex); std::lock_guard<std::mutex> lock(completion_items_mutex);

View File

@ -23,8 +23,8 @@ struct IncludeComplete {
void InsertIncludesFromDirectory(std::string directory, void InsertIncludesFromDirectory(std::string directory,
bool use_angle_brackets); bool use_angle_brackets);
std::optional<lsCompletionItem> FindCompletionItemForAbsolutePath( std::optional<lsCompletionItem>
const std::string& absolute_path); FindCompletionItemForAbsolutePath(const std::string &absolute_path);
// Insert item to |completion_items|. // Insert item to |completion_items|.
// Update |absolute_path_to_completion_item| and |inserted_paths|. // Update |absolute_path_to_completion_item| and |inserted_paths|.

View File

@ -21,9 +21,9 @@ using ccls::Intern;
using namespace clang; using namespace clang;
using llvm::Timer; using llvm::Timer;
#include <algorithm>
#include <inttypes.h> #include <inttypes.h>
#include <limits.h> #include <limits.h>
#include <algorithm>
#include <map> #include <map>
#include <unordered_set> #include <unordered_set>
@ -81,8 +81,9 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts,
StringRef Buf = SM.getBufferData(BInfo.first, &invalid); StringRef Buf = SM.getBufferData(BInfo.first, &invalid);
if (invalid) if (invalid)
return ""; return "";
return Buf.substr(BInfo.second, EInfo.second + Lexer::MeasureTokenLength( return Buf.substr(BInfo.second,
ELoc, SM, LangOpts) - EInfo.second +
Lexer::MeasureTokenLength(ELoc, SM, LangOpts) -
BInfo.second); BInfo.second);
} }
@ -200,8 +201,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) {
BaseType = ATy->getDeducedType(); BaseType = ATy->getDeducedType();
else else
break; break;
} } else
else
break; break;
} }
return BaseType; return BaseType;
@ -271,14 +271,14 @@ const Decl* GetSpecialized(const Decl* D) {
return D; return D;
Decl *Template = nullptr; Decl *Template = nullptr;
if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
if (const ClassTemplatePartialSpecializationDecl *PartialSpec if (const ClassTemplatePartialSpecializationDecl *PartialSpec =
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
Template = PartialSpec->getSpecializedTemplate(); Template = PartialSpec->getSpecializedTemplate();
else if (const ClassTemplateSpecializationDecl *ClassSpec else if (const ClassTemplateSpecializationDecl *ClassSpec =
= dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
llvm::PointerUnion<ClassTemplateDecl *, llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *> Result ClassTemplatePartialSpecializationDecl *>
= ClassSpec->getSpecializedTemplateOrPartial(); Result = ClassSpec->getSpecializedTemplateOrPartial();
if (Result.is<ClassTemplateDecl *>()) if (Result.is<ClassTemplateDecl *>())
Template = Result.get<ClassTemplateDecl *>(); Template = Result.get<ClassTemplateDecl *>();
else else
@ -293,8 +293,8 @@ const Decl* GetSpecialized(const Decl* D) {
} else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { } else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->isStaticDataMember()) if (Var->isStaticDataMember())
Template = Var->getInstantiatedFromStaticDataMember(); Template = Var->getInstantiatedFromStaticDataMember();
} else if (const RedeclarableTemplateDecl *Tmpl } else if (const RedeclarableTemplateDecl *Tmpl =
= dyn_cast<RedeclarableTemplateDecl>(D)) dyn_cast<RedeclarableTemplateDecl>(D))
Template = Tmpl->getInstantiatedFromMemberTemplate(); Template = Tmpl->getInstantiatedFromMemberTemplate();
else else
return nullptr; return nullptr;
@ -322,7 +322,8 @@ public:
std::string GetComment(const Decl *D) { std::string GetComment(const Decl *D) {
SourceManager &SM = Ctx->getSourceManager(); SourceManager &SM = Ctx->getSourceManager();
const RawComment *RC = Ctx->getRawCommentForAnyRedecl(D); const RawComment *RC = Ctx->getRawCommentForAnyRedecl(D);
if (!RC) return ""; if (!RC)
return "";
StringRef Raw = RC->getRawText(Ctx->getSourceManager()); StringRef Raw = RC->getRawText(Ctx->getSourceManager());
SourceRange R = RC->getSourceRange(); SourceRange R = RC->getSourceRange();
std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(R.getBegin()); std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(R.getBegin());
@ -533,7 +534,8 @@ public:
void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind, void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind,
SourceLocation Spell) const { SourceLocation Spell) const {
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell)); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell));
if (!FE) return; if (!FE)
return;
auto UID = FE->getUniqueID(); auto UID = FE->getUniqueID();
auto [it, inserted] = db->uid2lid_and_path.try_emplace(UID); auto [it, inserted] = db->uid2lid_and_path.try_emplace(UID);
if (inserted) { if (inserted) {
@ -566,9 +568,7 @@ public:
public: public:
IndexDataConsumer(IndexParam &param) : param(param) {} IndexDataConsumer(IndexParam &param) : param(param) {}
void initialize(ASTContext &Ctx) override { void initialize(ASTContext &Ctx) override { this->Ctx = param.Ctx = &Ctx; }
this->Ctx = param.Ctx = &Ctx;
}
bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
ArrayRef<index::SymbolRelation> Relations, ArrayRef<index::SymbolRelation> Relations,
#if LLVM_VERSION_MAJOR >= 7 #if LLVM_VERSION_MAJOR >= 7
@ -725,7 +725,8 @@ public:
it->second.instances.push_back(usr); it->second.instances.push_back(usr);
break; break;
} }
// e.g. TemplateTypeParmDecl is not handled by handleDeclOccurence. // e.g. TemplateTypeParmDecl is not handled by
// handleDeclOccurence.
SourceRange R1 = D1->getSourceRange(); SourceRange R1 = D1->getSourceRange();
if (SM.getFileID(R1.getBegin()) == LocFID) { if (SM.getFileID(R1.getBegin()) == LocFID) {
IndexType &type1 = db->ToType(usr1); IndexType &type1 = db->ToType(usr1);
@ -1053,8 +1054,8 @@ public:
} }
} }
} }
void MacroExpands(const Token &Tok, const MacroDefinition &MD, void MacroExpands(const Token &Tok, const MacroDefinition &MD, SourceRange R,
SourceRange R, const MacroArgs *Args) override { const MacroArgs *Args) override {
llvm::sys::fs::UniqueID UniqueID; llvm::sys::fs::UniqueID UniqueID;
SourceLocation L = SM.getSpellingLoc(R.getBegin()); SourceLocation L = SM.getSpellingLoc(R.getBegin());
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L)); const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L));
@ -1086,16 +1087,18 @@ public:
class IndexFrontendAction : public ASTFrontendAction { class IndexFrontendAction : public ASTFrontendAction {
IndexParam &param; IndexParam &param;
public: public:
IndexFrontendAction(IndexParam &param) : param(param) {} IndexFrontendAction(IndexParam &param) : param(param) {}
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override { StringRef InFile) override {
Preprocessor &PP = CI.getPreprocessor(); Preprocessor &PP = CI.getPreprocessor();
PP.addPPCallbacks(std::make_unique<IndexPPCallbacks>(PP.getSourceManager(), param)); PP.addPPCallbacks(
std::make_unique<IndexPPCallbacks>(PP.getSourceManager(), param));
return std::make_unique<ASTConsumer>(); return std::make_unique<ASTConsumer>();
} }
}; };
} } // namespace
const int IndexFile::kMajorVersion = 17; const int IndexFile::kMajorVersion = 17;
const int IndexFile::kMinorVersion = 1; const int IndexFile::kMinorVersion = 1;
@ -1129,8 +1132,7 @@ std::string IndexFile::ToString() {
return ccls::Serialize(SerializeFormat::Json, *this); return ccls::Serialize(SerializeFormat::Json, *this);
} }
template <typename T> template <typename T> void Uniquify(std::vector<T> &a) {
void Uniquify(std::vector<T>& a) {
std::unordered_set<T> seen; std::unordered_set<T> seen;
size_t n = 0; size_t n = 0;
for (size_t i = 0; i < a.size(); i++) for (size_t i = 0; i < a.size(); i++)
@ -1140,10 +1142,8 @@ void Uniquify(std::vector<T>& a) {
} }
namespace ccls::idx { namespace ccls::idx {
std::vector<std::unique_ptr<IndexFile>> Index( std::vector<std::unique_ptr<IndexFile>>
VFS* vfs, Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
const std::string& opt_wdir,
const std::string& file,
const std::vector<std::string> &args, const std::vector<std::string> &args,
const std::vector<FileContents> &file_contents) { const std::vector<FileContents> &file_contents) {
if (!g_config->index.enabled) if (!g_config->index.enabled)
@ -1153,8 +1153,8 @@ std::vector<std::unique_ptr<IndexFile>> Index(
for (auto &arg : args) for (auto &arg : args)
Args.push_back(arg.c_str()); Args.push_back(arg.c_str());
auto PCHCO = std::make_shared<PCHContainerOperations>(); auto PCHCO = std::make_shared<PCHContainerOperations>();
IntrusiveRefCntPtr<DiagnosticsEngine> IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); CompilerInstance::createDiagnostics(new DiagnosticOptions));
std::shared_ptr<CompilerInvocation> CI = std::shared_ptr<CompilerInvocation> CI =
createInvocationFromCommandLine(Args, Diags); createInvocationFromCommandLine(Args, Diags);
if (!CI) if (!CI)
@ -1270,7 +1270,7 @@ std::vector<std::unique_ptr<IndexFile>> Index(
return result; return result;
} }
} } // namespace ccls::idx
// |SymbolRef| is serialized this way. // |SymbolRef| is serialized this way.
// |Use| also uses this though it has an extra field |file|, // |Use| also uses this though it has an extra field |file|,

View File

@ -14,9 +14,9 @@
#include <clang/Basic/Specifiers.h> #include <clang/Basic/Specifiers.h>
#include <llvm/ADT/StringMap.h> #include <llvm/ADT/StringMap.h>
#include <stdint.h>
#include <algorithm> #include <algorithm>
#include <optional> #include <optional>
#include <stdint.h>
#include <string_view> #include <string_view>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -72,8 +72,7 @@ void Reflect(Writer& visitor, Reference& value);
void Reflect(Reader &visitor, Use &value); void Reflect(Reader &visitor, Use &value);
void Reflect(Writer &visitor, Use &value); void Reflect(Writer &visitor, Use &value);
template <typename D> template <typename D> struct NameMixin {
struct NameMixin {
std::string_view Name(bool qualified) const { std::string_view Name(bool qualified) const {
auto self = static_cast<const D *>(this); auto self = static_cast<const D *>(this);
return qualified return qualified
@ -112,20 +111,9 @@ struct FuncDef : NameMixin<FuncDef> {
std::vector<Usr> GetBases() const { return bases; } std::vector<Usr> GetBases() const { return bases; }
}; };
MAKE_REFLECT_STRUCT(FuncDef, MAKE_REFLECT_STRUCT(FuncDef, detailed_name, qual_name_offset, short_name_offset,
detailed_name, short_name_size, kind, storage, hover, comments, spell,
qual_name_offset, extent, bases, vars, callees);
short_name_offset,
short_name_size,
kind,
storage,
hover,
comments,
spell,
extent,
bases,
vars,
callees);
struct IndexFunc : NameMixin<IndexFunc> { struct IndexFunc : NameMixin<IndexFunc> {
using Def = FuncDef; using Def = FuncDef;
@ -163,21 +151,9 @@ struct TypeDef : NameMixin<TypeDef> {
std::vector<Usr> GetBases() const { return bases; } std::vector<Usr> GetBases() const { return bases; }
}; };
MAKE_REFLECT_STRUCT(TypeDef, MAKE_REFLECT_STRUCT(TypeDef, detailed_name, qual_name_offset, short_name_offset,
detailed_name, short_name_size, kind, hover, comments, spell, extent,
qual_name_offset, alias_of, bases, types, funcs, vars);
short_name_offset,
short_name_size,
kind,
hover,
comments,
spell,
extent,
alias_of,
bases,
types,
funcs,
vars);
struct IndexType { struct IndexType {
using Def = TypeDef; using Def = TypeDef;
@ -217,17 +193,8 @@ struct VarDef : NameMixin<VarDef> {
std::vector<Usr> GetBases() const { return {}; } std::vector<Usr> GetBases() const { return {}; }
}; };
MAKE_REFLECT_STRUCT(VarDef, MAKE_REFLECT_STRUCT(VarDef, detailed_name, qual_name_offset, short_name_offset,
detailed_name, short_name_size, hover, comments, spell, extent, type, kind,
qual_name_offset,
short_name_offset,
short_name_size,
hover,
comments,
spell,
extent,
type,
kind,
storage); storage);
struct IndexVar { struct IndexVar {

View File

@ -3,11 +3,11 @@
#include <llvm/ADT/SmallString.h> #include <llvm/ADT/SmallString.h>
#include <llvm/Support/Threading.h> #include <llvm/Support/Threading.h>
#include <iomanip>
#include <mutex>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <iomanip>
#include <mutex>
namespace ccls::log { namespace ccls::log {
static std::mutex mtx; static std::mutex mtx;
@ -52,11 +52,12 @@ Message::Message(Verbosity verbosity, const char* file, int line)
} }
Message::~Message() { Message::~Message() {
if (!file) return; if (!file)
return;
std::lock_guard<std::mutex> lock(mtx); std::lock_guard<std::mutex> lock(mtx);
stream_ << '\n'; stream_ << '\n';
fputs(stream_.str().c_str(), file); fputs(stream_.str().c_str(), file);
if (verbosity_ == Verbosity_FATAL) if (verbosity_ == Verbosity_FATAL)
abort(); abort();
} }
} } // namespace ccls::log

View File

@ -8,8 +8,7 @@
// Cache that evicts old entries which have not been used recently. Implemented // Cache that evicts old entries which have not been used recently. Implemented
// using array/linear search so this works well for small array sizes. // using array/linear search so this works well for small array sizes.
template <typename TKey, typename TValue> template <typename TKey, typename TValue> struct LruCache {
struct LruCache {
explicit LruCache(int max_entries); explicit LruCache(int max_entries);
// Fetches an entry for |key|. If it does not exist, |allocator| will be // Fetches an entry for |key|. If it does not exist, |allocator| will be
@ -26,8 +25,7 @@ struct LruCache {
// Call |func| on existing entries. If |func| returns false iteration // Call |func| on existing entries. If |func| returns false iteration
// temrinates early. // temrinates early.
template <typename TFunc> template <typename TFunc> void IterateValues(TFunc func);
void IterateValues(TFunc func);
// Empties the cache // Empties the cache
void Clear(void); void Clear(void);

View File

@ -17,8 +17,8 @@ lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const {
} }
// Reads a JsonRpc message. |read| returns the next input character. // Reads a JsonRpc message. |read| returns the next input character.
std::optional<std::string> ReadJsonRpcContentFrom( std::optional<std::string>
std::function<std::optional<char>()> read) { ReadJsonRpcContentFrom(std::function<std::optional<char>()> read) {
// Read the content length. It is terminated by the "\r\n" sequence. // Read the content length. It is terminated by the "\r\n" sequence.
int exit_seq = 0; int exit_seq = 0;
std::string stringified_content_length; std::string stringified_content_length;
@ -78,8 +78,8 @@ std::optional<char> ReadCharFromStdinBlocking() {
return std::nullopt; return std::nullopt;
} }
std::optional<std::string> MessageRegistry::ReadMessageFromStdin( std::optional<std::string>
std::unique_ptr<InMessage>* message) { MessageRegistry::ReadMessageFromStdin(std::unique_ptr<InMessage> *message) {
std::optional<std::string> content = std::optional<std::string> content =
ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking); ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking);
if (!content) { if (!content) {
@ -95,9 +95,8 @@ std::optional<std::string> MessageRegistry::ReadMessageFromStdin(
return Parse(json_reader, message); return Parse(json_reader, message);
} }
std::optional<std::string> MessageRegistry::Parse( std::optional<std::string>
Reader& visitor, MessageRegistry::Parse(Reader &visitor, std::unique_ptr<InMessage> *message) {
std::unique_ptr<InMessage>* message) {
if (!visitor.HasMember("jsonrpc") || if (!visitor.HasMember("jsonrpc") ||
std::string(visitor["jsonrpc"]->GetString()) != "2.0") { std::string(visitor["jsonrpc"]->GetString()) != "2.0") {
LOG_S(FATAL) << "Bad or missing jsonrpc version"; LOG_S(FATAL) << "Bad or missing jsonrpc version";

View File

@ -19,14 +19,13 @@ struct MessageRegistry {
std::function<void(Reader &visitor, std::unique_ptr<InMessage> *)>; std::function<void(Reader &visitor, std::unique_ptr<InMessage> *)>;
std::unordered_map<std::string, Allocator> allocators; std::unordered_map<std::string, Allocator> allocators;
std::optional<std::string> ReadMessageFromStdin( std::optional<std::string>
std::unique_ptr<InMessage>* message); ReadMessageFromStdin(std::unique_ptr<InMessage> *message);
std::optional<std::string> Parse(Reader &visitor, std::optional<std::string> Parse(Reader &visitor,
std::unique_ptr<InMessage> *message); std::unique_ptr<InMessage> *message);
}; };
template <typename T> template <typename T> struct MessageRegistryRegister {
struct MessageRegistryRegister {
MessageRegistryRegister() { MessageRegistryRegister() {
T dummy; T dummy;
std::string method_name = dummy.GetMethodType(); std::string method_name = dummy.GetMethodType();
@ -47,8 +46,7 @@ struct lsBaseOutMessage {
void Write(std::ostream &out); void Write(std::ostream &out);
}; };
template <typename TDerived> template <typename TDerived> struct lsOutMessage : lsBaseOutMessage {
struct lsOutMessage : lsBaseOutMessage {
// All derived types need to reflect on the |jsonrpc| member. // All derived types need to reflect on the |jsonrpc| member.
std::string jsonrpc = "2.0"; std::string jsonrpc = "2.0";
@ -192,8 +190,7 @@ struct lsLocationEx : lsLocation {
}; };
MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role); MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role);
template <typename T> template <typename T> struct lsCommand {
struct lsCommand {
// Title of the command (ie, 'save') // Title of the command (ie, 'save')
std::string title; std::string title;
// Actual command identifier. // Actual command identifier.
@ -212,8 +209,7 @@ void Reflect(TVisitor& visitor, lsCommand<T>& value) {
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
template <typename TData, typename TCommandArguments> template <typename TData, typename TCommandArguments> struct lsCodeLens {
struct lsCodeLens {
// The range in which this code lens is valid. Should only span a single line. // The range in which this code lens is valid. Should only span a single line.
lsRange range; lsRange range;
// The command this code lens represents. // The command this code lens represents.
@ -337,8 +333,7 @@ struct lsTextDocumentDidChangeParams {
lsVersionedTextDocumentIdentifier textDocument; lsVersionedTextDocumentIdentifier textDocument;
std::vector<lsTextDocumentContentChangeEvent> contentChanges; std::vector<lsTextDocumentContentChangeEvent> contentChanges;
}; };
MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, textDocument,
textDocument,
contentChanges); contentChanges);
// Show a message to the user. // Show a message to the user.

View File

@ -106,9 +106,9 @@ struct lsCompletionItem {
// nor with themselves. // nor with themselves.
// std::vector<TextEdit> additionalTextEdits; // std::vector<TextEdit> additionalTextEdits;
// An std::optional command that is executed *after* inserting this completion. // An std::optional command that is executed *after* inserting this
// *Note* that additional modifications to the current document should be // completion. *Note* that additional modifications to the current document
// described with the additionalTextEdits-property. Command command; // should be described with the additionalTextEdits-property. Command command;
// An data entry field that is preserved on a completion item between // An data entry field that is preserved on a completion item between
// a completion and a completion resolve request. // a completion and a completion resolve request.
@ -125,13 +125,6 @@ struct lsCompletionItem {
return label; return label;
} }
}; };
MAKE_REFLECT_STRUCT(lsCompletionItem, MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation,
label, sortText, insertText, filterText, insertTextFormat,
kind,
detail,
documentation,
sortText,
insertText,
filterText,
insertTextFormat,
textEdit); textEdit);

View File

@ -96,6 +96,5 @@ void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) {
REFLECT_MEMBER(params); REFLECT_MEMBER(params);
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, uri,
uri,
diagnostics); diagnostics);

View File

@ -28,17 +28,17 @@ std::string g_init_options;
namespace { namespace {
opt<bool> opt_help("h", desc("Alias for -help")); opt<bool> opt_help("h", desc("Alias for -help"));
opt<int> opt_verbose("v", desc("verbosity"), init(0)); opt<int> opt_verbose("v", desc("verbosity"), init(0));
opt<std::string> opt_test_index("test-index", ValueOptional, init("!"), desc("run index tests")); opt<std::string> opt_test_index("test-index", ValueOptional, init("!"),
desc("run index tests"));
opt<std::string> opt_init("init", desc("extra initialization options")); opt<std::string> opt_init("init", desc("extra initialization options"));
opt<std::string> opt_log_file("log-file", desc("log"), value_desc("filename")); opt<std::string> opt_log_file("log-file", desc("log"), value_desc("filename"));
opt<std::string> opt_log_file_append("log-file-append", desc("log"), value_desc("filename")); opt<std::string> opt_log_file_append("log-file-append", desc("log"),
value_desc("filename"));
list<std::string> opt_extra(Positional, ZeroOrMore, desc("extra")); list<std::string> opt_extra(Positional, ZeroOrMore, desc("extra"));
void CloseLog() { void CloseLog() { fclose(ccls::log::file); }
fclose(ccls::log::file);
}
} // namespace } // namespace
@ -108,11 +108,13 @@ int main(int argc, char** argv) {
sys::ChangeStdinToBinary(); sys::ChangeStdinToBinary();
sys::ChangeStdoutToBinary(); sys::ChangeStdoutToBinary();
// The thread that reads from stdin and dispatchs commands to the main thread. // The thread that reads from stdin and dispatchs commands to the main
// thread.
pipeline::LaunchStdin(); pipeline::LaunchStdin();
// The thread that writes responses from the main thread to stdout. // The thread that writes responses from the main thread to stdout.
pipeline::LaunchStdout(); pipeline::LaunchStdout();
// Main thread which also spawns indexer threads upon the "initialize" request. // Main thread which also spawns indexer threads upon the "initialize"
// request.
pipeline::MainLoop(); pipeline::MainLoop();
} }

View File

@ -19,8 +19,8 @@ std::optional<Matcher> Matcher::Create(const std::string& search) {
try { try {
Matcher m; Matcher m;
m.regex_string = search; m.regex_string = search;
m.regex = std::regex( m.regex = std::regex(search, std::regex_constants::ECMAScript |
search, std::regex_constants::ECMAScript | std::regex_constants::icase | std::regex_constants::icase |
std::regex_constants::optimize std::regex_constants::optimize
// std::regex_constants::nosubs // std::regex_constants::nosubs
); );
@ -29,8 +29,8 @@ std::optional<Matcher> Matcher::Create(const std::string& search) {
Out_ShowLogMessage out; Out_ShowLogMessage out;
out.display_type = Out_ShowLogMessage::DisplayType::Show; out.display_type = Out_ShowLogMessage::DisplayType::Show;
out.params.type = lsMessageType::Error; out.params.type = lsMessageType::Error;
out.params.message = "ccls: Parsing EMCAScript regex \"" + search + out.params.message =
"\" failed; " + e.what(); "ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what();
pipeline::WriteStdout(kMethodType_Unknown, out); pipeline::WriteStdout(kMethodType_Unknown, out);
return std::nullopt; return std::nullopt;
} }

View File

@ -4,10 +4,9 @@
#include <utility> #include <utility>
// Like std::optional, but the stored data is responsible for containing the empty // Like std::optional, but the stored data is responsible for containing the
// state. T should define a function `bool T::Valid()`. // empty state. T should define a function `bool T::Valid()`.
template <typename T> template <typename T> class Maybe {
class Maybe {
T storage; T storage;
public: public:

View File

@ -337,7 +337,8 @@ void EmitSemanticHighlighting(DB *db,
out.params.uri = lsDocumentUri::FromPath(wfile->filename); out.params.uri = lsDocumentUri::FromPath(wfile->filename);
// Transform lsRange into pair<int, int> (offset pairs) // Transform lsRange into pair<int, int> (offset pairs)
if (!g_config->highlight.lsRanges) { if (!g_config->highlight.lsRanges) {
std::vector<std::pair<lsRange, Out_CclsPublishSemanticHighlighting::Symbol *>> std::vector<
std::pair<lsRange, Out_CclsPublishSemanticHighlighting::Symbol *>>
scratch; scratch;
for (auto &entry : grouped_symbols) { for (auto &entry : grouped_symbols) {
for (auto &range : entry.second.lsRanges) for (auto &range : entry.second.lsRanges)
@ -357,11 +358,13 @@ void EmitSemanticHighlighting(DB *db,
if (uint8_t(buf[i]) < 128 || 192 <= uint8_t(buf[i])) if (uint8_t(buf[i]) < 128 || 192 <= uint8_t(buf[i]))
p++; p++;
} }
if (l < line) return true; if (l < line)
return true;
for (; c < col && i < buf.size() && buf[i] != '\n'; c++) for (; c < col && i < buf.size() && buf[i] != '\n'; c++)
if (p++, uint8_t(buf[i++]) >= 128) if (p++, uint8_t(buf[i++]) >= 128)
// Skip 0b10xxxxxx // Skip 0b10xxxxxx
while (i < buf.size() && uint8_t(buf[i]) >= 128 && uint8_t(buf[i]) < 192) while (i < buf.size() && uint8_t(buf[i]) >= 128 &&
uint8_t(buf[i]) < 192)
i++; i++;
return c < col; return c < col;
}; };

View File

@ -6,8 +6,8 @@
#include "method.h" #include "method.h"
#include "query.h" #include "query.h"
#include <optional>
#include <memory> #include <memory>
#include <optional>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@ -79,9 +79,7 @@ struct Out_CclsPublishSemanticHighlighting
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId, MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId,
parentKind, kind, storage, ranges, lsRanges); parentKind, kind, storage, ranges, lsRanges);
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols); MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols);
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method,
jsonrpc,
method,
params); params);
// Usage: // Usage:
@ -121,8 +119,7 @@ struct MessageHandler {
MessageHandler(); MessageHandler();
}; };
template <typename TMessage> template <typename TMessage> struct BaseMessageHandler : MessageHandler {
struct BaseMessageHandler : MessageHandler {
virtual void Run(TMessage *message) = 0; virtual void Run(TMessage *message) = 0;
// MessageHandler: // MessageHandler:
@ -131,17 +128,13 @@ struct BaseMessageHandler : MessageHandler {
} }
}; };
bool FindFileOrFail(DB* db, bool FindFileOrFail(DB *db, Project *project, std::optional<lsRequestId> id,
Project* project,
std::optional<lsRequestId> id,
const std::string &absolute_path, const std::string &absolute_path,
QueryFile** out_query_file, QueryFile **out_query_file, int *out_file_id = nullptr);
int* out_file_id = nullptr);
void EmitSkippedRanges(WorkingFile *working_file, void EmitSkippedRanges(WorkingFile *working_file,
const std::vector<Range> &skipped_ranges); const std::vector<Range> &skipped_ranges);
void EmitSemanticHighlighting(DB *db, void EmitSemanticHighlighting(DB *db,
SemanticHighlightSymbolCache *semantic_cache, SemanticHighlightSymbolCache *semantic_cache,
WorkingFile* working_file, WorkingFile *working_file, QueryFile *file);
QueryFile* file);

View File

@ -44,16 +44,9 @@ struct In_CclsCallHierarchy : public RequestInMessage {
int levels = 1; int levels = 1;
}; };
Params params; Params params;
}; };
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, textDocument, position, id,
textDocument, callee, callType, qualified, levels);
position,
id,
callee,
callType,
qualified,
levels);
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params); MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params);
REGISTER_IN_MESSAGE(In_CclsCallHierarchy); REGISTER_IN_MESSAGE(In_CclsCallHierarchy);
@ -72,24 +65,13 @@ struct Out_CclsCallHierarchy : public lsOutMessage<Out_CclsCallHierarchy> {
lsRequestId id; lsRequestId id;
std::optional<Entry> result; std::optional<Entry> result;
}; };
MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, id, name, location, callType,
id, numChildren, children);
name, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, jsonrpc, id,
location,
callType,
numChildren,
children);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy,
jsonrpc,
id,
result); result);
bool Expand(MessageHandler* m, bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee,
Out_CclsCallHierarchy::Entry* entry, CallType call_type, bool qualified, int levels) {
bool callee,
CallType call_type,
bool qualified,
int levels) {
const QueryFunc &func = m->db->Func(entry->usr); const QueryFunc &func = m->db->Func(entry->usr);
const QueryFunc::Def *def = func.AnyDef(); const QueryFunc::Def *def = func.AnyDef();
entry->numChildren = 0; entry->numChildren = 0;
@ -113,8 +95,7 @@ bool Expand(MessageHandler* m,
if (const auto *def = func.AnyDef()) if (const auto *def = func.AnyDef())
for (SymbolRef ref : def->callees) for (SymbolRef ref : def->callees)
if (ref.kind == SymbolKind::Func) if (ref.kind == SymbolKind::Func)
handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id},
def->file_id},
call_type); call_type);
} else { } else {
for (Use use : func.uses) for (Use use : func.uses)
@ -165,14 +146,11 @@ bool Expand(MessageHandler* m,
return true; return true;
} }
struct Handler_CclsCallHierarchy struct Handler_CclsCallHierarchy : BaseMessageHandler<In_CclsCallHierarchy> {
: BaseMessageHandler<In_CclsCallHierarchy> {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
std::optional<Out_CclsCallHierarchy::Entry> BuildInitial(Usr root_usr, std::optional<Out_CclsCallHierarchy::Entry>
bool callee, BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified,
CallType call_type,
bool qualified,
int levels) { int levels) {
const auto *def = db->Func(root_usr).AnyDef(); const auto *def = db->Func(root_usr).AnyDef();
if (!def) if (!def)

View File

@ -3,14 +3,8 @@
#include "query_utils.h" #include "query_utils.h"
using namespace ccls; using namespace ccls;
MAKE_REFLECT_STRUCT(QueryFile::Def, MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, outline, all_symbols,
path, skipped_ranges, dependencies);
args,
language,
outline,
all_symbols,
skipped_ranges,
dependencies);
namespace { namespace {
MethodType kMethodType = "$ccls/fileInfo"; MethodType kMethodType = "$ccls/fileInfo";

View File

@ -1,8 +1,8 @@
#include "match.h" #include "match.h"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh"
#include "platform.h" #include "platform.h"
#include "project.h" #include "project.h"
#include "pipeline.hh"
#include "working_files.h" #include "working_files.h"
using namespace ccls; using namespace ccls;
@ -21,9 +21,7 @@ struct In_CclsFreshenIndex : public NotificationInMessage {
}; };
Params params; Params params;
}; };
MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, dependencies, whitelist,
dependencies,
whitelist,
blacklist); blacklist);
MAKE_REFLECT_STRUCT(In_CclsFreshenIndex, params); MAKE_REFLECT_STRUCT(In_CclsFreshenIndex, params);
REGISTER_IN_MESSAGE(In_CclsFreshenIndex); REGISTER_IN_MESSAGE(In_CclsFreshenIndex);

View File

@ -51,31 +51,17 @@ struct Out_CclsInheritanceHierarchy
lsRequestId id; lsRequestId id;
std::optional<Entry> result; std::optional<Entry> result;
}; };
MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, id, kind, name,
id, location, numChildren, children);
kind, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, jsonrpc,
name, id, result);
location,
numChildren,
children);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy,
jsonrpc,
id,
result);
bool Expand(MessageHandler* m, bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
Out_CclsInheritanceHierarchy::Entry* entry, bool derived, bool qualified, int levels);
bool derived,
bool qualified,
int levels);
template <typename Q> template <typename Q>
bool ExpandHelper(MessageHandler* m, bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
Out_CclsInheritanceHierarchy::Entry* entry, bool derived, bool qualified, int levels, Q &entity) {
bool derived,
bool qualified,
int levels,
Q& entity) {
const auto *def = entity.AnyDef(); const auto *def = entity.AnyDef();
if (def) { if (def) {
entry->name = def->Name(qualified); entry->name = def->Name(qualified);
@ -122,11 +108,8 @@ bool ExpandHelper(MessageHandler* m,
return true; return true;
} }
bool Expand(MessageHandler* m, bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
Out_CclsInheritanceHierarchy::Entry* entry, bool derived, bool qualified, int levels) {
bool derived,
bool qualified,
int levels) {
if (entry->kind == SymbolKind::Func) if (entry->kind == SymbolKind::Func)
return ExpandHelper(m, entry, derived, qualified, levels, return ExpandHelper(m, entry, derived, qualified, levels,
m->db->Func(entry->usr)); m->db->Func(entry->usr));
@ -173,8 +156,7 @@ struct Handler_CclsInheritanceHierarchy
if (!FindFileOrFail(db, project, request->id, if (!FindFileOrFail(db, project, request->id,
params.textDocument.uri.GetPath(), &file)) params.textDocument.uri.GetPath(), &file))
return; return;
WorkingFile* wfile = WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
working_files->GetFileByFilename(file->def->path);
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position))
if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) { if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) {

View File

@ -30,17 +30,12 @@ struct In_CclsMemberHierarchy : public RequestInMessage {
Params params; Params params;
}; };
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id,
textDocument, qualified, levels);
position,
id,
qualified,
levels);
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params); MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params);
REGISTER_IN_MESSAGE(In_CclsMemberHierarchy); REGISTER_IN_MESSAGE(In_CclsMemberHierarchy);
struct Out_CclsMemberHierarchy struct Out_CclsMemberHierarchy : public lsOutMessage<Out_CclsMemberHierarchy> {
: public lsOutMessage<Out_CclsMemberHierarchy> {
struct Entry { struct Entry {
Usr usr; Usr usr;
std::string id; std::string id;
@ -56,30 +51,17 @@ struct Out_CclsMemberHierarchy
lsRequestId id; lsRequestId id;
std::optional<Entry> result; std::optional<Entry> result;
}; };
MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, id, name, fieldName,
id, location, numChildren, children);
name, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, jsonrpc, id,
fieldName,
location,
numChildren,
children);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy,
jsonrpc,
id,
result); result);
bool Expand(MessageHandler* m, bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
Out_CclsMemberHierarchy::Entry* entry, bool qualified, int levels);
bool qualified,
int levels);
// Add a field to |entry| which is a Func/Type. // Add a field to |entry| which is a Func/Type.
void DoField(MessageHandler* m, void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
Out_CclsMemberHierarchy::Entry* entry, const QueryVar &var, int64_t offset, bool qualified, int levels) {
const QueryVar& var,
int64_t offset,
bool qualified,
int levels) {
const QueryVar::Def *def1 = var.AnyDef(); const QueryVar::Def *def1 = var.AnyDef();
if (!def1) if (!def1)
return; return;
@ -120,10 +102,8 @@ void DoField(MessageHandler* m,
} }
// Expand a type node by adding members recursively to it. // Expand a type node by adding members recursively to it.
bool Expand(MessageHandler* m, bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
Out_CclsMemberHierarchy::Entry* entry, bool qualified, int levels) {
bool qualified,
int levels) {
if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) { if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) {
entry->name = ClangBuiltinTypeName(int(entry->usr)); entry->name = ClangBuiltinTypeName(int(entry->usr));
return true; return true;
@ -193,10 +173,8 @@ struct Handler_CclsMemberHierarchy
: BaseMessageHandler<In_CclsMemberHierarchy> { : BaseMessageHandler<In_CclsMemberHierarchy> {
MethodType GetMethodType() const override { return kMethodType; } MethodType GetMethodType() const override { return kMethodType; }
std::optional<Out_CclsMemberHierarchy::Entry> BuildInitial(SymbolKind kind, std::optional<Out_CclsMemberHierarchy::Entry>
Usr root_usr, BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) {
bool qualified,
int levels) {
switch (kind) { switch (kind) {
default: default:
return {}; return {};
@ -260,15 +238,14 @@ struct Handler_CclsMemberHierarchy
if (!FindFileOrFail(db, project, request->id, if (!FindFileOrFail(db, project, request->id,
params.textDocument.uri.GetPath(), &file)) params.textDocument.uri.GetPath(), &file))
return; return;
WorkingFile* wfile = WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
working_files->GetFileByFilename(file->def->path);
for (SymbolRef sym : for (SymbolRef sym :
FindSymbolsAtLocation(wfile, file, params.position)) { FindSymbolsAtLocation(wfile, file, params.position)) {
switch (sym.kind) { switch (sym.kind) {
case SymbolKind::Func: case SymbolKind::Func:
case SymbolKind::Type: case SymbolKind::Type:
out.result = BuildInitial(sym.kind, sym.usr, params.qualified, out.result =
params.levels); BuildInitial(sym.kind, sym.usr, params.qualified, params.levels);
break; break;
case SymbolKind::Var: { case SymbolKind::Var: {
const QueryVar::Def *def = db->GetVar(sym).AnyDef(); const QueryVar::Def *def = db->GetVar(sym).AnyDef();

View File

@ -1,6 +1,6 @@
#include "message_handler.h" #include "message_handler.h"
#include "query_utils.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h"
using namespace ccls; using namespace ccls;
namespace { namespace {
@ -15,10 +15,7 @@ struct In_CclsVars : public RequestInMessage {
unsigned kind = ~0u; unsigned kind = ~0u;
} params; } params;
}; };
MAKE_REFLECT_STRUCT(In_CclsVars::Params, MAKE_REFLECT_STRUCT(In_CclsVars::Params, textDocument, position, kind);
textDocument,
position,
kind);
MAKE_REFLECT_STRUCT(In_CclsVars, id, params); MAKE_REFLECT_STRUCT(In_CclsVars, id, params);
REGISTER_IN_MESSAGE(In_CclsVars); REGISTER_IN_MESSAGE(In_CclsVars);

View File

@ -10,9 +10,7 @@ REGISTER_IN_MESSAGE(In_Exit);
struct Handler_Exit : MessageHandler { struct Handler_Exit : MessageHandler {
MethodType GetMethodType() const override { return kMethodType_Exit; } MethodType GetMethodType() const override { return kMethodType_Exit; }
void Run(std::unique_ptr<InMessage> request) override { void Run(std::unique_ptr<InMessage> request) override { exit(0); }
exit(0);
}
}; };
REGISTER_MESSAGE_HANDLER(Handler_Exit); REGISTER_MESSAGE_HANDLER(Handler_Exit);
} // namespace } // namespace

View File

@ -55,8 +55,7 @@ struct lsDocumentOnTypeFormattingOptions {
// More trigger characters. // More trigger characters.
std::vector<std::string> moreTriggerCharacter; std::vector<std::string> moreTriggerCharacter;
}; };
MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter,
firstTriggerCharacter,
moreTriggerCharacter); moreTriggerCharacter);
// Document link options // Document link options
@ -119,12 +118,8 @@ struct lsTextDocumentSyncOptions {
// Save notifications are sent to the server. // Save notifications are sent to the server.
std::optional<lsSaveOptions> save; std::optional<lsSaveOptions> save;
}; };
MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, change, willSave,
openClose, willSaveWaitUntil, save);
change,
willSave,
willSaveWaitUntil,
save);
struct lsServerCapabilities { struct lsServerCapabilities {
// Defines how text documents are synced. Is either a detailed structure // Defines how text documents are synced. Is either a detailed structure
@ -161,7 +156,8 @@ struct lsServerCapabilities {
// The server provides document range formatting. // The server provides document range formatting.
bool documentRangeFormattingProvider = false; bool documentRangeFormattingProvider = false;
// The server provides document formatting on typing. // The server provides document formatting on typing.
std::optional<lsDocumentOnTypeFormattingOptions> documentOnTypeFormattingProvider; std::optional<lsDocumentOnTypeFormattingOptions>
documentOnTypeFormattingProvider;
// The server provides rename support. // The server provides rename support.
bool renameProvider = true; bool renameProvider = true;
// The server provides document link support. // The server provides document link support.
@ -169,25 +165,15 @@ struct lsServerCapabilities {
// The server provides execute command support. // The server provides execute command support.
lsExecuteCommandOptions executeCommandProvider; lsExecuteCommandOptions executeCommandProvider;
}; };
MAKE_REFLECT_STRUCT(lsServerCapabilities, MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider,
textDocumentSync, completionProvider, signatureHelpProvider,
hoverProvider, definitionProvider, typeDefinitionProvider,
completionProvider, referencesProvider, documentHighlightProvider,
signatureHelpProvider, documentSymbolProvider, workspaceSymbolProvider,
definitionProvider, codeActionProvider, codeLensProvider,
typeDefinitionProvider, documentFormattingProvider, documentRangeFormattingProvider,
referencesProvider, documentOnTypeFormattingProvider, renameProvider,
documentHighlightProvider, documentLinkProvider, executeCommandProvider);
documentSymbolProvider,
workspaceSymbolProvider,
codeActionProvider,
codeLensProvider,
documentFormattingProvider,
documentRangeFormattingProvider,
documentOnTypeFormattingProvider,
renameProvider,
documentLinkProvider,
executeCommandProvider);
// Workspace specific client capabilities. // Workspace specific client capabilities.
struct lsWorkspaceClientCapabilites { struct lsWorkspaceClientCapabilites {
@ -226,12 +212,8 @@ MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit,
documentChanges); documentChanges);
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg, MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg,
dynamicRegistration); dynamicRegistration);
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, applyEdit, workspaceEdit,
applyEdit, didChangeConfiguration, didChangeWatchedFiles, symbol,
workspaceEdit,
didChangeConfiguration,
didChangeWatchedFiles,
symbol,
executeCommand); executeCommand);
// Text document specific client capabilities. // Text document specific client capabilities.
@ -287,13 +269,9 @@ struct lsTextDocumentClientCapabilities {
}; };
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization, MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization,
dynamicRegistration, dynamicRegistration, willSave, willSaveWaitUntil, didSave);
willSave,
willSaveWaitUntil,
didSave);
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion, MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion,
dynamicRegistration, dynamicRegistration, completionItem);
completionItem);
MAKE_REFLECT_STRUCT( MAKE_REFLECT_STRUCT(
lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem, lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem,
snippetSupport); snippetSupport);
@ -301,12 +279,9 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg,
dynamicRegistration); dynamicRegistration);
MAKE_REFLECT_STRUCT( MAKE_REFLECT_STRUCT(
lsTextDocumentClientCapabilities::CodeLensRegistrationOptions, lsTextDocumentClientCapabilities::CodeLensRegistrationOptions,
dynamicRegistration, dynamicRegistration, resolveProvider);
resolveProvider); MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, synchronization,
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, completion, rename);
synchronization,
completion,
rename);
struct lsClientCapabilities { struct lsClientCapabilities {
// Workspace specific client capabilities. // Workspace specific client capabilities.
@ -382,13 +357,8 @@ void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) {
} }
#endif #endif
MAKE_REFLECT_STRUCT(lsInitializeParams, MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri,
processId, initializationOptions, capabilities, trace);
rootPath,
rootUri,
initializationOptions,
capabilities,
trace);
struct lsInitializeError { struct lsInitializeError {
// Indicates whether the client should retry to send the // Indicates whether the client should retry to send the
@ -508,7 +478,8 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
std::string name = "indexer" + std::to_string(i); std::string name = "indexer" + std::to_string(i);
set_thread_name(name.c_str()); set_thread_name(name.c_str());
pipeline::Indexer_Main(diag_pub, vfs, project, working_files); pipeline::Indexer_Main(diag_pub, vfs, project, working_files);
}).detach(); })
.detach();
} }
// Start scanning include directories before dispatching project // Start scanning include directories before dispatching project

View File

@ -33,10 +33,8 @@ struct In_TextDocumentCodeAction : public RequestInMessage {
}; };
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext, MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext,
diagnostics); diagnostics);
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, textDocument,
textDocument, range, context);
range,
context);
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params); MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params);
REGISTER_IN_MESSAGE(In_TextDocumentCodeAction); REGISTER_IN_MESSAGE(In_TextDocumentCodeAction);
@ -74,4 +72,4 @@ struct Handler_TextDocumentCodeAction
} }
}; };
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction); REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction);
} } // namespace

View File

@ -1,8 +1,8 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "lsp_code_action.h" #include "lsp_code_action.h"
#include "message_handler.h" #include "message_handler.h"
#include "query_utils.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h"
using namespace ccls; using namespace ccls;
namespace { namespace {
@ -41,12 +41,9 @@ Use OffsetStartColumn(Use use, int16_t offset) {
return use; return use;
} }
void AddCodeLens(const char* singular, void AddCodeLens(const char *singular, const char *plural,
const char* plural, CommonCodeLensParams *common, Use use,
CommonCodeLensParams* common, const std::vector<Use> &uses, bool force_display) {
Use use,
const std::vector<Use>& uses,
bool force_display) {
TCodeLens code_lens; TCodeLens code_lens;
std::optional<lsRange> range = GetLsRange(common->working_file, use.range); std::optional<lsRange> range = GetLsRange(common->working_file, use.range);
if (!range) if (!range)
@ -166,10 +163,9 @@ struct Handler_TextDocumentCodeLens
false /*force_display*/); false /*force_display*/);
} }
AddCodeLens("derived", "derived", &common, AddCodeLens(
OffsetStartColumn(use, offset++), "derived", "derived", &common, OffsetStartColumn(use, offset++),
GetFuncDeclarations(db, func.derived), GetFuncDeclarations(db, func.derived), false /*force_display*/);
false /*force_display*/);
// "Base" // "Base"
if (def->bases.size() == 1) { if (def->bases.size() == 1) {
@ -214,8 +210,8 @@ struct Handler_TextDocumentCodeLens
if (def->kind == lsSymbolKind::Macro) if (def->kind == lsSymbolKind::Macro)
force_display = false; force_display = false;
AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), var.uses,
var.uses, force_display); force_display);
break; break;
} }
case SymbolKind::File: case SymbolKind::File:

View File

@ -104,8 +104,7 @@ struct ParseIncludeLineResult {
}; };
ParseIncludeLineResult ParseIncludeLine(const std::string &line) { ParseIncludeLineResult ParseIncludeLine(const std::string &line) {
static const std::regex pattern( static const std::regex pattern("(\\s*)" // [1]: spaces before '#'
"(\\s*)" // [1]: spaces before '#'
"#" // "#" //
"(\\s*)" // [2]: spaces after '#' "(\\s*)" // [2]: spaces after '#'
"([^\\s\"<]*)" // [3]: "include" "([^\\s\"<]*)" // [3]: "include"
@ -123,8 +122,8 @@ static const std::vector<std::string> preprocessorKeywords = {
"define", "undef", "include", "if", "ifdef", "ifndef", "define", "undef", "include", "if", "ifdef", "ifndef",
"else", "elif", "endif", "line", "error", "pragma"}; "else", "elif", "endif", "line", "error", "pragma"};
std::vector<lsCompletionItem> PreprocessorKeywordCompletionItems( std::vector<lsCompletionItem>
const std::smatch& match) { PreprocessorKeywordCompletionItems(const std::smatch &match) {
std::vector<lsCompletionItem> items; std::vector<lsCompletionItem> items;
for (auto &keyword : preprocessorKeywords) { for (auto &keyword : preprocessorKeywords) {
lsCompletionItem item; lsCompletionItem item;
@ -140,10 +139,8 @@ std::vector<lsCompletionItem> PreprocessorKeywordCompletionItems(
return items; return items;
} }
template <typename T> template <typename T> char *tofixedbase64(T input, char *out) {
char* tofixedbase64(T input, char* out) { const char *digits = "./0123456789"
const char* digits =
"./0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"; "abcdefghijklmnopqrstuvwxyz";
int len = (sizeof(T) * 8 - 1) / 6 + 1; int len = (sizeof(T) * 8 - 1) / 6 + 1;
@ -160,8 +157,7 @@ char* tofixedbase64(T input, char* out) {
// when given 1000+ completion items. // when given 1000+ completion items.
void FilterAndSortCompletionResponse( void FilterAndSortCompletionResponse(
Out_TextDocumentComplete *complete_response, Out_TextDocumentComplete *complete_response,
const std::string& complete_text, const std::string &complete_text, bool has_open_paren) {
bool has_open_paren) {
if (!g_config->completion.filterAndSort) if (!g_config->completion.filterAndSort)
return; return;
@ -240,7 +236,8 @@ bool IsOpenParenOrAngle(const std::vector<std::string>& lines,
return false; return false;
if (line[c] == '(' || line[c] == '<') if (line[c] == '(' || line[c] == '<')
return true; return true;
if (!isspace(line[c])) break; if (!isspace(line[c]))
break;
if (++c >= line.size()) { if (++c >= line.size()) {
c = 0; c = 0;
l++; l++;
@ -351,7 +348,8 @@ struct Handler_TextDocumentCompletion : MessageHandler {
lock.lock(); lock.lock();
std::string quote = result.match[5]; std::string quote = result.match[5];
for (auto &item : include_complete->completion_items) for (auto &item : include_complete->completion_items)
if (quote.empty() || quote == (item.use_angle_brackets_ ? "<" : "\"")) if (quote.empty() ||
quote == (item.use_angle_brackets_ ? "<" : "\""))
out.result.items.push_back(item); out.result.items.push_back(item);
} }
FilterAndSortCompletionResponse(&out, result.pattern, has_open_paren); FilterAndSortCompletionResponse(&out, result.pattern, has_open_paren);
@ -376,7 +374,8 @@ struct Handler_TextDocumentCompletion : MessageHandler {
out.result.items = results; out.result.items = results;
// Emit completion results. // Emit completion results.
FilterAndSortCompletionResponse(&out, existing_completion, has_open_paren); FilterAndSortCompletionResponse(&out, existing_completion,
has_open_paren);
pipeline::WriteStdout(kMethodType, out); pipeline::WriteStdout(kMethodType, out);
// Cache completion results. // Cache completion results.

View File

@ -3,9 +3,9 @@
#include "query_utils.h" #include "query_utils.h"
using namespace ccls; using namespace ccls;
#include <cstdlib>
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <cstdlib>
namespace { namespace {
MethodType kMethodType = "textDocument/definition"; MethodType kMethodType = "textDocument/definition";
@ -62,8 +62,7 @@ struct Handler_TextDocumentDefinition
Maybe<Use> on_def; Maybe<Use> on_def;
bool has_symbol = false; bool has_symbol = false;
WorkingFile* wfile = WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
working_files->GetFileByFilename(file->def->path);
lsPosition &ls_pos = params.position; lsPosition &ls_pos = params.position;
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) { for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) {

View File

@ -1,8 +1,8 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh"
#include "project.h" #include "project.h"
#include "working_files.h" #include "working_files.h"
#include "pipeline.hh"
using namespace ccls; using namespace ccls;
namespace { namespace {

View File

@ -1,8 +1,8 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "include_complete.h" #include "include_complete.h"
#include "message_handler.h" #include "message_handler.h"
#include "project.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h"
#include "working_files.h" #include "working_files.h"
using namespace ccls; using namespace ccls;

View File

@ -1,7 +1,7 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "message_handler.h" #include "message_handler.h"
#include "project.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h"
using namespace ccls; using namespace ccls;
namespace { namespace {

View File

@ -21,8 +21,7 @@ std::optional<lsMarkedString> GetComments(DB* db, SymbolRef sym) {
} }
// Returns the hover or detailed name for `sym`, if any. // Returns the hover or detailed name for `sym`, if any.
std::optional<lsMarkedString> GetHoverOrName(DB* db, std::optional<lsMarkedString> GetHoverOrName(DB *db, LanguageId lang,
LanguageId lang,
SymbolRef sym) { SymbolRef sym) {
std::optional<lsMarkedString> ret; std::optional<lsMarkedString> ret;
WithEntity(db, sym, [&](const auto &entity) { WithEntity(db, sym, [&](const auto &entity) {
@ -58,9 +57,7 @@ struct Out_TextDocumentHover : public lsOutMessage<Out_TextDocumentHover> {
std::optional<Result> result; std::optional<Result> result;
}; };
MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range); MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range);
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, jsonrpc, id,
jsonrpc,
id,
result); result);
struct Handler_TextDocumentHover : BaseMessageHandler<In_TextDocumentHover> { struct Handler_TextDocumentHover : BaseMessageHandler<In_TextDocumentHover> {

View File

@ -1,6 +1,6 @@
#include "message_handler.h" #include "message_handler.h"
#include "query_utils.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h"
using namespace ccls; using namespace ccls;
namespace { namespace {

View File

@ -27,14 +27,9 @@ struct In_TextDocumentReferences : public RequestInMessage {
Params params; Params params;
}; };
MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, base,
base, excludeRole, includeDeclaration, role);
excludeRole, MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position,
includeDeclaration,
role);
MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params,
textDocument,
position,
context); context);
MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params); MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params);
REGISTER_IN_MESSAGE(In_TextDocumentReferences); REGISTER_IN_MESSAGE(In_TextDocumentReferences);
@ -57,8 +52,7 @@ struct Handler_TextDocumentReferences
params.textDocument.uri.GetPath(), &file)) params.textDocument.uri.GetPath(), &file))
return; return;
WorkingFile* wfile = WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
working_files->GetFileByFilename(file->def->path);
Out_TextDocumentReferences out; Out_TextDocumentReferences out;
out.id = request->id; out.id = request->id;
@ -133,8 +127,7 @@ struct Handler_TextDocumentReferences
// Another file |file1| has the same include line. // Another file |file1| has the same include line.
lsLocationEx result; lsLocationEx result;
result.uri = lsDocumentUri::FromPath(file1.def->path); result.uri = lsDocumentUri::FromPath(file1.def->path);
result.range.start.line = result.range.end.line = result.range.start.line = result.range.end.line = include.line;
include.line;
out.result.push_back(std::move(result)); out.result.push_back(std::move(result));
break; break;
} }

View File

@ -1,19 +1,18 @@
#include "message_handler.h" #include "message_handler.h"
#include "query_utils.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h"
using namespace ccls; using namespace ccls;
namespace { namespace {
MethodType kMethodType = "textDocument/rename"; MethodType kMethodType = "textDocument/rename";
lsWorkspaceEdit BuildWorkspaceEdit(DB* db, lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files,
WorkingFiles* working_files, SymbolRef sym, const std::string &new_text) {
SymbolRef sym,
const std::string& new_text) {
std::unordered_map<int, lsTextDocumentEdit> path_to_edit; std::unordered_map<int, lsTextDocumentEdit> path_to_edit;
EachOccurrence(db, sym, true, [&](Use use) { EachOccurrence(db, sym, true, [&](Use use) {
std::optional<lsLocation> ls_location = GetLsLocation(db, working_files, use); std::optional<lsLocation> ls_location =
GetLsLocation(db, working_files, use);
if (!ls_location) if (!ls_location)
return; return;
@ -65,9 +64,7 @@ struct In_TextDocumentRename : public RequestInMessage {
}; };
Params params; Params params;
}; };
MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, textDocument, position,
textDocument,
position,
newName); newName);
MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params); MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params);
REGISTER_IN_MESSAGE(In_TextDocumentRename); REGISTER_IN_MESSAGE(In_TextDocumentRename);

View File

@ -70,9 +70,7 @@ struct lsSignatureHelp {
// active signature does have any. // active signature does have any.
std::optional<int> activeParameter; std::optional<int> activeParameter;
}; };
MAKE_REFLECT_STRUCT(lsSignatureHelp, MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature,
signatures,
activeSignature,
activeParameter); activeParameter);
struct Out_TextDocumentSignatureHelp struct Out_TextDocumentSignatureHelp

View File

@ -1,7 +1,7 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "message_handler.h" #include "message_handler.h"
#include "project.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h"
#include "working_files.h" #include "working_files.h"
using namespace ccls; using namespace ccls;

View File

@ -1,7 +1,7 @@
#include "clang_complete.h" #include "clang_complete.h"
#include "message_handler.h" #include "message_handler.h"
#include "project.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "project.h"
#include "working_files.h" #include "working_files.h"
using namespace ccls; using namespace ccls;

View File

@ -1,7 +1,7 @@
#include "lsp_code_action.h" #include "lsp_code_action.h"
#include "message_handler.h" #include "message_handler.h"
#include "query_utils.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "query_utils.h"
using namespace ccls; using namespace ccls;
namespace { namespace {

View File

@ -4,20 +4,17 @@
#include "query_utils.h" #include "query_utils.h"
using namespace ccls; using namespace ccls;
#include <ctype.h>
#include <limits.h>
#include <algorithm> #include <algorithm>
#include <ctype.h>
#include <functional> #include <functional>
#include <limits.h>
namespace { namespace {
MethodType kMethodType = "workspace/symbol"; MethodType kMethodType = "workspace/symbol";
// Lookup |symbol| in |db| and insert the value into |result|. // Lookup |symbol| in |db| and insert the value into |result|.
bool AddSymbol( bool AddSymbol(
DB* db, DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed,
WorkingFiles* working_files,
SymbolIdx sym,
bool use_detailed,
std::vector<std::tuple<lsSymbolInformation, int, SymbolIdx>> *result) { std::vector<std::tuple<lsSymbolInformation, int, SymbolIdx>> *result) {
std::optional<lsSymbolInformation> info = std::optional<lsSymbolInformation> info =
GetSymbolInfo(db, working_files, sym, true); GetSymbolInfo(db, working_files, sym, true);
@ -102,7 +99,8 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler<In_WorkspaceSymbol> {
goto done_add; goto done_add;
done_add: done_add:
if (g_config->workspaceSymbol.sort && query.size() <= FuzzyMatcher::kMaxPat) { if (g_config->workspaceSymbol.sort &&
query.size() <= FuzzyMatcher::kMaxPat) {
// Sort results with a fuzzy matching algorithm. // Sort results with a fuzzy matching algorithm.
int longest = 0; int longest = 0;
for (auto &cand : cands) for (auto &cand : cands)

View File

@ -4,8 +4,7 @@ MethodType kMethodType_Unknown = "$unknown";
MethodType kMethodType_Exit = "exit"; MethodType kMethodType_Exit = "exit";
MethodType kMethodType_TextDocumentPublishDiagnostics = MethodType kMethodType_TextDocumentPublishDiagnostics =
"textDocument/publishDiagnostics"; "textDocument/publishDiagnostics";
MethodType kMethodType_CclsPublishSkippedRanges = MethodType kMethodType_CclsPublishSkippedRanges = "$ccls/publishSkippedRanges";
"$ccls/publishSkippedRanges";
MethodType kMethodType_CclsPublishSemanticHighlighting = MethodType kMethodType_CclsPublishSemanticHighlighting =
"$ccls/publishSemanticHighlighting"; "$ccls/publishSemanticHighlighting";

View File

@ -35,14 +35,10 @@ struct InMessage {
struct RequestInMessage : public InMessage { struct RequestInMessage : public InMessage {
// number or string, actually no null // number or string, actually no null
lsRequestId id; lsRequestId id;
lsRequestId GetRequestId() const override { lsRequestId GetRequestId() const override { return id; }
return id;
}
}; };
// NotificationInMessage does not have |id|. // NotificationInMessage does not have |id|.
struct NotificationInMessage : public InMessage { struct NotificationInMessage : public InMessage {
lsRequestId GetRequestId() const override { lsRequestId GetRequestId() const override { return lsRequestId(); }
return lsRequestId();
}
}; };

View File

@ -6,10 +6,10 @@
#include "log.hh" #include "log.hh"
#include "lsp.h" #include "lsp.h"
#include "message_handler.h" #include "message_handler.h"
#include "pipeline.hh"
#include "platform.h" #include "platform.h"
#include "project.h" #include "project.h"
#include "query_utils.h" #include "query_utils.h"
#include "pipeline.hh"
#include <llvm/ADT/Twine.h> #include <llvm/ADT/Twine.h>
#include <llvm/Support/Threading.h> #include <llvm/Support/Threading.h>
@ -52,7 +52,8 @@ void DiagnosticsPublisher::Publish(WorkingFiles* working_files,
Out_TextDocumentPublishDiagnostics out; Out_TextDocumentPublishDiagnostics out;
out.params.uri = lsDocumentUri::FromPath(path); out.params.uri = lsDocumentUri::FromPath(path);
out.params.diagnostics = diagnostics; out.params.diagnostics = diagnostics;
ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics, out); ccls::pipeline::WriteStdout(kMethodType_TextDocumentPublishDiagnostics,
out);
} }
} }
@ -92,7 +93,8 @@ bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path,
} }
if (prev->args != args) { if (prev->args != args) {
LOG_S(INFO) << "args changed for " << path << (from ? " (via " + *from + ")" : std::string()); LOG_S(INFO) << "args changed for " << path
<< (from ? " (via " + *from + ")" : std::string());
return true; return true;
} }
@ -122,8 +124,7 @@ std::string GetCachePath(const std::string& source_file) {
return g_config->cacheDirectory + cache_file; return g_config->cacheDirectory + cache_file;
} }
std::unique_ptr<IndexFile> RawCacheLoad( std::unique_ptr<IndexFile> RawCacheLoad(const std::string &path) {
const std::string& path) {
std::string cache_path = GetCachePath(path); std::string cache_path = GetCachePath(path);
std::optional<std::string> file_content = ReadContent(cache_path); std::optional<std::string> file_content = ReadContent(cache_path);
std::optional<std::string> serialized_indexed_content = std::optional<std::string> serialized_indexed_content =
@ -136,10 +137,8 @@ std::unique_ptr<IndexFile> RawCacheLoad(
IndexFile::kMajorVersion); IndexFile::kMajorVersion);
} }
bool Indexer_Parse(DiagnosticsPublisher* diag_pub, bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files,
WorkingFiles* working_files, Project *project, VFS *vfs) {
Project* project,
VFS* vfs) {
std::optional<Index_Request> opt_request = index_request->TryPopFront(); std::optional<Index_Request> opt_request = index_request->TryPopFront();
if (!opt_request) if (!opt_request)
return false; return false;
@ -218,7 +217,8 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub,
LOG_S(INFO) << "parse " << path_to_index; LOG_S(INFO) << "parse " << path_to_index;
auto indexes = idx::Index(vfs, entry.directory, path_to_index, entry.args, {}); auto indexes =
idx::Index(vfs, entry.directory, path_to_index, entry.args, {});
if (indexes.empty()) { if (indexes.empty()) {
if (g_config->index.enabled && request.id.Valid()) { if (g_config->index.enabled && request.id.Valid()) {
@ -288,22 +288,19 @@ void Init() {
for_stdout = new ThreadedQueue<Stdout_Request>(stdout_waiter); for_stdout = new ThreadedQueue<Stdout_Request>(stdout_waiter);
} }
void Indexer_Main(DiagnosticsPublisher* diag_pub, void Indexer_Main(DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project,
VFS* vfs,
Project* project,
WorkingFiles *working_files) { WorkingFiles *working_files) {
while (true) while (true)
if (!Indexer_Parse(diag_pub, working_files, project, vfs)) if (!Indexer_Parse(diag_pub, working_files, project, vfs))
indexer_waiter->Wait(index_request); indexer_waiter->Wait(index_request);
} }
void Main_OnIndexed(DB* db, void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache,
SemanticHighlightSymbolCache* semantic_cache, WorkingFiles *working_files, IndexUpdate *update) {
WorkingFiles* working_files,
IndexUpdate* update) {
if (update->refresh) { if (update->refresh) {
Project::loaded = true; Project::loaded = true;
LOG_S(INFO) << "loaded project. Refresh semantic highlight for all working file."; LOG_S(INFO)
<< "loaded project. Refresh semantic highlight for all working file.";
std::lock_guard<std::mutex> lock(working_files->files_mutex); std::lock_guard<std::mutex> lock(working_files->files_mutex);
for (auto &f : working_files->files) { for (auto &f : working_files->files) {
std::string filename = LowerPathIfInsensitive(f->filename); std::string filename = LowerPathIfInsensitive(f->filename);
@ -369,7 +366,8 @@ void LaunchStdin() {
if (method_type == kMethodType_Exit) if (method_type == kMethodType_Exit)
break; break;
} }
}).detach(); })
.detach();
} }
void LaunchStdout() { void LaunchStdout() {
@ -392,7 +390,8 @@ void LaunchStdout() {
#endif #endif
} }
} }
}).detach(); })
.detach();
} }
void MainLoop() { void MainLoop() {
@ -412,8 +411,7 @@ void MainLoop() {
Out_Error out; Out_Error out;
out.id = id; out.id = id;
out.error.code = lsErrorCodes::InternalError; out.error.code = lsErrorCodes::InternalError;
out.error.message = out.error.message = "Dropping completion request; a newer request "
"Dropping completion request; a newer request "
"has come in that will be serviced instead."; "has come in that will be serviced instead.";
pipeline::WriteStdout(kMethodType_Unknown, out); pipeline::WriteStdout(kMethodType_Unknown, out);
} }
@ -473,10 +471,8 @@ void MainLoop() {
} }
} }
void Index(const std::string& path, void Index(const std::string &path, const std::vector<std::string> &args,
const std::vector<std::string>& args, bool interactive, lsRequestId id) {
bool interactive,
lsRequestId id) {
index_request->PushBack({path, args, interactive, id}, interactive); index_request->PushBack({path, args, interactive, id}, interactive);
} }
@ -494,4 +490,4 @@ void WriteStdout(MethodType method, lsBaseOutMessage& response) {
for_stdout->PushBack(std::move(out)); for_stdout->PushBack(std::move(out));
} }
} } // namespace ccls::pipeline

View File

@ -14,10 +14,10 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> // required for stat.h #include <sys/types.h> // required for stat.h
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h>
#ifdef __GLIBC__ #ifdef __GLIBC__
#include <malloc.h> #include <malloc.h>
#endif #endif

View File

@ -49,8 +49,7 @@ struct Range {
}; };
namespace std { namespace std {
template <> template <> struct hash<Range> {
struct hash<Range> {
std::size_t operator()(Range x) const { std::size_t operator()(Range x) const {
union U { union U {
Range range = {}; Range range = {};
@ -61,7 +60,7 @@ struct hash<Range> {
return hash<uint64_t>()(u.u64); return hash<uint64_t>()(u.u64);
} }
}; };
} } // namespace std
// Reflection // Reflection
class Reader; class Reader;

View File

@ -5,8 +5,8 @@
#include "language.h" #include "language.h"
#include "log.hh" #include "log.hh"
#include "match.h" #include "match.h"
#include "platform.h"
#include "pipeline.hh" #include "pipeline.hh"
#include "platform.h"
#include "serializers/json.h" #include "serializers/json.h"
#include "utils.h" #include "utils.h"
#include "working_files.h" #include "working_files.h"
@ -67,8 +67,8 @@ enum OptionClass {
Separate, Separate,
}; };
Project::Entry GetCompilationEntryFromCompileCommandEntry( Project::Entry
ProjectConfig* config, GetCompilationEntryFromCompileCommandEntry(ProjectConfig *config,
const CompileCommandsEntry &entry) { const CompileCommandsEntry &entry) {
Project::Entry result; Project::Entry result;
result.filename = entry.file; result.filename = entry.file;
@ -155,7 +155,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
continue; continue;
} }
// if (!sys::fs::exists(HeaderOpts.ResourceDir) && HeaderOpts.UseBuiltinIncludes) // if (!sys::fs::exists(HeaderOpts.ResourceDir) &&
// HeaderOpts.UseBuiltinIncludes)
args.push_back("-resource-dir=" + g_config->clang.resourceDir); args.push_back("-resource-dir=" + g_config->clang.resourceDir);
if (CI->getFileSystemOpts().WorkingDir.empty()) if (CI->getFileSystemOpts().WorkingDir.empty())
args.push_back("-working-directory=" + entry.directory); args.push_back("-working-directory=" + entry.directory);
@ -169,10 +170,11 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
return result; return result;
} }
std::vector<std::string> ReadCompilerArgumentsFromFile( std::vector<std::string>
const std::string& path) { ReadCompilerArgumentsFromFile(const std::string &path) {
auto MBOrErr = MemoryBuffer::getFile(path); auto MBOrErr = MemoryBuffer::getFile(path);
if (!MBOrErr) return {}; if (!MBOrErr)
return {};
std::vector<std::string> args; std::vector<std::string> args;
for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I) for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I)
args.push_back(*I); args.push_back(*I);
@ -209,7 +211,8 @@ std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
LOG_IF_S(INFO, !project_dir_args.empty()) LOG_IF_S(INFO, !project_dir_args.empty())
<< "Using .ccls arguments " << StringJoin(project_dir_args); << "Using .ccls arguments " << StringJoin(project_dir_args);
auto GetCompilerArgumentForFile = [&project_dir, &folder_args](std::string cur) { auto GetCompilerArgumentForFile = [&project_dir,
&folder_args](std::string cur) {
while (!(cur = sys::path::parent_path(cur)).empty()) { while (!(cur = sys::path::parent_path(cur)).empty()) {
auto it = folder_args.find(cur); auto it = folder_args.find(cur);
if (it != folder_args.end()) if (it != folder_args.end())
@ -237,8 +240,8 @@ std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
return result; return result;
} }
std::vector<Project::Entry> LoadCompilationEntriesFromDirectory( std::vector<Project::Entry>
ProjectConfig* project, LoadCompilationEntriesFromDirectory(ProjectConfig *project,
const std::string &opt_compilation_db_dir) { const std::string &opt_compilation_db_dir) {
// If there is a .ccls file always load using directory listing. // If there is a .ccls file always load using directory listing.
SmallString<256> Path; SmallString<256> Path;
@ -362,8 +365,7 @@ void Project::Load(const std::string& root_directory) {
} }
} }
void Project::SetFlagsForFile( void Project::SetFlagsForFile(const std::vector<std::string> &flags,
const std::vector<std::string>& flags,
const std::string &path) { const std::string &path) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
auto it = absolute_path_to_entry_index_.find(path); auto it = absolute_path_to_entry_index_.find(path);
@ -380,8 +382,8 @@ void Project::SetFlagsForFile(
} }
} }
Project::Entry Project::FindCompilationEntryForFile( Project::Entry
const std::string& filename) { Project::FindCompilationEntryForFile(const std::string &filename) {
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
auto it = absolute_path_to_entry_index_.find(filename); auto it = absolute_path_to_entry_index_.find(filename);
@ -412,7 +414,8 @@ Project::Entry Project::FindCompilationEntryForFile(
// |best_entry| probably has its own path in the arguments. We need to remap // |best_entry| probably has its own path in the arguments. We need to remap
// that path to the new filename. // that path to the new filename.
std::string best_entry_base_name = sys::path::filename(best_entry->filename); std::string best_entry_base_name =
sys::path::filename(best_entry->filename);
for (std::string &arg : result.args) { for (std::string &arg : result.args) {
try { try {
if (arg == best_entry->filename || if (arg == best_entry->filename ||
@ -441,8 +444,7 @@ void Project::ForAllFilteredFiles(
} }
} }
void Project::Index(WorkingFiles* wfiles, void Project::Index(WorkingFiles *wfiles, lsRequestId id) {
lsRequestId id) {
ForAllFilteredFiles([&](int i, const Project::Entry &entry) { ForAllFilteredFiles([&](int i, const Project::Entry &entry) {
bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr; bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr;
pipeline::Index(entry.filename, entry.args, is_interactive, id); pipeline::Index(entry.filename, entry.args, is_interactive, id);

View File

@ -49,13 +49,12 @@ struct Project {
// If the client has overridden the flags, or specified them for a file // If the client has overridden the flags, or specified them for a file
// that is not in the compilation_database.json make sure those changes // that is not in the compilation_database.json make sure those changes
// are permanent. // are permanent.
void SetFlagsForFile( void SetFlagsForFile(const std::vector<std::string> &flags,
const std::vector<std::string>& flags,
const std::string &path); const std::string &path);
// Run |action| on every file in the project. // Run |action| on every file in the project.
void ForAllFilteredFiles( void
std::function<void(int i, const Entry& entry)> action); ForAllFilteredFiles(std::function<void(int i, const Entry &entry)> action);
void Index(WorkingFiles *wfiles, lsRequestId id); void Index(WorkingFiles *wfiles, lsRequestId id);

View File

@ -164,8 +164,7 @@ bool TryReplaceDef(llvm::SmallVectorImpl<Q>& def_list, Q&& def) {
} // namespace } // namespace
IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous, IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) {
IndexFile* current) {
IndexUpdate r; IndexUpdate r;
static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path, static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path,
"<empty>"); "<empty>");
@ -233,14 +232,14 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous,
return r; return r;
} }
void DB::RemoveUsrs(SymbolKind kind, void DB::RemoveUsrs(SymbolKind kind, int file_id,
int file_id,
const std::vector<Usr> &to_remove) { const std::vector<Usr> &to_remove) {
switch (kind) { switch (kind) {
case SymbolKind::Func: { case SymbolKind::Func: {
for (Usr usr : to_remove) { for (Usr usr : to_remove) {
// FIXME // FIXME
if (!HasFunc(usr)) continue; if (!HasFunc(usr))
continue;
QueryFunc &func = Func(usr); QueryFunc &func = Func(usr);
auto it = llvm::find_if(func.def, [=](const QueryFunc::Def &def) { auto it = llvm::find_if(func.def, [=](const QueryFunc::Def &def) {
return def.file_id == file_id; return def.file_id == file_id;
@ -253,7 +252,8 @@ void DB::RemoveUsrs(SymbolKind kind,
case SymbolKind::Type: { case SymbolKind::Type: {
for (Usr usr : to_remove) { for (Usr usr : to_remove) {
// FIXME // FIXME
if (!HasType(usr)) continue; if (!HasType(usr))
continue;
QueryType &type = Type(usr); QueryType &type = Type(usr);
auto it = llvm::find_if(type.def, [=](const QueryType::Def &def) { auto it = llvm::find_if(type.def, [=](const QueryType::Def &def) {
return def.file_id == file_id; return def.file_id == file_id;
@ -266,7 +266,8 @@ void DB::RemoveUsrs(SymbolKind kind,
case SymbolKind::Var: { case SymbolKind::Var: {
for (Usr usr : to_remove) { for (Usr usr : to_remove) {
// FIXME // FIXME
if (!HasVar(usr)) continue; if (!HasVar(usr))
continue;
QueryVar &var = Var(usr); QueryVar &var = Var(usr);
auto it = llvm::find_if(var.def, [=](const QueryVar::Def &def) { auto it = llvm::find_if(var.def, [=](const QueryVar::Def &def) {
return def.file_id == file_id; return def.file_id == file_id;

View File

@ -31,8 +31,7 @@ struct QueryFile {
std::unordered_map<SymbolRef, int> symbol2refcnt; std::unordered_map<SymbolRef, int> symbol2refcnt;
}; };
template <typename Q, typename QDef> template <typename Q, typename QDef> struct QueryEntity {
struct QueryEntity {
using Def = QDef; using Def = QDef;
Def *AnyDef() { Def *AnyDef() {
Def *ret = nullptr; Def *ret = nullptr;
@ -43,7 +42,9 @@ struct QueryEntity {
} }
return ret; return ret;
} }
const Def* AnyDef() const { return const_cast<QueryEntity*>(this)->AnyDef(); } const Def *AnyDef() const {
return const_cast<QueryEntity *>(this)->AnyDef();
}
}; };
using UseUpdate = using UseUpdate =
@ -78,8 +79,7 @@ struct QueryVar : QueryEntity<QueryVar, VarDef> {
struct IndexUpdate { struct IndexUpdate {
// Creates a new IndexUpdate based on the delta from previous to current. If // Creates a new IndexUpdate based on the delta from previous to current. If
// no delta computation should be done just pass null for previous. // no delta computation should be done just pass null for previous.
static IndexUpdate CreateDelta(IndexFile* previous, static IndexUpdate CreateDelta(IndexFile *previous, IndexFile *current);
IndexFile* current);
int file_id; int file_id;
@ -121,8 +121,7 @@ struct IndexUpdate {
struct WrappedUsr { struct WrappedUsr {
Usr usr; Usr usr;
}; };
template <> template <> struct llvm::DenseMapInfo<WrappedUsr> {
struct llvm::DenseMapInfo<WrappedUsr> {
static inline WrappedUsr getEmptyKey() { return {0}; } static inline WrappedUsr getEmptyKey() { return {0}; }
static inline WrappedUsr getTombstoneKey() { return {~0ULL}; } static inline WrappedUsr getTombstoneKey() { return {~0ULL}; }
static unsigned getHashValue(WrappedUsr w) { return w.usr; } static unsigned getHashValue(WrappedUsr w) { return w.usr; }
@ -141,7 +140,8 @@ struct DB {
std::vector<QueryType> types; std::vector<QueryType> types;
std::vector<QueryVar> vars; std::vector<QueryVar> vars;
void RemoveUsrs(SymbolKind kind, int file_id, const std::vector<Usr>& to_remove); void RemoveUsrs(SymbolKind kind, int file_id,
const std::vector<Usr> &to_remove);
// Insert the contents of |update| into |db|. // Insert the contents of |update| into |db|.
void ApplyIndexUpdate(IndexUpdate *update); void ApplyIndexUpdate(IndexUpdate *update);
int GetFileId(const std::string &path); int GetFileId(const std::string &path);

View File

@ -59,8 +59,7 @@ std::vector<Use> GetFuncDeclarations(DB* db, const std::vector<Usr>& usrs) {
std::vector<Use> GetTypeDeclarations(DB *db, const std::vector<Usr> &usrs) { std::vector<Use> GetTypeDeclarations(DB *db, const std::vector<Usr> &usrs) {
return GetDeclarations(db->type_usr, db->types, usrs); return GetDeclarations(db->type_usr, db->types, usrs);
} }
std::vector<Use> GetVarDeclarations(DB* db, std::vector<Use> GetVarDeclarations(DB *db, const std::vector<Usr> &usrs,
const std::vector<Usr>& usrs,
unsigned kind) { unsigned kind) {
std::vector<Use> ret; std::vector<Use> ret;
ret.reserve(usrs.size()); ret.reserve(usrs.size());
@ -207,8 +206,7 @@ lsDocumentUri GetLsDocumentUri(DB* db, int file_id) {
} }
} }
std::optional<lsLocation> GetLsLocation(DB* db, std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *working_files,
WorkingFiles* working_files,
Use use) { Use use) {
std::string path; std::string path;
lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path); lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path);
@ -219,10 +217,8 @@ std::optional<lsLocation> GetLsLocation(DB* db,
return lsLocation{uri, *range}; return lsLocation{uri, *range};
} }
std::optional<lsLocationEx> GetLsLocationEx(DB* db, std::optional<lsLocationEx> GetLsLocationEx(DB *db, WorkingFiles *working_files,
WorkingFiles* working_files, Use use, bool container) {
Use use,
bool container) {
std::optional<lsLocation> ls_loc = GetLsLocation(db, working_files, use); std::optional<lsLocation> ls_loc = GetLsLocation(db, working_files, use);
if (!ls_loc) if (!ls_loc)
return std::nullopt; return std::nullopt;
@ -238,8 +234,7 @@ std::optional<lsLocationEx> GetLsLocationEx(DB* db,
return ret; return ret;
} }
std::vector<lsLocationEx> GetLsLocationExs(DB* db, std::vector<lsLocationEx> GetLsLocationExs(DB *db, WorkingFiles *working_files,
WorkingFiles* working_files,
const std::vector<Use> &uses) { const std::vector<Use> &uses) {
std::vector<lsLocationEx> ret; std::vector<lsLocationEx> ret;
for (Use use : uses) for (Use use : uses)
@ -337,7 +332,8 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
// //
// Then order functions before other types, which makes goto definition work // Then order functions before other types, which makes goto definition work
// better on constructors. // better on constructors.
std::sort(symbols.begin(), symbols.end(), std::sort(
symbols.begin(), symbols.end(),
[](const SymbolRef &a, const SymbolRef &b) { [](const SymbolRef &a, const SymbolRef &b) {
int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range); int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range);
if (t) if (t)

View File

@ -26,15 +26,11 @@ std::optional<lsRange> GetLsRange(WorkingFile* working_file,
lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path); lsDocumentUri GetLsDocumentUri(DB *db, int file_id, std::string *path);
lsDocumentUri GetLsDocumentUri(DB *db, int file_id); lsDocumentUri GetLsDocumentUri(DB *db, int file_id);
std::optional<lsLocation> GetLsLocation(DB* db, std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *working_files,
WorkingFiles* working_files,
Use use); Use use);
std::optional<lsLocationEx> GetLsLocationEx(DB* db, std::optional<lsLocationEx> GetLsLocationEx(DB *db, WorkingFiles *working_files,
WorkingFiles* working_files, Use use, bool container);
Use use, std::vector<lsLocationEx> GetLsLocationExs(DB *db, WorkingFiles *working_files,
bool container);
std::vector<lsLocationEx> GetLsLocationExs(DB* db,
WorkingFiles* working_files,
const std::vector<Use> &refs); const std::vector<Use> &refs);
// Returns a symbol. The symbol will have *NOT* have a location assigned. // Returns a symbol. The symbol will have *NOT* have a location assigned.
std::optional<lsSymbolInformation> GetSymbolInfo(DB *db, std::optional<lsSymbolInformation> GetSymbolInfo(DB *db,
@ -46,8 +42,7 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
QueryFile *file, QueryFile *file,
lsPosition &ls_pos); lsPosition &ls_pos);
template <typename Fn> template <typename Fn> void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) {
void WithEntity(DB* db, SymbolIdx sym, Fn&& fn) {
switch (sym.kind) { switch (sym.kind) {
case SymbolKind::Invalid: case SymbolKind::Invalid:
case SymbolKind::File: case SymbolKind::File:
@ -64,8 +59,7 @@ void WithEntity(DB* db, SymbolIdx sym, Fn&& fn) {
} }
} }
template <typename Fn> template <typename Fn> void EachEntityDef(DB *db, SymbolIdx sym, Fn &&fn) {
void EachEntityDef(DB* db, SymbolIdx sym, Fn&& fn) {
WithEntity(db, sym, [&](const auto &entity) { WithEntity(db, sym, [&](const auto &entity) {
for (auto &def : entity.def) for (auto &def : entity.def)
if (!fn(def)) if (!fn(def))
@ -99,7 +93,6 @@ void EachDefinedFunc(DB* db, const std::vector<Usr>& usrs, Fn&& fn) {
} }
} }
template <typename Fn> template <typename Fn>
void EachDefinedType(DB *db, const std::vector<Usr> &usrs, Fn &&fn) { void EachDefinedType(DB *db, const std::vector<Usr> &usrs, Fn &&fn) {
for (Usr usr : usrs) { for (Usr usr : usrs) {

View File

@ -18,75 +18,57 @@ bool gTestOutputMode = false;
//// Elementary types //// Elementary types
void Reflect(Reader& visitor, uint8_t& value) { void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); }
value = visitor.GetUInt8(); void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); }
}
void Reflect(Writer& visitor, uint8_t& value) {
visitor.UInt8(value);
}
void Reflect(Reader &visitor, short &value) { void Reflect(Reader &visitor, short &value) {
if (!visitor.IsInt()) if (!visitor.IsInt())
throw std::invalid_argument("short"); throw std::invalid_argument("short");
value = (short)visitor.GetInt(); value = (short)visitor.GetInt();
} }
void Reflect(Writer& visitor, short& value) { void Reflect(Writer &visitor, short &value) { visitor.Int(value); }
visitor.Int(value);
}
void Reflect(Reader &visitor, unsigned short &value) { void Reflect(Reader &visitor, unsigned short &value) {
if (!visitor.IsInt()) if (!visitor.IsInt())
throw std::invalid_argument("unsigned short"); throw std::invalid_argument("unsigned short");
value = (unsigned short)visitor.GetInt(); value = (unsigned short)visitor.GetInt();
} }
void Reflect(Writer& visitor, unsigned short& value) { void Reflect(Writer &visitor, unsigned short &value) { visitor.Int(value); }
visitor.Int(value);
}
void Reflect(Reader &visitor, int &value) { void Reflect(Reader &visitor, int &value) {
if (!visitor.IsInt()) if (!visitor.IsInt())
throw std::invalid_argument("int"); throw std::invalid_argument("int");
value = visitor.GetInt(); value = visitor.GetInt();
} }
void Reflect(Writer& visitor, int& value) { void Reflect(Writer &visitor, int &value) { visitor.Int(value); }
visitor.Int(value);
}
void Reflect(Reader &visitor, unsigned &value) { void Reflect(Reader &visitor, unsigned &value) {
if (!visitor.IsUInt64()) if (!visitor.IsUInt64())
throw std::invalid_argument("unsigned"); throw std::invalid_argument("unsigned");
value = visitor.GetUInt32(); value = visitor.GetUInt32();
} }
void Reflect(Writer& visitor, unsigned& value) { void Reflect(Writer &visitor, unsigned &value) { visitor.UInt32(value); }
visitor.UInt32(value);
}
void Reflect(Reader &visitor, long &value) { void Reflect(Reader &visitor, long &value) {
if (!visitor.IsInt64()) if (!visitor.IsInt64())
throw std::invalid_argument("long"); throw std::invalid_argument("long");
value = long(visitor.GetInt64()); value = long(visitor.GetInt64());
} }
void Reflect(Writer& visitor, long& value) { void Reflect(Writer &visitor, long &value) { visitor.Int64(value); }
visitor.Int64(value);
}
void Reflect(Reader &visitor, unsigned long &value) { void Reflect(Reader &visitor, unsigned long &value) {
if (!visitor.IsUInt64()) if (!visitor.IsUInt64())
throw std::invalid_argument("unsigned long"); throw std::invalid_argument("unsigned long");
value = (unsigned long)visitor.GetUInt64(); value = (unsigned long)visitor.GetUInt64();
} }
void Reflect(Writer& visitor, unsigned long& value) { void Reflect(Writer &visitor, unsigned long &value) { visitor.UInt64(value); }
visitor.UInt64(value);
}
void Reflect(Reader &visitor, long long &value) { void Reflect(Reader &visitor, long long &value) {
if (!visitor.IsInt64()) if (!visitor.IsInt64())
throw std::invalid_argument("long long"); throw std::invalid_argument("long long");
value = visitor.GetInt64(); value = visitor.GetInt64();
} }
void Reflect(Writer& visitor, long long& value) { void Reflect(Writer &visitor, long long &value) { visitor.Int64(value); }
visitor.Int64(value);
}
void Reflect(Reader &visitor, unsigned long long &value) { void Reflect(Reader &visitor, unsigned long long &value) {
if (!visitor.IsUInt64()) if (!visitor.IsUInt64())
@ -102,18 +84,14 @@ void Reflect(Reader& visitor, double& value) {
throw std::invalid_argument("double"); throw std::invalid_argument("double");
value = visitor.GetDouble(); value = visitor.GetDouble();
} }
void Reflect(Writer& visitor, double& value) { void Reflect(Writer &visitor, double &value) { visitor.Double(value); }
visitor.Double(value);
}
void Reflect(Reader &visitor, bool &value) { void Reflect(Reader &visitor, bool &value) {
if (!visitor.IsBool()) if (!visitor.IsBool())
throw std::invalid_argument("bool"); throw std::invalid_argument("bool");
value = visitor.GetBool(); value = visitor.GetBool();
} }
void Reflect(Writer& visitor, bool& value) { void Reflect(Writer &visitor, bool &value) { visitor.Bool(value); }
visitor.Bool(value);
}
void Reflect(Reader &visitor, std::string &value) { void Reflect(Reader &visitor, std::string &value) {
if (!visitor.IsString()) if (!visitor.IsString())
@ -124,9 +102,7 @@ void Reflect(Writer& visitor, std::string& value) {
visitor.String(value.c_str(), (rapidjson::SizeType)value.size()); visitor.String(value.c_str(), (rapidjson::SizeType)value.size());
} }
void Reflect(Reader&, std::string_view&) { void Reflect(Reader &, std::string_view &) { assert(0); }
assert(0);
}
void Reflect(Writer &visitor, std::string_view &data) { void Reflect(Writer &visitor, std::string_view &data) {
if (data.empty()) if (data.empty())
visitor.String(""); visitor.String("");
@ -138,18 +114,14 @@ void Reflect(Reader& vis, const char*& v) {
const char *str = vis.GetString(); const char *str = vis.GetString();
v = ccls::Intern(str); v = ccls::Intern(str);
} }
void Reflect(Writer& vis, const char*& v) { void Reflect(Writer &vis, const char *&v) { vis.String(v); }
vis.String(v);
}
void Reflect(Reader &visitor, JsonNull &value) { void Reflect(Reader &visitor, JsonNull &value) {
assert(visitor.Format() == SerializeFormat::Json); assert(visitor.Format() == SerializeFormat::Json);
visitor.GetNull(); visitor.GetNull();
} }
void Reflect(Writer& visitor, JsonNull& value) { void Reflect(Writer &visitor, JsonNull &value) { visitor.Null(); }
visitor.Null();
}
// std::unordered_map // std::unordered_map
template <typename V> template <typename V>
@ -230,12 +202,12 @@ void ReflectHoverAndComments(Writer& visitor, Def& def) {
ReflectMember(visitor, "comments", def.comments); ReflectMember(visitor, "comments", def.comments);
} }
template <typename Def> template <typename Def> void ReflectShortName(Reader &visitor, Def &def) {
void ReflectShortName(Reader& visitor, Def& def) {
if (gTestOutputMode) { if (gTestOutputMode) {
std::string short_name; std::string short_name;
ReflectMember(visitor, "short_name", short_name); ReflectMember(visitor, "short_name", short_name);
def.short_name_offset = std::string_view(def.detailed_name).find(short_name); def.short_name_offset =
std::string_view(def.detailed_name).find(short_name);
assert(def.short_name_offset != std::string::npos); assert(def.short_name_offset != std::string::npos);
def.short_name_size = short_name.size(); def.short_name_size = short_name.size();
} else { } else {
@ -244,8 +216,7 @@ void ReflectShortName(Reader& visitor, Def& def) {
} }
} }
template <typename Def> template <typename Def> void ReflectShortName(Writer &visitor, Def &def) {
void ReflectShortName(Writer& visitor, Def& def) {
if (gTestOutputMode) { if (gTestOutputMode) {
std::string_view short_name(def.detailed_name + def.short_name_offset, std::string_view short_name(def.detailed_name + def.short_name_offset,
def.short_name_size); def.short_name_size);
@ -256,8 +227,7 @@ void ReflectShortName(Writer& visitor, Def& def) {
} }
} }
template <typename TVisitor> template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) {
void Reflect(TVisitor& visitor, IndexType& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
@ -279,8 +249,7 @@ void Reflect(TVisitor& visitor, IndexType& value) {
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
template <typename TVisitor> template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) {
void Reflect(TVisitor& visitor, IndexFunc& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
@ -300,8 +269,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) {
REFLECT_MEMBER_END(); REFLECT_MEMBER_END();
} }
template <typename TVisitor> template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) {
void Reflect(TVisitor& visitor, IndexVar& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr); REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name); REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
@ -323,8 +291,7 @@ bool ReflectMemberStart(Writer& visitor, IndexFile& value) {
visitor.StartObject(); visitor.StartObject();
return true; return true;
} }
template <typename TVisitor> template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFile &value) {
void Reflect(TVisitor& visitor, IndexFile& value) {
REFLECT_MEMBER_START(); REFLECT_MEMBER_START();
if (!gTestOutputMode) { if (!gTestOutputMode) {
REFLECT_MEMBER(last_write_time); REFLECT_MEMBER(last_write_time);
@ -364,7 +331,8 @@ static DenseSet<StringRef> Strings;
static std::mutex AllocMutex; static std::mutex AllocMutex;
const char *Intern(const std::string &str) { const char *Intern(const std::string &str) {
if (str.empty()) return ""; if (str.empty())
return "";
StringRef Str(str.data(), str.size() + 1); StringRef Str(str.data(), str.size() + 1);
std::lock_guard lock(AllocMutex); std::lock_guard lock(AllocMutex);
auto R = Strings.insert(Str); auto R = Strings.insert(Str);
@ -404,9 +372,8 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
return ""; return "";
} }
std::unique_ptr<IndexFile> Deserialize( std::unique_ptr<IndexFile>
SerializeFormat format, Deserialize(SerializeFormat format, const std::string &path,
const std::string& path,
const std::string &serialized_index_content, const std::string &serialized_index_content,
const std::string &file_content, const std::string &file_content,
std::optional<int> expected_version) { std::optional<int> expected_version) {
@ -430,8 +397,7 @@ std::unique_ptr<IndexFile> Deserialize(
file_content); file_content);
Reflect(reader, *file); Reflect(reader, *file);
} catch (std::invalid_argument &e) { } catch (std::invalid_argument &e) {
LOG_S(INFO) << "failed to deserialize '" << path LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what();
<< "': " << e.what();
return nullptr; return nullptr;
} }
break; break;
@ -469,4 +435,4 @@ std::unique_ptr<IndexFile> Deserialize(
file->path = path; file->path = path;
return file; return file;
} }
} } // namespace ccls

View File

@ -99,23 +99,20 @@ struct IndexFile;
REFLECT_MEMBER_MANDATORY_OPTIONAL(name); REFLECT_MEMBER_MANDATORY_OPTIONAL(name);
#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \ #define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
template <typename TVisitor> \ template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
void Reflect(TVisitor& visitor, type& value) { \
REFLECT_MEMBER_START(); \ REFLECT_MEMBER_START(); \
REFLECT_MEMBER_END(); \ REFLECT_MEMBER_END(); \
} }
#define MAKE_REFLECT_STRUCT(type, ...) \ #define MAKE_REFLECT_STRUCT(type, ...) \
template <typename TVisitor> \ template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
void Reflect(TVisitor& visitor, type& value) { \
REFLECT_MEMBER_START(); \ REFLECT_MEMBER_START(); \
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
REFLECT_MEMBER_END(); \ REFLECT_MEMBER_END(); \
} }
#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \ #define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \
template <typename TVisitor> \ template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
void Reflect(TVisitor& visitor, type& value) { \
REFLECT_MEMBER_START(); \ REFLECT_MEMBER_START(); \
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \
REFLECT_MEMBER_END(); \ REFLECT_MEMBER_END(); \
@ -190,12 +187,11 @@ void Reflect(Writer& visitor, SerializeFormat& value);
//// Type constructors //// Type constructors
// ReflectMember std::optional<T> is used to represent TypeScript optional properties // ReflectMember std::optional<T> is used to represent TypeScript optional
// (in `key: value` context). // properties (in `key: value` context). Reflect std::optional<T> is used for a
// Reflect std::optional<T> is used for a different purpose, whether an object is // different purpose, whether an object is nullable (possibly in `value`
// nullable (possibly in `value` context). // context).
template <typename T> template <typename T> void Reflect(Reader &visitor, std::optional<T> &value) {
void Reflect(Reader& visitor, std::optional<T>& value) {
if (visitor.IsNull()) { if (visitor.IsNull()) {
visitor.GetNull(); visitor.GetNull();
return; return;
@ -204,8 +200,7 @@ void Reflect(Reader& visitor, std::optional<T>& value) {
Reflect(visitor, real_value); Reflect(visitor, real_value);
value = std::move(real_value); value = std::move(real_value);
} }
template <typename T> template <typename T> void Reflect(Writer &visitor, std::optional<T> &value) {
void Reflect(Writer& visitor, std::optional<T>& value) {
if (value) { if (value) {
if (visitor.Format() != SerializeFormat::Json) if (visitor.Format() != SerializeFormat::Json)
visitor.UInt8(1); visitor.UInt8(1);
@ -215,8 +210,7 @@ void Reflect(Writer& visitor, std::optional<T>& value) {
} }
// The same as std::optional // The same as std::optional
template <typename T> template <typename T> void Reflect(Reader &visitor, Maybe<T> &value) {
void Reflect(Reader& visitor, Maybe<T>& value) {
if (visitor.IsNull()) { if (visitor.IsNull()) {
visitor.GetNull(); visitor.GetNull();
return; return;
@ -225,8 +219,7 @@ void Reflect(Reader& visitor, Maybe<T>& value) {
Reflect(visitor, real_value); Reflect(visitor, real_value);
value = std::move(real_value); value = std::move(real_value);
} }
template <typename T> template <typename T> void Reflect(Writer &visitor, Maybe<T> &value) {
void Reflect(Writer& visitor, Maybe<T>& value) {
if (value) { if (value) {
if (visitor.Format() != SerializeFormat::Json) if (visitor.Format() != SerializeFormat::Json)
visitor.UInt8(1); visitor.UInt8(1);
@ -256,9 +249,7 @@ void ReflectMember(Writer& visitor, const char* name, Maybe<T>& value) {
} }
template <typename T> template <typename T>
void ReflectMember(Writer& visitor, void ReflectMember(Writer &visitor, const char *name, T &value,
const char* name,
T& value,
mandatory_optional_tag) { mandatory_optional_tag) {
visitor.Key(name); visitor.Key(name);
Reflect(visitor, value); Reflect(visitor, value);
@ -278,16 +269,14 @@ void Reflect(Writer& vis, std::pair<L, R>& v) {
} }
// std::vector // std::vector
template <typename T> template <typename T> void Reflect(Reader &visitor, std::vector<T> &values) {
void Reflect(Reader& visitor, std::vector<T>& values) {
visitor.IterArray([&](Reader &entry) { visitor.IterArray([&](Reader &entry) {
T entry_value; T entry_value;
Reflect(entry, entry_value); Reflect(entry, entry_value);
values.push_back(std::move(entry_value)); values.push_back(std::move(entry_value));
}); });
} }
template <typename T> template <typename T> void Reflect(Writer &visitor, std::vector<T> &values) {
void Reflect(Writer& visitor, std::vector<T>& values) {
visitor.StartArray(values.size()); visitor.StartArray(values.size());
for (auto &value : values) for (auto &value : values)
Reflect(visitor, value); Reflect(visitor, value);
@ -296,25 +285,19 @@ void Reflect(Writer& visitor, std::vector<T>& values) {
// ReflectMember // ReflectMember
inline bool ReflectMemberStart(Reader& vis) { inline bool ReflectMemberStart(Reader &vis) { return false; }
return false;
}
inline bool ReflectMemberStart(Writer &vis) { inline bool ReflectMemberStart(Writer &vis) {
vis.StartObject(); vis.StartObject();
return true; return true;
} }
inline void ReflectMemberEnd(Reader &vis) {} inline void ReflectMemberEnd(Reader &vis) {}
inline void ReflectMemberEnd(Writer& vis) { inline void ReflectMemberEnd(Writer &vis) { vis.EndObject(); }
vis.EndObject();
}
template <typename T> template <typename T> void ReflectMember(Reader &vis, const char *name, T &v) {
void ReflectMember(Reader& vis, const char* name, T& v) {
vis.Member(name, [&]() { Reflect(vis, v); }); vis.Member(name, [&]() { Reflect(vis, v); });
} }
template <typename T> template <typename T> void ReflectMember(Writer &vis, const char *name, T &v) {
void ReflectMember(Writer& vis, const char* name, T& v) {
vis.Key(name); vis.Key(name);
Reflect(vis, v); Reflect(vis, v);
} }
@ -324,10 +307,9 @@ void ReflectMember(Writer& vis, const char* name, T& v) {
namespace ccls { namespace ccls {
const char *Intern(const std::string &str); const char *Intern(const std::string &str);
std::string Serialize(SerializeFormat format, IndexFile &file); std::string Serialize(SerializeFormat format, IndexFile &file);
std::unique_ptr<IndexFile> Deserialize( std::unique_ptr<IndexFile>
SerializeFormat format, Deserialize(SerializeFormat format, const std::string &path,
const std::string& path,
const std::string &serialized_index_content, const std::string &serialized_index_content,
const std::string &file_content, const std::string &file_content,
std::optional<int> expected_version); std::optional<int> expected_version);
} } // namespace ccls

View File

@ -7,8 +7,7 @@
class BinaryReader : public Reader { class BinaryReader : public Reader {
const char *p_; const char *p_;
template <typename T> template <typename T> T Get() {
T Get() {
auto ret = *reinterpret_cast<const T *>(p_); auto ret = *reinterpret_cast<const T *>(p_);
p_ += sizeof(T); p_ += sizeof(T);
return ret; return ret;
@ -31,9 +30,7 @@ class BinaryReader : public Reader {
public: public:
BinaryReader(std::string_view buf) : p_(buf.data()) {} BinaryReader(std::string_view buf) : p_(buf.data()) {}
SerializeFormat Format() const override { SerializeFormat Format() const override { return SerializeFormat::Binary; }
return SerializeFormat::Binary;
}
bool IsBool() override { return true; } bool IsBool() override { return true; }
// Abuse how the function is called in serializer.h // Abuse how the function is called in serializer.h
@ -68,16 +65,13 @@ class BinaryReader : public Reader {
fn(*this); fn(*this);
} }
void Member(const char*, std::function<void()> fn) override { void Member(const char *, std::function<void()> fn) override { fn(); }
fn();
}
}; };
class BinaryWriter : public Writer { class BinaryWriter : public Writer {
std::string buf_; std::string buf_;
template <typename T> template <typename T> void Pack(T x) {
void Pack(T x) {
auto i = buf_.size(); auto i = buf_.size();
buf_.resize(i + sizeof(x)); buf_.resize(i + sizeof(x));
*reinterpret_cast<T *>(buf_.data() + i) = x; *reinterpret_cast<T *>(buf_.data() + i) = x;
@ -97,14 +91,10 @@ class BinaryWriter : public Writer {
Pack<uint64_t>(n); Pack<uint64_t>(n);
} }
} }
void VarInt(int64_t n) { void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); }
VarUInt(uint64_t(n) << 1 ^ n >> 63);
}
public: public:
SerializeFormat Format() const override { SerializeFormat Format() const override { return SerializeFormat::Binary; }
return SerializeFormat::Binary;
}
std::string Take() { return std::move(buf_); } std::string Take() { return std::move(buf_); }
void Null() override { Pack(uint8_t(0)); } void Null() override { Pack(uint8_t(0)); }

View File

@ -13,9 +13,9 @@
#include <rapidjson/stringbuffer.h> #include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h> #include <rapidjson/writer.h>
#include <fstream>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <fstream>
// The 'diff' utility is available and we can use dprintf(3). // The 'diff' utility is available and we can use dprintf(3).
#if _POSIX_C_SOURCE >= 200809L #if _POSIX_C_SOURCE >= 200809L
@ -66,8 +66,7 @@ struct TextReplacer {
void ParseTestExpectation( void ParseTestExpectation(
const std::string &filename, const std::string &filename,
const std::vector<std::string>& lines_with_endings, const std::vector<std::string> &lines_with_endings, TextReplacer *replacer,
TextReplacer* replacer,
std::vector<std::string> *flags, std::vector<std::string> *flags,
std::unordered_map<std::string, std::string> *output_sections) { std::unordered_map<std::string, std::string> *output_sections) {
// Scan for EXTRA_FLAGS: // Scan for EXTRA_FLAGS:
@ -148,10 +147,8 @@ void UpdateTestExpectation(const std::string& filename,
WriteToFile(filename, str); WriteToFile(filename, str);
} }
void DiffDocuments(std::string path, void DiffDocuments(std::string path, std::string path_section,
std::string path_section, rapidjson::Document &expected, rapidjson::Document &actual) {
rapidjson::Document& expected,
rapidjson::Document& actual) {
std::string joined_actual_output = ToString(actual); std::string joined_actual_output = ToString(actual);
std::string joined_expected_output = ToString(expected); std::string joined_expected_output = ToString(expected);
printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str()); printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str());
@ -217,8 +214,8 @@ std::string FindExpectedOutputForFilename(
return "{}"; return "{}";
} }
IndexFile* FindDbForPathEnding( IndexFile *
const std::string& path, FindDbForPathEnding(const std::string &path,
const std::vector<std::unique_ptr<IndexFile>> &dbs) { const std::vector<std::unique_ptr<IndexFile>> &dbs) {
for (auto &db : dbs) { for (auto &db : dbs) {
if (EndsWith(db->path, path)) if (EndsWith(db->path, path))
@ -353,8 +350,7 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
DiffDocuments(path, expected_path, expected, actual); DiffDocuments(path, expected_path, expected, actual);
puts("\n"); puts("\n");
if (enable_update) { if (enable_update) {
printf( printf("[Enter to continue - type u to update test, a to update "
"[Enter to continue - type u to update test, a to update "
"all]"); "all]");
char c = 'u'; char c = 'u';
if (!update_all) { if (!update_all) {

View File

@ -18,27 +18,21 @@ struct BaseThreadQueue {
// std::lock accepts two or more arguments. We define an overload for one // std::lock accepts two or more arguments. We define an overload for one
// argument. // argument.
namespace std { namespace std {
template <typename Lockable> template <typename Lockable> void lock(Lockable &l) { l.lock(); }
void lock(Lockable& l) {
l.lock();
}
} // namespace std } // namespace std
template <typename... Queue> template <typename... Queue> struct MultiQueueLock {
struct MultiQueueLock {
MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); } MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); }
~MultiQueueLock() { unlock(); } ~MultiQueueLock() { unlock(); }
void lock() { lock_impl(typename std::index_sequence_for<Queue...>{}); } void lock() { lock_impl(typename std::index_sequence_for<Queue...>{}); }
void unlock() { unlock_impl(typename std::index_sequence_for<Queue...>{}); } void unlock() { unlock_impl(typename std::index_sequence_for<Queue...>{}); }
private: private:
template <size_t... Is> template <size_t... Is> void lock_impl(std::index_sequence<Is...>) {
void lock_impl(std::index_sequence<Is...>) {
std::lock(std::get<Is>(tuple_)->mutex_...); std::lock(std::get<Is>(tuple_)->mutex_...);
} }
template <size_t... Is> template <size_t... Is> void unlock_impl(std::index_sequence<Is...>) {
void unlock_impl(std::index_sequence<Is...>) {
(void)std::initializer_list<int>{ (void)std::initializer_list<int>{
(std::get<Is>(tuple_)->mutex_.unlock(), 0)...}; (std::get<Is>(tuple_)->mutex_.unlock(), 0)...};
} }
@ -57,8 +51,7 @@ struct MultiQueueWaiter {
return false; return false;
} }
template <typename... BaseThreadQueue> template <typename... BaseThreadQueue> void Wait(BaseThreadQueue... queues) {
void Wait(BaseThreadQueue... queues) {
MultiQueueLock<BaseThreadQueue...> l(queues...); MultiQueueLock<BaseThreadQueue...> l(queues...);
while (!HasState({queues...})) while (!HasState({queues...}))
cv.wait(l); cv.wait(l);
@ -66,8 +59,7 @@ struct MultiQueueWaiter {
}; };
// A threadsafe-queue. http://stackoverflow.com/a/16075550 // A threadsafe-queue. http://stackoverflow.com/a/16075550
template <class T> template <class T> struct ThreadedQueue : public BaseThreadQueue {
struct ThreadedQueue : public BaseThreadQueue {
public: public:
ThreadedQueue() { ThreadedQueue() {
owned_waiter_ = std::make_unique<MultiQueueWaiter>(); owned_waiter_ = std::make_unique<MultiQueueWaiter>();
@ -79,8 +71,7 @@ struct ThreadedQueue : public BaseThreadQueue {
size_t Size() const { return total_count_; } size_t Size() const { return total_count_; }
// Add an element to the queue. // Add an element to the queue.
template <void (std::deque<T>::*push)(T&&)> template <void (std::deque<T>::*push)(T &&)> void Push(T &&t, bool priority) {
void Push(T&& t, bool priority) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
if (priority) if (priority)
(priority_.*push)(std::move(t)); (priority_.*push)(std::move(t));
@ -151,8 +142,7 @@ struct ThreadedQueue : public BaseThreadQueue {
return std::nullopt; return std::nullopt;
} }
template <typename Fn> template <typename Fn> void Iterate(Fn fn) {
void Iterate(Fn fn) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
for (auto &entry : priority_) for (auto &entry : priority_)
fn(entry); fn(entry);

View File

@ -7,12 +7,12 @@ using namespace llvm;
#include <siphash.h> #include <siphash.h>
#include <algorithm>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <string.h>
#include <algorithm>
#include <functional> #include <functional>
#include <string.h>
#include <unordered_map> #include <unordered_map>
using namespace std::placeholders; using namespace std::placeholders;
@ -34,7 +34,8 @@ uint64_t HashUsr(std::string_view s) {
// k is an arbitrary key. Don't change it. // k is an arbitrary key. Don't change it.
const uint8_t k[16] = {0xd0, 0xe5, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, const uint8_t k[16] = {0xd0, 0xe5, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52,
0x61, 0x79, 0xea, 0x70, 0xca, 0x70, 0xf0, 0x0d}; 0x61, 0x79, 0xea, 0x70, 0xca, 0x70, 0xf0, 0x0d};
(void)siphash(reinterpret_cast<const uint8_t*>(s.data()), s.size(), k, out, 8); (void)siphash(reinterpret_cast<const uint8_t *>(s.data()), s.size(), k, out,
8);
return ret; return ret;
} }
@ -112,7 +113,8 @@ std::optional<std::string> ReadContent(const std::string& filename) {
char buf[4096]; char buf[4096];
std::string ret; std::string ret;
FILE *f = fopen(filename.c_str(), "rb"); FILE *f = fopen(filename.c_str(), "rb");
if (!f) return {}; if (!f)
return {};
size_t n; size_t n;
while ((n = fread(buf, 1, sizeof buf, f)) > 0) while ((n = fread(buf, 1, sizeof buf, f)) > 0)
ret.append(buf, n); ret.append(buf, n);
@ -139,8 +141,7 @@ std::optional<int64_t> LastWriteTime(const std::string& filename) {
// Find discontinous |search| in |content|. // Find discontinous |search| in |content|.
// Return |found| and the count of skipped chars before found. // Return |found| and the count of skipped chars before found.
int ReverseSubseqMatch(std::string_view pat, int ReverseSubseqMatch(std::string_view pat, std::string_view text,
std::string_view text,
int case_sensitivity) { int case_sensitivity) {
if (case_sensitivity == 1) if (case_sensitivity == 1)
case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0; case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0;
@ -155,6 +156,4 @@ int ReverseSubseqMatch(std::string_view pat,
return -1; return -1;
} }
std::string GetDefaultResourceDirectory() { std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; }
return DEFAULT_RESOURCE_DIRECTORY;
}

View File

@ -32,8 +32,7 @@ std::vector<std::string> SplitString(const std::string& str,
std::string LowerPathIfInsensitive(const std::string &path); std::string LowerPathIfInsensitive(const std::string &path);
template <typename TValues, typename TMap> template <typename TValues, typename TMap>
std::string StringJoinMap(const TValues& values, std::string StringJoinMap(const TValues &values, const TMap &map,
const TMap& map,
const std::string &sep = ", ") { const std::string &sep = ", ") {
std::string result; std::string result;
bool first = true; bool first = true;
@ -63,8 +62,7 @@ std::optional<std::string> ReadContent(const std::string& filename);
void WriteToFile(const std::string &filename, const std::string &content); void WriteToFile(const std::string &filename, const std::string &content);
std::optional<int64_t> LastWriteTime(const std::string &filename); std::optional<int64_t> LastWriteTime(const std::string &filename);
int ReverseSubseqMatch(std::string_view pat, int ReverseSubseqMatch(std::string_view pat, std::string_view text,
std::string_view text,
int case_sensitivity); int case_sensitivity);
// http://stackoverflow.com/a/38140932 // http://stackoverflow.com/a/38140932
@ -87,8 +85,7 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) {
#define MAKE_HASHABLE(type, ...) \ #define MAKE_HASHABLE(type, ...) \
namespace std { \ namespace std { \
template <> \ template <> struct hash<type> { \
struct hash<type> { \
std::size_t operator()(const type &t) const { \ std::size_t operator()(const type &t) const { \
std::size_t ret = 0; \ std::size_t ret = 0; \
hash_combine(ret, __VA_ARGS__); \ hash_combine(ret, __VA_ARGS__); \

View File

@ -149,12 +149,10 @@ int AlignColumn(const std::string& a, int column, std::string b, bool is_end) {
// Find matching buffer line of index_lines[line]. // Find matching buffer line of index_lines[line].
// By symmetry, this can also be used to find matching index line of a buffer // By symmetry, this can also be used to find matching index line of a buffer
// line. // line.
std::optional<int> FindMatchingLine(const std::vector<std::string>& index_lines, std::optional<int>
const std::vector<int>& index_to_buffer, FindMatchingLine(const std::vector<std::string> &index_lines,
int line, const std::vector<int> &index_to_buffer, int line, int *column,
int* column, const std::vector<std::string> &buffer_lines, bool is_end) {
const std::vector<std::string>& buffer_lines,
bool is_end) {
// If this is a confident mapping, returns. // If this is a confident mapping, returns.
if (index_to_buffer[line] >= 0) { if (index_to_buffer[line] >= 0) {
int ret = index_to_buffer[line]; int ret = index_to_buffer[line];
@ -300,8 +298,7 @@ void WorkingFile::ComputeLineMapping() {
buffer_to_index[index_to_buffer[i]] = i; buffer_to_index[index_to_buffer[i]] = i;
} }
std::optional<int> WorkingFile::GetBufferPosFromIndexPos(int line, std::optional<int> WorkingFile::GetBufferPosFromIndexPos(int line, int *column,
int* column,
bool is_end) { bool is_end) {
if (line < 0 || line >= (int)index_lines.size()) { if (line < 0 || line >= (int)index_lines.size()) {
LOG_S(WARNING) << "bad index_line (got " << line << ", expected [0, " LOG_S(WARNING) << "bad index_line (got " << line << ", expected [0, "
@ -315,8 +312,7 @@ std::optional<int> WorkingFile::GetBufferPosFromIndexPos(int line,
buffer_lines, is_end); buffer_lines, is_end);
} }
std::optional<int> WorkingFile::GetIndexPosFromBufferPos(int line, std::optional<int> WorkingFile::GetIndexPosFromBufferPos(int line, int *column,
int* column,
bool is_end) { bool is_end) {
// See GetBufferLineFromIndexLine for additional comments. // See GetBufferLineFromIndexLine for additional comments.
if (line < 0 || line >= (int)buffer_lines.size()) if (line < 0 || line >= (int)buffer_lines.size())
@ -329,8 +325,7 @@ std::optional<int> WorkingFile::GetIndexPosFromBufferPos(int line,
} }
std::string WorkingFile::FindClosestCallNameInBuffer( std::string WorkingFile::FindClosestCallNameInBuffer(
lsPosition position, lsPosition position, int *active_parameter,
int* active_parameter,
lsPosition *completion_position) const { lsPosition *completion_position) const {
*active_parameter = 0; *active_parameter = 0;
@ -378,10 +373,8 @@ std::string WorkingFile::FindClosestCallNameInBuffer(
} }
lsPosition WorkingFile::FindStableCompletionSource( lsPosition WorkingFile::FindStableCompletionSource(
lsPosition position, lsPosition position, bool *is_global_completion,
bool* is_global_completion, std::string *existing_completion, lsPosition *replace_end_pos) const {
std::string* existing_completion,
lsPosition* replace_end_pos) const {
*is_global_completion = true; *is_global_completion = true;
int start_offset = GetOffsetForPosition(position, buffer_content); int start_offset = GetOffsetForPosition(position, buffer_content);
@ -410,7 +403,8 @@ lsPosition WorkingFile::FindStableCompletionSource(
*replace_end_pos = position; *replace_end_pos = position;
for (int i = start_offset; i < buffer_content.size(); i++) { for (int i = start_offset; i < buffer_content.size(); i++) {
char c = buffer_content[i]; char c = buffer_content[i];
if (!isalnum(c) && c != '_') break; if (!isalnum(c) && c != '_')
break;
// We know that replace_end_pos and position are on the same line. // We know that replace_end_pos and position are on the same line.
replace_end_pos->character++; replace_end_pos->character++;
} }
@ -424,8 +418,8 @@ WorkingFile* WorkingFiles::GetFileByFilename(const std::string& filename) {
return GetFileByFilenameNoLock(filename); return GetFileByFilenameNoLock(filename);
} }
WorkingFile* WorkingFiles::GetFileByFilenameNoLock( WorkingFile *
const std::string& filename) { WorkingFiles::GetFileByFilenameNoLock(const std::string &filename) {
for (auto &file : files) { for (auto &file : files) {
if (file->filename == filename) if (file->filename == filename)
return file.get(); return file.get();
@ -516,8 +510,8 @@ void WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) {
<< " because it was not open"; << " because it was not open";
} }
WorkingFiles::Snapshot WorkingFiles::AsSnapshot( WorkingFiles::Snapshot
const std::vector<std::string>& filter_paths) { WorkingFiles::AsSnapshot(const std::vector<std::string> &filter_paths) {
std::lock_guard<std::mutex> lock(files_mutex); std::lock_guard<std::mutex> lock(files_mutex);
Snapshot result; Snapshot result;

View File

@ -40,10 +40,12 @@ struct WorkingFile {
// Also resolves |column| if not NULL. // Also resolves |column| if not NULL.
// When resolving a range, use is_end = false for begin() and is_end = // When resolving a range, use is_end = false for begin() and is_end =
// true for end() to get a better alignment of |column|. // true for end() to get a better alignment of |column|.
std::optional<int> GetBufferPosFromIndexPos(int line, int* column, bool is_end); std::optional<int> GetBufferPosFromIndexPos(int line, int *column,
bool is_end);
// Finds the index line number which maps to buffer line number |line|. // Finds the index line number which maps to buffer line number |line|.
// Also resolves |column| if not NULL. // Also resolves |column| if not NULL.
std::optional<int> GetIndexPosFromBufferPos(int line, int* column, bool is_end); std::optional<int> GetIndexPosFromBufferPos(int line, int *column,
bool is_end);
// TODO: Move FindClosestCallNameInBuffer and FindStableCompletionSource into // TODO: Move FindClosestCallNameInBuffer and FindStableCompletionSource into
// lex_utils.h/cc // lex_utils.h/cc
@ -53,9 +55,8 @@ struct WorkingFile {
// //
// |completion_position| will be point to a good code completion location to // |completion_position| will be point to a good code completion location to
// for fetching signatures. // for fetching signatures.
std::string FindClosestCallNameInBuffer( std::string
lsPosition position, FindClosestCallNameInBuffer(lsPosition position, int *active_parameter,
int* active_parameter,
lsPosition *completion_position = nullptr) const; lsPosition *completion_position = nullptr) const;
// Returns a relatively stable completion position (it jumps back until there // Returns a relatively stable completion position (it jumps back until there