mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
clang-format
DEF CON 26 CTF
This commit is contained in:
parent
87f36a4a96
commit
39787d2851
@ -197,8 +197,9 @@ void BuildCompletionItemTexts(std::vector<lsCompletionItem> &out,
|
||||
continue;
|
||||
|
||||
if (Kind == CodeCompletionString::CK_Placeholder) {
|
||||
out[i].insertText +=
|
||||
"${" + std::to_string(out[i].parameters_.size()) + ":" + text + "}";
|
||||
out[i].insertText += "${" +
|
||||
std::to_string(out[i].parameters_.size()) + ":" +
|
||||
text + "}";
|
||||
out[i].insertTextFormat = lsInsertTextFormat::Snippet;
|
||||
} else {
|
||||
out[i].insertText += text;
|
||||
@ -238,7 +239,8 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item,
|
||||
item.detail += Chunk.Text;
|
||||
// Add parameter declarations as snippets if enabled
|
||||
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;
|
||||
} else
|
||||
do_insert = false;
|
||||
@ -250,8 +252,8 @@ void BuildDetailString(const CodeCompletionString &CCS, lsCompletionItem &item,
|
||||
case CodeCompletionString::CK_Optional: {
|
||||
// Do not add text to insert string if we're in angle brackets.
|
||||
bool should_insert = do_insert && angle_stack == 0;
|
||||
BuildDetailString(*Chunk.Optional, item, should_insert,
|
||||
parameters, include_snippets, angle_stack);
|
||||
BuildDetailString(*Chunk.Optional, item, should_insert, parameters,
|
||||
include_snippets, angle_stack);
|
||||
break;
|
||||
}
|
||||
case CodeCompletionString::CK_ResultType:
|
||||
@ -298,8 +300,7 @@ public:
|
||||
Alloc(std::make_shared<clang::GlobalCodeCompletionAllocator>()),
|
||||
CCTUInfo(Alloc) {}
|
||||
|
||||
void ProcessCodeCompleteResults(Sema &S,
|
||||
CodeCompletionContext Context,
|
||||
void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
|
||||
CodeCompletionResult *Results,
|
||||
unsigned NumResults) override {
|
||||
ls_items.reserve(NumResults);
|
||||
@ -334,8 +335,7 @@ public:
|
||||
} else {
|
||||
bool do_insert = true;
|
||||
int angle_stack = 0;
|
||||
BuildDetailString(*CCS, ls_item, do_insert,
|
||||
&ls_item.parameters_,
|
||||
BuildDetailString(*CCS, ls_item, do_insert, &ls_item.parameters_,
|
||||
g_config->client.snippetSupport, angle_stack);
|
||||
if (g_config->client.snippetSupport &&
|
||||
ls_item.insertTextFormat == lsInsertTextFormat::Snippet)
|
||||
@ -427,7 +427,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
|
||||
true /*create_if_needed*/);
|
||||
|
||||
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
|
||||
// |TryEnsureDocumentParsed|.
|
||||
@ -464,7 +465,8 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
|
||||
capture, tu->PCHCO, *Diag, LangOpts, *SrcMgr,
|
||||
*FileMgr, Diagnostics, TemporaryBuffers);
|
||||
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?
|
||||
continue;
|
||||
const FileEntry *FE = FLoc.getFileEntry();
|
||||
if (!FE || FileName(*FE) != path) continue;
|
||||
if (!FE || FileName(*FE) != path)
|
||||
continue;
|
||||
const auto &SM = FLoc.getManager();
|
||||
SourceRange R;
|
||||
for (const auto &CR : I->getRanges()) {
|
||||
@ -559,24 +562,25 @@ ClangCompleteManager::ClangCompleteManager(Project* project,
|
||||
WorkingFiles *working_files,
|
||||
OnDiagnostic on_diagnostic,
|
||||
OnDropped on_dropped)
|
||||
: project_(project),
|
||||
working_files_(working_files),
|
||||
on_diagnostic_(on_diagnostic),
|
||||
on_dropped_(on_dropped),
|
||||
: project_(project), working_files_(working_files),
|
||||
on_diagnostic_(on_diagnostic), on_dropped_(on_dropped),
|
||||
preloaded_sessions_(kMaxPreloadedSessions),
|
||||
completion_sessions_(kMaxCompletionSessions) {
|
||||
std::thread([&]() {
|
||||
set_thread_name("comp-query");
|
||||
CompletionQueryMain(this);
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
std::thread([&]() {
|
||||
set_thread_name("comp-preload");
|
||||
CompletionPreloadMain(this);
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
std::thread([&]() {
|
||||
set_thread_name("diag-query");
|
||||
DiagnosticQueryMain(this);
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
void ClangCompleteManager::CodeComplete(
|
||||
@ -668,8 +672,8 @@ bool ClangCompleteManager::EnsureCompletionOrCreatePreloadSession(
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<CompletionSession> ClangCompleteManager::TryGetSession(
|
||||
const std::string& filename,
|
||||
std::shared_ptr<CompletionSession>
|
||||
ClangCompleteManager::TryGetSession(const std::string &filename,
|
||||
bool mark_as_completion,
|
||||
bool create_if_needed) {
|
||||
std::lock_guard<std::mutex> lock(sessions_lock_);
|
||||
|
@ -36,12 +36,10 @@ struct CompletionSession
|
||||
};
|
||||
|
||||
struct ClangCompleteManager {
|
||||
using OnDiagnostic =
|
||||
std::function<void(std::string path,
|
||||
std::vector<lsDiagnostic> diagnostics)>;
|
||||
using OnComplete =
|
||||
std::function<void(const std::vector<lsCompletionItem>& results,
|
||||
bool is_cached_result)>;
|
||||
using OnDiagnostic = std::function<void(
|
||||
std::string path, std::vector<lsDiagnostic> diagnostics)>;
|
||||
using OnComplete = std::function<void(
|
||||
const std::vector<lsCompletionItem> &results, bool is_cached_result)>;
|
||||
using OnDropped = std::function<void(lsRequestId request_id)>;
|
||||
|
||||
struct PreloadRequest {
|
||||
@ -54,11 +52,8 @@ struct ClangCompleteManager {
|
||||
struct CompletionRequest {
|
||||
CompletionRequest(const lsRequestId &id,
|
||||
const lsTextDocumentIdentifier &document,
|
||||
const lsPosition& position,
|
||||
const OnComplete& on_complete)
|
||||
: id(id),
|
||||
document(document),
|
||||
position(position),
|
||||
const lsPosition &position, const OnComplete &on_complete)
|
||||
: id(id), document(document), position(position),
|
||||
on_complete(on_complete) {}
|
||||
|
||||
lsRequestId id;
|
||||
@ -70,10 +65,8 @@ struct ClangCompleteManager {
|
||||
lsTextDocumentIdentifier document;
|
||||
};
|
||||
|
||||
ClangCompleteManager(Project* project,
|
||||
WorkingFiles* working_files,
|
||||
OnDiagnostic on_diagnostic,
|
||||
OnDropped on_dropped);
|
||||
ClangCompleteManager(Project *project, WorkingFiles *working_files,
|
||||
OnDiagnostic on_diagnostic, OnDropped on_dropped);
|
||||
|
||||
// Start a code completion at the given location. |on_complete| will run when
|
||||
// completion results are available. |on_complete| may run on any thread.
|
||||
|
@ -103,8 +103,7 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
|
||||
ret->PCHCO->getRawReader().getFormat(), &ErrUnit));
|
||||
};
|
||||
if (!CRC.RunSafely(parse)) {
|
||||
LOG_S(ERROR)
|
||||
<< "clang crashed for " << filepath << "\n"
|
||||
LOG_S(ERROR) << "clang crashed for " << filepath << "\n"
|
||||
<< StringJoin(args, " ") + " -fsyntax-only";
|
||||
return {};
|
||||
}
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include <llvm/Support/CrashRecoveryContext.h>
|
||||
|
||||
#include <memory>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
|
||||
std::vector<clang::ASTUnit::RemappedFile>
|
||||
GetRemapped(const WorkingFiles::Snapshot &snapshot);
|
||||
@ -19,12 +19,12 @@ Range FromCharSourceRange(const clang::SourceManager &SM,
|
||||
clang::CharSourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||
|
||||
Range FromCharRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts,
|
||||
clang::SourceRange R,
|
||||
Range FromCharRange(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &LangOpts, clang::SourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||
|
||||
Range FromTokenRange(const clang::SourceManager &SM, const clang::LangOptions &LangOpts,
|
||||
clang::SourceRange R,
|
||||
Range FromTokenRange(const clang::SourceManager &SM,
|
||||
const clang::LangOptions &LangOpts, clang::SourceRange R,
|
||||
llvm::sys::fs::UniqueID *UniqueID = nullptr);
|
||||
|
||||
struct ClangTranslationUnit {
|
||||
|
50
src/config.h
50
src/config.h
@ -218,49 +218,23 @@ struct Config {
|
||||
MAKE_REFLECT_STRUCT(Config::Clang, extraArgs, resourceDir);
|
||||
MAKE_REFLECT_STRUCT(Config::ClientCapability, snippetSupport);
|
||||
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
|
||||
MAKE_REFLECT_STRUCT(Config::Completion,
|
||||
caseSensitivity,
|
||||
dropOldRequests,
|
||||
detailedLabel,
|
||||
filterAndSort,
|
||||
includeBlacklist,
|
||||
includeMaxPathSize,
|
||||
includeSuffixWhitelist,
|
||||
MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, dropOldRequests,
|
||||
detailedLabel, filterAndSort, includeBlacklist,
|
||||
includeMaxPathSize, includeSuffixWhitelist,
|
||||
includeWhitelist);
|
||||
MAKE_REFLECT_STRUCT(Config::Diagnostics,
|
||||
blacklist,
|
||||
frequencyMs,
|
||||
onParse,
|
||||
onType,
|
||||
whitelist)
|
||||
MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, frequencyMs, onParse,
|
||||
onType, whitelist)
|
||||
MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist)
|
||||
MAKE_REFLECT_STRUCT(Config::Index,
|
||||
attributeMakeCallsToCtor,
|
||||
blacklist,
|
||||
comments,
|
||||
enabled,
|
||||
onDidChange,
|
||||
reparseForDependency,
|
||||
threads,
|
||||
whitelist);
|
||||
MAKE_REFLECT_STRUCT(Config::Index, attributeMakeCallsToCtor, blacklist,
|
||||
comments, enabled, onDidChange, reparseForDependency,
|
||||
threads, whitelist);
|
||||
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
||||
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
||||
MAKE_REFLECT_STRUCT(Config,
|
||||
compilationDatabaseCommand,
|
||||
compilationDatabaseDirectory,
|
||||
cacheDirectory,
|
||||
cacheFormat,
|
||||
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
||||
compilationDatabaseDirectory, cacheDirectory, cacheFormat,
|
||||
|
||||
clang,
|
||||
client,
|
||||
codeLens,
|
||||
completion,
|
||||
diagnostics,
|
||||
highlight,
|
||||
index,
|
||||
largeFileSize,
|
||||
workspaceSymbol,
|
||||
xref);
|
||||
clang, client, codeLens, completion, diagnostics, highlight,
|
||||
index, largeFileSize, workspaceSymbol, xref);
|
||||
|
||||
extern Config *g_config;
|
||||
thread_local extern int g_thread_id;
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
namespace {
|
||||
|
||||
std::optional<std::string> GetFileContents(
|
||||
const std::string& path,
|
||||
std::optional<std::string>
|
||||
GetFileContents(const std::string &path,
|
||||
std::unordered_map<std::string, FileContents> *file_contents) {
|
||||
auto it = file_contents->find(path);
|
||||
if (it == file_contents->end()) {
|
||||
@ -115,7 +115,8 @@ IndexFile* FileConsumer::TryConsumeFile(
|
||||
return nullptr;
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -42,15 +42,14 @@ struct VFS {
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<llvm::sys::fs::UniqueID> {
|
||||
template <> struct hash<llvm::sys::fs::UniqueID> {
|
||||
std::size_t operator()(llvm::sys::fs::UniqueID ID) const {
|
||||
size_t ret = ID.getDevice();
|
||||
hash_combine(ret, ID.getFile());
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
// 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
|
||||
@ -68,14 +67,16 @@ struct FileConsumer {
|
||||
//
|
||||
// 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.
|
||||
IndexFile* TryConsumeFile(const clang::FileEntry& file,
|
||||
IndexFile *
|
||||
TryConsumeFile(const clang::FileEntry &file,
|
||||
std::unordered_map<std::string, FileContents> *file_contents);
|
||||
|
||||
// Returns and passes ownership of all local state.
|
||||
std::vector<std::unique_ptr<IndexFile>> TakeLocalState();
|
||||
|
||||
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_;
|
||||
std::string parse_file_;
|
||||
int thread_id_;
|
||||
|
@ -6,9 +6,7 @@ using namespace llvm;
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
void GetFilesInFolder(std::string folder,
|
||||
bool recursive,
|
||||
bool dir_prefix,
|
||||
void GetFilesInFolder(std::string folder, bool recursive, bool dir_prefix,
|
||||
const std::function<void(const std::string &)> &handler) {
|
||||
EnsureEndsInSlash(folder);
|
||||
sys::fs::file_status Status;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "fuzzy_match.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
enum CharClass { Other, Lower, Upper };
|
||||
|
@ -46,8 +46,7 @@ size_t TrimCommonPathPrefix(const std::string& result,
|
||||
}
|
||||
|
||||
// Returns true iff angle brackets should be used.
|
||||
bool TrimPath(Project* project,
|
||||
const std::string& project_root,
|
||||
bool TrimPath(Project *project, const std::string &project_root,
|
||||
std::string *insert_path) {
|
||||
size_t start = TrimCommonPathPrefix(*insert_path, project_root);
|
||||
bool angle = false;
|
||||
@ -68,8 +67,7 @@ bool TrimPath(Project* project,
|
||||
}
|
||||
|
||||
lsCompletionItem BuildCompletionItem(const std::string &path,
|
||||
bool use_angle_brackets,
|
||||
bool is_stl) {
|
||||
bool use_angle_brackets, bool is_stl) {
|
||||
lsCompletionItem item;
|
||||
item.label = ElideLongPath(path);
|
||||
item.detail = path; // the include path, used in de-duplicating
|
||||
@ -102,7 +100,8 @@ void IncludeComplete::Rescan() {
|
||||
|
||||
if (!match_ && (g_config->completion.includeWhitelist.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);
|
||||
|
||||
is_scanning = true;
|
||||
@ -117,7 +116,8 @@ void IncludeComplete::Rescan() {
|
||||
InsertIncludesFromDirectory(dir, true /*use_angle_brackets*/);
|
||||
|
||||
is_scanning = false;
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
void IncludeComplete::InsertCompletionItem(const std::string &absolute_path,
|
||||
@ -189,7 +189,8 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
|
||||
std::move(result.completion_item));
|
||||
}
|
||||
|
||||
std::optional<lsCompletionItem> IncludeComplete::FindCompletionItemForAbsolutePath(
|
||||
std::optional<lsCompletionItem>
|
||||
IncludeComplete::FindCompletionItemForAbsolutePath(
|
||||
const std::string &absolute_path) {
|
||||
std::lock_guard<std::mutex> lock(completion_items_mutex);
|
||||
|
||||
|
@ -23,8 +23,8 @@ struct IncludeComplete {
|
||||
void InsertIncludesFromDirectory(std::string directory,
|
||||
bool use_angle_brackets);
|
||||
|
||||
std::optional<lsCompletionItem> FindCompletionItemForAbsolutePath(
|
||||
const std::string& absolute_path);
|
||||
std::optional<lsCompletionItem>
|
||||
FindCompletionItemForAbsolutePath(const std::string &absolute_path);
|
||||
|
||||
// Insert item to |completion_items|.
|
||||
// Update |absolute_path_to_completion_item| and |inserted_paths|.
|
||||
|
@ -21,9 +21,9 @@ using ccls::Intern;
|
||||
using namespace clang;
|
||||
using llvm::Timer;
|
||||
|
||||
#include <algorithm>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
|
||||
@ -81,8 +81,9 @@ StringRef GetSourceInRange(const SourceManager &SM, const LangOptions &LangOpts,
|
||||
StringRef Buf = SM.getBufferData(BInfo.first, &invalid);
|
||||
if (invalid)
|
||||
return "";
|
||||
return Buf.substr(BInfo.second, EInfo.second + Lexer::MeasureTokenLength(
|
||||
ELoc, SM, LangOpts) -
|
||||
return Buf.substr(BInfo.second,
|
||||
EInfo.second +
|
||||
Lexer::MeasureTokenLength(ELoc, SM, LangOpts) -
|
||||
BInfo.second);
|
||||
}
|
||||
|
||||
@ -200,8 +201,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) {
|
||||
BaseType = ATy->getDeducedType();
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return BaseType;
|
||||
@ -271,14 +271,14 @@ const Decl* GetSpecialized(const Decl* D) {
|
||||
return D;
|
||||
Decl *Template = nullptr;
|
||||
if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
|
||||
if (const ClassTemplatePartialSpecializationDecl *PartialSpec
|
||||
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
|
||||
if (const ClassTemplatePartialSpecializationDecl *PartialSpec =
|
||||
dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
|
||||
Template = PartialSpec->getSpecializedTemplate();
|
||||
else if (const ClassTemplateSpecializationDecl *ClassSpec
|
||||
= dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
|
||||
else if (const ClassTemplateSpecializationDecl *ClassSpec =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
|
||||
llvm::PointerUnion<ClassTemplateDecl *,
|
||||
ClassTemplatePartialSpecializationDecl *> Result
|
||||
= ClassSpec->getSpecializedTemplateOrPartial();
|
||||
ClassTemplatePartialSpecializationDecl *>
|
||||
Result = ClassSpec->getSpecializedTemplateOrPartial();
|
||||
if (Result.is<ClassTemplateDecl *>())
|
||||
Template = Result.get<ClassTemplateDecl *>();
|
||||
else
|
||||
@ -293,8 +293,8 @@ const Decl* GetSpecialized(const Decl* D) {
|
||||
} else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
|
||||
if (Var->isStaticDataMember())
|
||||
Template = Var->getInstantiatedFromStaticDataMember();
|
||||
} else if (const RedeclarableTemplateDecl *Tmpl
|
||||
= dyn_cast<RedeclarableTemplateDecl>(D))
|
||||
} else if (const RedeclarableTemplateDecl *Tmpl =
|
||||
dyn_cast<RedeclarableTemplateDecl>(D))
|
||||
Template = Tmpl->getInstantiatedFromMemberTemplate();
|
||||
else
|
||||
return nullptr;
|
||||
@ -322,7 +322,8 @@ public:
|
||||
std::string GetComment(const Decl *D) {
|
||||
SourceManager &SM = Ctx->getSourceManager();
|
||||
const RawComment *RC = Ctx->getRawCommentForAnyRedecl(D);
|
||||
if (!RC) return "";
|
||||
if (!RC)
|
||||
return "";
|
||||
StringRef Raw = RC->getRawText(Ctx->getSourceManager());
|
||||
SourceRange R = RC->getSourceRange();
|
||||
std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(R.getBegin());
|
||||
@ -533,7 +534,8 @@ public:
|
||||
void AddMacroUse(IndexFile *db, SourceManager &SM, Usr usr, SymbolKind kind,
|
||||
SourceLocation Spell) const {
|
||||
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(Spell));
|
||||
if (!FE) return;
|
||||
if (!FE)
|
||||
return;
|
||||
auto UID = FE->getUniqueID();
|
||||
auto [it, inserted] = db->uid2lid_and_path.try_emplace(UID);
|
||||
if (inserted) {
|
||||
@ -566,9 +568,7 @@ public:
|
||||
|
||||
public:
|
||||
IndexDataConsumer(IndexParam ¶m) : param(param) {}
|
||||
void initialize(ASTContext &Ctx) override {
|
||||
this->Ctx = param.Ctx = &Ctx;
|
||||
}
|
||||
void initialize(ASTContext &Ctx) override { this->Ctx = param.Ctx = &Ctx; }
|
||||
bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
|
||||
ArrayRef<index::SymbolRelation> Relations,
|
||||
#if LLVM_VERSION_MAJOR >= 7
|
||||
@ -725,7 +725,8 @@ public:
|
||||
it->second.instances.push_back(usr);
|
||||
break;
|
||||
}
|
||||
// e.g. TemplateTypeParmDecl is not handled by handleDeclOccurence.
|
||||
// e.g. TemplateTypeParmDecl is not handled by
|
||||
// handleDeclOccurence.
|
||||
SourceRange R1 = D1->getSourceRange();
|
||||
if (SM.getFileID(R1.getBegin()) == LocFID) {
|
||||
IndexType &type1 = db->ToType(usr1);
|
||||
@ -1053,8 +1054,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
void MacroExpands(const Token &Tok, const MacroDefinition &MD,
|
||||
SourceRange R, const MacroArgs *Args) override {
|
||||
void MacroExpands(const Token &Tok, const MacroDefinition &MD, SourceRange R,
|
||||
const MacroArgs *Args) override {
|
||||
llvm::sys::fs::UniqueID UniqueID;
|
||||
SourceLocation L = SM.getSpellingLoc(R.getBegin());
|
||||
const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(L));
|
||||
@ -1086,16 +1087,18 @@ public:
|
||||
|
||||
class IndexFrontendAction : public ASTFrontendAction {
|
||||
IndexParam ¶m;
|
||||
|
||||
public:
|
||||
IndexFrontendAction(IndexParam ¶m) : param(param) {}
|
||||
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
|
||||
StringRef InFile) override {
|
||||
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>();
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const int IndexFile::kMajorVersion = 17;
|
||||
const int IndexFile::kMinorVersion = 1;
|
||||
@ -1129,8 +1132,7 @@ std::string IndexFile::ToString() {
|
||||
return ccls::Serialize(SerializeFormat::Json, *this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Uniquify(std::vector<T>& a) {
|
||||
template <typename T> void Uniquify(std::vector<T> &a) {
|
||||
std::unordered_set<T> seen;
|
||||
size_t n = 0;
|
||||
for (size_t i = 0; i < a.size(); i++)
|
||||
@ -1140,10 +1142,8 @@ void Uniquify(std::vector<T>& a) {
|
||||
}
|
||||
|
||||
namespace ccls::idx {
|
||||
std::vector<std::unique_ptr<IndexFile>> Index(
|
||||
VFS* vfs,
|
||||
const std::string& opt_wdir,
|
||||
const std::string& file,
|
||||
std::vector<std::unique_ptr<IndexFile>>
|
||||
Index(VFS *vfs, const std::string &opt_wdir, const std::string &file,
|
||||
const std::vector<std::string> &args,
|
||||
const std::vector<FileContents> &file_contents) {
|
||||
if (!g_config->index.enabled)
|
||||
@ -1153,8 +1153,8 @@ std::vector<std::unique_ptr<IndexFile>> Index(
|
||||
for (auto &arg : args)
|
||||
Args.push_back(arg.c_str());
|
||||
auto PCHCO = std::make_shared<PCHContainerOperations>();
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine>
|
||||
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
|
||||
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
|
||||
CompilerInstance::createDiagnostics(new DiagnosticOptions));
|
||||
std::shared_ptr<CompilerInvocation> CI =
|
||||
createInvocationFromCommandLine(Args, Diags);
|
||||
if (!CI)
|
||||
@ -1270,7 +1270,7 @@ std::vector<std::unique_ptr<IndexFile>> Index(
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} // namespace ccls::idx
|
||||
|
||||
// |SymbolRef| is serialized this way.
|
||||
// |Use| also uses this though it has an extra field |file|,
|
||||
|
@ -14,9 +14,9 @@
|
||||
#include <clang/Basic/Specifiers.h>
|
||||
#include <llvm/ADT/StringMap.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <stdint.h>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -72,8 +72,7 @@ void Reflect(Writer& visitor, Reference& value);
|
||||
void Reflect(Reader &visitor, Use &value);
|
||||
void Reflect(Writer &visitor, Use &value);
|
||||
|
||||
template <typename D>
|
||||
struct NameMixin {
|
||||
template <typename D> struct NameMixin {
|
||||
std::string_view Name(bool qualified) const {
|
||||
auto self = static_cast<const D *>(this);
|
||||
return qualified
|
||||
@ -112,20 +111,9 @@ struct FuncDef : NameMixin<FuncDef> {
|
||||
|
||||
std::vector<Usr> GetBases() const { return bases; }
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(FuncDef,
|
||||
detailed_name,
|
||||
qual_name_offset,
|
||||
short_name_offset,
|
||||
short_name_size,
|
||||
kind,
|
||||
storage,
|
||||
hover,
|
||||
comments,
|
||||
spell,
|
||||
extent,
|
||||
bases,
|
||||
vars,
|
||||
callees);
|
||||
MAKE_REFLECT_STRUCT(FuncDef, detailed_name, qual_name_offset, short_name_offset,
|
||||
short_name_size, kind, storage, hover, comments, spell,
|
||||
extent, bases, vars, callees);
|
||||
|
||||
struct IndexFunc : NameMixin<IndexFunc> {
|
||||
using Def = FuncDef;
|
||||
@ -163,21 +151,9 @@ struct TypeDef : NameMixin<TypeDef> {
|
||||
|
||||
std::vector<Usr> GetBases() const { return bases; }
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(TypeDef,
|
||||
detailed_name,
|
||||
qual_name_offset,
|
||||
short_name_offset,
|
||||
short_name_size,
|
||||
kind,
|
||||
hover,
|
||||
comments,
|
||||
spell,
|
||||
extent,
|
||||
alias_of,
|
||||
bases,
|
||||
types,
|
||||
funcs,
|
||||
vars);
|
||||
MAKE_REFLECT_STRUCT(TypeDef, detailed_name, qual_name_offset, short_name_offset,
|
||||
short_name_size, kind, hover, comments, spell, extent,
|
||||
alias_of, bases, types, funcs, vars);
|
||||
|
||||
struct IndexType {
|
||||
using Def = TypeDef;
|
||||
@ -217,17 +193,8 @@ struct VarDef : NameMixin<VarDef> {
|
||||
|
||||
std::vector<Usr> GetBases() const { return {}; }
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(VarDef,
|
||||
detailed_name,
|
||||
qual_name_offset,
|
||||
short_name_offset,
|
||||
short_name_size,
|
||||
hover,
|
||||
comments,
|
||||
spell,
|
||||
extent,
|
||||
type,
|
||||
kind,
|
||||
MAKE_REFLECT_STRUCT(VarDef, detailed_name, qual_name_offset, short_name_offset,
|
||||
short_name_size, hover, comments, spell, extent, type, kind,
|
||||
storage);
|
||||
|
||||
struct IndexVar {
|
||||
|
@ -3,11 +3,11 @@
|
||||
#include <llvm/ADT/SmallString.h>
|
||||
#include <llvm/Support/Threading.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <mutex>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <iomanip>
|
||||
#include <mutex>
|
||||
|
||||
namespace ccls::log {
|
||||
static std::mutex mtx;
|
||||
@ -52,11 +52,12 @@ Message::Message(Verbosity verbosity, const char* file, int line)
|
||||
}
|
||||
|
||||
Message::~Message() {
|
||||
if (!file) return;
|
||||
if (!file)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
stream_ << '\n';
|
||||
fputs(stream_.str().c_str(), file);
|
||||
if (verbosity_ == Verbosity_FATAL)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
} // namespace ccls::log
|
||||
|
@ -8,8 +8,7 @@
|
||||
|
||||
// Cache that evicts old entries which have not been used recently. Implemented
|
||||
// using array/linear search so this works well for small array sizes.
|
||||
template <typename TKey, typename TValue>
|
||||
struct LruCache {
|
||||
template <typename TKey, typename TValue> struct LruCache {
|
||||
explicit LruCache(int max_entries);
|
||||
|
||||
// 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
|
||||
// temrinates early.
|
||||
template <typename TFunc>
|
||||
void IterateValues(TFunc func);
|
||||
template <typename TFunc> void IterateValues(TFunc func);
|
||||
|
||||
// Empties the cache
|
||||
void Clear(void);
|
||||
|
13
src/lsp.cc
13
src/lsp.cc
@ -17,8 +17,8 @@ lsVersionedTextDocumentIdentifier::AsTextDocumentIdentifier() const {
|
||||
}
|
||||
|
||||
// Reads a JsonRpc message. |read| returns the next input character.
|
||||
std::optional<std::string> ReadJsonRpcContentFrom(
|
||||
std::function<std::optional<char>()> read) {
|
||||
std::optional<std::string>
|
||||
ReadJsonRpcContentFrom(std::function<std::optional<char>()> read) {
|
||||
// Read the content length. It is terminated by the "\r\n" sequence.
|
||||
int exit_seq = 0;
|
||||
std::string stringified_content_length;
|
||||
@ -78,8 +78,8 @@ std::optional<char> ReadCharFromStdinBlocking() {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> MessageRegistry::ReadMessageFromStdin(
|
||||
std::unique_ptr<InMessage>* message) {
|
||||
std::optional<std::string>
|
||||
MessageRegistry::ReadMessageFromStdin(std::unique_ptr<InMessage> *message) {
|
||||
std::optional<std::string> content =
|
||||
ReadJsonRpcContentFrom(&ReadCharFromStdinBlocking);
|
||||
if (!content) {
|
||||
@ -95,9 +95,8 @@ std::optional<std::string> MessageRegistry::ReadMessageFromStdin(
|
||||
return Parse(json_reader, message);
|
||||
}
|
||||
|
||||
std::optional<std::string> MessageRegistry::Parse(
|
||||
Reader& visitor,
|
||||
std::unique_ptr<InMessage>* message) {
|
||||
std::optional<std::string>
|
||||
MessageRegistry::Parse(Reader &visitor, std::unique_ptr<InMessage> *message) {
|
||||
if (!visitor.HasMember("jsonrpc") ||
|
||||
std::string(visitor["jsonrpc"]->GetString()) != "2.0") {
|
||||
LOG_S(FATAL) << "Bad or missing jsonrpc version";
|
||||
|
19
src/lsp.h
19
src/lsp.h
@ -19,14 +19,13 @@ struct MessageRegistry {
|
||||
std::function<void(Reader &visitor, std::unique_ptr<InMessage> *)>;
|
||||
std::unordered_map<std::string, Allocator> allocators;
|
||||
|
||||
std::optional<std::string> ReadMessageFromStdin(
|
||||
std::unique_ptr<InMessage>* message);
|
||||
std::optional<std::string>
|
||||
ReadMessageFromStdin(std::unique_ptr<InMessage> *message);
|
||||
std::optional<std::string> Parse(Reader &visitor,
|
||||
std::unique_ptr<InMessage> *message);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct MessageRegistryRegister {
|
||||
template <typename T> struct MessageRegistryRegister {
|
||||
MessageRegistryRegister() {
|
||||
T dummy;
|
||||
std::string method_name = dummy.GetMethodType();
|
||||
@ -47,8 +46,7 @@ struct lsBaseOutMessage {
|
||||
void Write(std::ostream &out);
|
||||
};
|
||||
|
||||
template <typename TDerived>
|
||||
struct lsOutMessage : lsBaseOutMessage {
|
||||
template <typename TDerived> struct lsOutMessage : lsBaseOutMessage {
|
||||
// All derived types need to reflect on the |jsonrpc| member.
|
||||
std::string jsonrpc = "2.0";
|
||||
|
||||
@ -192,8 +190,7 @@ struct lsLocationEx : lsLocation {
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsLocationEx, uri, range, containerName, parentKind, role);
|
||||
|
||||
template <typename T>
|
||||
struct lsCommand {
|
||||
template <typename T> struct lsCommand {
|
||||
// Title of the command (ie, 'save')
|
||||
std::string title;
|
||||
// Actual command identifier.
|
||||
@ -212,8 +209,7 @@ void Reflect(TVisitor& visitor, lsCommand<T>& value) {
|
||||
REFLECT_MEMBER_END();
|
||||
}
|
||||
|
||||
template <typename TData, typename TCommandArguments>
|
||||
struct lsCodeLens {
|
||||
template <typename TData, typename TCommandArguments> struct lsCodeLens {
|
||||
// The range in which this code lens is valid. Should only span a single line.
|
||||
lsRange range;
|
||||
// The command this code lens represents.
|
||||
@ -337,8 +333,7 @@ struct lsTextDocumentDidChangeParams {
|
||||
lsVersionedTextDocumentIdentifier textDocument;
|
||||
std::vector<lsTextDocumentContentChangeEvent> contentChanges;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams,
|
||||
textDocument,
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentDidChangeParams, textDocument,
|
||||
contentChanges);
|
||||
|
||||
// Show a message to the user.
|
||||
|
@ -106,9 +106,9 @@ struct lsCompletionItem {
|
||||
// nor with themselves.
|
||||
// std::vector<TextEdit> additionalTextEdits;
|
||||
|
||||
// An std::optional command that is executed *after* inserting this completion.
|
||||
// *Note* that additional modifications to the current document should be
|
||||
// described with the additionalTextEdits-property. Command command;
|
||||
// An std::optional command that is executed *after* inserting this
|
||||
// completion. *Note* that additional modifications to the current document
|
||||
// should be described with the additionalTextEdits-property. Command command;
|
||||
|
||||
// An data entry field that is preserved on a completion item between
|
||||
// a completion and a completion resolve request.
|
||||
@ -125,13 +125,6 @@ struct lsCompletionItem {
|
||||
return label;
|
||||
}
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsCompletionItem,
|
||||
label,
|
||||
kind,
|
||||
detail,
|
||||
documentation,
|
||||
sortText,
|
||||
insertText,
|
||||
filterText,
|
||||
insertTextFormat,
|
||||
MAKE_REFLECT_STRUCT(lsCompletionItem, label, kind, detail, documentation,
|
||||
sortText, insertText, filterText, insertTextFormat,
|
||||
textEdit);
|
||||
|
@ -96,6 +96,5 @@ void Reflect(TVisitor& visitor, Out_TextDocumentPublishDiagnostics& value) {
|
||||
REFLECT_MEMBER(params);
|
||||
REFLECT_MEMBER_END();
|
||||
}
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params,
|
||||
uri,
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentPublishDiagnostics::Params, uri,
|
||||
diagnostics);
|
||||
|
16
src/main.cc
16
src/main.cc
@ -28,17 +28,17 @@ std::string g_init_options;
|
||||
namespace {
|
||||
opt<bool> opt_help("h", desc("Alias for -help"));
|
||||
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_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"));
|
||||
|
||||
void CloseLog() {
|
||||
fclose(ccls::log::file);
|
||||
}
|
||||
void CloseLog() { fclose(ccls::log::file); }
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -108,11 +108,13 @@ int main(int argc, char** argv) {
|
||||
|
||||
sys::ChangeStdinToBinary();
|
||||
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();
|
||||
// The thread that writes responses from the main thread to stdout.
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,8 @@ std::optional<Matcher> Matcher::Create(const std::string& search) {
|
||||
try {
|
||||
Matcher m;
|
||||
m.regex_string = search;
|
||||
m.regex = std::regex(
|
||||
search, std::regex_constants::ECMAScript | std::regex_constants::icase |
|
||||
m.regex = std::regex(search, std::regex_constants::ECMAScript |
|
||||
std::regex_constants::icase |
|
||||
std::regex_constants::optimize
|
||||
// std::regex_constants::nosubs
|
||||
);
|
||||
@ -29,8 +29,8 @@ std::optional<Matcher> Matcher::Create(const std::string& search) {
|
||||
Out_ShowLogMessage out;
|
||||
out.display_type = Out_ShowLogMessage::DisplayType::Show;
|
||||
out.params.type = lsMessageType::Error;
|
||||
out.params.message = "ccls: Parsing EMCAScript regex \"" + search +
|
||||
"\" failed; " + e.what();
|
||||
out.params.message =
|
||||
"ccls: Parsing EMCAScript regex \"" + search + "\" failed; " + e.what();
|
||||
pipeline::WriteStdout(kMethodType_Unknown, out);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -4,10 +4,9 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
// Like std::optional, but the stored data is responsible for containing the empty
|
||||
// state. T should define a function `bool T::Valid()`.
|
||||
template <typename T>
|
||||
class Maybe {
|
||||
// Like std::optional, but the stored data is responsible for containing the
|
||||
// empty state. T should define a function `bool T::Valid()`.
|
||||
template <typename T> class Maybe {
|
||||
T storage;
|
||||
|
||||
public:
|
||||
|
@ -337,7 +337,8 @@ void EmitSemanticHighlighting(DB *db,
|
||||
out.params.uri = lsDocumentUri::FromPath(wfile->filename);
|
||||
// Transform lsRange into pair<int, int> (offset pairs)
|
||||
if (!g_config->highlight.lsRanges) {
|
||||
std::vector<std::pair<lsRange, Out_CclsPublishSemanticHighlighting::Symbol *>>
|
||||
std::vector<
|
||||
std::pair<lsRange, Out_CclsPublishSemanticHighlighting::Symbol *>>
|
||||
scratch;
|
||||
for (auto &entry : grouped_symbols) {
|
||||
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]))
|
||||
p++;
|
||||
}
|
||||
if (l < line) return true;
|
||||
if (l < line)
|
||||
return true;
|
||||
for (; c < col && i < buf.size() && buf[i] != '\n'; c++)
|
||||
if (p++, uint8_t(buf[i++]) >= 128)
|
||||
// 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++;
|
||||
return c < col;
|
||||
};
|
||||
|
@ -6,8 +6,8 @@
|
||||
#include "method.h"
|
||||
#include "query.h"
|
||||
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
@ -79,9 +79,7 @@ struct Out_CclsPublishSemanticHighlighting
|
||||
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Symbol, stableId,
|
||||
parentKind, kind, storage, ranges, lsRanges);
|
||||
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting::Params, uri, symbols);
|
||||
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting,
|
||||
jsonrpc,
|
||||
method,
|
||||
MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method,
|
||||
params);
|
||||
|
||||
// Usage:
|
||||
@ -121,8 +119,7 @@ struct MessageHandler {
|
||||
MessageHandler();
|
||||
};
|
||||
|
||||
template <typename TMessage>
|
||||
struct BaseMessageHandler : MessageHandler {
|
||||
template <typename TMessage> struct BaseMessageHandler : MessageHandler {
|
||||
virtual void Run(TMessage *message) = 0;
|
||||
|
||||
// MessageHandler:
|
||||
@ -131,17 +128,13 @@ struct BaseMessageHandler : MessageHandler {
|
||||
}
|
||||
};
|
||||
|
||||
bool FindFileOrFail(DB* db,
|
||||
Project* project,
|
||||
std::optional<lsRequestId> id,
|
||||
bool FindFileOrFail(DB *db, Project *project, std::optional<lsRequestId> id,
|
||||
const std::string &absolute_path,
|
||||
QueryFile** out_query_file,
|
||||
int* out_file_id = nullptr);
|
||||
QueryFile **out_query_file, int *out_file_id = nullptr);
|
||||
|
||||
void EmitSkippedRanges(WorkingFile *working_file,
|
||||
const std::vector<Range> &skipped_ranges);
|
||||
|
||||
void EmitSemanticHighlighting(DB *db,
|
||||
SemanticHighlightSymbolCache *semantic_cache,
|
||||
WorkingFile* working_file,
|
||||
QueryFile* file);
|
||||
WorkingFile *working_file, QueryFile *file);
|
||||
|
@ -44,16 +44,9 @@ struct In_CclsCallHierarchy : public RequestInMessage {
|
||||
int levels = 1;
|
||||
};
|
||||
Params params;
|
||||
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params,
|
||||
textDocument,
|
||||
position,
|
||||
id,
|
||||
callee,
|
||||
callType,
|
||||
qualified,
|
||||
levels);
|
||||
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy::Params, textDocument, position, id,
|
||||
callee, callType, qualified, levels);
|
||||
MAKE_REFLECT_STRUCT(In_CclsCallHierarchy, id, params);
|
||||
REGISTER_IN_MESSAGE(In_CclsCallHierarchy);
|
||||
|
||||
@ -72,24 +65,13 @@ struct Out_CclsCallHierarchy : public lsOutMessage<Out_CclsCallHierarchy> {
|
||||
lsRequestId id;
|
||||
std::optional<Entry> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry,
|
||||
id,
|
||||
name,
|
||||
location,
|
||||
callType,
|
||||
numChildren,
|
||||
children);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy,
|
||||
jsonrpc,
|
||||
id,
|
||||
MAKE_REFLECT_STRUCT(Out_CclsCallHierarchy::Entry, id, name, location, callType,
|
||||
numChildren, children);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsCallHierarchy, jsonrpc, id,
|
||||
result);
|
||||
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CclsCallHierarchy::Entry* entry,
|
||||
bool callee,
|
||||
CallType call_type,
|
||||
bool qualified,
|
||||
int levels) {
|
||||
bool Expand(MessageHandler *m, Out_CclsCallHierarchy::Entry *entry, bool callee,
|
||||
CallType call_type, bool qualified, int levels) {
|
||||
const QueryFunc &func = m->db->Func(entry->usr);
|
||||
const QueryFunc::Def *def = func.AnyDef();
|
||||
entry->numChildren = 0;
|
||||
@ -113,8 +95,7 @@ bool Expand(MessageHandler* m,
|
||||
if (const auto *def = func.AnyDef())
|
||||
for (SymbolRef ref : def->callees)
|
||||
if (ref.kind == SymbolKind::Func)
|
||||
handle(Use{{ref.range, ref.usr, ref.kind, ref.role},
|
||||
def->file_id},
|
||||
handle(Use{{ref.range, ref.usr, ref.kind, ref.role}, def->file_id},
|
||||
call_type);
|
||||
} else {
|
||||
for (Use use : func.uses)
|
||||
@ -165,14 +146,11 @@ bool Expand(MessageHandler* m,
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Handler_CclsCallHierarchy
|
||||
: BaseMessageHandler<In_CclsCallHierarchy> {
|
||||
struct Handler_CclsCallHierarchy : BaseMessageHandler<In_CclsCallHierarchy> {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
|
||||
std::optional<Out_CclsCallHierarchy::Entry> BuildInitial(Usr root_usr,
|
||||
bool callee,
|
||||
CallType call_type,
|
||||
bool qualified,
|
||||
std::optional<Out_CclsCallHierarchy::Entry>
|
||||
BuildInitial(Usr root_usr, bool callee, CallType call_type, bool qualified,
|
||||
int levels) {
|
||||
const auto *def = db->Func(root_usr).AnyDef();
|
||||
if (!def)
|
||||
|
@ -3,14 +3,8 @@
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
MAKE_REFLECT_STRUCT(QueryFile::Def,
|
||||
path,
|
||||
args,
|
||||
language,
|
||||
outline,
|
||||
all_symbols,
|
||||
skipped_ranges,
|
||||
dependencies);
|
||||
MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, outline, all_symbols,
|
||||
skipped_ranges, dependencies);
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "$ccls/fileInfo";
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "match.h"
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "platform.h"
|
||||
#include "project.h"
|
||||
#include "pipeline.hh"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
@ -21,9 +21,7 @@ struct In_CclsFreshenIndex : public NotificationInMessage {
|
||||
};
|
||||
Params params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params,
|
||||
dependencies,
|
||||
whitelist,
|
||||
MAKE_REFLECT_STRUCT(In_CclsFreshenIndex::Params, dependencies, whitelist,
|
||||
blacklist);
|
||||
MAKE_REFLECT_STRUCT(In_CclsFreshenIndex, params);
|
||||
REGISTER_IN_MESSAGE(In_CclsFreshenIndex);
|
||||
|
@ -51,31 +51,17 @@ struct Out_CclsInheritanceHierarchy
|
||||
lsRequestId id;
|
||||
std::optional<Entry> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry,
|
||||
id,
|
||||
kind,
|
||||
name,
|
||||
location,
|
||||
numChildren,
|
||||
children);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy,
|
||||
jsonrpc,
|
||||
id,
|
||||
result);
|
||||
MAKE_REFLECT_STRUCT(Out_CclsInheritanceHierarchy::Entry, id, kind, name,
|
||||
location, numChildren, children);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsInheritanceHierarchy, jsonrpc,
|
||||
id, result);
|
||||
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CclsInheritanceHierarchy::Entry* entry,
|
||||
bool derived,
|
||||
bool qualified,
|
||||
int levels);
|
||||
bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
|
||||
bool derived, bool qualified, int levels);
|
||||
|
||||
template <typename Q>
|
||||
bool ExpandHelper(MessageHandler* m,
|
||||
Out_CclsInheritanceHierarchy::Entry* entry,
|
||||
bool derived,
|
||||
bool qualified,
|
||||
int levels,
|
||||
Q& entity) {
|
||||
bool ExpandHelper(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
|
||||
bool derived, bool qualified, int levels, Q &entity) {
|
||||
const auto *def = entity.AnyDef();
|
||||
if (def) {
|
||||
entry->name = def->Name(qualified);
|
||||
@ -122,11 +108,8 @@ bool ExpandHelper(MessageHandler* m,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CclsInheritanceHierarchy::Entry* entry,
|
||||
bool derived,
|
||||
bool qualified,
|
||||
int levels) {
|
||||
bool Expand(MessageHandler *m, Out_CclsInheritanceHierarchy::Entry *entry,
|
||||
bool derived, bool qualified, int levels) {
|
||||
if (entry->kind == SymbolKind::Func)
|
||||
return ExpandHelper(m, entry, derived, qualified, levels,
|
||||
m->db->Func(entry->usr));
|
||||
@ -173,8 +156,7 @@ struct Handler_CclsInheritanceHierarchy
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position))
|
||||
if (sym.kind == SymbolKind::Func || sym.kind == SymbolKind::Type) {
|
||||
|
@ -30,17 +30,12 @@ struct In_CclsMemberHierarchy : public RequestInMessage {
|
||||
Params params;
|
||||
};
|
||||
|
||||
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params,
|
||||
textDocument,
|
||||
position,
|
||||
id,
|
||||
qualified,
|
||||
levels);
|
||||
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy::Params, textDocument, position, id,
|
||||
qualified, levels);
|
||||
MAKE_REFLECT_STRUCT(In_CclsMemberHierarchy, id, params);
|
||||
REGISTER_IN_MESSAGE(In_CclsMemberHierarchy);
|
||||
|
||||
struct Out_CclsMemberHierarchy
|
||||
: public lsOutMessage<Out_CclsMemberHierarchy> {
|
||||
struct Out_CclsMemberHierarchy : public lsOutMessage<Out_CclsMemberHierarchy> {
|
||||
struct Entry {
|
||||
Usr usr;
|
||||
std::string id;
|
||||
@ -56,30 +51,17 @@ struct Out_CclsMemberHierarchy
|
||||
lsRequestId id;
|
||||
std::optional<Entry> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry,
|
||||
id,
|
||||
name,
|
||||
fieldName,
|
||||
location,
|
||||
numChildren,
|
||||
children);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy,
|
||||
jsonrpc,
|
||||
id,
|
||||
MAKE_REFLECT_STRUCT(Out_CclsMemberHierarchy::Entry, id, name, fieldName,
|
||||
location, numChildren, children);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_CclsMemberHierarchy, jsonrpc, id,
|
||||
result);
|
||||
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CclsMemberHierarchy::Entry* entry,
|
||||
bool qualified,
|
||||
int levels);
|
||||
bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
|
||||
bool qualified, int levels);
|
||||
|
||||
// Add a field to |entry| which is a Func/Type.
|
||||
void DoField(MessageHandler* m,
|
||||
Out_CclsMemberHierarchy::Entry* entry,
|
||||
const QueryVar& var,
|
||||
int64_t offset,
|
||||
bool qualified,
|
||||
int levels) {
|
||||
void DoField(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
|
||||
const QueryVar &var, int64_t offset, bool qualified, int levels) {
|
||||
const QueryVar::Def *def1 = var.AnyDef();
|
||||
if (!def1)
|
||||
return;
|
||||
@ -120,10 +102,8 @@ void DoField(MessageHandler* m,
|
||||
}
|
||||
|
||||
// Expand a type node by adding members recursively to it.
|
||||
bool Expand(MessageHandler* m,
|
||||
Out_CclsMemberHierarchy::Entry* entry,
|
||||
bool qualified,
|
||||
int levels) {
|
||||
bool Expand(MessageHandler *m, Out_CclsMemberHierarchy::Entry *entry,
|
||||
bool qualified, int levels) {
|
||||
if (0 < entry->usr && entry->usr <= BuiltinType::LastKind) {
|
||||
entry->name = ClangBuiltinTypeName(int(entry->usr));
|
||||
return true;
|
||||
@ -193,10 +173,8 @@ struct Handler_CclsMemberHierarchy
|
||||
: BaseMessageHandler<In_CclsMemberHierarchy> {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
|
||||
std::optional<Out_CclsMemberHierarchy::Entry> BuildInitial(SymbolKind kind,
|
||||
Usr root_usr,
|
||||
bool qualified,
|
||||
int levels) {
|
||||
std::optional<Out_CclsMemberHierarchy::Entry>
|
||||
BuildInitial(SymbolKind kind, Usr root_usr, bool qualified, int levels) {
|
||||
switch (kind) {
|
||||
default:
|
||||
return {};
|
||||
@ -260,15 +238,14 @@ struct Handler_CclsMemberHierarchy
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
for (SymbolRef sym :
|
||||
FindSymbolsAtLocation(wfile, file, params.position)) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func:
|
||||
case SymbolKind::Type:
|
||||
out.result = BuildInitial(sym.kind, sym.usr, params.qualified,
|
||||
params.levels);
|
||||
out.result =
|
||||
BuildInitial(sym.kind, sym.usr, params.qualified, params.levels);
|
||||
break;
|
||||
case SymbolKind::Var: {
|
||||
const QueryVar::Def *def = db->GetVar(sym).AnyDef();
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "message_handler.h"
|
||||
#include "query_utils.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
@ -15,10 +15,7 @@ struct In_CclsVars : public RequestInMessage {
|
||||
unsigned kind = ~0u;
|
||||
} params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_CclsVars::Params,
|
||||
textDocument,
|
||||
position,
|
||||
kind);
|
||||
MAKE_REFLECT_STRUCT(In_CclsVars::Params, textDocument, position, kind);
|
||||
MAKE_REFLECT_STRUCT(In_CclsVars, id, params);
|
||||
REGISTER_IN_MESSAGE(In_CclsVars);
|
||||
|
||||
|
@ -10,9 +10,7 @@ REGISTER_IN_MESSAGE(In_Exit);
|
||||
struct Handler_Exit : MessageHandler {
|
||||
MethodType GetMethodType() const override { return kMethodType_Exit; }
|
||||
|
||||
void Run(std::unique_ptr<InMessage> request) override {
|
||||
exit(0);
|
||||
}
|
||||
void Run(std::unique_ptr<InMessage> request) override { exit(0); }
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(Handler_Exit);
|
||||
} // namespace
|
||||
|
@ -55,8 +55,7 @@ struct lsDocumentOnTypeFormattingOptions {
|
||||
// More trigger characters.
|
||||
std::vector<std::string> moreTriggerCharacter;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions,
|
||||
firstTriggerCharacter,
|
||||
MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter,
|
||||
moreTriggerCharacter);
|
||||
|
||||
// Document link options
|
||||
@ -119,12 +118,8 @@ struct lsTextDocumentSyncOptions {
|
||||
// Save notifications are sent to the server.
|
||||
std::optional<lsSaveOptions> save;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions,
|
||||
openClose,
|
||||
change,
|
||||
willSave,
|
||||
willSaveWaitUntil,
|
||||
save);
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentSyncOptions, openClose, change, willSave,
|
||||
willSaveWaitUntil, save);
|
||||
|
||||
struct lsServerCapabilities {
|
||||
// Defines how text documents are synced. Is either a detailed structure
|
||||
@ -161,7 +156,8 @@ struct lsServerCapabilities {
|
||||
// The server provides document range formatting.
|
||||
bool documentRangeFormattingProvider = false;
|
||||
// The server provides document formatting on typing.
|
||||
std::optional<lsDocumentOnTypeFormattingOptions> documentOnTypeFormattingProvider;
|
||||
std::optional<lsDocumentOnTypeFormattingOptions>
|
||||
documentOnTypeFormattingProvider;
|
||||
// The server provides rename support.
|
||||
bool renameProvider = true;
|
||||
// The server provides document link support.
|
||||
@ -169,25 +165,15 @@ struct lsServerCapabilities {
|
||||
// The server provides execute command support.
|
||||
lsExecuteCommandOptions executeCommandProvider;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsServerCapabilities,
|
||||
textDocumentSync,
|
||||
hoverProvider,
|
||||
completionProvider,
|
||||
signatureHelpProvider,
|
||||
definitionProvider,
|
||||
typeDefinitionProvider,
|
||||
referencesProvider,
|
||||
documentHighlightProvider,
|
||||
documentSymbolProvider,
|
||||
workspaceSymbolProvider,
|
||||
codeActionProvider,
|
||||
codeLensProvider,
|
||||
documentFormattingProvider,
|
||||
documentRangeFormattingProvider,
|
||||
documentOnTypeFormattingProvider,
|
||||
renameProvider,
|
||||
documentLinkProvider,
|
||||
executeCommandProvider);
|
||||
MAKE_REFLECT_STRUCT(lsServerCapabilities, textDocumentSync, hoverProvider,
|
||||
completionProvider, signatureHelpProvider,
|
||||
definitionProvider, typeDefinitionProvider,
|
||||
referencesProvider, documentHighlightProvider,
|
||||
documentSymbolProvider, workspaceSymbolProvider,
|
||||
codeActionProvider, codeLensProvider,
|
||||
documentFormattingProvider, documentRangeFormattingProvider,
|
||||
documentOnTypeFormattingProvider, renameProvider,
|
||||
documentLinkProvider, executeCommandProvider);
|
||||
|
||||
// Workspace specific client capabilities.
|
||||
struct lsWorkspaceClientCapabilites {
|
||||
@ -226,12 +212,8 @@ MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsWorkspaceEdit,
|
||||
documentChanges);
|
||||
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites::lsGenericDynamicReg,
|
||||
dynamicRegistration);
|
||||
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites,
|
||||
applyEdit,
|
||||
workspaceEdit,
|
||||
didChangeConfiguration,
|
||||
didChangeWatchedFiles,
|
||||
symbol,
|
||||
MAKE_REFLECT_STRUCT(lsWorkspaceClientCapabilites, applyEdit, workspaceEdit,
|
||||
didChangeConfiguration, didChangeWatchedFiles, symbol,
|
||||
executeCommand);
|
||||
|
||||
// Text document specific client capabilities.
|
||||
@ -287,13 +269,9 @@ struct lsTextDocumentClientCapabilities {
|
||||
};
|
||||
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsSynchronization,
|
||||
dynamicRegistration,
|
||||
willSave,
|
||||
willSaveWaitUntil,
|
||||
didSave);
|
||||
dynamicRegistration, willSave, willSaveWaitUntil, didSave);
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsCompletion,
|
||||
dynamicRegistration,
|
||||
completionItem);
|
||||
dynamicRegistration, completionItem);
|
||||
MAKE_REFLECT_STRUCT(
|
||||
lsTextDocumentClientCapabilities::lsCompletion::lsCompletionItem,
|
||||
snippetSupport);
|
||||
@ -301,12 +279,9 @@ MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities::lsGenericDynamicReg,
|
||||
dynamicRegistration);
|
||||
MAKE_REFLECT_STRUCT(
|
||||
lsTextDocumentClientCapabilities::CodeLensRegistrationOptions,
|
||||
dynamicRegistration,
|
||||
resolveProvider);
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities,
|
||||
synchronization,
|
||||
completion,
|
||||
rename);
|
||||
dynamicRegistration, resolveProvider);
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentClientCapabilities, synchronization,
|
||||
completion, rename);
|
||||
|
||||
struct lsClientCapabilities {
|
||||
// Workspace specific client capabilities.
|
||||
@ -382,13 +357,8 @@ void Reflect(Writer& writer, lsInitializeParams::lsTrace& value) {
|
||||
}
|
||||
#endif
|
||||
|
||||
MAKE_REFLECT_STRUCT(lsInitializeParams,
|
||||
processId,
|
||||
rootPath,
|
||||
rootUri,
|
||||
initializationOptions,
|
||||
capabilities,
|
||||
trace);
|
||||
MAKE_REFLECT_STRUCT(lsInitializeParams, processId, rootPath, rootUri,
|
||||
initializationOptions, capabilities, trace);
|
||||
|
||||
struct lsInitializeError {
|
||||
// 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);
|
||||
set_thread_name(name.c_str());
|
||||
pipeline::Indexer_Main(diag_pub, vfs, project, working_files);
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
// Start scanning include directories before dispatching project
|
||||
|
@ -33,10 +33,8 @@ struct In_TextDocumentCodeAction : public RequestInMessage {
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionContext,
|
||||
diagnostics);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams,
|
||||
textDocument,
|
||||
range,
|
||||
context);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction::lsCodeActionParams, textDocument,
|
||||
range, context);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentCodeAction, id, params);
|
||||
REGISTER_IN_MESSAGE(In_TextDocumentCodeAction);
|
||||
|
||||
@ -74,4 +72,4 @@ struct Handler_TextDocumentCodeAction
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentCodeAction);
|
||||
}
|
||||
} // namespace
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "clang_complete.h"
|
||||
#include "lsp_code_action.h"
|
||||
#include "message_handler.h"
|
||||
#include "query_utils.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
@ -41,12 +41,9 @@ Use OffsetStartColumn(Use use, int16_t offset) {
|
||||
return use;
|
||||
}
|
||||
|
||||
void AddCodeLens(const char* singular,
|
||||
const char* plural,
|
||||
CommonCodeLensParams* common,
|
||||
Use use,
|
||||
const std::vector<Use>& uses,
|
||||
bool force_display) {
|
||||
void AddCodeLens(const char *singular, const char *plural,
|
||||
CommonCodeLensParams *common, Use use,
|
||||
const std::vector<Use> &uses, bool force_display) {
|
||||
TCodeLens code_lens;
|
||||
std::optional<lsRange> range = GetLsRange(common->working_file, use.range);
|
||||
if (!range)
|
||||
@ -166,10 +163,9 @@ struct Handler_TextDocumentCodeLens
|
||||
false /*force_display*/);
|
||||
}
|
||||
|
||||
AddCodeLens("derived", "derived", &common,
|
||||
OffsetStartColumn(use, offset++),
|
||||
GetFuncDeclarations(db, func.derived),
|
||||
false /*force_display*/);
|
||||
AddCodeLens(
|
||||
"derived", "derived", &common, OffsetStartColumn(use, offset++),
|
||||
GetFuncDeclarations(db, func.derived), false /*force_display*/);
|
||||
|
||||
// "Base"
|
||||
if (def->bases.size() == 1) {
|
||||
@ -214,8 +210,8 @@ struct Handler_TextDocumentCodeLens
|
||||
if (def->kind == lsSymbolKind::Macro)
|
||||
force_display = false;
|
||||
|
||||
AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0),
|
||||
var.uses, force_display);
|
||||
AddCodeLens("ref", "refs", &common, OffsetStartColumn(use, 0), var.uses,
|
||||
force_display);
|
||||
break;
|
||||
}
|
||||
case SymbolKind::File:
|
||||
|
@ -104,8 +104,7 @@ struct ParseIncludeLineResult {
|
||||
};
|
||||
|
||||
ParseIncludeLineResult ParseIncludeLine(const std::string &line) {
|
||||
static const std::regex pattern(
|
||||
"(\\s*)" // [1]: spaces before '#'
|
||||
static const std::regex pattern("(\\s*)" // [1]: spaces before '#'
|
||||
"#" //
|
||||
"(\\s*)" // [2]: spaces after '#'
|
||||
"([^\\s\"<]*)" // [3]: "include"
|
||||
@ -123,8 +122,8 @@ static const std::vector<std::string> preprocessorKeywords = {
|
||||
"define", "undef", "include", "if", "ifdef", "ifndef",
|
||||
"else", "elif", "endif", "line", "error", "pragma"};
|
||||
|
||||
std::vector<lsCompletionItem> PreprocessorKeywordCompletionItems(
|
||||
const std::smatch& match) {
|
||||
std::vector<lsCompletionItem>
|
||||
PreprocessorKeywordCompletionItems(const std::smatch &match) {
|
||||
std::vector<lsCompletionItem> items;
|
||||
for (auto &keyword : preprocessorKeywords) {
|
||||
lsCompletionItem item;
|
||||
@ -140,10 +139,8 @@ std::vector<lsCompletionItem> PreprocessorKeywordCompletionItems(
|
||||
return items;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
char* tofixedbase64(T input, char* out) {
|
||||
const char* digits =
|
||||
"./0123456789"
|
||||
template <typename T> char *tofixedbase64(T input, char *out) {
|
||||
const char *digits = "./0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
int len = (sizeof(T) * 8 - 1) / 6 + 1;
|
||||
@ -160,8 +157,7 @@ char* tofixedbase64(T input, char* out) {
|
||||
// when given 1000+ completion items.
|
||||
void FilterAndSortCompletionResponse(
|
||||
Out_TextDocumentComplete *complete_response,
|
||||
const std::string& complete_text,
|
||||
bool has_open_paren) {
|
||||
const std::string &complete_text, bool has_open_paren) {
|
||||
if (!g_config->completion.filterAndSort)
|
||||
return;
|
||||
|
||||
@ -240,7 +236,8 @@ bool IsOpenParenOrAngle(const std::vector<std::string>& lines,
|
||||
return false;
|
||||
if (line[c] == '(' || line[c] == '<')
|
||||
return true;
|
||||
if (!isspace(line[c])) break;
|
||||
if (!isspace(line[c]))
|
||||
break;
|
||||
if (++c >= line.size()) {
|
||||
c = 0;
|
||||
l++;
|
||||
@ -351,7 +348,8 @@ struct Handler_TextDocumentCompletion : MessageHandler {
|
||||
lock.lock();
|
||||
std::string quote = result.match[5];
|
||||
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);
|
||||
}
|
||||
FilterAndSortCompletionResponse(&out, result.pattern, has_open_paren);
|
||||
@ -376,7 +374,8 @@ struct Handler_TextDocumentCompletion : MessageHandler {
|
||||
out.result.items = results;
|
||||
|
||||
// Emit completion results.
|
||||
FilterAndSortCompletionResponse(&out, existing_completion, has_open_paren);
|
||||
FilterAndSortCompletionResponse(&out, existing_completion,
|
||||
has_open_paren);
|
||||
pipeline::WriteStdout(kMethodType, out);
|
||||
|
||||
// Cache completion results.
|
||||
|
@ -3,9 +3,9 @@
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/definition";
|
||||
@ -62,8 +62,7 @@ struct Handler_TextDocumentDefinition
|
||||
|
||||
Maybe<Use> on_def;
|
||||
bool has_symbol = false;
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
lsPosition &ls_pos = params.position;
|
||||
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, ls_pos)) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "clang_complete.h"
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "project.h"
|
||||
#include "working_files.h"
|
||||
#include "pipeline.hh"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "clang_complete.h"
|
||||
#include "include_complete.h"
|
||||
#include "message_handler.h"
|
||||
#include "project.h"
|
||||
#include "pipeline.hh"
|
||||
#include "project.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "clang_complete.h"
|
||||
#include "message_handler.h"
|
||||
#include "project.h"
|
||||
#include "pipeline.hh"
|
||||
#include "project.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
|
@ -21,8 +21,7 @@ std::optional<lsMarkedString> GetComments(DB* db, SymbolRef sym) {
|
||||
}
|
||||
|
||||
// Returns the hover or detailed name for `sym`, if any.
|
||||
std::optional<lsMarkedString> GetHoverOrName(DB* db,
|
||||
LanguageId lang,
|
||||
std::optional<lsMarkedString> GetHoverOrName(DB *db, LanguageId lang,
|
||||
SymbolRef sym) {
|
||||
std::optional<lsMarkedString> ret;
|
||||
WithEntity(db, sym, [&](const auto &entity) {
|
||||
@ -58,9 +57,7 @@ struct Out_TextDocumentHover : public lsOutMessage<Out_TextDocumentHover> {
|
||||
std::optional<Result> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentHover::Result, contents, range);
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover,
|
||||
jsonrpc,
|
||||
id,
|
||||
MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(Out_TextDocumentHover, jsonrpc, id,
|
||||
result);
|
||||
|
||||
struct Handler_TextDocumentHover : BaseMessageHandler<In_TextDocumentHover> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "message_handler.h"
|
||||
#include "query_utils.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
|
@ -27,14 +27,9 @@ struct In_TextDocumentReferences : public RequestInMessage {
|
||||
|
||||
Params params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext,
|
||||
base,
|
||||
excludeRole,
|
||||
includeDeclaration,
|
||||
role);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params,
|
||||
textDocument,
|
||||
position,
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentReferences::lsReferenceContext, base,
|
||||
excludeRole, includeDeclaration, role);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentReferences::Params, textDocument, position,
|
||||
context);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentReferences, id, params);
|
||||
REGISTER_IN_MESSAGE(In_TextDocumentReferences);
|
||||
@ -57,8 +52,7 @@ struct Handler_TextDocumentReferences
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
|
||||
WorkingFile* wfile =
|
||||
working_files->GetFileByFilename(file->def->path);
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
Out_TextDocumentReferences out;
|
||||
out.id = request->id;
|
||||
@ -133,8 +127,7 @@ struct Handler_TextDocumentReferences
|
||||
// Another file |file1| has the same include line.
|
||||
lsLocationEx result;
|
||||
result.uri = lsDocumentUri::FromPath(file1.def->path);
|
||||
result.range.start.line = result.range.end.line =
|
||||
include.line;
|
||||
result.range.start.line = result.range.end.line = include.line;
|
||||
out.result.push_back(std::move(result));
|
||||
break;
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
#include "message_handler.h"
|
||||
#include "query_utils.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/rename";
|
||||
|
||||
lsWorkspaceEdit BuildWorkspaceEdit(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
SymbolRef sym,
|
||||
const std::string& new_text) {
|
||||
lsWorkspaceEdit BuildWorkspaceEdit(DB *db, WorkingFiles *working_files,
|
||||
SymbolRef sym, const std::string &new_text) {
|
||||
std::unordered_map<int, lsTextDocumentEdit> path_to_edit;
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
@ -65,9 +64,7 @@ struct In_TextDocumentRename : public RequestInMessage {
|
||||
};
|
||||
Params params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params,
|
||||
textDocument,
|
||||
position,
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentRename::Params, textDocument, position,
|
||||
newName);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentRename, id, params);
|
||||
REGISTER_IN_MESSAGE(In_TextDocumentRename);
|
||||
|
@ -70,9 +70,7 @@ struct lsSignatureHelp {
|
||||
// active signature does have any.
|
||||
std::optional<int> activeParameter;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsSignatureHelp,
|
||||
signatures,
|
||||
activeSignature,
|
||||
MAKE_REFLECT_STRUCT(lsSignatureHelp, signatures, activeSignature,
|
||||
activeParameter);
|
||||
|
||||
struct Out_TextDocumentSignatureHelp
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "clang_complete.h"
|
||||
#include "message_handler.h"
|
||||
#include "project.h"
|
||||
#include "pipeline.hh"
|
||||
#include "project.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "clang_complete.h"
|
||||
#include "message_handler.h"
|
||||
#include "project.h"
|
||||
#include "pipeline.hh"
|
||||
#include "project.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "lsp_code_action.h"
|
||||
#include "message_handler.h"
|
||||
#include "query_utils.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
|
@ -4,20 +4,17 @@
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
#include <functional>
|
||||
#include <limits.h>
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "workspace/symbol";
|
||||
|
||||
// Lookup |symbol| in |db| and insert the value into |result|.
|
||||
bool AddSymbol(
|
||||
DB* db,
|
||||
WorkingFiles* working_files,
|
||||
SymbolIdx sym,
|
||||
bool use_detailed,
|
||||
DB *db, WorkingFiles *working_files, SymbolIdx sym, bool use_detailed,
|
||||
std::vector<std::tuple<lsSymbolInformation, int, SymbolIdx>> *result) {
|
||||
std::optional<lsSymbolInformation> info =
|
||||
GetSymbolInfo(db, working_files, sym, true);
|
||||
@ -102,7 +99,8 @@ struct Handler_WorkspaceSymbol : BaseMessageHandler<In_WorkspaceSymbol> {
|
||||
goto 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.
|
||||
int longest = 0;
|
||||
for (auto &cand : cands)
|
||||
|
@ -4,8 +4,7 @@ MethodType kMethodType_Unknown = "$unknown";
|
||||
MethodType kMethodType_Exit = "exit";
|
||||
MethodType kMethodType_TextDocumentPublishDiagnostics =
|
||||
"textDocument/publishDiagnostics";
|
||||
MethodType kMethodType_CclsPublishSkippedRanges =
|
||||
"$ccls/publishSkippedRanges";
|
||||
MethodType kMethodType_CclsPublishSkippedRanges = "$ccls/publishSkippedRanges";
|
||||
MethodType kMethodType_CclsPublishSemanticHighlighting =
|
||||
"$ccls/publishSemanticHighlighting";
|
||||
|
||||
|
@ -35,14 +35,10 @@ struct InMessage {
|
||||
struct RequestInMessage : public InMessage {
|
||||
// number or string, actually no null
|
||||
lsRequestId id;
|
||||
lsRequestId GetRequestId() const override {
|
||||
return id;
|
||||
}
|
||||
lsRequestId GetRequestId() const override { return id; }
|
||||
};
|
||||
|
||||
// NotificationInMessage does not have |id|.
|
||||
struct NotificationInMessage : public InMessage {
|
||||
lsRequestId GetRequestId() const override {
|
||||
return lsRequestId();
|
||||
}
|
||||
lsRequestId GetRequestId() const override { return lsRequestId(); }
|
||||
};
|
||||
|
@ -6,10 +6,10 @@
|
||||
#include "log.hh"
|
||||
#include "lsp.h"
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "platform.h"
|
||||
#include "project.h"
|
||||
#include "query_utils.h"
|
||||
#include "pipeline.hh"
|
||||
|
||||
#include <llvm/ADT/Twine.h>
|
||||
#include <llvm/Support/Threading.h>
|
||||
@ -52,7 +52,8 @@ void DiagnosticsPublisher::Publish(WorkingFiles* working_files,
|
||||
Out_TextDocumentPublishDiagnostics out;
|
||||
out.params.uri = lsDocumentUri::FromPath(path);
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -122,8 +124,7 @@ std::string GetCachePath(const std::string& source_file) {
|
||||
return g_config->cacheDirectory + cache_file;
|
||||
}
|
||||
|
||||
std::unique_ptr<IndexFile> RawCacheLoad(
|
||||
const std::string& path) {
|
||||
std::unique_ptr<IndexFile> RawCacheLoad(const std::string &path) {
|
||||
std::string cache_path = GetCachePath(path);
|
||||
std::optional<std::string> file_content = ReadContent(cache_path);
|
||||
std::optional<std::string> serialized_indexed_content =
|
||||
@ -136,10 +137,8 @@ std::unique_ptr<IndexFile> RawCacheLoad(
|
||||
IndexFile::kMajorVersion);
|
||||
}
|
||||
|
||||
bool Indexer_Parse(DiagnosticsPublisher* diag_pub,
|
||||
WorkingFiles* working_files,
|
||||
Project* project,
|
||||
VFS* vfs) {
|
||||
bool Indexer_Parse(DiagnosticsPublisher *diag_pub, WorkingFiles *working_files,
|
||||
Project *project, VFS *vfs) {
|
||||
std::optional<Index_Request> opt_request = index_request->TryPopFront();
|
||||
if (!opt_request)
|
||||
return false;
|
||||
@ -218,7 +217,8 @@ bool Indexer_Parse(DiagnosticsPublisher* diag_pub,
|
||||
|
||||
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 (g_config->index.enabled && request.id.Valid()) {
|
||||
@ -288,22 +288,19 @@ void Init() {
|
||||
for_stdout = new ThreadedQueue<Stdout_Request>(stdout_waiter);
|
||||
}
|
||||
|
||||
void Indexer_Main(DiagnosticsPublisher* diag_pub,
|
||||
VFS* vfs,
|
||||
Project* project,
|
||||
void Indexer_Main(DiagnosticsPublisher *diag_pub, VFS *vfs, Project *project,
|
||||
WorkingFiles *working_files) {
|
||||
while (true)
|
||||
if (!Indexer_Parse(diag_pub, working_files, project, vfs))
|
||||
indexer_waiter->Wait(index_request);
|
||||
}
|
||||
|
||||
void Main_OnIndexed(DB* db,
|
||||
SemanticHighlightSymbolCache* semantic_cache,
|
||||
WorkingFiles* working_files,
|
||||
IndexUpdate* update) {
|
||||
void Main_OnIndexed(DB *db, SemanticHighlightSymbolCache *semantic_cache,
|
||||
WorkingFiles *working_files, IndexUpdate *update) {
|
||||
if (update->refresh) {
|
||||
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);
|
||||
for (auto &f : working_files->files) {
|
||||
std::string filename = LowerPathIfInsensitive(f->filename);
|
||||
@ -369,7 +366,8 @@ void LaunchStdin() {
|
||||
if (method_type == kMethodType_Exit)
|
||||
break;
|
||||
}
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
void LaunchStdout() {
|
||||
@ -392,7 +390,8 @@ void LaunchStdout() {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}).detach();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
void MainLoop() {
|
||||
@ -412,8 +411,7 @@ void MainLoop() {
|
||||
Out_Error out;
|
||||
out.id = id;
|
||||
out.error.code = lsErrorCodes::InternalError;
|
||||
out.error.message =
|
||||
"Dropping completion request; a newer request "
|
||||
out.error.message = "Dropping completion request; a newer request "
|
||||
"has come in that will be serviced instead.";
|
||||
pipeline::WriteStdout(kMethodType_Unknown, out);
|
||||
}
|
||||
@ -473,10 +471,8 @@ void MainLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
void Index(const std::string& path,
|
||||
const std::vector<std::string>& args,
|
||||
bool interactive,
|
||||
lsRequestId id) {
|
||||
void Index(const std::string &path, const std::vector<std::string> &args,
|
||||
bool interactive, lsRequestId id) {
|
||||
index_request->PushBack({path, args, interactive, id}, interactive);
|
||||
}
|
||||
|
||||
@ -494,4 +490,4 @@ void WriteStdout(MethodType method, lsBaseOutMessage& response) {
|
||||
for_stdout->PushBack(std::move(out));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ccls::pipeline
|
||||
|
@ -14,10 +14,10 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h> // required for stat.h
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __GLIBC__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
@ -49,8 +49,7 @@ struct Range {
|
||||
};
|
||||
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<Range> {
|
||||
template <> struct hash<Range> {
|
||||
std::size_t operator()(Range x) const {
|
||||
union U {
|
||||
Range range = {};
|
||||
@ -61,7 +60,7 @@ struct hash<Range> {
|
||||
return hash<uint64_t>()(u.u64);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
// Reflection
|
||||
class Reader;
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "language.h"
|
||||
#include "log.hh"
|
||||
#include "match.h"
|
||||
#include "platform.h"
|
||||
#include "pipeline.hh"
|
||||
#include "platform.h"
|
||||
#include "serializers/json.h"
|
||||
#include "utils.h"
|
||||
#include "working_files.h"
|
||||
@ -67,8 +67,8 @@ enum OptionClass {
|
||||
Separate,
|
||||
};
|
||||
|
||||
Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
ProjectConfig* config,
|
||||
Project::Entry
|
||||
GetCompilationEntryFromCompileCommandEntry(ProjectConfig *config,
|
||||
const CompileCommandsEntry &entry) {
|
||||
Project::Entry result;
|
||||
result.filename = entry.file;
|
||||
@ -155,7 +155,8 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
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);
|
||||
if (CI->getFileSystemOpts().WorkingDir.empty())
|
||||
args.push_back("-working-directory=" + entry.directory);
|
||||
@ -169,10 +170,11 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> ReadCompilerArgumentsFromFile(
|
||||
const std::string& path) {
|
||||
std::vector<std::string>
|
||||
ReadCompilerArgumentsFromFile(const std::string &path) {
|
||||
auto MBOrErr = MemoryBuffer::getFile(path);
|
||||
if (!MBOrErr) return {};
|
||||
if (!MBOrErr)
|
||||
return {};
|
||||
std::vector<std::string> args;
|
||||
for (line_iterator I(*MBOrErr.get(), true, '#'), E; I != E; ++I)
|
||||
args.push_back(*I);
|
||||
@ -209,7 +211,8 @@ std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
|
||||
LOG_IF_S(INFO, !project_dir_args.empty())
|
||||
<< "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()) {
|
||||
auto it = folder_args.find(cur);
|
||||
if (it != folder_args.end())
|
||||
@ -237,8 +240,8 @@ std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
||||
ProjectConfig* project,
|
||||
std::vector<Project::Entry>
|
||||
LoadCompilationEntriesFromDirectory(ProjectConfig *project,
|
||||
const std::string &opt_compilation_db_dir) {
|
||||
// If there is a .ccls file always load using directory listing.
|
||||
SmallString<256> Path;
|
||||
@ -362,8 +365,7 @@ void Project::Load(const std::string& root_directory) {
|
||||
}
|
||||
}
|
||||
|
||||
void Project::SetFlagsForFile(
|
||||
const std::vector<std::string>& flags,
|
||||
void Project::SetFlagsForFile(const std::vector<std::string> &flags,
|
||||
const std::string &path) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto it = absolute_path_to_entry_index_.find(path);
|
||||
@ -380,8 +382,8 @@ void Project::SetFlagsForFile(
|
||||
}
|
||||
}
|
||||
|
||||
Project::Entry Project::FindCompilationEntryForFile(
|
||||
const std::string& filename) {
|
||||
Project::Entry
|
||||
Project::FindCompilationEntryForFile(const std::string &filename) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
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
|
||||
// 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) {
|
||||
try {
|
||||
if (arg == best_entry->filename ||
|
||||
@ -441,8 +444,7 @@ void Project::ForAllFilteredFiles(
|
||||
}
|
||||
}
|
||||
|
||||
void Project::Index(WorkingFiles* wfiles,
|
||||
lsRequestId id) {
|
||||
void Project::Index(WorkingFiles *wfiles, lsRequestId id) {
|
||||
ForAllFilteredFiles([&](int i, const Project::Entry &entry) {
|
||||
bool is_interactive = wfiles->GetFileByFilename(entry.filename) != nullptr;
|
||||
pipeline::Index(entry.filename, entry.args, is_interactive, id);
|
||||
|
@ -49,13 +49,12 @@ struct Project {
|
||||
// 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
|
||||
// are permanent.
|
||||
void SetFlagsForFile(
|
||||
const std::vector<std::string>& flags,
|
||||
void SetFlagsForFile(const std::vector<std::string> &flags,
|
||||
const std::string &path);
|
||||
|
||||
// Run |action| on every file in the project.
|
||||
void ForAllFilteredFiles(
|
||||
std::function<void(int i, const Entry& entry)> action);
|
||||
void
|
||||
ForAllFilteredFiles(std::function<void(int i, const Entry &entry)> action);
|
||||
|
||||
void Index(WorkingFiles *wfiles, lsRequestId id);
|
||||
|
||||
|
15
src/query.cc
15
src/query.cc
@ -164,8 +164,7 @@ bool TryReplaceDef(llvm::SmallVectorImpl<Q>& def_list, Q&& def) {
|
||||
|
||||
} // namespace
|
||||
|
||||
IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous,
|
||||
IndexFile* current) {
|
||||
IndexUpdate IndexUpdate::CreateDelta(IndexFile *previous, IndexFile *current) {
|
||||
IndexUpdate r;
|
||||
static IndexFile empty(llvm::sys::fs::UniqueID(0, 0), current->path,
|
||||
"<empty>");
|
||||
@ -233,14 +232,14 @@ IndexUpdate IndexUpdate::CreateDelta(IndexFile* previous,
|
||||
return r;
|
||||
}
|
||||
|
||||
void DB::RemoveUsrs(SymbolKind kind,
|
||||
int file_id,
|
||||
void DB::RemoveUsrs(SymbolKind kind, int file_id,
|
||||
const std::vector<Usr> &to_remove) {
|
||||
switch (kind) {
|
||||
case SymbolKind::Func: {
|
||||
for (Usr usr : to_remove) {
|
||||
// FIXME
|
||||
if (!HasFunc(usr)) continue;
|
||||
if (!HasFunc(usr))
|
||||
continue;
|
||||
QueryFunc &func = Func(usr);
|
||||
auto it = llvm::find_if(func.def, [=](const QueryFunc::Def &def) {
|
||||
return def.file_id == file_id;
|
||||
@ -253,7 +252,8 @@ void DB::RemoveUsrs(SymbolKind kind,
|
||||
case SymbolKind::Type: {
|
||||
for (Usr usr : to_remove) {
|
||||
// FIXME
|
||||
if (!HasType(usr)) continue;
|
||||
if (!HasType(usr))
|
||||
continue;
|
||||
QueryType &type = Type(usr);
|
||||
auto it = llvm::find_if(type.def, [=](const QueryType::Def &def) {
|
||||
return def.file_id == file_id;
|
||||
@ -266,7 +266,8 @@ void DB::RemoveUsrs(SymbolKind kind,
|
||||
case SymbolKind::Var: {
|
||||
for (Usr usr : to_remove) {
|
||||
// FIXME
|
||||
if (!HasVar(usr)) continue;
|
||||
if (!HasVar(usr))
|
||||
continue;
|
||||
QueryVar &var = Var(usr);
|
||||
auto it = llvm::find_if(var.def, [=](const QueryVar::Def &def) {
|
||||
return def.file_id == file_id;
|
||||
|
16
src/query.h
16
src/query.h
@ -31,8 +31,7 @@ struct QueryFile {
|
||||
std::unordered_map<SymbolRef, int> symbol2refcnt;
|
||||
};
|
||||
|
||||
template <typename Q, typename QDef>
|
||||
struct QueryEntity {
|
||||
template <typename Q, typename QDef> struct QueryEntity {
|
||||
using Def = QDef;
|
||||
Def *AnyDef() {
|
||||
Def *ret = nullptr;
|
||||
@ -43,7 +42,9 @@ struct QueryEntity {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const Def* AnyDef() const { return const_cast<QueryEntity*>(this)->AnyDef(); }
|
||||
const Def *AnyDef() const {
|
||||
return const_cast<QueryEntity *>(this)->AnyDef();
|
||||
}
|
||||
};
|
||||
|
||||
using UseUpdate =
|
||||
@ -78,8 +79,7 @@ struct QueryVar : QueryEntity<QueryVar, VarDef> {
|
||||
struct IndexUpdate {
|
||||
// Creates a new IndexUpdate based on the delta from previous to current. If
|
||||
// no delta computation should be done just pass null for previous.
|
||||
static IndexUpdate CreateDelta(IndexFile* previous,
|
||||
IndexFile* current);
|
||||
static IndexUpdate CreateDelta(IndexFile *previous, IndexFile *current);
|
||||
|
||||
int file_id;
|
||||
|
||||
@ -121,8 +121,7 @@ struct IndexUpdate {
|
||||
struct WrappedUsr {
|
||||
Usr usr;
|
||||
};
|
||||
template <>
|
||||
struct llvm::DenseMapInfo<WrappedUsr> {
|
||||
template <> struct llvm::DenseMapInfo<WrappedUsr> {
|
||||
static inline WrappedUsr getEmptyKey() { return {0}; }
|
||||
static inline WrappedUsr getTombstoneKey() { return {~0ULL}; }
|
||||
static unsigned getHashValue(WrappedUsr w) { return w.usr; }
|
||||
@ -141,7 +140,8 @@ struct DB {
|
||||
std::vector<QueryType> types;
|
||||
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|.
|
||||
void ApplyIndexUpdate(IndexUpdate *update);
|
||||
int GetFileId(const std::string &path);
|
||||
|
@ -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) {
|
||||
return GetDeclarations(db->type_usr, db->types, usrs);
|
||||
}
|
||||
std::vector<Use> GetVarDeclarations(DB* db,
|
||||
const std::vector<Usr>& usrs,
|
||||
std::vector<Use> GetVarDeclarations(DB *db, const std::vector<Usr> &usrs,
|
||||
unsigned kind) {
|
||||
std::vector<Use> ret;
|
||||
ret.reserve(usrs.size());
|
||||
@ -207,8 +206,7 @@ lsDocumentUri GetLsDocumentUri(DB* db, int file_id) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<lsLocation> GetLsLocation(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *working_files,
|
||||
Use use) {
|
||||
std::string path;
|
||||
lsDocumentUri uri = GetLsDocumentUri(db, use.file_id, &path);
|
||||
@ -219,10 +217,8 @@ std::optional<lsLocation> GetLsLocation(DB* db,
|
||||
return lsLocation{uri, *range};
|
||||
}
|
||||
|
||||
std::optional<lsLocationEx> GetLsLocationEx(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
Use use,
|
||||
bool container) {
|
||||
std::optional<lsLocationEx> GetLsLocationEx(DB *db, WorkingFiles *working_files,
|
||||
Use use, bool container) {
|
||||
std::optional<lsLocation> ls_loc = GetLsLocation(db, working_files, use);
|
||||
if (!ls_loc)
|
||||
return std::nullopt;
|
||||
@ -238,8 +234,7 @@ std::optional<lsLocationEx> GetLsLocationEx(DB* db,
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<lsLocationEx> GetLsLocationExs(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
std::vector<lsLocationEx> GetLsLocationExs(DB *db, WorkingFiles *working_files,
|
||||
const std::vector<Use> &uses) {
|
||||
std::vector<lsLocationEx> ret;
|
||||
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
|
||||
// better on constructors.
|
||||
std::sort(symbols.begin(), symbols.end(),
|
||||
std::sort(
|
||||
symbols.begin(), symbols.end(),
|
||||
[](const SymbolRef &a, const SymbolRef &b) {
|
||||
int t = ComputeRangeSize(a.range) - ComputeRangeSize(b.range);
|
||||
if (t)
|
||||
|
@ -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::optional<lsLocation> GetLsLocation(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
std::optional<lsLocation> GetLsLocation(DB *db, WorkingFiles *working_files,
|
||||
Use use);
|
||||
std::optional<lsLocationEx> GetLsLocationEx(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
Use use,
|
||||
bool container);
|
||||
std::vector<lsLocationEx> GetLsLocationExs(DB* db,
|
||||
WorkingFiles* working_files,
|
||||
std::optional<lsLocationEx> GetLsLocationEx(DB *db, WorkingFiles *working_files,
|
||||
Use use, bool container);
|
||||
std::vector<lsLocationEx> GetLsLocationExs(DB *db, WorkingFiles *working_files,
|
||||
const std::vector<Use> &refs);
|
||||
// Returns a symbol. The symbol will have *NOT* have a location assigned.
|
||||
std::optional<lsSymbolInformation> GetSymbolInfo(DB *db,
|
||||
@ -46,8 +42,7 @@ std::vector<SymbolRef> FindSymbolsAtLocation(WorkingFile* working_file,
|
||||
QueryFile *file,
|
||||
lsPosition &ls_pos);
|
||||
|
||||
template <typename Fn>
|
||||
void WithEntity(DB* db, SymbolIdx sym, Fn&& fn) {
|
||||
template <typename Fn> void WithEntity(DB *db, SymbolIdx sym, Fn &&fn) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Invalid:
|
||||
case SymbolKind::File:
|
||||
@ -64,8 +59,7 @@ void WithEntity(DB* db, SymbolIdx sym, Fn&& fn) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
void EachEntityDef(DB* db, SymbolIdx sym, Fn&& fn) {
|
||||
template <typename Fn> void EachEntityDef(DB *db, SymbolIdx sym, Fn &&fn) {
|
||||
WithEntity(db, sym, [&](const auto &entity) {
|
||||
for (auto &def : entity.def)
|
||||
if (!fn(def))
|
||||
@ -99,7 +93,6 @@ void EachDefinedFunc(DB* db, const std::vector<Usr>& usrs, Fn&& fn) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename Fn>
|
||||
void EachDefinedType(DB *db, const std::vector<Usr> &usrs, Fn &&fn) {
|
||||
for (Usr usr : usrs) {
|
||||
|
@ -18,75 +18,57 @@ bool gTestOutputMode = false;
|
||||
|
||||
//// Elementary types
|
||||
|
||||
void Reflect(Reader& visitor, uint8_t& value) {
|
||||
value = visitor.GetUInt8();
|
||||
}
|
||||
void Reflect(Writer& visitor, uint8_t& value) {
|
||||
visitor.UInt8(value);
|
||||
}
|
||||
void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); }
|
||||
void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); }
|
||||
|
||||
void Reflect(Reader &visitor, short &value) {
|
||||
if (!visitor.IsInt())
|
||||
throw std::invalid_argument("short");
|
||||
value = (short)visitor.GetInt();
|
||||
}
|
||||
void Reflect(Writer& visitor, short& value) {
|
||||
visitor.Int(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, short &value) { visitor.Int(value); }
|
||||
|
||||
void Reflect(Reader &visitor, unsigned short &value) {
|
||||
if (!visitor.IsInt())
|
||||
throw std::invalid_argument("unsigned short");
|
||||
value = (unsigned short)visitor.GetInt();
|
||||
}
|
||||
void Reflect(Writer& visitor, unsigned short& value) {
|
||||
visitor.Int(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, unsigned short &value) { visitor.Int(value); }
|
||||
|
||||
void Reflect(Reader &visitor, int &value) {
|
||||
if (!visitor.IsInt())
|
||||
throw std::invalid_argument("int");
|
||||
value = visitor.GetInt();
|
||||
}
|
||||
void Reflect(Writer& visitor, int& value) {
|
||||
visitor.Int(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, int &value) { visitor.Int(value); }
|
||||
|
||||
void Reflect(Reader &visitor, unsigned &value) {
|
||||
if (!visitor.IsUInt64())
|
||||
throw std::invalid_argument("unsigned");
|
||||
value = visitor.GetUInt32();
|
||||
}
|
||||
void Reflect(Writer& visitor, unsigned& value) {
|
||||
visitor.UInt32(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, unsigned &value) { visitor.UInt32(value); }
|
||||
|
||||
void Reflect(Reader &visitor, long &value) {
|
||||
if (!visitor.IsInt64())
|
||||
throw std::invalid_argument("long");
|
||||
value = long(visitor.GetInt64());
|
||||
}
|
||||
void Reflect(Writer& visitor, long& value) {
|
||||
visitor.Int64(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, long &value) { visitor.Int64(value); }
|
||||
|
||||
void Reflect(Reader &visitor, unsigned long &value) {
|
||||
if (!visitor.IsUInt64())
|
||||
throw std::invalid_argument("unsigned long");
|
||||
value = (unsigned long)visitor.GetUInt64();
|
||||
}
|
||||
void Reflect(Writer& visitor, unsigned long& value) {
|
||||
visitor.UInt64(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, unsigned long &value) { visitor.UInt64(value); }
|
||||
|
||||
void Reflect(Reader &visitor, long long &value) {
|
||||
if (!visitor.IsInt64())
|
||||
throw std::invalid_argument("long long");
|
||||
value = visitor.GetInt64();
|
||||
}
|
||||
void Reflect(Writer& visitor, long long& value) {
|
||||
visitor.Int64(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, long long &value) { visitor.Int64(value); }
|
||||
|
||||
void Reflect(Reader &visitor, unsigned long long &value) {
|
||||
if (!visitor.IsUInt64())
|
||||
@ -102,18 +84,14 @@ void Reflect(Reader& visitor, double& value) {
|
||||
throw std::invalid_argument("double");
|
||||
value = visitor.GetDouble();
|
||||
}
|
||||
void Reflect(Writer& visitor, double& value) {
|
||||
visitor.Double(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, double &value) { visitor.Double(value); }
|
||||
|
||||
void Reflect(Reader &visitor, bool &value) {
|
||||
if (!visitor.IsBool())
|
||||
throw std::invalid_argument("bool");
|
||||
value = visitor.GetBool();
|
||||
}
|
||||
void Reflect(Writer& visitor, bool& value) {
|
||||
visitor.Bool(value);
|
||||
}
|
||||
void Reflect(Writer &visitor, bool &value) { visitor.Bool(value); }
|
||||
|
||||
void Reflect(Reader &visitor, std::string &value) {
|
||||
if (!visitor.IsString())
|
||||
@ -124,9 +102,7 @@ void Reflect(Writer& visitor, std::string& value) {
|
||||
visitor.String(value.c_str(), (rapidjson::SizeType)value.size());
|
||||
}
|
||||
|
||||
void Reflect(Reader&, std::string_view&) {
|
||||
assert(0);
|
||||
}
|
||||
void Reflect(Reader &, std::string_view &) { assert(0); }
|
||||
void Reflect(Writer &visitor, std::string_view &data) {
|
||||
if (data.empty())
|
||||
visitor.String("");
|
||||
@ -138,18 +114,14 @@ void Reflect(Reader& vis, const char*& v) {
|
||||
const char *str = vis.GetString();
|
||||
v = ccls::Intern(str);
|
||||
}
|
||||
void Reflect(Writer& vis, const char*& v) {
|
||||
vis.String(v);
|
||||
}
|
||||
void Reflect(Writer &vis, const char *&v) { vis.String(v); }
|
||||
|
||||
void Reflect(Reader &visitor, JsonNull &value) {
|
||||
assert(visitor.Format() == SerializeFormat::Json);
|
||||
visitor.GetNull();
|
||||
}
|
||||
|
||||
void Reflect(Writer& visitor, JsonNull& value) {
|
||||
visitor.Null();
|
||||
}
|
||||
void Reflect(Writer &visitor, JsonNull &value) { visitor.Null(); }
|
||||
|
||||
// std::unordered_map
|
||||
template <typename V>
|
||||
@ -230,12 +202,12 @@ void ReflectHoverAndComments(Writer& visitor, Def& def) {
|
||||
ReflectMember(visitor, "comments", def.comments);
|
||||
}
|
||||
|
||||
template <typename Def>
|
||||
void ReflectShortName(Reader& visitor, Def& def) {
|
||||
template <typename Def> void ReflectShortName(Reader &visitor, Def &def) {
|
||||
if (gTestOutputMode) {
|
||||
std::string 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);
|
||||
def.short_name_size = short_name.size();
|
||||
} else {
|
||||
@ -244,8 +216,7 @@ void ReflectShortName(Reader& visitor, Def& def) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Def>
|
||||
void ReflectShortName(Writer& visitor, Def& def) {
|
||||
template <typename Def> void ReflectShortName(Writer &visitor, Def &def) {
|
||||
if (gTestOutputMode) {
|
||||
std::string_view short_name(def.detailed_name + def.short_name_offset,
|
||||
def.short_name_size);
|
||||
@ -256,8 +227,7 @@ void ReflectShortName(Writer& visitor, Def& def) {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, IndexType& value) {
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) {
|
||||
REFLECT_MEMBER_START();
|
||||
REFLECT_MEMBER2("usr", value.usr);
|
||||
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
||||
@ -279,8 +249,7 @@ void Reflect(TVisitor& visitor, IndexType& value) {
|
||||
REFLECT_MEMBER_END();
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, IndexFunc& value) {
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) {
|
||||
REFLECT_MEMBER_START();
|
||||
REFLECT_MEMBER2("usr", value.usr);
|
||||
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
||||
@ -300,8 +269,7 @@ void Reflect(TVisitor& visitor, IndexFunc& value) {
|
||||
REFLECT_MEMBER_END();
|
||||
}
|
||||
|
||||
template <typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, IndexVar& value) {
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) {
|
||||
REFLECT_MEMBER_START();
|
||||
REFLECT_MEMBER2("usr", value.usr);
|
||||
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
||||
@ -323,8 +291,7 @@ bool ReflectMemberStart(Writer& visitor, IndexFile& value) {
|
||||
visitor.StartObject();
|
||||
return true;
|
||||
}
|
||||
template <typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, IndexFile& value) {
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFile &value) {
|
||||
REFLECT_MEMBER_START();
|
||||
if (!gTestOutputMode) {
|
||||
REFLECT_MEMBER(last_write_time);
|
||||
@ -364,7 +331,8 @@ static DenseSet<StringRef> Strings;
|
||||
static std::mutex AllocMutex;
|
||||
|
||||
const char *Intern(const std::string &str) {
|
||||
if (str.empty()) return "";
|
||||
if (str.empty())
|
||||
return "";
|
||||
StringRef Str(str.data(), str.size() + 1);
|
||||
std::lock_guard lock(AllocMutex);
|
||||
auto R = Strings.insert(Str);
|
||||
@ -404,9 +372,8 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::unique_ptr<IndexFile> Deserialize(
|
||||
SerializeFormat format,
|
||||
const std::string& path,
|
||||
std::unique_ptr<IndexFile>
|
||||
Deserialize(SerializeFormat format, const std::string &path,
|
||||
const std::string &serialized_index_content,
|
||||
const std::string &file_content,
|
||||
std::optional<int> expected_version) {
|
||||
@ -430,8 +397,7 @@ std::unique_ptr<IndexFile> Deserialize(
|
||||
file_content);
|
||||
Reflect(reader, *file);
|
||||
} catch (std::invalid_argument &e) {
|
||||
LOG_S(INFO) << "failed to deserialize '" << path
|
||||
<< "': " << e.what();
|
||||
LOG_S(INFO) << "failed to deserialize '" << path << "': " << e.what();
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
@ -469,4 +435,4 @@ std::unique_ptr<IndexFile> Deserialize(
|
||||
file->path = path;
|
||||
return file;
|
||||
}
|
||||
}
|
||||
} // namespace ccls
|
||||
|
@ -99,23 +99,20 @@ struct IndexFile;
|
||||
REFLECT_MEMBER_MANDATORY_OPTIONAL(name);
|
||||
|
||||
#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
|
||||
template <typename TVisitor> \
|
||||
void Reflect(TVisitor& visitor, type& value) { \
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
|
||||
REFLECT_MEMBER_START(); \
|
||||
REFLECT_MEMBER_END(); \
|
||||
}
|
||||
|
||||
#define MAKE_REFLECT_STRUCT(type, ...) \
|
||||
template <typename TVisitor> \
|
||||
void Reflect(TVisitor& visitor, type& value) { \
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
|
||||
REFLECT_MEMBER_START(); \
|
||||
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
|
||||
REFLECT_MEMBER_END(); \
|
||||
}
|
||||
|
||||
#define MAKE_REFLECT_STRUCT_MANDATORY_OPTIONAL(type, ...) \
|
||||
template <typename TVisitor> \
|
||||
void Reflect(TVisitor& visitor, type& value) { \
|
||||
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
|
||||
REFLECT_MEMBER_START(); \
|
||||
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER_MANDATORY_OPTIONAL, __VA_ARGS__) \
|
||||
REFLECT_MEMBER_END(); \
|
||||
@ -190,12 +187,11 @@ void Reflect(Writer& visitor, SerializeFormat& value);
|
||||
|
||||
//// Type constructors
|
||||
|
||||
// ReflectMember std::optional<T> is used to represent TypeScript optional properties
|
||||
// (in `key: value` context).
|
||||
// Reflect std::optional<T> is used for a different purpose, whether an object is
|
||||
// nullable (possibly in `value` context).
|
||||
template <typename T>
|
||||
void Reflect(Reader& visitor, std::optional<T>& value) {
|
||||
// ReflectMember std::optional<T> is used to represent TypeScript optional
|
||||
// properties (in `key: value` context). Reflect std::optional<T> is used for a
|
||||
// different purpose, whether an object is nullable (possibly in `value`
|
||||
// context).
|
||||
template <typename T> void Reflect(Reader &visitor, std::optional<T> &value) {
|
||||
if (visitor.IsNull()) {
|
||||
visitor.GetNull();
|
||||
return;
|
||||
@ -204,8 +200,7 @@ void Reflect(Reader& visitor, std::optional<T>& value) {
|
||||
Reflect(visitor, real_value);
|
||||
value = std::move(real_value);
|
||||
}
|
||||
template <typename T>
|
||||
void Reflect(Writer& visitor, std::optional<T>& value) {
|
||||
template <typename T> void Reflect(Writer &visitor, std::optional<T> &value) {
|
||||
if (value) {
|
||||
if (visitor.Format() != SerializeFormat::Json)
|
||||
visitor.UInt8(1);
|
||||
@ -215,8 +210,7 @@ void Reflect(Writer& visitor, std::optional<T>& value) {
|
||||
}
|
||||
|
||||
// The same as std::optional
|
||||
template <typename T>
|
||||
void Reflect(Reader& visitor, Maybe<T>& value) {
|
||||
template <typename T> void Reflect(Reader &visitor, Maybe<T> &value) {
|
||||
if (visitor.IsNull()) {
|
||||
visitor.GetNull();
|
||||
return;
|
||||
@ -225,8 +219,7 @@ void Reflect(Reader& visitor, Maybe<T>& value) {
|
||||
Reflect(visitor, real_value);
|
||||
value = std::move(real_value);
|
||||
}
|
||||
template <typename T>
|
||||
void Reflect(Writer& visitor, Maybe<T>& value) {
|
||||
template <typename T> void Reflect(Writer &visitor, Maybe<T> &value) {
|
||||
if (value) {
|
||||
if (visitor.Format() != SerializeFormat::Json)
|
||||
visitor.UInt8(1);
|
||||
@ -256,9 +249,7 @@ void ReflectMember(Writer& visitor, const char* name, Maybe<T>& value) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ReflectMember(Writer& visitor,
|
||||
const char* name,
|
||||
T& value,
|
||||
void ReflectMember(Writer &visitor, const char *name, T &value,
|
||||
mandatory_optional_tag) {
|
||||
visitor.Key(name);
|
||||
Reflect(visitor, value);
|
||||
@ -278,16 +269,14 @@ void Reflect(Writer& vis, std::pair<L, R>& v) {
|
||||
}
|
||||
|
||||
// std::vector
|
||||
template <typename T>
|
||||
void Reflect(Reader& visitor, std::vector<T>& values) {
|
||||
template <typename T> void Reflect(Reader &visitor, std::vector<T> &values) {
|
||||
visitor.IterArray([&](Reader &entry) {
|
||||
T entry_value;
|
||||
Reflect(entry, entry_value);
|
||||
values.push_back(std::move(entry_value));
|
||||
});
|
||||
}
|
||||
template <typename T>
|
||||
void Reflect(Writer& visitor, std::vector<T>& values) {
|
||||
template <typename T> void Reflect(Writer &visitor, std::vector<T> &values) {
|
||||
visitor.StartArray(values.size());
|
||||
for (auto &value : values)
|
||||
Reflect(visitor, value);
|
||||
@ -296,25 +285,19 @@ void Reflect(Writer& visitor, std::vector<T>& values) {
|
||||
|
||||
// ReflectMember
|
||||
|
||||
inline bool ReflectMemberStart(Reader& vis) {
|
||||
return false;
|
||||
}
|
||||
inline bool ReflectMemberStart(Reader &vis) { return false; }
|
||||
inline bool ReflectMemberStart(Writer &vis) {
|
||||
vis.StartObject();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void ReflectMemberEnd(Reader &vis) {}
|
||||
inline void ReflectMemberEnd(Writer& vis) {
|
||||
vis.EndObject();
|
||||
}
|
||||
inline void ReflectMemberEnd(Writer &vis) { vis.EndObject(); }
|
||||
|
||||
template <typename T>
|
||||
void ReflectMember(Reader& vis, const char* name, T& v) {
|
||||
template <typename T> void ReflectMember(Reader &vis, const char *name, T &v) {
|
||||
vis.Member(name, [&]() { Reflect(vis, v); });
|
||||
}
|
||||
template <typename T>
|
||||
void ReflectMember(Writer& vis, const char* name, T& v) {
|
||||
template <typename T> void ReflectMember(Writer &vis, const char *name, T &v) {
|
||||
vis.Key(name);
|
||||
Reflect(vis, v);
|
||||
}
|
||||
@ -324,10 +307,9 @@ void ReflectMember(Writer& vis, const char* name, T& v) {
|
||||
namespace ccls {
|
||||
const char *Intern(const std::string &str);
|
||||
std::string Serialize(SerializeFormat format, IndexFile &file);
|
||||
std::unique_ptr<IndexFile> Deserialize(
|
||||
SerializeFormat format,
|
||||
const std::string& path,
|
||||
std::unique_ptr<IndexFile>
|
||||
Deserialize(SerializeFormat format, const std::string &path,
|
||||
const std::string &serialized_index_content,
|
||||
const std::string &file_content,
|
||||
std::optional<int> expected_version);
|
||||
}
|
||||
} // namespace ccls
|
||||
|
@ -7,8 +7,7 @@
|
||||
class BinaryReader : public Reader {
|
||||
const char *p_;
|
||||
|
||||
template <typename T>
|
||||
T Get() {
|
||||
template <typename T> T Get() {
|
||||
auto ret = *reinterpret_cast<const T *>(p_);
|
||||
p_ += sizeof(T);
|
||||
return ret;
|
||||
@ -31,9 +30,7 @@ class BinaryReader : public Reader {
|
||||
|
||||
public:
|
||||
BinaryReader(std::string_view buf) : p_(buf.data()) {}
|
||||
SerializeFormat Format() const override {
|
||||
return SerializeFormat::Binary;
|
||||
}
|
||||
SerializeFormat Format() const override { return SerializeFormat::Binary; }
|
||||
|
||||
bool IsBool() override { return true; }
|
||||
// Abuse how the function is called in serializer.h
|
||||
@ -68,16 +65,13 @@ class BinaryReader : public Reader {
|
||||
fn(*this);
|
||||
}
|
||||
|
||||
void Member(const char*, std::function<void()> fn) override {
|
||||
fn();
|
||||
}
|
||||
void Member(const char *, std::function<void()> fn) override { fn(); }
|
||||
};
|
||||
|
||||
class BinaryWriter : public Writer {
|
||||
std::string buf_;
|
||||
|
||||
template <typename T>
|
||||
void Pack(T x) {
|
||||
template <typename T> void Pack(T x) {
|
||||
auto i = buf_.size();
|
||||
buf_.resize(i + sizeof(x));
|
||||
*reinterpret_cast<T *>(buf_.data() + i) = x;
|
||||
@ -97,14 +91,10 @@ class BinaryWriter : public Writer {
|
||||
Pack<uint64_t>(n);
|
||||
}
|
||||
}
|
||||
void VarInt(int64_t n) {
|
||||
VarUInt(uint64_t(n) << 1 ^ n >> 63);
|
||||
}
|
||||
void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); }
|
||||
|
||||
public:
|
||||
SerializeFormat Format() const override {
|
||||
return SerializeFormat::Binary;
|
||||
}
|
||||
SerializeFormat Format() const override { return SerializeFormat::Binary; }
|
||||
std::string Take() { return std::move(buf_); }
|
||||
|
||||
void Null() override { Pack(uint8_t(0)); }
|
||||
|
18
src/test.cc
18
src/test.cc
@ -13,9 +13,9 @@
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fstream>
|
||||
|
||||
// The 'diff' utility is available and we can use dprintf(3).
|
||||
#if _POSIX_C_SOURCE >= 200809L
|
||||
@ -66,8 +66,7 @@ struct TextReplacer {
|
||||
|
||||
void ParseTestExpectation(
|
||||
const std::string &filename,
|
||||
const std::vector<std::string>& lines_with_endings,
|
||||
TextReplacer* replacer,
|
||||
const std::vector<std::string> &lines_with_endings, TextReplacer *replacer,
|
||||
std::vector<std::string> *flags,
|
||||
std::unordered_map<std::string, std::string> *output_sections) {
|
||||
// Scan for EXTRA_FLAGS:
|
||||
@ -148,10 +147,8 @@ void UpdateTestExpectation(const std::string& filename,
|
||||
WriteToFile(filename, str);
|
||||
}
|
||||
|
||||
void DiffDocuments(std::string path,
|
||||
std::string path_section,
|
||||
rapidjson::Document& expected,
|
||||
rapidjson::Document& actual) {
|
||||
void DiffDocuments(std::string path, std::string path_section,
|
||||
rapidjson::Document &expected, rapidjson::Document &actual) {
|
||||
std::string joined_actual_output = ToString(actual);
|
||||
std::string joined_expected_output = ToString(expected);
|
||||
printf("[FAILED] %s (section %s)\n", path.c_str(), path_section.c_str());
|
||||
@ -217,8 +214,8 @@ std::string FindExpectedOutputForFilename(
|
||||
return "{}";
|
||||
}
|
||||
|
||||
IndexFile* FindDbForPathEnding(
|
||||
const std::string& path,
|
||||
IndexFile *
|
||||
FindDbForPathEnding(const std::string &path,
|
||||
const std::vector<std::unique_ptr<IndexFile>> &dbs) {
|
||||
for (auto &db : dbs) {
|
||||
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);
|
||||
puts("\n");
|
||||
if (enable_update) {
|
||||
printf(
|
||||
"[Enter to continue - type u to update test, a to update "
|
||||
printf("[Enter to continue - type u to update test, a to update "
|
||||
"all]");
|
||||
char c = 'u';
|
||||
if (!update_all) {
|
||||
|
@ -18,27 +18,21 @@ struct BaseThreadQueue {
|
||||
// std::lock accepts two or more arguments. We define an overload for one
|
||||
// argument.
|
||||
namespace std {
|
||||
template <typename Lockable>
|
||||
void lock(Lockable& l) {
|
||||
l.lock();
|
||||
}
|
||||
template <typename Lockable> void lock(Lockable &l) { l.lock(); }
|
||||
} // namespace std
|
||||
|
||||
template <typename... Queue>
|
||||
struct MultiQueueLock {
|
||||
template <typename... Queue> struct MultiQueueLock {
|
||||
MultiQueueLock(Queue... lockable) : tuple_{lockable...} { lock(); }
|
||||
~MultiQueueLock() { unlock(); }
|
||||
void lock() { lock_impl(typename std::index_sequence_for<Queue...>{}); }
|
||||
void unlock() { unlock_impl(typename std::index_sequence_for<Queue...>{}); }
|
||||
|
||||
private:
|
||||
template <size_t... Is>
|
||||
void lock_impl(std::index_sequence<Is...>) {
|
||||
template <size_t... Is> void lock_impl(std::index_sequence<Is...>) {
|
||||
std::lock(std::get<Is>(tuple_)->mutex_...);
|
||||
}
|
||||
|
||||
template <size_t... Is>
|
||||
void unlock_impl(std::index_sequence<Is...>) {
|
||||
template <size_t... Is> void unlock_impl(std::index_sequence<Is...>) {
|
||||
(void)std::initializer_list<int>{
|
||||
(std::get<Is>(tuple_)->mutex_.unlock(), 0)...};
|
||||
}
|
||||
@ -57,8 +51,7 @@ struct MultiQueueWaiter {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename... BaseThreadQueue>
|
||||
void Wait(BaseThreadQueue... queues) {
|
||||
template <typename... BaseThreadQueue> void Wait(BaseThreadQueue... queues) {
|
||||
MultiQueueLock<BaseThreadQueue...> l(queues...);
|
||||
while (!HasState({queues...}))
|
||||
cv.wait(l);
|
||||
@ -66,8 +59,7 @@ struct MultiQueueWaiter {
|
||||
};
|
||||
|
||||
// A threadsafe-queue. http://stackoverflow.com/a/16075550
|
||||
template <class T>
|
||||
struct ThreadedQueue : public BaseThreadQueue {
|
||||
template <class T> struct ThreadedQueue : public BaseThreadQueue {
|
||||
public:
|
||||
ThreadedQueue() {
|
||||
owned_waiter_ = std::make_unique<MultiQueueWaiter>();
|
||||
@ -79,8 +71,7 @@ struct ThreadedQueue : public BaseThreadQueue {
|
||||
size_t Size() const { return total_count_; }
|
||||
|
||||
// Add an element to the queue.
|
||||
template <void (std::deque<T>::*push)(T&&)>
|
||||
void Push(T&& t, bool priority) {
|
||||
template <void (std::deque<T>::*push)(T &&)> void Push(T &&t, bool priority) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (priority)
|
||||
(priority_.*push)(std::move(t));
|
||||
@ -151,8 +142,7 @@ struct ThreadedQueue : public BaseThreadQueue {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
void Iterate(Fn fn) {
|
||||
template <typename Fn> void Iterate(Fn fn) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
for (auto &entry : priority_)
|
||||
fn(entry);
|
||||
|
17
src/utils.cc
17
src/utils.cc
@ -7,12 +7,12 @@ using namespace llvm;
|
||||
|
||||
#include <siphash.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <string.h>
|
||||
#include <unordered_map>
|
||||
using namespace std::placeholders;
|
||||
|
||||
@ -34,7 +34,8 @@ uint64_t HashUsr(std::string_view s) {
|
||||
// k is an arbitrary key. Don't change it.
|
||||
const uint8_t k[16] = {0xd0, 0xe5, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -112,7 +113,8 @@ std::optional<std::string> ReadContent(const std::string& filename) {
|
||||
char buf[4096];
|
||||
std::string ret;
|
||||
FILE *f = fopen(filename.c_str(), "rb");
|
||||
if (!f) return {};
|
||||
if (!f)
|
||||
return {};
|
||||
size_t n;
|
||||
while ((n = fread(buf, 1, sizeof buf, f)) > 0)
|
||||
ret.append(buf, n);
|
||||
@ -139,8 +141,7 @@ std::optional<int64_t> LastWriteTime(const std::string& filename) {
|
||||
|
||||
// Find discontinous |search| in |content|.
|
||||
// Return |found| and the count of skipped chars before found.
|
||||
int ReverseSubseqMatch(std::string_view pat,
|
||||
std::string_view text,
|
||||
int ReverseSubseqMatch(std::string_view pat, std::string_view text,
|
||||
int case_sensitivity) {
|
||||
if (case_sensitivity == 1)
|
||||
case_sensitivity = std::any_of(pat.begin(), pat.end(), isupper) ? 2 : 0;
|
||||
@ -155,6 +156,4 @@ int ReverseSubseqMatch(std::string_view pat,
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string GetDefaultResourceDirectory() {
|
||||
return DEFAULT_RESOURCE_DIRECTORY;
|
||||
}
|
||||
std::string GetDefaultResourceDirectory() { return DEFAULT_RESOURCE_DIRECTORY; }
|
||||
|
@ -32,8 +32,7 @@ std::vector<std::string> SplitString(const std::string& str,
|
||||
std::string LowerPathIfInsensitive(const std::string &path);
|
||||
|
||||
template <typename TValues, typename TMap>
|
||||
std::string StringJoinMap(const TValues& values,
|
||||
const TMap& map,
|
||||
std::string StringJoinMap(const TValues &values, const TMap &map,
|
||||
const std::string &sep = ", ") {
|
||||
std::string result;
|
||||
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);
|
||||
std::optional<int64_t> LastWriteTime(const std::string &filename);
|
||||
|
||||
int ReverseSubseqMatch(std::string_view pat,
|
||||
std::string_view text,
|
||||
int ReverseSubseqMatch(std::string_view pat, std::string_view text,
|
||||
int case_sensitivity);
|
||||
|
||||
// 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, ...) \
|
||||
namespace std { \
|
||||
template <> \
|
||||
struct hash<type> { \
|
||||
template <> struct hash<type> { \
|
||||
std::size_t operator()(const type &t) const { \
|
||||
std::size_t ret = 0; \
|
||||
hash_combine(ret, __VA_ARGS__); \
|
||||
|
@ -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].
|
||||
// By symmetry, this can also be used to find matching index line of a buffer
|
||||
// line.
|
||||
std::optional<int> FindMatchingLine(const std::vector<std::string>& index_lines,
|
||||
const std::vector<int>& index_to_buffer,
|
||||
int line,
|
||||
int* column,
|
||||
const std::vector<std::string>& buffer_lines,
|
||||
bool is_end) {
|
||||
std::optional<int>
|
||||
FindMatchingLine(const std::vector<std::string> &index_lines,
|
||||
const std::vector<int> &index_to_buffer, int line, int *column,
|
||||
const std::vector<std::string> &buffer_lines, bool is_end) {
|
||||
// If this is a confident mapping, returns.
|
||||
if (index_to_buffer[line] >= 0) {
|
||||
int ret = index_to_buffer[line];
|
||||
@ -300,8 +298,7 @@ void WorkingFile::ComputeLineMapping() {
|
||||
buffer_to_index[index_to_buffer[i]] = i;
|
||||
}
|
||||
|
||||
std::optional<int> WorkingFile::GetBufferPosFromIndexPos(int line,
|
||||
int* column,
|
||||
std::optional<int> WorkingFile::GetBufferPosFromIndexPos(int line, int *column,
|
||||
bool is_end) {
|
||||
if (line < 0 || line >= (int)index_lines.size()) {
|
||||
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);
|
||||
}
|
||||
|
||||
std::optional<int> WorkingFile::GetIndexPosFromBufferPos(int line,
|
||||
int* column,
|
||||
std::optional<int> WorkingFile::GetIndexPosFromBufferPos(int line, int *column,
|
||||
bool is_end) {
|
||||
// See GetBufferLineFromIndexLine for additional comments.
|
||||
if (line < 0 || line >= (int)buffer_lines.size())
|
||||
@ -329,8 +325,7 @@ std::optional<int> WorkingFile::GetIndexPosFromBufferPos(int line,
|
||||
}
|
||||
|
||||
std::string WorkingFile::FindClosestCallNameInBuffer(
|
||||
lsPosition position,
|
||||
int* active_parameter,
|
||||
lsPosition position, int *active_parameter,
|
||||
lsPosition *completion_position) const {
|
||||
*active_parameter = 0;
|
||||
|
||||
@ -378,10 +373,8 @@ std::string WorkingFile::FindClosestCallNameInBuffer(
|
||||
}
|
||||
|
||||
lsPosition WorkingFile::FindStableCompletionSource(
|
||||
lsPosition position,
|
||||
bool* is_global_completion,
|
||||
std::string* existing_completion,
|
||||
lsPosition* replace_end_pos) const {
|
||||
lsPosition position, bool *is_global_completion,
|
||||
std::string *existing_completion, lsPosition *replace_end_pos) const {
|
||||
*is_global_completion = true;
|
||||
|
||||
int start_offset = GetOffsetForPosition(position, buffer_content);
|
||||
@ -410,7 +403,8 @@ lsPosition WorkingFile::FindStableCompletionSource(
|
||||
*replace_end_pos = position;
|
||||
for (int i = start_offset; i < buffer_content.size(); 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.
|
||||
replace_end_pos->character++;
|
||||
}
|
||||
@ -424,8 +418,8 @@ WorkingFile* WorkingFiles::GetFileByFilename(const std::string& filename) {
|
||||
return GetFileByFilenameNoLock(filename);
|
||||
}
|
||||
|
||||
WorkingFile* WorkingFiles::GetFileByFilenameNoLock(
|
||||
const std::string& filename) {
|
||||
WorkingFile *
|
||||
WorkingFiles::GetFileByFilenameNoLock(const std::string &filename) {
|
||||
for (auto &file : files) {
|
||||
if (file->filename == filename)
|
||||
return file.get();
|
||||
@ -516,8 +510,8 @@ void WorkingFiles::OnClose(const lsTextDocumentIdentifier& close) {
|
||||
<< " because it was not open";
|
||||
}
|
||||
|
||||
WorkingFiles::Snapshot WorkingFiles::AsSnapshot(
|
||||
const std::vector<std::string>& filter_paths) {
|
||||
WorkingFiles::Snapshot
|
||||
WorkingFiles::AsSnapshot(const std::vector<std::string> &filter_paths) {
|
||||
std::lock_guard<std::mutex> lock(files_mutex);
|
||||
|
||||
Snapshot result;
|
||||
|
@ -40,10 +40,12 @@ struct WorkingFile {
|
||||
// Also resolves |column| if not NULL.
|
||||
// When resolving a range, use is_end = false for begin() and is_end =
|
||||
// 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|.
|
||||
// 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
|
||||
// lex_utils.h/cc
|
||||
@ -53,9 +55,8 @@ struct WorkingFile {
|
||||
//
|
||||
// |completion_position| will be point to a good code completion location to
|
||||
// for fetching signatures.
|
||||
std::string FindClosestCallNameInBuffer(
|
||||
lsPosition position,
|
||||
int* active_parameter,
|
||||
std::string
|
||||
FindClosestCallNameInBuffer(lsPosition position, int *active_parameter,
|
||||
lsPosition *completion_position = nullptr) const;
|
||||
|
||||
// Returns a relatively stable completion position (it jumps back until there
|
||||
|
Loading…
Reference in New Issue
Block a user