mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Misc
Move using below #include to make preamble happy textDocument/references: if no references, first line or last line => list where this file is included malloc_trim() only if files have been indexed in last cycle Intern: use CachedHashStringRef
This commit is contained in:
parent
174466516e
commit
395e9d8724
@ -163,7 +163,9 @@ std::unique_ptr<CompilerInstance> BuildCompilerInstance(
|
||||
CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
|
||||
DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot,
|
||||
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
|
||||
std::string main = ResolveIfRelative(session.file.directory, CI->getFrontendOpts().Inputs[0].getFile());
|
||||
std::string main = ResolveIfRelative(
|
||||
session.file.directory,
|
||||
sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile()));
|
||||
for (auto &file : snapshot.files) {
|
||||
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
|
||||
if (file.filename == main)
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "pipeline.hh"
|
||||
#include "platform.h"
|
||||
#include "serializer.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <clang/AST/AST.h>
|
||||
#include <clang/Frontend/FrontendAction.h>
|
||||
@ -21,16 +20,15 @@ using namespace ccls;
|
||||
#include <llvm/ADT/DenseSet.h>
|
||||
#include <llvm/Support/CrashRecoveryContext.h>
|
||||
#include <llvm/Support/Path.h>
|
||||
#include <llvm/Support/Timer.h>
|
||||
using namespace clang;
|
||||
using llvm::Timer;
|
||||
|
||||
#include <algorithm>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace ccls;
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kInitializerMaxLines = 3;
|
||||
@ -494,7 +492,7 @@ public:
|
||||
def.short_name_offset = Str.size() + qualified.size() - short_name.size();
|
||||
def.short_name_size = short_name.size();
|
||||
Str += StringRef(qualified.data(), qualified.size());
|
||||
def.detailed_name = Intern(Str.str());
|
||||
def.detailed_name = Intern(Str);
|
||||
} else {
|
||||
SetName(D, short_name, qualified, def);
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <llvm/ADT/DenseMap.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <stdint.h>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
@ -8,15 +8,12 @@
|
||||
#include "serializers/json.h"
|
||||
#include "test.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
#include <llvm/Support/CrashRecoveryContext.h>
|
||||
#include <llvm/Support/Process.h>
|
||||
#include <llvm/Support/Program.h>
|
||||
#include <llvm/Support/Signals.h>
|
||||
using namespace llvm;
|
||||
using namespace llvm::cl;
|
||||
|
||||
#include <rapidjson/error/en.h>
|
||||
|
||||
@ -26,6 +23,10 @@ using namespace llvm::cl;
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
using namespace ccls;
|
||||
using namespace llvm;
|
||||
using namespace llvm::cl;
|
||||
|
||||
std::string g_init_options;
|
||||
|
||||
namespace {
|
||||
|
@ -75,7 +75,6 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method,
|
||||
|
||||
struct MessageHandler {
|
||||
DB *db = nullptr;
|
||||
MultiQueueWaiter *waiter = nullptr;
|
||||
Project *project = nullptr;
|
||||
VFS *vfs = nullptr;
|
||||
SemanticHighlight *highlight = nullptr;
|
||||
|
@ -5,10 +5,11 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
|
||||
MethodType kMethodType = "$ccls/call";
|
||||
|
@ -5,14 +5,15 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <clang/AST/Type.h>
|
||||
#include <llvm/ADT/DenseSet.h>
|
||||
using namespace clang;
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace ccls;
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "$ccls/member";
|
||||
|
||||
|
@ -5,14 +5,14 @@
|
||||
#include "match.h"
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "platform.h"
|
||||
#include "project.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "$ccls/reload";
|
||||
|
||||
@ -22,8 +22,7 @@ struct In_CclsReload : public NotificationInMessage {
|
||||
bool dependencies = true;
|
||||
std::vector<std::string> whitelist;
|
||||
std::vector<std::string> blacklist;
|
||||
};
|
||||
Params params;
|
||||
} params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist,
|
||||
blacklist);
|
||||
|
@ -11,16 +11,16 @@
|
||||
#include "project.h"
|
||||
#include "serializers/json.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <llvm/ADT/Twine.h>
|
||||
#include <llvm/Support/Threading.h>
|
||||
using namespace llvm;
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
|
||||
using namespace ccls;
|
||||
using namespace llvm;
|
||||
|
||||
// TODO Cleanup global variables
|
||||
extern std::string g_init_options;
|
||||
|
||||
|
@ -8,16 +8,16 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <clang/Sema/CodeCompleteConsumer.h>
|
||||
#include <clang/Sema/Sema.h>
|
||||
#include <llvm/Support/Timer.h>
|
||||
using namespace clang;
|
||||
using namespace llvm;
|
||||
|
||||
#include <regex>
|
||||
|
||||
using namespace ccls;
|
||||
using namespace clang;
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/completion";
|
||||
|
||||
@ -167,10 +167,6 @@ void FilterAndSortCompletionResponse(
|
||||
const std::string &complete_text, bool has_open_paren) {
|
||||
if (!g_config->completion.filterAndSort)
|
||||
return;
|
||||
|
||||
static Timer timer("FilterAndSortCompletionResponse", "");
|
||||
TimeRegion region(timer);
|
||||
|
||||
auto &items = complete_response->result.items;
|
||||
|
||||
auto finalize = [&]() {
|
||||
|
@ -4,11 +4,12 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/definition";
|
||||
|
@ -14,8 +14,7 @@ struct In_TextDocumentDidClose : public NotificationInMessage {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
struct Params {
|
||||
lsTextDocumentIdentifier textDocument;
|
||||
};
|
||||
Params params;
|
||||
} params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params);
|
||||
|
@ -12,7 +12,6 @@ using namespace ccls;
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/didOpen";
|
||||
|
||||
// Open, view, change, close file
|
||||
struct In_TextDocumentDidOpen : public NotificationInMessage {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
|
||||
@ -37,7 +36,7 @@ struct Handler_TextDocumentDidOpen
|
||||
// NOTE: This function blocks code lens. If it starts taking a long time
|
||||
// we will need to find a way to unblock the code lens request.
|
||||
const auto ¶ms = request->params;
|
||||
std::string path = params.textDocument.uri.GetPath();
|
||||
const std::string &path = params.textDocument.uri.GetPath();
|
||||
|
||||
WorkingFile *working_file = working_files->OnOpen(params.textDocument);
|
||||
if (std::optional<std::string> cached_file_contents =
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "clang_complete.hh"
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "project.h"
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
@ -32,7 +31,7 @@ struct Handler_TextDocumentDidSave
|
||||
|
||||
void Run(In_TextDocumentDidSave *request) override {
|
||||
const auto ¶ms = request->params;
|
||||
std::string path = params.textDocument.uri.GetPath();
|
||||
const std::string &path = params.textDocument.uri.GetPath();
|
||||
pipeline::Index(path, {}, IndexMode::Normal);
|
||||
clang_complete->NotifySave(path);
|
||||
}
|
||||
|
@ -4,10 +4,11 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/references";
|
||||
|
||||
@ -54,13 +55,17 @@ struct Handler_TextDocumentReferences
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
|
||||
Out_TextDocumentReferences out;
|
||||
out.id = request->id;
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
if (!file) {
|
||||
pipeline::WriteStdout(kMethodType, out);
|
||||
return;
|
||||
}
|
||||
|
||||
bool container = g_config->xref.container;
|
||||
std::unordered_set<Use> seen_uses;
|
||||
int line = params.position.line;
|
||||
|
||||
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) {
|
||||
// Found symbol. Return references.
|
||||
@ -115,7 +120,7 @@ struct Handler_TextDocumentReferences
|
||||
// = 0,
|
||||
// use the current filename.
|
||||
std::string path;
|
||||
if (params.position.line == 0)
|
||||
if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1)
|
||||
path = file->def->path;
|
||||
for (const IndexInclude &include : file->def->includes)
|
||||
if (include.line == params.position.line) {
|
||||
|
@ -4,12 +4,11 @@
|
||||
#include "clang_complete.hh"
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
using namespace ccls;
|
||||
|
||||
#include <clang/Sema/Sema.h>
|
||||
using namespace clang;
|
||||
|
||||
#include <stdint.h>
|
||||
using namespace ccls;
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/signatureHelp";
|
||||
|
@ -5,13 +5,14 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctype.h>
|
||||
#include <functional>
|
||||
#include <limits.h>
|
||||
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "workspace/symbol";
|
||||
|
||||
|
@ -478,7 +478,6 @@ void MainLoop() {
|
||||
// Setup shared references.
|
||||
for (MessageHandler *handler : *MessageHandler::message_handlers) {
|
||||
handler->db = &db;
|
||||
handler->waiter = indexer_waiter;
|
||||
handler->project = &project;
|
||||
handler->vfs = &vfs;
|
||||
handler->highlight = &highlight;
|
||||
@ -487,6 +486,7 @@ void MainLoop() {
|
||||
handler->include_complete = &include_complete;
|
||||
}
|
||||
|
||||
bool last_indexed = false;
|
||||
while (true) {
|
||||
std::vector<std::unique_ptr<InMessage>> messages = on_request->DequeueAll();
|
||||
bool did_work = messages.size();
|
||||
@ -503,18 +503,22 @@ void MainLoop() {
|
||||
LOG_S(ERROR) << "No handler for " << message->GetMethodType();
|
||||
}
|
||||
|
||||
for (int i = 80; i--;) {
|
||||
bool indexed = false;
|
||||
for (int i = 20; i--;) {
|
||||
std::optional<IndexUpdate> update = on_indexed->TryPopFront();
|
||||
if (!update)
|
||||
break;
|
||||
did_work = true;
|
||||
indexed = true;
|
||||
Main_OnIndexed(&db, &highlight, &working_files, &*update);
|
||||
}
|
||||
|
||||
if (!did_work) {
|
||||
FreeUnusedMemory();
|
||||
if (last_indexed)
|
||||
FreeUnusedMemory();
|
||||
main_waiter->Wait(on_indexed, on_request);
|
||||
}
|
||||
last_indexed = indexed;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ std::string NormalizePath(const std::string &path) {
|
||||
|
||||
void FreeUnusedMemory() {
|
||||
#ifdef __GLIBC__
|
||||
malloc_trim(0);
|
||||
malloc_trim(4 * 1024 * 1024);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -13,18 +13,14 @@
|
||||
#include "serializers/json.h"
|
||||
#include "utils.h"
|
||||
#include "working_files.h"
|
||||
using namespace ccls;
|
||||
|
||||
#include <clang/Driver/Compilation.h>
|
||||
#include <clang/Driver/Driver.h>
|
||||
#include <clang/Frontend/CompilerInstance.h>
|
||||
#include <clang/Tooling/CompilationDatabase.h>
|
||||
#include <llvm/ADT/ArrayRef.h>
|
||||
#include <llvm/ADT/STLExtras.h>
|
||||
#include <llvm/ADT/StringSet.h>
|
||||
#include <llvm/Support/LineIterator.h>
|
||||
using namespace clang;
|
||||
using namespace llvm;
|
||||
|
||||
#include <rapidjson/writer.h>
|
||||
|
||||
@ -32,10 +28,14 @@ using namespace llvm;
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
#include <limits.h>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
using namespace ccls;
|
||||
using namespace clang;
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand };
|
||||
@ -387,7 +387,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) {
|
||||
// We couldn't find the file. Try to infer it.
|
||||
// TODO: Cache inferred file in a separate array (using a lock or similar)
|
||||
Entry *best_entry = nullptr;
|
||||
int best_score = std::numeric_limits<int>::min();
|
||||
int best_score = INT_MIN;
|
||||
for (Entry &entry : entries) {
|
||||
int score = ComputeGuessScore(filename, entry.filename);
|
||||
if (score > best_score) {
|
||||
|
@ -154,12 +154,11 @@ void Reflect(Reader &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
||||
if (vis.Format() == SerializeFormat::Json) {
|
||||
auto &vis1 = static_cast<JsonReader&>(vis);
|
||||
for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it)
|
||||
v[CachedHashStringRef(Intern(it->name.GetString()))] =
|
||||
it->value.GetInt64();
|
||||
v[InternH(it->name.GetString())] = it->value.GetInt64();
|
||||
} else {
|
||||
vis.IterArray([&](Reader &entry) {
|
||||
Reflect(entry, name);
|
||||
Reflect(entry, v[CachedHashStringRef(Intern(name))]);
|
||||
Reflect(entry, v[InternH(name)]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -344,18 +343,26 @@ void Reflect(Writer &visitor, SerializeFormat &value) {
|
||||
|
||||
namespace ccls {
|
||||
static BumpPtrAllocator Alloc;
|
||||
static DenseSet<StringRef> Strings;
|
||||
static DenseSet<CachedHashStringRef> Strings;
|
||||
static std::mutex AllocMutex;
|
||||
|
||||
const char *Intern(const std::string &str) {
|
||||
if (str.empty())
|
||||
return "";
|
||||
StringRef Str(str.data(), str.size() + 1);
|
||||
CachedHashStringRef InternH(StringRef S) {
|
||||
if (S.empty())
|
||||
S = "";
|
||||
CachedHashString HS(S);
|
||||
std::lock_guard lock(AllocMutex);
|
||||
auto R = Strings.insert(Str);
|
||||
if (R.second)
|
||||
*R.first = Str.copy(Alloc);
|
||||
return R.first->data();
|
||||
auto R = Strings.insert(HS);
|
||||
if (R.second) {
|
||||
char *P = Alloc.Allocate<char>(S.size() + 1);
|
||||
memcpy(P, S.data(), S.size());
|
||||
P[S.size()] = '\0';
|
||||
*R.first = CachedHashStringRef(StringRef(P, S.size()), HS.hash());
|
||||
}
|
||||
return *R.first;
|
||||
}
|
||||
|
||||
const char *Intern(StringRef S) {
|
||||
return InternH(S).val().data();
|
||||
}
|
||||
|
||||
std::string Serialize(SerializeFormat format, IndexFile &file) {
|
||||
@ -470,7 +477,7 @@ Deserialize(SerializeFormat format, const std::string &path,
|
||||
for (auto &it : file->dependencies) {
|
||||
std::string path = it.first.val().str();
|
||||
DoPathMapping(path);
|
||||
dependencies[CachedHashStringRef(Intern(path))] = it.second;
|
||||
dependencies[InternH(path)] = it.second;
|
||||
}
|
||||
file->dependencies = std::move(dependencies);
|
||||
}
|
||||
|
@ -18,6 +18,11 @@
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class CachedHashStringRef;
|
||||
class StringRef;
|
||||
}
|
||||
|
||||
enum class SerializeFormat { Binary, Json };
|
||||
|
||||
struct JsonNull {};
|
||||
@ -308,7 +313,8 @@ template <typename T> void ReflectMember(Writer &vis, const char *name, T &v) {
|
||||
// API
|
||||
|
||||
namespace ccls {
|
||||
const char *Intern(const std::string &str);
|
||||
const char *Intern(llvm::StringRef str);
|
||||
llvm::CachedHashStringRef InternH(llvm::StringRef str);
|
||||
std::string Serialize(SerializeFormat format, IndexFile &file);
|
||||
std::unique_ptr<IndexFile>
|
||||
Deserialize(SerializeFormat format, const std::string &path,
|
||||
|
Loading…
Reference in New Issue
Block a user