mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 01:51:57 +00:00
Refactor serializer
Delete virtual bases Reader & Writer Delete unused MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY Merge serializers/{json,binary}.hh into serializer.{hh,cc} MAKE_REFLECT_STRUCT => REFLECT_STRUCT MAKE_REFLECT_TYPE_PROXY => REFLECT_UNDERLYING
This commit is contained in:
parent
1a7e463553
commit
cc11d30dad
@ -247,28 +247,28 @@ struct Config {
|
|||||||
int maxNum = 2000;
|
int maxNum = 2000;
|
||||||
} xref;
|
} xref;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings,
|
REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings,
|
||||||
resourceDir);
|
resourceDir);
|
||||||
MAKE_REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport,
|
REFLECT_STRUCT(Config::ClientCapability, hierarchicalDocumentSymbolSupport,
|
||||||
snippetSupport);
|
snippetSupport);
|
||||||
MAKE_REFLECT_STRUCT(Config::CodeLens, localVariables);
|
REFLECT_STRUCT(Config::CodeLens, localVariables);
|
||||||
MAKE_REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize,
|
REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize,
|
||||||
suffixWhitelist, whitelist);
|
suffixWhitelist, whitelist);
|
||||||
MAKE_REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel,
|
REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel,
|
||||||
dropOldRequests, duplicateOptional, filterAndSort, include,
|
dropOldRequests, duplicateOptional, filterAndSort, include,
|
||||||
maxNum);
|
maxNum);
|
||||||
MAKE_REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave,
|
REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave,
|
||||||
spellChecking, whitelist)
|
spellChecking, whitelist)
|
||||||
MAKE_REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist,
|
REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist,
|
||||||
whitelist)
|
whitelist)
|
||||||
MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist,
|
REFLECT_STRUCT(Config::Index, blacklist, comments, initialBlacklist,
|
||||||
initialWhitelist, multiVersion, multiVersionBlacklist,
|
initialWhitelist, multiVersion, multiVersionBlacklist,
|
||||||
multiVersionWhitelist, onChange, threads, trackDependency,
|
multiVersionWhitelist, onChange, threads, trackDependency,
|
||||||
whitelist);
|
whitelist);
|
||||||
MAKE_REFLECT_STRUCT(Config::Session, maxNum);
|
REFLECT_STRUCT(Config::Session, maxNum);
|
||||||
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
||||||
MAKE_REFLECT_STRUCT(Config::Xref, maxNum);
|
REFLECT_STRUCT(Config::Xref, maxNum);
|
||||||
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
||||||
compilationDatabaseDirectory, cacheDirectory, cacheFormat,
|
compilationDatabaseDirectory, cacheDirectory, cacheFormat,
|
||||||
clang, client, codeLens, completion, diagnostics, highlight,
|
clang, client, codeLens, completion, diagnostics, highlight,
|
||||||
index, session, workspaceSymbol, xref);
|
index, session, workspaceSymbol, xref);
|
||||||
|
154
src/indexer.cc
154
src/indexer.cc
@ -8,7 +8,6 @@
|
|||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "sema_manager.hh"
|
#include "sema_manager.hh"
|
||||||
#include "serializer.hh"
|
|
||||||
|
|
||||||
#include <clang/AST/AST.h>
|
#include <clang/AST/AST.h>
|
||||||
#include <clang/Frontend/FrontendAction.h>
|
#include <clang/Frontend/FrontendAction.h>
|
||||||
@ -1172,7 +1171,7 @@ public:
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
const int IndexFile::kMajorVersion = 19;
|
const int IndexFile::kMajorVersion = 19;
|
||||||
const int IndexFile::kMinorVersion = 0;
|
const int IndexFile::kMinorVersion = 1;
|
||||||
|
|
||||||
IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path,
|
IndexFile::IndexFile(llvm::sys::fs::UniqueID UniqueID, const std::string &path,
|
||||||
const std::string &contents)
|
const std::string &contents)
|
||||||
@ -1354,90 +1353,85 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
|
|||||||
}
|
}
|
||||||
} // namespace idx
|
} // namespace idx
|
||||||
|
|
||||||
void Reflect(Reader &vis, SymbolRef &v) {
|
void Reflect(JsonReader &vis, SymbolRef &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
std::string t = vis.GetString();
|
||||||
std::string t = vis.GetString();
|
char *s = const_cast<char *>(t.c_str());
|
||||||
char *s = const_cast<char *>(t.c_str());
|
v.range = Range::FromString(s);
|
||||||
v.range = Range::FromString(s);
|
s = strchr(s, '|');
|
||||||
s = strchr(s, '|');
|
v.usr = strtoull(s + 1, &s, 10);
|
||||||
v.usr = strtoull(s + 1, &s, 10);
|
v.kind = static_cast<Kind>(strtol(s + 1, &s, 10));
|
||||||
v.kind = static_cast<Kind>(strtol(s + 1, &s, 10));
|
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
||||||
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
|
||||||
} else {
|
|
||||||
Reflect(vis, v.range);
|
|
||||||
Reflect(vis, v.usr);
|
|
||||||
Reflect(vis, v.kind);
|
|
||||||
Reflect(vis, v.role);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, SymbolRef &v) {
|
void Reflect(JsonReader &vis, Use &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
std::string t = vis.GetString();
|
||||||
char buf[99];
|
char *s = const_cast<char *>(t.c_str());
|
||||||
snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d",
|
v.range = Range::FromString(s);
|
||||||
v.range.ToString().c_str(), v.usr, int(v.kind), int(v.role));
|
s = strchr(s, '|');
|
||||||
std::string s(buf);
|
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
||||||
Reflect(vis, s);
|
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
||||||
} else {
|
}
|
||||||
Reflect(vis, v.range);
|
void Reflect(JsonReader &vis, DeclRef &v) {
|
||||||
Reflect(vis, v.usr);
|
std::string t = vis.GetString();
|
||||||
Reflect(vis, v.kind);
|
char *s = const_cast<char *>(t.c_str());
|
||||||
Reflect(vis, v.role);
|
v.range = Range::FromString(s);
|
||||||
}
|
s = strchr(s, '|') + 1;
|
||||||
|
v.extent = Range::FromString(s);
|
||||||
|
s = strchr(s, '|');
|
||||||
|
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
||||||
|
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader &vis, Use &v) {
|
void Reflect(JsonWriter &vis, SymbolRef &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
char buf[99];
|
||||||
std::string t = vis.GetString();
|
snprintf(buf, sizeof buf, "%s|%" PRIu64 "|%d|%d", v.range.ToString().c_str(),
|
||||||
char *s = const_cast<char *>(t.c_str());
|
v.usr, int(v.kind), int(v.role));
|
||||||
v.range = Range::FromString(s);
|
std::string s(buf);
|
||||||
s = strchr(s, '|');
|
Reflect(vis, s);
|
||||||
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
|
||||||
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
|
||||||
} else {
|
|
||||||
Reflect(vis, v.range);
|
|
||||||
Reflect(vis, v.role);
|
|
||||||
Reflect(vis, v.file_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, Use &v) {
|
void Reflect(JsonWriter &vis, Use &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
char buf[99];
|
||||||
char buf[99];
|
snprintf(buf, sizeof buf, "%s|%d|%d", v.range.ToString().c_str(), int(v.role),
|
||||||
snprintf(buf, sizeof buf, "%s|%d|%d", v.range.ToString().c_str(),
|
v.file_id);
|
||||||
int(v.role), v.file_id);
|
std::string s(buf);
|
||||||
std::string s(buf);
|
Reflect(vis, s);
|
||||||
Reflect(vis, s);
|
}
|
||||||
} else {
|
void Reflect(JsonWriter &vis, DeclRef &v) {
|
||||||
Reflect(vis, v.range);
|
char buf[99];
|
||||||
Reflect(vis, v.role);
|
snprintf(buf, sizeof buf, "%s|%s|%d|%d", v.range.ToString().c_str(),
|
||||||
Reflect(vis, v.file_id);
|
v.extent.ToString().c_str(), int(v.role), v.file_id);
|
||||||
}
|
std::string s(buf);
|
||||||
|
Reflect(vis, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader &vis, DeclRef &v) {
|
void Reflect(BinaryReader &vis, SymbolRef &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
Reflect(vis, v.range);
|
||||||
std::string t = vis.GetString();
|
Reflect(vis, v.usr);
|
||||||
char *s = const_cast<char *>(t.c_str());
|
Reflect(vis, v.kind);
|
||||||
v.range = Range::FromString(s);
|
Reflect(vis, v.role);
|
||||||
s = strchr(s, '|') + 1;
|
|
||||||
v.extent = Range::FromString(s);
|
|
||||||
s = strchr(s, '|');
|
|
||||||
v.role = static_cast<Role>(strtol(s + 1, &s, 10));
|
|
||||||
v.file_id = static_cast<int>(strtol(s + 1, &s, 10));
|
|
||||||
} else {
|
|
||||||
Reflect(vis, static_cast<Use &>(v));
|
|
||||||
Reflect(vis, v.extent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, DeclRef &v) {
|
void Reflect(BinaryReader &vis, Use &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
Reflect(vis, v.range);
|
||||||
char buf[99];
|
Reflect(vis, v.role);
|
||||||
snprintf(buf, sizeof buf, "%s|%s|%d|%d", v.range.ToString().c_str(),
|
Reflect(vis, v.file_id);
|
||||||
v.extent.ToString().c_str(), int(v.role), v.file_id);
|
}
|
||||||
std::string s(buf);
|
void Reflect(BinaryReader &vis, DeclRef &v) {
|
||||||
Reflect(vis, s);
|
Reflect(vis, static_cast<Use &>(v));
|
||||||
} else {
|
Reflect(vis, v.extent);
|
||||||
Reflect(vis, static_cast<Use &>(v));
|
}
|
||||||
Reflect(vis, v.extent);
|
|
||||||
}
|
void Reflect(BinaryWriter &vis, SymbolRef &v) {
|
||||||
|
Reflect(vis, v.range);
|
||||||
|
Reflect(vis, v.usr);
|
||||||
|
Reflect(vis, v.kind);
|
||||||
|
Reflect(vis, v.role);
|
||||||
|
}
|
||||||
|
void Reflect(BinaryWriter &vis, Use &v) {
|
||||||
|
Reflect(vis, v.range);
|
||||||
|
Reflect(vis, v.role);
|
||||||
|
Reflect(vis, v.file_id);
|
||||||
|
}
|
||||||
|
void Reflect(BinaryWriter &vis, DeclRef &v) {
|
||||||
|
Reflect(vis, static_cast<Use &>(v));
|
||||||
|
Reflect(vis, v.extent);
|
||||||
}
|
}
|
||||||
} // namespace ccls
|
} // namespace ccls
|
||||||
|
@ -34,7 +34,7 @@ using Usr = uint64_t;
|
|||||||
// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in
|
// The order matters. In FindSymbolsAtLocation, we want Var/Func ordered in
|
||||||
// front of others.
|
// front of others.
|
||||||
enum class Kind : uint8_t { Invalid, File, Type, Func, Var };
|
enum class Kind : uint8_t { Invalid, File, Type, Func, Var };
|
||||||
MAKE_REFLECT_TYPE_PROXY(Kind);
|
REFLECT_UNDERLYING_B(Kind);
|
||||||
|
|
||||||
enum class Role : uint16_t {
|
enum class Role : uint16_t {
|
||||||
None = 0,
|
None = 0,
|
||||||
@ -49,7 +49,7 @@ enum class Role : uint16_t {
|
|||||||
Implicit = 1 << 8,
|
Implicit = 1 << 8,
|
||||||
All = (1 << 9) - 1,
|
All = (1 << 9) - 1,
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_TYPE_PROXY(Role);
|
REFLECT_UNDERLYING_B(Role);
|
||||||
inline uint16_t operator&(Role lhs, Role rhs) {
|
inline uint16_t operator&(Role lhs, Role rhs) {
|
||||||
return uint16_t(lhs) & uint16_t(rhs);
|
return uint16_t(lhs) & uint16_t(rhs);
|
||||||
}
|
}
|
||||||
@ -118,12 +118,18 @@ struct DeclRef : Use {
|
|||||||
Range extent;
|
Range extent;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Reflect(Reader &visitor, SymbolRef &value);
|
void Reflect(JsonReader &visitor, SymbolRef &value);
|
||||||
void Reflect(Writer &visitor, SymbolRef &value);
|
void Reflect(JsonReader &visitor, Use &value);
|
||||||
void Reflect(Reader &visitor, Use &value);
|
void Reflect(JsonReader &visitor, DeclRef &value);
|
||||||
void Reflect(Writer &visitor, Use &value);
|
void Reflect(JsonWriter &visitor, SymbolRef &value);
|
||||||
void Reflect(Reader &visitor, DeclRef &value);
|
void Reflect(JsonWriter &visitor, Use &value);
|
||||||
void Reflect(Writer &visitor, DeclRef &value);
|
void Reflect(JsonWriter &visitor, DeclRef &value);
|
||||||
|
void Reflect(BinaryReader &visitor, SymbolRef &value);
|
||||||
|
void Reflect(BinaryReader &visitor, Use &value);
|
||||||
|
void Reflect(BinaryReader &visitor, DeclRef &value);
|
||||||
|
void Reflect(BinaryWriter &visitor, SymbolRef &value);
|
||||||
|
void Reflect(BinaryWriter &visitor, Use &value);
|
||||||
|
void Reflect(BinaryWriter &visitor, DeclRef &value);
|
||||||
|
|
||||||
template <typename D> struct NameMixin {
|
template <typename D> struct NameMixin {
|
||||||
std::string_view Name(bool qualified) const {
|
std::string_view Name(bool qualified) const {
|
||||||
@ -162,7 +168,7 @@ struct FuncDef : NameMixin<FuncDef> {
|
|||||||
|
|
||||||
std::vector<Usr> GetBases() const { return bases; }
|
std::vector<Usr> GetBases() const { return bases; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars,
|
REFLECT_STRUCT(FuncDef, detailed_name, hover, comments, spell, bases, vars,
|
||||||
callees, qual_name_offset, short_name_offset,
|
callees, qual_name_offset, short_name_offset,
|
||||||
short_name_size, kind, parent_kind, storage);
|
short_name_size, kind, parent_kind, storage);
|
||||||
|
|
||||||
@ -199,7 +205,7 @@ struct TypeDef : NameMixin<TypeDef> {
|
|||||||
|
|
||||||
std::vector<Usr> GetBases() const { return bases; }
|
std::vector<Usr> GetBases() const { return bases; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, bases,
|
REFLECT_STRUCT(TypeDef, detailed_name, hover, comments, spell, bases,
|
||||||
funcs, types, vars, alias_of, qual_name_offset,
|
funcs, types, vars, alias_of, qual_name_offset,
|
||||||
short_name_offset, short_name_size, kind, parent_kind);
|
short_name_offset, short_name_size, kind, parent_kind);
|
||||||
|
|
||||||
@ -243,7 +249,7 @@ struct VarDef : NameMixin<VarDef> {
|
|||||||
|
|
||||||
std::vector<Usr> GetBases() const { return {}; }
|
std::vector<Usr> GetBases() const { return {}; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type,
|
REFLECT_STRUCT(VarDef, detailed_name, hover, comments, spell, type,
|
||||||
qual_name_offset, short_name_offset, short_name_size, kind,
|
qual_name_offset, short_name_offset, short_name_size, kind,
|
||||||
parent_kind, storage);
|
parent_kind, storage);
|
||||||
|
|
||||||
|
31
src/lsp.cc
31
src/lsp.cc
@ -4,29 +4,30 @@
|
|||||||
#include "lsp.hh"
|
#include "lsp.hh"
|
||||||
|
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
void Reflect(Reader &visitor, RequestId &value) {
|
void Reflect(JsonReader &vis, RequestId &v) {
|
||||||
if (visitor.IsInt64()) {
|
if (vis.m->IsInt64()) {
|
||||||
value.type = RequestId::kInt;
|
v.type = RequestId::kInt;
|
||||||
value.value = int(visitor.GetInt64());
|
v.value = int(vis.m->GetInt64());
|
||||||
} else if (visitor.IsInt()) {
|
} else if (vis.m->IsInt()) {
|
||||||
value.type = RequestId::kInt;
|
v.type = RequestId::kInt;
|
||||||
value.value = visitor.GetInt();
|
v.value = vis.m->GetInt();
|
||||||
} else if (visitor.IsString()) {
|
} else if (vis.m->IsString()) {
|
||||||
value.type = RequestId::kString;
|
v.type = RequestId::kString;
|
||||||
value.value = atoll(visitor.GetString());
|
v.value = atoll(vis.m->GetString());
|
||||||
} else {
|
} else {
|
||||||
value.type = RequestId::kNone;
|
v.type = RequestId::kNone;
|
||||||
value.value = -1;
|
v.value = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Writer &visitor, RequestId &value) {
|
void Reflect(JsonWriter &visitor, RequestId &value) {
|
||||||
switch (value.type) {
|
switch (value.type) {
|
||||||
case RequestId::kNone:
|
case RequestId::kNone:
|
||||||
visitor.Null();
|
visitor.Null();
|
||||||
@ -36,7 +37,7 @@ void Reflect(Writer &visitor, RequestId &value) {
|
|||||||
break;
|
break;
|
||||||
case RequestId::kString:
|
case RequestId::kString:
|
||||||
auto s = std::to_string(value.value);
|
auto s = std::to_string(value.value);
|
||||||
visitor.String(s.c_str(), s.length());
|
visitor.String(s.c_str(), s.size());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/lsp.hh
11
src/lsp.hh
@ -23,8 +23,8 @@ struct RequestId {
|
|||||||
|
|
||||||
bool Valid() const { return type != kNone; }
|
bool Valid() const { return type != kNone; }
|
||||||
};
|
};
|
||||||
void Reflect(Reader &visitor, RequestId &value);
|
void Reflect(JsonReader &visitor, RequestId &value);
|
||||||
void Reflect(Writer &visitor, RequestId &value);
|
void Reflect(JsonWriter &visitor, RequestId &value);
|
||||||
|
|
||||||
struct InMessage {
|
struct InMessage {
|
||||||
RequestId id;
|
RequestId id;
|
||||||
@ -68,11 +68,6 @@ struct DocumentUri {
|
|||||||
std::string raw_uri;
|
std::string raw_uri;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TVisitor>
|
|
||||||
void Reflect(TVisitor &visitor, DocumentUri &value) {
|
|
||||||
Reflect(visitor, value.raw_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Position {
|
struct Position {
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int character = 0;
|
int character = 0;
|
||||||
@ -208,7 +203,7 @@ struct WorkspaceFolder {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
enum class MessageType : int { Error = 1, Warning = 2, Info = 3, Log = 4 };
|
||||||
MAKE_REFLECT_TYPE_PROXY(MessageType)
|
REFLECT_UNDERLYING(MessageType)
|
||||||
|
|
||||||
struct Diagnostic {
|
struct Diagnostic {
|
||||||
lsRange range;
|
lsRange range;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "serializer.hh"
|
#include "serializer.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
#include "test.hh"
|
#include "test.hh"
|
||||||
#include "working_files.hh"
|
#include "working_files.hh"
|
||||||
|
|
||||||
@ -17,6 +16,7 @@
|
|||||||
#include <llvm/Support/Program.h>
|
#include <llvm/Support/Program.h>
|
||||||
#include <llvm/Support/Signals.h>
|
#include <llvm/Support/Signals.h>
|
||||||
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
#include <rapidjson/error/en.h>
|
#include <rapidjson/error/en.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
#include "query.hh"
|
#include "query.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/reader.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -17,35 +19,35 @@ using namespace clang;
|
|||||||
MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind);
|
MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind);
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
MAKE_REFLECT_STRUCT(CodeActionParam::Context, diagnostics);
|
REFLECT_STRUCT(CodeActionParam::Context, diagnostics);
|
||||||
MAKE_REFLECT_STRUCT(CodeActionParam, textDocument, range, context);
|
REFLECT_STRUCT(CodeActionParam, textDocument, range, context);
|
||||||
void Reflect(Reader &, EmptyParam &) {}
|
void Reflect(JsonReader &, EmptyParam &) {}
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentParam, textDocument);
|
REFLECT_STRUCT(TextDocumentParam, textDocument);
|
||||||
MAKE_REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument);
|
REFLECT_STRUCT(DidOpenTextDocumentParam, textDocument);
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentContentChangeEvent, range, rangeLength, text);
|
REFLECT_STRUCT(TextDocumentContentChangeEvent, range, rangeLength, text);
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentDidChangeParam, textDocument, contentChanges);
|
REFLECT_STRUCT(TextDocumentDidChangeParam, textDocument, contentChanges);
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentPositionParam, textDocument, position);
|
REFLECT_STRUCT(TextDocumentPositionParam, textDocument, position);
|
||||||
MAKE_REFLECT_STRUCT(RenameParam, textDocument, position, newName);
|
REFLECT_STRUCT(RenameParam, textDocument, position, newName);
|
||||||
|
|
||||||
// completion
|
// completion
|
||||||
MAKE_REFLECT_TYPE_PROXY(CompletionTriggerKind);
|
REFLECT_UNDERLYING(CompletionTriggerKind);
|
||||||
MAKE_REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter);
|
REFLECT_STRUCT(CompletionContext, triggerKind, triggerCharacter);
|
||||||
MAKE_REFLECT_STRUCT(CompletionParam, textDocument, position, context);
|
REFLECT_STRUCT(CompletionParam, textDocument, position, context);
|
||||||
|
|
||||||
// formatting
|
// formatting
|
||||||
MAKE_REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces);
|
REFLECT_STRUCT(FormattingOptions, tabSize, insertSpaces);
|
||||||
MAKE_REFLECT_STRUCT(DocumentFormattingParam, textDocument, options);
|
REFLECT_STRUCT(DocumentFormattingParam, textDocument, options);
|
||||||
MAKE_REFLECT_STRUCT(DocumentOnTypeFormattingParam, textDocument, position,
|
REFLECT_STRUCT(DocumentOnTypeFormattingParam, textDocument, position, ch,
|
||||||
ch, options);
|
options);
|
||||||
MAKE_REFLECT_STRUCT(DocumentRangeFormattingParam, textDocument, range, options);
|
REFLECT_STRUCT(DocumentRangeFormattingParam, textDocument, range, options);
|
||||||
|
|
||||||
// workspace
|
// workspace
|
||||||
MAKE_REFLECT_TYPE_PROXY(FileChangeType);
|
REFLECT_UNDERLYING(FileChangeType);
|
||||||
MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam::Event, uri, type);
|
REFLECT_STRUCT(DidChangeWatchedFilesParam::Event, uri, type);
|
||||||
MAKE_REFLECT_STRUCT(DidChangeWatchedFilesParam, changes);
|
REFLECT_STRUCT(DidChangeWatchedFilesParam, changes);
|
||||||
MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam::Event, added, removed);
|
REFLECT_STRUCT(DidChangeWorkspaceFoldersParam::Event, added, removed);
|
||||||
MAKE_REFLECT_STRUCT(DidChangeWorkspaceFoldersParam, event);
|
REFLECT_STRUCT(DidChangeWorkspaceFoldersParam, event);
|
||||||
MAKE_REFLECT_STRUCT(WorkspaceSymbolParam, query, folders);
|
REFLECT_STRUCT(WorkspaceSymbolParam, query, folders);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct CclsSemanticHighlightSymbol {
|
struct CclsSemanticHighlightSymbol {
|
||||||
@ -63,15 +65,15 @@ struct CclsSemanticHighlight {
|
|||||||
DocumentUri uri;
|
DocumentUri uri;
|
||||||
std::vector<CclsSemanticHighlightSymbol> symbols;
|
std::vector<CclsSemanticHighlightSymbol> symbols;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage,
|
REFLECT_STRUCT(CclsSemanticHighlightSymbol, id, parentKind, kind, storage,
|
||||||
ranges, lsRanges);
|
ranges, lsRanges);
|
||||||
MAKE_REFLECT_STRUCT(CclsSemanticHighlight, uri, symbols);
|
REFLECT_STRUCT(CclsSemanticHighlight, uri, symbols);
|
||||||
|
|
||||||
struct CclsSetSkippedRanges {
|
struct CclsSetSkippedRanges {
|
||||||
DocumentUri uri;
|
DocumentUri uri;
|
||||||
std::vector<lsRange> skippedRanges;
|
std::vector<lsRange> skippedRanges;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(CclsSetSkippedRanges, uri, skippedRanges);
|
REFLECT_STRUCT(CclsSetSkippedRanges, uri, skippedRanges);
|
||||||
|
|
||||||
struct ScanLineEvent {
|
struct ScanLineEvent {
|
||||||
Position pos;
|
Position pos;
|
||||||
@ -102,8 +104,9 @@ void ReplyOnce::NotReady(bool file) {
|
|||||||
Error(ErrorCode::InternalError, "not indexed");
|
Error(ErrorCode::InternalError, "not indexed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Reader &)) {
|
void MessageHandler::Bind(const char *method,
|
||||||
method2notification[method] = [this, handler](Reader &reader) {
|
void (MessageHandler::*handler)(JsonReader &)) {
|
||||||
|
method2notification[method] = [this, handler](JsonReader &reader) {
|
||||||
(this->*handler)(reader);
|
(this->*handler)(reader);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -111,7 +114,7 @@ void MessageHandler::Bind(const char *method, void (MessageHandler::*handler)(Re
|
|||||||
template <typename Param>
|
template <typename Param>
|
||||||
void MessageHandler::Bind(const char *method,
|
void MessageHandler::Bind(const char *method,
|
||||||
void (MessageHandler::*handler)(Param &)) {
|
void (MessageHandler::*handler)(Param &)) {
|
||||||
method2notification[method] = [this, handler](Reader &reader) {
|
method2notification[method] = [this, handler](JsonReader &reader) {
|
||||||
Param param{};
|
Param param{};
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
(this->*handler)(param);
|
(this->*handler)(param);
|
||||||
@ -119,9 +122,10 @@ void MessageHandler::Bind(const char *method,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessageHandler::Bind(const char *method,
|
void MessageHandler::Bind(const char *method,
|
||||||
void (MessageHandler::*handler)(Reader &,
|
void (MessageHandler::*handler)(JsonReader &,
|
||||||
ReplyOnce &)) {
|
ReplyOnce &)) {
|
||||||
method2request[method] = [this, handler](Reader &reader, ReplyOnce &reply) {
|
method2request[method] = [this, handler](JsonReader &reader,
|
||||||
|
ReplyOnce &reply) {
|
||||||
(this->*handler)(reader, reply);
|
(this->*handler)(reader, reply);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -130,7 +134,8 @@ template <typename Param>
|
|||||||
void MessageHandler::Bind(const char *method,
|
void MessageHandler::Bind(const char *method,
|
||||||
void (MessageHandler::*handler)(Param &,
|
void (MessageHandler::*handler)(Param &,
|
||||||
ReplyOnce &)) {
|
ReplyOnce &)) {
|
||||||
method2request[method] = [this, handler](Reader &reader, ReplyOnce &reply) {
|
method2request[method] = [this, handler](JsonReader &reader,
|
||||||
|
ReplyOnce &reply) {
|
||||||
Param param{};
|
Param param{};
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
(this->*handler)(param, reply);
|
(this->*handler)(param, reply);
|
||||||
@ -202,7 +207,8 @@ void MessageHandler::Run(InMessage &msg) {
|
|||||||
it->second(reader, reply);
|
it->second(reader, reply);
|
||||||
} catch (std::invalid_argument &ex) {
|
} catch (std::invalid_argument &ex) {
|
||||||
reply.Error(ErrorCode::InvalidParams,
|
reply.Error(ErrorCode::InvalidParams,
|
||||||
"invalid params of " + msg.method + ": " + ex.what());
|
"invalid params of " + msg.method + ": expected " +
|
||||||
|
ex.what() + " for " + reader.GetPath());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
reply.Error(ErrorCode::InternalError, "failed to process " + msg.method);
|
reply.Error(ErrorCode::InternalError, "failed to process " + msg.method);
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ struct WorkingFile;
|
|||||||
struct WorkingFiles;
|
struct WorkingFiles;
|
||||||
|
|
||||||
namespace pipeline {
|
namespace pipeline {
|
||||||
void Reply(RequestId id, const std::function<void(Writer &)> &fn);
|
void Reply(RequestId id, const std::function<void(JsonWriter &)> &fn);
|
||||||
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn);
|
void ReplyError(RequestId id, const std::function<void(JsonWriter &)> &fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CodeActionParam {
|
struct CodeActionParam {
|
||||||
@ -63,11 +63,11 @@ struct TextDocumentEdit {
|
|||||||
VersionedTextDocumentIdentifier textDocument;
|
VersionedTextDocumentIdentifier textDocument;
|
||||||
std::vector<TextEdit> edits;
|
std::vector<TextEdit> edits;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentEdit, textDocument, edits);
|
REFLECT_STRUCT(TextDocumentEdit, textDocument, edits);
|
||||||
struct WorkspaceEdit {
|
struct WorkspaceEdit {
|
||||||
std::vector<TextDocumentEdit> documentChanges;
|
std::vector<TextDocumentEdit> documentChanges;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(WorkspaceEdit, documentChanges);
|
REFLECT_STRUCT(WorkspaceEdit, documentChanges);
|
||||||
|
|
||||||
// completion
|
// completion
|
||||||
enum class CompletionTriggerKind {
|
enum class CompletionTriggerKind {
|
||||||
@ -175,32 +175,39 @@ struct WorkspaceSymbolParam {
|
|||||||
// ccls extensions
|
// ccls extensions
|
||||||
std::vector<std::string> folders;
|
std::vector<std::string> folders;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(WorkspaceFolder, uri, name);
|
REFLECT_STRUCT(WorkspaceFolder, uri, name);
|
||||||
|
|
||||||
MAKE_REFLECT_TYPE_PROXY(ErrorCode);
|
inline void Reflect(JsonReader &visitor, DocumentUri &value) {
|
||||||
MAKE_REFLECT_STRUCT(ResponseError, code, message);
|
Reflect(visitor, value.raw_uri);
|
||||||
MAKE_REFLECT_STRUCT(Position, line, character);
|
}
|
||||||
MAKE_REFLECT_STRUCT(lsRange, start, end);
|
inline void Reflect(JsonWriter &visitor, DocumentUri &value) {
|
||||||
MAKE_REFLECT_STRUCT(Location, uri, range);
|
Reflect(visitor, value.raw_uri);
|
||||||
MAKE_REFLECT_TYPE_PROXY(SymbolKind);
|
}
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentIdentifier, uri);
|
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
REFLECT_UNDERLYING(ErrorCode);
|
||||||
MAKE_REFLECT_STRUCT(TextEdit, range, newText);
|
REFLECT_STRUCT(ResponseError, code, message);
|
||||||
MAKE_REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version);
|
REFLECT_STRUCT(Position, line, character);
|
||||||
MAKE_REFLECT_STRUCT(Diagnostic, range, severity, code, source, message);
|
REFLECT_STRUCT(lsRange, start, end);
|
||||||
MAKE_REFLECT_STRUCT(ShowMessageParam, type, message);
|
REFLECT_STRUCT(Location, uri, range);
|
||||||
MAKE_REFLECT_TYPE_PROXY(LanguageId);
|
REFLECT_UNDERLYING_B(SymbolKind);
|
||||||
|
REFLECT_STRUCT(TextDocumentIdentifier, uri);
|
||||||
|
REFLECT_STRUCT(TextDocumentItem, uri, languageId, version, text);
|
||||||
|
REFLECT_STRUCT(TextEdit, range, newText);
|
||||||
|
REFLECT_STRUCT(VersionedTextDocumentIdentifier, uri, version);
|
||||||
|
REFLECT_STRUCT(Diagnostic, range, severity, code, source, message);
|
||||||
|
REFLECT_STRUCT(ShowMessageParam, type, message);
|
||||||
|
REFLECT_UNDERLYING_B(LanguageId);
|
||||||
|
|
||||||
struct ReplyOnce {
|
struct ReplyOnce {
|
||||||
RequestId id;
|
RequestId id;
|
||||||
template <typename Res> void operator()(Res &&result) const {
|
template <typename Res> void operator()(Res &&result) const {
|
||||||
if (id.Valid())
|
if (id.Valid())
|
||||||
pipeline::Reply(id, [&](Writer &w) { Reflect(w, result); });
|
pipeline::Reply(id, [&](JsonWriter &w) { Reflect(w, result); });
|
||||||
}
|
}
|
||||||
void Error(ErrorCode code, std::string message) const {
|
void Error(ErrorCode code, std::string message) const {
|
||||||
ResponseError err{code, std::move(message)};
|
ResponseError err{code, std::move(message)};
|
||||||
if (id.Valid())
|
if (id.Valid())
|
||||||
pipeline::ReplyError(id, [&](Writer &w) { Reflect(w, err); });
|
pipeline::ReplyError(id, [&](JsonWriter &w) { Reflect(w, err); });
|
||||||
}
|
}
|
||||||
void NotReady(bool file);
|
void NotReady(bool file);
|
||||||
};
|
};
|
||||||
@ -213,33 +220,34 @@ struct MessageHandler {
|
|||||||
VFS *vfs = nullptr;
|
VFS *vfs = nullptr;
|
||||||
WorkingFiles *wfiles = nullptr;
|
WorkingFiles *wfiles = nullptr;
|
||||||
|
|
||||||
llvm::StringMap<std::function<void(Reader &)>> method2notification;
|
llvm::StringMap<std::function<void(JsonReader &)>> method2notification;
|
||||||
llvm::StringMap<std::function<void(Reader &, ReplyOnce &)>> method2request;
|
llvm::StringMap<std::function<void(JsonReader &, ReplyOnce &)>>
|
||||||
|
method2request;
|
||||||
|
|
||||||
MessageHandler();
|
MessageHandler();
|
||||||
void Run(InMessage &msg);
|
void Run(InMessage &msg);
|
||||||
QueryFile *FindFile(const std::string &path, int *out_file_id = nullptr);
|
QueryFile *FindFile(const std::string &path, int *out_file_id = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Bind(const char *method, void (MessageHandler::*handler)(Reader &));
|
void Bind(const char *method, void (MessageHandler::*handler)(JsonReader &));
|
||||||
template <typename Param>
|
template <typename Param>
|
||||||
void Bind(const char *method, void (MessageHandler::*handler)(Param &));
|
void Bind(const char *method, void (MessageHandler::*handler)(Param &));
|
||||||
void Bind(const char *method,
|
void Bind(const char *method,
|
||||||
void (MessageHandler::*handler)(Reader &, ReplyOnce &));
|
void (MessageHandler::*handler)(JsonReader &, ReplyOnce &));
|
||||||
template <typename Param>
|
template <typename Param>
|
||||||
void Bind(const char *method,
|
void Bind(const char *method,
|
||||||
void (MessageHandler::*handler)(Param &, ReplyOnce &));
|
void (MessageHandler::*handler)(Param &, ReplyOnce &));
|
||||||
|
|
||||||
void ccls_call(Reader &, ReplyOnce &);
|
void ccls_call(JsonReader &, ReplyOnce &);
|
||||||
void ccls_fileInfo(TextDocumentParam &, ReplyOnce &);
|
void ccls_fileInfo(TextDocumentParam &, ReplyOnce &);
|
||||||
void ccls_info(EmptyParam &, ReplyOnce &);
|
void ccls_info(EmptyParam &, ReplyOnce &);
|
||||||
void ccls_inheritance(Reader &, ReplyOnce &);
|
void ccls_inheritance(JsonReader &, ReplyOnce &);
|
||||||
void ccls_member(Reader &, ReplyOnce &);
|
void ccls_member(JsonReader &, ReplyOnce &);
|
||||||
void ccls_navigate(Reader &, ReplyOnce &);
|
void ccls_navigate(JsonReader &, ReplyOnce &);
|
||||||
void ccls_reload(Reader &);
|
void ccls_reload(JsonReader &);
|
||||||
void ccls_vars(Reader &, ReplyOnce &);
|
void ccls_vars(JsonReader &, ReplyOnce &);
|
||||||
void exit(EmptyParam &);
|
void exit(EmptyParam &);
|
||||||
void initialize(Reader &, ReplyOnce &);
|
void initialize(JsonReader &, ReplyOnce &);
|
||||||
void shutdown(EmptyParam &, ReplyOnce &);
|
void shutdown(EmptyParam &, ReplyOnce &);
|
||||||
void textDocument_codeAction(CodeActionParam &, ReplyOnce &);
|
void textDocument_codeAction(CodeActionParam &, ReplyOnce &);
|
||||||
void textDocument_codeLens(TextDocumentParam &, ReplyOnce &);
|
void textDocument_codeLens(TextDocumentParam &, ReplyOnce &);
|
||||||
@ -251,7 +259,7 @@ private:
|
|||||||
void textDocument_didSave(TextDocumentParam &);
|
void textDocument_didSave(TextDocumentParam &);
|
||||||
void textDocument_documentHighlight(TextDocumentPositionParam &, ReplyOnce &);
|
void textDocument_documentHighlight(TextDocumentPositionParam &, ReplyOnce &);
|
||||||
void textDocument_documentLink(TextDocumentParam &, ReplyOnce &);
|
void textDocument_documentLink(TextDocumentParam &, ReplyOnce &);
|
||||||
void textDocument_documentSymbol(Reader &, ReplyOnce &);
|
void textDocument_documentSymbol(JsonReader &, ReplyOnce &);
|
||||||
void textDocument_foldingRange(TextDocumentParam &, ReplyOnce &);
|
void textDocument_foldingRange(TextDocumentParam &, ReplyOnce &);
|
||||||
void textDocument_formatting(DocumentFormattingParam &, ReplyOnce &);
|
void textDocument_formatting(DocumentFormattingParam &, ReplyOnce &);
|
||||||
void textDocument_hover(TextDocumentPositionParam &, ReplyOnce &);
|
void textDocument_hover(TextDocumentPositionParam &, ReplyOnce &);
|
||||||
@ -260,14 +268,14 @@ private:
|
|||||||
ReplyOnce &);
|
ReplyOnce &);
|
||||||
void textDocument_rangeFormatting(DocumentRangeFormattingParam &,
|
void textDocument_rangeFormatting(DocumentRangeFormattingParam &,
|
||||||
ReplyOnce &);
|
ReplyOnce &);
|
||||||
void textDocument_references(Reader &, ReplyOnce &);
|
void textDocument_references(JsonReader &, ReplyOnce &);
|
||||||
void textDocument_rename(RenameParam &, ReplyOnce &);
|
void textDocument_rename(RenameParam &, ReplyOnce &);
|
||||||
void textDocument_signatureHelp(TextDocumentPositionParam &, ReplyOnce &);
|
void textDocument_signatureHelp(TextDocumentPositionParam &, ReplyOnce &);
|
||||||
void textDocument_typeDefinition(TextDocumentPositionParam &, ReplyOnce &);
|
void textDocument_typeDefinition(TextDocumentPositionParam &, ReplyOnce &);
|
||||||
void workspace_didChangeConfiguration(EmptyParam &);
|
void workspace_didChangeConfiguration(EmptyParam &);
|
||||||
void workspace_didChangeWatchedFiles(DidChangeWatchedFilesParam &);
|
void workspace_didChangeWatchedFiles(DidChangeWatchedFilesParam &);
|
||||||
void workspace_didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParam &);
|
void workspace_didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParam &);
|
||||||
void workspace_executeCommand(Reader &, ReplyOnce &);
|
void workspace_executeCommand(JsonReader &, ReplyOnce &);
|
||||||
void workspace_symbol(WorkspaceSymbolParam &, ReplyOnce &);
|
void workspace_symbol(WorkspaceSymbolParam &, ReplyOnce &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ enum class CallType : uint8_t {
|
|||||||
Derived = 2,
|
Derived = 2,
|
||||||
All = 1 | 2
|
All = 1 | 2
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_TYPE_PROXY(CallType);
|
REFLECT_UNDERLYING(CallType);
|
||||||
|
|
||||||
bool operator&(CallType lhs, CallType rhs) {
|
bool operator&(CallType lhs, CallType rhs) {
|
||||||
return uint8_t(lhs) & uint8_t(rhs);
|
return uint8_t(lhs) & uint8_t(rhs);
|
||||||
@ -40,8 +40,8 @@ struct Param : TextDocumentPositionParam {
|
|||||||
int levels = 1;
|
int levels = 1;
|
||||||
bool hierarchy = false;
|
bool hierarchy = false;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Param, textDocument, position, id, callee, callType,
|
REFLECT_STRUCT(Param, textDocument, position, id, callee, callType, qualified,
|
||||||
qualified, levels, hierarchy);
|
levels, hierarchy);
|
||||||
|
|
||||||
struct Out_cclsCall {
|
struct Out_cclsCall {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
@ -57,8 +57,8 @@ struct Out_cclsCall {
|
|||||||
}
|
}
|
||||||
bool operator<(const Out_cclsCall &o) const { return location < o.location; }
|
bool operator<(const Out_cclsCall &o) const { return location < o.location; }
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsCall, id, name, location, callType, numChildren,
|
REFLECT_STRUCT(Out_cclsCall, id, name, location, callType, numChildren,
|
||||||
children);
|
children);
|
||||||
|
|
||||||
bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee,
|
bool Expand(MessageHandler *m, Out_cclsCall *entry, bool callee,
|
||||||
CallType call_type, bool qualified, int levels) {
|
CallType call_type, bool qualified, int levels) {
|
||||||
@ -170,7 +170,7 @@ std::optional<Out_cclsCall> BuildInitial(MessageHandler *m, Usr root_usr,
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_call(Reader &reader, ReplyOnce &reply) {
|
void MessageHandler::ccls_call(JsonReader &reader, ReplyOnce &reply) {
|
||||||
Param param;
|
Param param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
std::optional<Out_cclsCall> result;
|
std::optional<Out_cclsCall> result;
|
||||||
|
@ -19,8 +19,8 @@ limitations under the License.
|
|||||||
#include "query.hh"
|
#include "query.hh"
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
MAKE_REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges,
|
REFLECT_STRUCT(QueryFile::Def, path, args, language, skipped_ranges,
|
||||||
dependencies);
|
dependencies);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct Out_cclsInfo {
|
struct Out_cclsInfo {
|
||||||
@ -34,10 +34,10 @@ struct Out_cclsInfo {
|
|||||||
int entries;
|
int entries;
|
||||||
} project;
|
} project;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars);
|
REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars);
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests);
|
REFLECT_STRUCT(Out_cclsInfo::Pipeline, pendingIndexRequests);
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsInfo::Project, entries);
|
REFLECT_STRUCT(Out_cclsInfo::Project, entries);
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project);
|
REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) {
|
void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) {
|
||||||
|
@ -24,8 +24,8 @@ struct Param : TextDocumentPositionParam {
|
|||||||
bool hierarchy = false;
|
bool hierarchy = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
MAKE_REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified,
|
REFLECT_STRUCT(Param, textDocument, position, id, kind, derived, qualified,
|
||||||
levels, hierarchy);
|
levels, hierarchy);
|
||||||
|
|
||||||
struct Out_cclsInheritance {
|
struct Out_cclsInheritance {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
@ -39,8 +39,8 @@ struct Out_cclsInheritance {
|
|||||||
// Empty if the |levels| limit is reached.
|
// Empty if the |levels| limit is reached.
|
||||||
std::vector<Out_cclsInheritance> children;
|
std::vector<Out_cclsInheritance> children;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsInheritance, id, kind, name, location, numChildren,
|
REFLECT_STRUCT(Out_cclsInheritance, id, kind, name, location, numChildren,
|
||||||
children);
|
children);
|
||||||
|
|
||||||
bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived,
|
bool Expand(MessageHandler *m, Out_cclsInheritance *entry, bool derived,
|
||||||
bool qualified, int levels);
|
bool qualified, int levels);
|
||||||
@ -153,7 +153,7 @@ void Inheritance(MessageHandler *m, Param ¶m, ReplyOnce &reply) {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_inheritance(Reader &reader, ReplyOnce &reply) {
|
void MessageHandler::ccls_inheritance(JsonReader &reader, ReplyOnce &reply) {
|
||||||
Param param;
|
Param param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
Inheritance(this, param, reply);
|
Inheritance(this, param, reply);
|
||||||
|
@ -30,8 +30,8 @@ struct Param : TextDocumentPositionParam {
|
|||||||
bool hierarchy = false;
|
bool hierarchy = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
MAKE_REFLECT_STRUCT(Param, textDocument, position, id, qualified, levels, kind,
|
REFLECT_STRUCT(Param, textDocument, position, id, qualified, levels, kind,
|
||||||
hierarchy);
|
hierarchy);
|
||||||
|
|
||||||
struct Out_cclsMember {
|
struct Out_cclsMember {
|
||||||
Usr usr;
|
Usr usr;
|
||||||
@ -45,8 +45,8 @@ struct Out_cclsMember {
|
|||||||
// Empty if the |levels| limit is reached.
|
// Empty if the |levels| limit is reached.
|
||||||
std::vector<Out_cclsMember> children;
|
std::vector<Out_cclsMember> children;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren,
|
REFLECT_STRUCT(Out_cclsMember, id, name, fieldName, location, numChildren,
|
||||||
children);
|
children);
|
||||||
|
|
||||||
bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
|
bool Expand(MessageHandler *m, Out_cclsMember *entry, bool qualified,
|
||||||
int levels, Kind memberKind);
|
int levels, Kind memberKind);
|
||||||
@ -251,7 +251,7 @@ std::optional<Out_cclsMember> BuildInitial(MessageHandler *m, Kind kind,
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_member(Reader &reader, ReplyOnce &reply) {
|
void MessageHandler::ccls_member(JsonReader &reader, ReplyOnce &reply) {
|
||||||
Param param;
|
Param param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
std::optional<Out_cclsMember> result;
|
std::optional<Out_cclsMember> result;
|
||||||
|
@ -23,7 +23,7 @@ struct Param {
|
|||||||
Position position;
|
Position position;
|
||||||
std::string direction;
|
std::string direction;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Param, textDocument, position, direction);
|
REFLECT_STRUCT(Param, textDocument, position, direction);
|
||||||
|
|
||||||
Maybe<Range> FindParent(QueryFile *file, Pos pos) {
|
Maybe<Range> FindParent(QueryFile *file, Pos pos) {
|
||||||
Maybe<Range> parent;
|
Maybe<Range> parent;
|
||||||
@ -38,8 +38,7 @@ Maybe<Range> FindParent(QueryFile *file, Pos pos) {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_navigate(Reader &reader,
|
void MessageHandler::ccls_navigate(JsonReader &reader, ReplyOnce &reply) {
|
||||||
ReplyOnce &reply) {
|
|
||||||
Param param;
|
Param param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
|
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
|
||||||
|
@ -17,10 +17,10 @@ struct Param {
|
|||||||
std::vector<std::string> whitelist;
|
std::vector<std::string> whitelist;
|
||||||
std::vector<std::string> blacklist;
|
std::vector<std::string> blacklist;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Param, dependencies, whitelist, blacklist);
|
REFLECT_STRUCT(Param, dependencies, whitelist, blacklist);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_reload(Reader &reader) {
|
void MessageHandler::ccls_reload(JsonReader &reader) {
|
||||||
Param param;
|
Param param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
// Send index requests for every file.
|
// Send index requests for every file.
|
||||||
|
@ -13,10 +13,10 @@ struct Param : TextDocumentPositionParam {
|
|||||||
// 4: parameter
|
// 4: parameter
|
||||||
unsigned kind = ~0u;
|
unsigned kind = ~0u;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Param, textDocument, position, kind);
|
REFLECT_STRUCT(Param, textDocument, position, kind);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::ccls_vars(Reader &reader, ReplyOnce &reply) {
|
void MessageHandler::ccls_vars(JsonReader &reader, ReplyOnce &reply) {
|
||||||
Param param;
|
Param param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
|
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
|
||||||
|
@ -9,12 +9,14 @@
|
|||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
#include "working_files.hh"
|
#include "working_files.hh"
|
||||||
|
|
||||||
#include <llvm/ADT/Twine.h>
|
#include <llvm/ADT/Twine.h>
|
||||||
#include <llvm/Support/Threading.h>
|
#include <llvm/Support/Threading.h>
|
||||||
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/writer.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -27,7 +29,7 @@ extern std::string g_init_options;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 };
|
enum class TextDocumentSyncKind { None = 0, Full = 1, Incremental = 2 };
|
||||||
MAKE_REFLECT_TYPE_PROXY(TextDocumentSyncKind)
|
REFLECT_UNDERLYING(TextDocumentSyncKind)
|
||||||
|
|
||||||
struct ServerCap {
|
struct ServerCap {
|
||||||
struct SaveOptions {
|
struct SaveOptions {
|
||||||
@ -92,37 +94,36 @@ struct ServerCap {
|
|||||||
} workspaceFolders;
|
} workspaceFolders;
|
||||||
} workspace;
|
} workspace;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::CodeActionOptions, codeActionKinds);
|
REFLECT_STRUCT(ServerCap::CodeActionOptions, codeActionKinds);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider);
|
REFLECT_STRUCT(ServerCap::CodeLensOptions, resolveProvider);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider,
|
REFLECT_STRUCT(ServerCap::CompletionOptions, resolveProvider,
|
||||||
triggerCharacters);
|
triggerCharacters);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider);
|
REFLECT_STRUCT(ServerCap::DocumentLinkOptions, resolveProvider);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions,
|
REFLECT_STRUCT(ServerCap::DocumentOnTypeFormattingOptions,
|
||||||
firstTriggerCharacter, moreTriggerCharacter);
|
firstTriggerCharacter, moreTriggerCharacter);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands);
|
REFLECT_STRUCT(ServerCap::ExecuteCommandOptions, commands);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::SaveOptions, includeText);
|
REFLECT_STRUCT(ServerCap::SaveOptions, includeText);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters);
|
REFLECT_STRUCT(ServerCap::SignatureHelpOptions, triggerCharacters);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change,
|
REFLECT_STRUCT(ServerCap::TextDocumentSyncOptions, openClose, change, willSave,
|
||||||
willSave, willSaveWaitUntil, save);
|
willSaveWaitUntil, save);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported,
|
REFLECT_STRUCT(ServerCap::Workspace::WorkspaceFolders, supported,
|
||||||
changeNotifications);
|
changeNotifications);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders);
|
REFLECT_STRUCT(ServerCap::Workspace, workspaceFolders);
|
||||||
MAKE_REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider,
|
REFLECT_STRUCT(ServerCap, textDocumentSync, hoverProvider, completionProvider,
|
||||||
completionProvider, signatureHelpProvider,
|
signatureHelpProvider, definitionProvider,
|
||||||
definitionProvider, implementationProvider,
|
implementationProvider, typeDefinitionProvider,
|
||||||
typeDefinitionProvider, referencesProvider,
|
referencesProvider, documentHighlightProvider,
|
||||||
documentHighlightProvider, documentSymbolProvider,
|
documentSymbolProvider, workspaceSymbolProvider,
|
||||||
workspaceSymbolProvider, codeActionProvider,
|
codeActionProvider, codeLensProvider, documentFormattingProvider,
|
||||||
codeLensProvider, documentFormattingProvider,
|
documentRangeFormattingProvider,
|
||||||
documentRangeFormattingProvider,
|
documentOnTypeFormattingProvider, renameProvider,
|
||||||
documentOnTypeFormattingProvider, renameProvider,
|
documentLinkProvider, foldingRangeProvider,
|
||||||
documentLinkProvider, foldingRangeProvider,
|
executeCommandProvider, workspace);
|
||||||
executeCommandProvider, workspace);
|
|
||||||
|
|
||||||
struct DynamicReg {
|
struct DynamicReg {
|
||||||
bool dynamicRegistration = false;
|
bool dynamicRegistration = false;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(DynamicReg, dynamicRegistration);
|
REFLECT_STRUCT(DynamicReg, dynamicRegistration);
|
||||||
|
|
||||||
// Workspace specific client capabilities.
|
// Workspace specific client capabilities.
|
||||||
struct WorkspaceClientCap {
|
struct WorkspaceClientCap {
|
||||||
@ -142,10 +143,10 @@ struct WorkspaceClientCap {
|
|||||||
DynamicReg executeCommand;
|
DynamicReg executeCommand;
|
||||||
};
|
};
|
||||||
|
|
||||||
MAKE_REFLECT_STRUCT(WorkspaceClientCap::WorkspaceEdit, documentChanges);
|
REFLECT_STRUCT(WorkspaceClientCap::WorkspaceEdit, documentChanges);
|
||||||
MAKE_REFLECT_STRUCT(WorkspaceClientCap, applyEdit, workspaceEdit,
|
REFLECT_STRUCT(WorkspaceClientCap, applyEdit, workspaceEdit,
|
||||||
didChangeConfiguration, didChangeWatchedFiles, symbol,
|
didChangeConfiguration, didChangeWatchedFiles, symbol,
|
||||||
executeCommand);
|
executeCommand);
|
||||||
|
|
||||||
// Text document specific client capabilities.
|
// Text document specific client capabilities.
|
||||||
struct TextDocumentClientCap {
|
struct TextDocumentClientCap {
|
||||||
@ -166,18 +167,18 @@ struct TextDocumentClientCap {
|
|||||||
} documentSymbol;
|
} documentSymbol;
|
||||||
};
|
};
|
||||||
|
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
|
REFLECT_STRUCT(TextDocumentClientCap::Completion::CompletionItem,
|
||||||
snippetSupport);
|
snippetSupport);
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem);
|
REFLECT_STRUCT(TextDocumentClientCap::Completion, completionItem);
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
|
REFLECT_STRUCT(TextDocumentClientCap::DocumentSymbol,
|
||||||
hierarchicalDocumentSymbolSupport);
|
hierarchicalDocumentSymbolSupport);
|
||||||
MAKE_REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol);
|
REFLECT_STRUCT(TextDocumentClientCap, completion, documentSymbol);
|
||||||
|
|
||||||
struct ClientCap {
|
struct ClientCap {
|
||||||
WorkspaceClientCap workspace;
|
WorkspaceClientCap workspace;
|
||||||
TextDocumentClientCap textDocument;
|
TextDocumentClientCap textDocument;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(ClientCap, workspace, textDocument);
|
REFLECT_STRUCT(ClientCap, workspace, textDocument);
|
||||||
|
|
||||||
struct InitializeParam {
|
struct InitializeParam {
|
||||||
// The rootUri of the workspace. Is null if no
|
// The rootUri of the workspace. Is null if no
|
||||||
@ -199,12 +200,12 @@ struct InitializeParam {
|
|||||||
std::vector<WorkspaceFolder> workspaceFolders;
|
std::vector<WorkspaceFolder> workspaceFolders;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Reflect(Reader &reader, InitializeParam::Trace &value) {
|
void Reflect(JsonReader &reader, InitializeParam::Trace &value) {
|
||||||
if (!reader.IsString()) {
|
if (!reader.m->IsString()) {
|
||||||
value = InitializeParam::Trace::Off;
|
value = InitializeParam::Trace::Off;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string v = reader.GetString();
|
std::string v = reader.m->GetString();
|
||||||
if (v == "off")
|
if (v == "off")
|
||||||
value = InitializeParam::Trace::Off;
|
value = InitializeParam::Trace::Off;
|
||||||
else if (v == "messages")
|
else if (v == "messages")
|
||||||
@ -213,13 +214,13 @@ void Reflect(Reader &reader, InitializeParam::Trace &value) {
|
|||||||
value = InitializeParam::Trace::Verbose;
|
value = InitializeParam::Trace::Verbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
MAKE_REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions,
|
REFLECT_STRUCT(InitializeParam, rootUri, initializationOptions, capabilities,
|
||||||
capabilities, trace, workspaceFolders);
|
trace, workspaceFolders);
|
||||||
|
|
||||||
struct InitializeResult {
|
struct InitializeResult {
|
||||||
ServerCap capabilities;
|
ServerCap capabilities;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(InitializeResult, capabilities);
|
REFLECT_STRUCT(InitializeResult, capabilities);
|
||||||
|
|
||||||
void *Indexer(void *arg_) {
|
void *Indexer(void *arg_) {
|
||||||
MessageHandler *h;
|
MessageHandler *h;
|
||||||
@ -329,7 +330,7 @@ void Initialize(MessageHandler *m, InitializeParam ¶m, ReplyOnce &reply) {
|
|||||||
m->manager->sessions.SetCapacity(g_config->session.maxNum);
|
m->manager->sessions.SetCapacity(g_config->session.maxNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageHandler::initialize(Reader &reader, ReplyOnce &reply) {
|
void MessageHandler::initialize(JsonReader &reader, ReplyOnce &reply) {
|
||||||
InitializeParam param;
|
InitializeParam param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
if (!param.rootUri) {
|
if (!param.rootUri) {
|
||||||
|
@ -16,10 +16,12 @@ limitations under the License.
|
|||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "query.hh"
|
#include "query.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
|
|
||||||
#include <llvm/Support/FormatVariadic.h>
|
#include <llvm/Support/FormatVariadic.h>
|
||||||
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/writer.h>
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
@ -29,7 +31,7 @@ struct CodeAction {
|
|||||||
const char *kind = "quickfix";
|
const char *kind = "quickfix";
|
||||||
WorkspaceEdit edit;
|
WorkspaceEdit edit;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(CodeAction, title, kind, edit);
|
REFLECT_STRUCT(CodeAction, title, kind, edit);
|
||||||
}
|
}
|
||||||
void MessageHandler::textDocument_codeAction(CodeActionParam ¶m,
|
void MessageHandler::textDocument_codeAction(CodeActionParam ¶m,
|
||||||
ReplyOnce &reply) {
|
ReplyOnce &reply) {
|
||||||
@ -72,9 +74,9 @@ struct CodeLens {
|
|||||||
lsRange range;
|
lsRange range;
|
||||||
std::optional<Command> command;
|
std::optional<Command> command;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Cmd_xref, usr, kind, field);
|
REFLECT_STRUCT(Cmd_xref, usr, kind, field);
|
||||||
MAKE_REFLECT_STRUCT(Command, title, command, arguments);
|
REFLECT_STRUCT(Command, title, command, arguments);
|
||||||
MAKE_REFLECT_STRUCT(CodeLens, range, command);
|
REFLECT_STRUCT(CodeLens, range, command);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string ToString(T &v) {
|
std::string ToString(T &v) {
|
||||||
@ -174,7 +176,7 @@ void MessageHandler::textDocument_codeLens(TextDocumentParam ¶m,
|
|||||||
reply(result);
|
reply(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageHandler::workspace_executeCommand(Reader &reader,
|
void MessageHandler::workspace_executeCommand(JsonReader &reader,
|
||||||
ReplyOnce &reply) {
|
ReplyOnce &reply) {
|
||||||
Command param;
|
Command param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
|
@ -20,11 +20,11 @@ namespace ccls {
|
|||||||
using namespace clang;
|
using namespace clang;
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
MAKE_REFLECT_TYPE_PROXY(InsertTextFormat);
|
REFLECT_UNDERLYING(InsertTextFormat);
|
||||||
MAKE_REFLECT_TYPE_PROXY(CompletionItemKind);
|
REFLECT_UNDERLYING(CompletionItemKind);
|
||||||
|
|
||||||
void Reflect(Writer &vis, CompletionItem &v) {
|
void Reflect(JsonWriter &vis, CompletionItem &v) {
|
||||||
REFLECT_MEMBER_START();
|
ReflectMemberStart(vis);
|
||||||
REFLECT_MEMBER(label);
|
REFLECT_MEMBER(label);
|
||||||
REFLECT_MEMBER(kind);
|
REFLECT_MEMBER(kind);
|
||||||
REFLECT_MEMBER(detail);
|
REFLECT_MEMBER(detail);
|
||||||
@ -37,7 +37,7 @@ void Reflect(Writer &vis, CompletionItem &v) {
|
|||||||
REFLECT_MEMBER(textEdit);
|
REFLECT_MEMBER(textEdit);
|
||||||
if (v.additionalTextEdits.size())
|
if (v.additionalTextEdits.size())
|
||||||
REFLECT_MEMBER(additionalTextEdits);
|
REFLECT_MEMBER(additionalTextEdits);
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -45,7 +45,7 @@ struct CompletionList {
|
|||||||
bool isIncomplete = false;
|
bool isIncomplete = false;
|
||||||
std::vector<CompletionItem> items;
|
std::vector<CompletionItem> items;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(CompletionList, isIncomplete, items);
|
REFLECT_STRUCT(CompletionList, isIncomplete, items);
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR < 8
|
#if LLVM_VERSION_MAJOR < 8
|
||||||
void DecorateIncludePaths(const std::smatch &match,
|
void DecorateIncludePaths(const std::smatch &match,
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind);
|
MAKE_HASHABLE(ccls::SymbolIdx, t.usr, t.kind);
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName);
|
REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct DocumentHighlight {
|
struct DocumentHighlight {
|
||||||
@ -26,7 +26,7 @@ struct DocumentHighlight {
|
|||||||
return !(range == o.range) ? range < o.range : kind < o.kind;
|
return !(range == o.range) ? range < o.range : kind < o.kind;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(DocumentHighlight, range, kind, role);
|
REFLECT_STRUCT(DocumentHighlight, range, kind, role);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::textDocument_documentHighlight(
|
void MessageHandler::textDocument_documentHighlight(
|
||||||
@ -73,7 +73,7 @@ struct DocumentLink {
|
|||||||
lsRange range;
|
lsRange range;
|
||||||
DocumentUri target;
|
DocumentUri target;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(DocumentLink, range, target);
|
REFLECT_STRUCT(DocumentLink, range, target);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m,
|
void MessageHandler::textDocument_documentLink(TextDocumentParam ¶m,
|
||||||
@ -106,7 +106,7 @@ struct DocumentSymbolParam : TextDocumentParam {
|
|||||||
int startLine = -1;
|
int startLine = -1;
|
||||||
int endLine = -1;
|
int endLine = -1;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine);
|
REFLECT_STRUCT(DocumentSymbolParam, textDocument, all, startLine, endLine);
|
||||||
|
|
||||||
struct DocumentSymbol {
|
struct DocumentSymbol {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -116,10 +116,10 @@ struct DocumentSymbol {
|
|||||||
lsRange selectionRange;
|
lsRange selectionRange;
|
||||||
std::vector<std::unique_ptr<DocumentSymbol>> children;
|
std::vector<std::unique_ptr<DocumentSymbol>> children;
|
||||||
};
|
};
|
||||||
void Reflect(Writer &vis, std::unique_ptr<DocumentSymbol> &v);
|
void Reflect(JsonWriter &vis, std::unique_ptr<DocumentSymbol> &v);
|
||||||
MAKE_REFLECT_STRUCT(DocumentSymbol, name, detail, kind, range, selectionRange,
|
REFLECT_STRUCT(DocumentSymbol, name, detail, kind, range, selectionRange,
|
||||||
children);
|
children);
|
||||||
void Reflect(Writer &vis, std::unique_ptr<DocumentSymbol> &v) {
|
void Reflect(JsonWriter &vis, std::unique_ptr<DocumentSymbol> &v) {
|
||||||
Reflect(vis, *v);
|
Reflect(vis, *v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ void Uniquify(std::vector<std::unique_ptr<DocumentSymbol>> &cs) {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::textDocument_documentSymbol(Reader &reader,
|
void MessageHandler::textDocument_documentSymbol(JsonReader &reader,
|
||||||
ReplyOnce &reply) {
|
ReplyOnce &reply) {
|
||||||
DocumentSymbolParam param;
|
DocumentSymbolParam param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
|
@ -25,8 +25,8 @@ struct FoldingRange {
|
|||||||
int startLine, startCharacter, endLine, endCharacter;
|
int startLine, startCharacter, endLine, endCharacter;
|
||||||
std::string kind = "region";
|
std::string kind = "region";
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine,
|
REFLECT_STRUCT(FoldingRange, startLine, startCharacter, endLine, endCharacter,
|
||||||
endCharacter, kind);
|
kind);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m,
|
void MessageHandler::textDocument_foldingRange(TextDocumentParam ¶m,
|
||||||
|
@ -15,19 +15,19 @@ struct Hover {
|
|||||||
std::optional<lsRange> range;
|
std::optional<lsRange> range;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Reflect(Writer &vis, MarkedString &v) {
|
void Reflect(JsonWriter &vis, MarkedString &v) {
|
||||||
// If there is a language, emit a `{language:string, value:string}` object. If
|
// If there is a language, emit a `{language:string, value:string}` object. If
|
||||||
// not, emit a string.
|
// not, emit a string.
|
||||||
if (v.language) {
|
if (v.language) {
|
||||||
REFLECT_MEMBER_START();
|
vis.StartObject();
|
||||||
REFLECT_MEMBER(language);
|
REFLECT_MEMBER(language);
|
||||||
REFLECT_MEMBER(value);
|
REFLECT_MEMBER(value);
|
||||||
REFLECT_MEMBER_END();
|
vis.EndObject();
|
||||||
} else {
|
} else {
|
||||||
Reflect(vis, v.value);
|
Reflect(vis, v.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MAKE_REFLECT_STRUCT(Hover, contents, range);
|
REFLECT_STRUCT(Hover, contents, range);
|
||||||
|
|
||||||
const char *LanguageIdentifier(LanguageId lang) {
|
const char *LanguageIdentifier(LanguageId lang) {
|
||||||
switch (lang) {
|
switch (lang) {
|
||||||
|
@ -24,12 +24,13 @@ struct ReferenceParam : public TextDocumentPositionParam {
|
|||||||
// Include references with all |Role| bits set.
|
// Include references with all |Role| bits set.
|
||||||
Role role = Role::None;
|
Role role = Role::None;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(ReferenceParam::Context, includeDeclaration);
|
REFLECT_STRUCT(ReferenceParam::Context, includeDeclaration);
|
||||||
MAKE_REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders,
|
REFLECT_STRUCT(ReferenceParam, textDocument, position, context, folders, base,
|
||||||
base, excludeRole, role);
|
excludeRole, role);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void MessageHandler::textDocument_references(Reader &reader, ReplyOnce &reply) {
|
void MessageHandler::textDocument_references(JsonReader &reader,
|
||||||
|
ReplyOnce &reply) {
|
||||||
ReferenceParam param;
|
ReferenceParam param;
|
||||||
Reflect(reader, param);
|
Reflect(reader, param);
|
||||||
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
|
QueryFile *file = FindFile(param.textDocument.uri.GetPath());
|
||||||
|
@ -24,10 +24,9 @@ struct SignatureHelp {
|
|||||||
int activeSignature = 0;
|
int activeSignature = 0;
|
||||||
int activeParameter = 0;
|
int activeParameter = 0;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(ParameterInformation, label);
|
REFLECT_STRUCT(ParameterInformation, label);
|
||||||
MAKE_REFLECT_STRUCT(SignatureInformation, label, documentation, parameters);
|
REFLECT_STRUCT(SignatureInformation, label, documentation, parameters);
|
||||||
MAKE_REFLECT_STRUCT(SignatureHelp, signatures, activeSignature,
|
REFLECT_STRUCT(SignatureHelp, signatures, activeSignature, activeParameter);
|
||||||
activeParameter);
|
|
||||||
|
|
||||||
std::string BuildOptional(const CodeCompletionString &CCS,
|
std::string BuildOptional(const CodeCompletionString &CCS,
|
||||||
std::vector<ParameterInformation> &ls_params) {
|
std::vector<ParameterInformation> &ls_params) {
|
||||||
|
@ -30,7 +30,7 @@ limitations under the License.
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
MAKE_REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName);
|
REFLECT_STRUCT(SymbolInformation, name, kind, location, containerName);
|
||||||
|
|
||||||
void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) {
|
void MessageHandler::workspace_didChangeConfiguration(EmptyParam &) {
|
||||||
for (const std::string &folder : g_config->workspaceFolders)
|
for (const std::string &folder : g_config->workspaceFolders)
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "project.hh"
|
#include "project.hh"
|
||||||
#include "query.hh"
|
#include "query.hh"
|
||||||
#include "sema_manager.hh"
|
#include "sema_manager.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
|
|
||||||
#include <rapidjson/document.h>
|
#include <rapidjson/document.h>
|
||||||
#include <rapidjson/writer.h>
|
#include <rapidjson/writer.h>
|
||||||
@ -37,7 +36,7 @@ struct PublishDiagnosticParam {
|
|||||||
DocumentUri uri;
|
DocumentUri uri;
|
||||||
std::vector<Diagnostic> diagnostics;
|
std::vector<Diagnostic> diagnostics;
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics);
|
REFLECT_STRUCT(PublishDiagnosticParam, uri, diagnostics);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void VFS::Clear() {
|
void VFS::Clear() {
|
||||||
@ -445,8 +444,8 @@ void LaunchStdin() {
|
|||||||
assert(!document->HasParseError());
|
assert(!document->HasParseError());
|
||||||
|
|
||||||
JsonReader reader{document.get()};
|
JsonReader reader{document.get()};
|
||||||
if (!reader.HasMember("jsonrpc") ||
|
if (!reader.m->HasMember("jsonrpc") ||
|
||||||
std::string(reader["jsonrpc"]->GetString()) != "2.0")
|
std::string((*reader.m)["jsonrpc"].GetString()) != "2.0")
|
||||||
return;
|
return;
|
||||||
RequestId id;
|
RequestId id;
|
||||||
std::string method;
|
std::string method;
|
||||||
@ -598,7 +597,7 @@ std::optional<std::string> LoadIndexedContent(const std::string &path) {
|
|||||||
return ReadContent(GetCachePath(path));
|
return ReadContent(GetCachePath(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notify(const char *method, const std::function<void(Writer &)> &fn) {
|
void Notify(const char *method, const std::function<void(JsonWriter &)> &fn) {
|
||||||
rapidjson::StringBuffer output;
|
rapidjson::StringBuffer output;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> w(output);
|
rapidjson::Writer<rapidjson::StringBuffer> w(output);
|
||||||
w.StartObject();
|
w.StartObject();
|
||||||
@ -614,7 +613,7 @@ void Notify(const char *method, const std::function<void(Writer &)> &fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Reply(RequestId id, const char *key,
|
static void Reply(RequestId id, const char *key,
|
||||||
const std::function<void(Writer &)> &fn) {
|
const std::function<void(JsonWriter &)> &fn) {
|
||||||
rapidjson::StringBuffer output;
|
rapidjson::StringBuffer output;
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> w(output);
|
rapidjson::Writer<rapidjson::StringBuffer> w(output);
|
||||||
w.StartObject();
|
w.StartObject();
|
||||||
@ -640,11 +639,11 @@ static void Reply(RequestId id, const char *key,
|
|||||||
for_stdout->PushBack(output.GetString());
|
for_stdout->PushBack(output.GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reply(RequestId id, const std::function<void(Writer &)> &fn) {
|
void Reply(RequestId id, const std::function<void(JsonWriter &)> &fn) {
|
||||||
Reply(id, "result", fn);
|
Reply(id, "result", fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn) {
|
void ReplyError(RequestId id, const std::function<void(JsonWriter &)> &fn) {
|
||||||
Reply(id, "error", fn);
|
Reply(id, "error", fn);
|
||||||
}
|
}
|
||||||
} // namespace pipeline
|
} // namespace pipeline
|
||||||
|
@ -54,16 +54,16 @@ void Index(const std::string &path, const std::vector<const char *> &args,
|
|||||||
|
|
||||||
std::optional<std::string> LoadIndexedContent(const std::string& path);
|
std::optional<std::string> LoadIndexedContent(const std::string& path);
|
||||||
|
|
||||||
void Notify(const char *method, const std::function<void(Writer &)> &fn);
|
void Notify(const char *method, const std::function<void(JsonWriter &)> &fn);
|
||||||
template <typename T> void Notify(const char *method, T &result) {
|
template <typename T> void Notify(const char *method, T &result) {
|
||||||
Notify(method, [&](Writer &w) { Reflect(w, result); });
|
Notify(method, [&](JsonWriter &w) { Reflect(w, result); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reply(RequestId id, const std::function<void(Writer &)> &fn);
|
void Reply(RequestId id, const std::function<void(JsonWriter &)> &fn);
|
||||||
|
|
||||||
void ReplyError(RequestId id, const std::function<void(Writer &)> &fn);
|
void ReplyError(RequestId id, const std::function<void(JsonWriter &)> &fn);
|
||||||
template <typename T> void ReplyError(RequestId id, T &result) {
|
template <typename T> void ReplyError(RequestId id, T &result) {
|
||||||
ReplyError(id, [&](Writer &w) { Reflect(w, result); });
|
ReplyError(id, [&](JsonWriter &w) { Reflect(w, result); });
|
||||||
}
|
}
|
||||||
} // namespace pipeline
|
} // namespace pipeline
|
||||||
} // namespace ccls
|
} // namespace ccls
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
|
|
||||||
#include "serializer.hh"
|
#include "serializer.hh"
|
||||||
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/writer.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -57,45 +60,39 @@ std::string Range::ToString() {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position
|
void Reflect(JsonReader &vis, Pos &v) { v = Pos::FromString(vis.GetString()); }
|
||||||
void Reflect(Reader &visitor, Pos &value) {
|
void Reflect(JsonReader &vis, Range &v) {
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
v = Range::FromString(vis.GetString());
|
||||||
value = Pos::FromString(visitor.GetString());
|
|
||||||
} else {
|
|
||||||
Reflect(visitor, value.line);
|
|
||||||
Reflect(visitor, value.column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Reflect(Writer &visitor, Pos &value) {
|
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
|
||||||
std::string output = value.ToString();
|
|
||||||
visitor.String(output.c_str(), output.size());
|
|
||||||
} else {
|
|
||||||
Reflect(visitor, value.line);
|
|
||||||
Reflect(visitor, value.column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Range
|
void Reflect(JsonWriter &vis, Pos &v) {
|
||||||
void Reflect(Reader &visitor, Range &value) {
|
std::string output = v.ToString();
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
vis.String(output.c_str(), output.size());
|
||||||
value = Range::FromString(visitor.GetString());
|
|
||||||
} else {
|
|
||||||
Reflect(visitor, value.start.line);
|
|
||||||
Reflect(visitor, value.start.column);
|
|
||||||
Reflect(visitor, value.end.line);
|
|
||||||
Reflect(visitor, value.end.column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void Reflect(Writer &visitor, Range &value) {
|
void Reflect(JsonWriter &vis, Range &v) {
|
||||||
if (visitor.Format() == SerializeFormat::Json) {
|
std::string output = v.ToString();
|
||||||
std::string output = value.ToString();
|
vis.String(output.c_str(), output.size());
|
||||||
visitor.String(output.c_str(), output.size());
|
}
|
||||||
} else {
|
|
||||||
Reflect(visitor, value.start.line);
|
void Reflect(BinaryReader &visitor, Pos &value) {
|
||||||
Reflect(visitor, value.start.column);
|
Reflect(visitor, value.line);
|
||||||
Reflect(visitor, value.end.line);
|
Reflect(visitor, value.column);
|
||||||
Reflect(visitor, value.end.column);
|
}
|
||||||
}
|
void Reflect(BinaryReader &visitor, Range &value) {
|
||||||
|
Reflect(visitor, value.start.line);
|
||||||
|
Reflect(visitor, value.start.column);
|
||||||
|
Reflect(visitor, value.end.line);
|
||||||
|
Reflect(visitor, value.end.column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reflect(BinaryWriter &vis, Pos &v) {
|
||||||
|
Reflect(vis, v.line);
|
||||||
|
Reflect(vis, v.column);
|
||||||
|
}
|
||||||
|
void Reflect(BinaryWriter &vis, Range &v) {
|
||||||
|
Reflect(vis, v.start.line);
|
||||||
|
Reflect(vis, v.start.column);
|
||||||
|
Reflect(vis, v.end.line);
|
||||||
|
Reflect(vis, v.end.column);
|
||||||
}
|
}
|
||||||
} // namespace ccls
|
} // namespace ccls
|
||||||
|
@ -51,12 +51,19 @@ struct Range {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Reflection
|
// Reflection
|
||||||
class Reader;
|
struct JsonReader;
|
||||||
class Writer;
|
struct JsonWriter;
|
||||||
void Reflect(Reader &visitor, Pos &value);
|
struct BinaryReader;
|
||||||
void Reflect(Writer &visitor, Pos &value);
|
struct BinaryWriter;
|
||||||
void Reflect(Reader &visitor, Range &value);
|
|
||||||
void Reflect(Writer &visitor, Range &value);
|
void Reflect(JsonReader &visitor, Pos &value);
|
||||||
|
void Reflect(JsonReader &visitor, Range &value);
|
||||||
|
void Reflect(JsonWriter &visitor, Pos &value);
|
||||||
|
void Reflect(JsonWriter &visitor, Range &value);
|
||||||
|
void Reflect(BinaryReader &visitor, Pos &value);
|
||||||
|
void Reflect(BinaryReader &visitor, Range &value);
|
||||||
|
void Reflect(BinaryWriter &visitor, Pos &value);
|
||||||
|
void Reflect(BinaryWriter &visitor, Range &value);
|
||||||
} // namespace ccls
|
} // namespace ccls
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.hh"
|
#include "platform.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
#include "working_files.hh"
|
#include "working_files.hh"
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
#include "indexer.hh"
|
#include "indexer.hh"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "serializer.hh"
|
#include "serializer.hh"
|
||||||
#include "serializers/json.hh"
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
#include "indexer.hh"
|
#include "indexer.hh"
|
||||||
#include "log.hh"
|
#include "log.hh"
|
||||||
#include "message_handler.hh"
|
#include "message_handler.hh"
|
||||||
#include "serializers/binary.hh"
|
|
||||||
#include "serializers/json.hh"
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/prettywriter.h>
|
||||||
|
|
||||||
#include <llvm/ADT/CachedHashString.h>
|
#include <llvm/ADT/CachedHashString.h>
|
||||||
#include <llvm/ADT/DenseSet.h>
|
#include <llvm/ADT/DenseSet.h>
|
||||||
@ -21,181 +22,198 @@ using namespace llvm;
|
|||||||
bool gTestOutputMode = false;
|
bool gTestOutputMode = false;
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
Reader::~Reader() {}
|
|
||||||
BinaryReader::~BinaryReader() {}
|
|
||||||
JsonReader::~JsonReader() {}
|
|
||||||
|
|
||||||
Writer::~Writer() {}
|
void JsonReader::IterArray(std::function<void()> fn) {
|
||||||
BinaryWriter::~BinaryWriter() {}
|
if (!m->IsArray())
|
||||||
JsonWriter::~JsonWriter() {}
|
throw std::invalid_argument("array");
|
||||||
|
// Use "0" to indicate any element for now.
|
||||||
void Reflect(Reader &vis, uint8_t &v) { v = vis.GetUInt8(); }
|
path_.push_back("0");
|
||||||
void Reflect(Writer &vis, uint8_t &v) { vis.UInt8(v); }
|
for (auto &entry : m->GetArray()) {
|
||||||
|
auto saved = m;
|
||||||
void Reflect(Reader &vis, short &v) {
|
m = &entry;
|
||||||
if (!vis.IsInt())
|
fn();
|
||||||
throw std::invalid_argument("short");
|
m = saved;
|
||||||
v = (short)vis.GetInt();
|
}
|
||||||
|
path_.pop_back();
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, short &v) { vis.Int(v); }
|
void JsonReader::Member(const char *name, std::function<void()> fn) {
|
||||||
|
path_.push_back(name);
|
||||||
void Reflect(Reader &vis, unsigned short &v) {
|
auto it = m->FindMember(name);
|
||||||
if (!vis.IsInt())
|
if (it != m->MemberEnd()) {
|
||||||
throw std::invalid_argument("unsigned short");
|
auto saved = m;
|
||||||
v = (unsigned short)vis.GetInt();
|
m = &it->value;
|
||||||
|
fn();
|
||||||
|
m = saved;
|
||||||
|
}
|
||||||
|
path_.pop_back();
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, unsigned short &v) { vis.Int(v); }
|
bool JsonReader::IsNull() { return m->IsNull(); }
|
||||||
|
std::string JsonReader::GetString() { return m->GetString(); }
|
||||||
void Reflect(Reader &vis, int &v) {
|
std::string JsonReader::GetPath() const {
|
||||||
if (!vis.IsInt())
|
std::string ret;
|
||||||
throw std::invalid_argument("int");
|
for (auto &t : path_)
|
||||||
v = vis.GetInt();
|
if (t[0] == '0') {
|
||||||
}
|
ret += '[';
|
||||||
void Reflect(Writer &vis, int &v) { vis.Int(v); }
|
ret += t;
|
||||||
|
ret += ']';
|
||||||
void Reflect(Reader &vis, unsigned &v) {
|
} else {
|
||||||
if (!vis.IsUInt64())
|
ret += '/';
|
||||||
throw std::invalid_argument("unsigned");
|
ret += t;
|
||||||
v = vis.GetUInt32();
|
}
|
||||||
}
|
return ret;
|
||||||
void Reflect(Writer &vis, unsigned &v) { vis.UInt32(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, long &v) {
|
|
||||||
if (!vis.IsInt64())
|
|
||||||
throw std::invalid_argument("long");
|
|
||||||
v = long(vis.GetInt64());
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, long &v) { vis.Int64(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, unsigned long &v) {
|
|
||||||
if (!vis.IsUInt64())
|
|
||||||
throw std::invalid_argument("unsigned long");
|
|
||||||
v = (unsigned long)vis.GetUInt64();
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, unsigned long &v) { vis.UInt64(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, long long &v) {
|
|
||||||
if (!vis.IsInt64())
|
|
||||||
throw std::invalid_argument("long long");
|
|
||||||
v = vis.GetInt64();
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, long long &v) { vis.Int64(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, unsigned long long &v) {
|
|
||||||
if (!vis.IsUInt64())
|
|
||||||
throw std::invalid_argument("unsigned long long");
|
|
||||||
v = vis.GetUInt64();
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, unsigned long long &v) { vis.UInt64(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, double &v) {
|
|
||||||
if (!vis.IsDouble())
|
|
||||||
throw std::invalid_argument("double");
|
|
||||||
v = vis.GetDouble();
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, double &v) { vis.Double(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, bool &v) {
|
|
||||||
if (!vis.IsBool())
|
|
||||||
throw std::invalid_argument("bool");
|
|
||||||
v = vis.GetBool();
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, bool &v) { vis.Bool(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, std::string &v) {
|
|
||||||
if (!vis.IsString())
|
|
||||||
throw std::invalid_argument("std::string");
|
|
||||||
v = vis.GetString();
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, std::string &v) {
|
|
||||||
vis.String(v.c_str(), (rapidjson::SizeType)v.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader &, std::string_view &) { assert(0); }
|
void JsonWriter::StartArray() { m->StartArray(); }
|
||||||
void Reflect(Writer &vis, std::string_view &data) {
|
void JsonWriter::EndArray() { m->EndArray(); }
|
||||||
|
void JsonWriter::StartObject() { m->StartObject(); }
|
||||||
|
void JsonWriter::EndObject() { m->EndObject(); }
|
||||||
|
void JsonWriter::Key(const char *name) { m->Key(name); }
|
||||||
|
void JsonWriter::Null() { m->Null(); }
|
||||||
|
void JsonWriter::Int(int v) { m->Int(v); }
|
||||||
|
void JsonWriter::String(const char *s) { m->String(s); }
|
||||||
|
void JsonWriter::String(const char *s, size_t len) { m->String(s, len); }
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
void Reflect(JsonReader &vis, bool &v ) { if (!vis.m->IsBool()) throw std::invalid_argument("bool"); v = vis.m->GetBool(); }
|
||||||
|
void Reflect(JsonReader &vis, unsigned char &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("uint8_t"); v = (uint8_t)vis.m->GetInt(); }
|
||||||
|
void Reflect(JsonReader &vis, short &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("short"); v = (short)vis.m->GetInt(); }
|
||||||
|
void Reflect(JsonReader &vis, unsigned short &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("unsigned short"); v = (unsigned short)vis.m->GetInt(); }
|
||||||
|
void Reflect(JsonReader &vis, int &v ) { if (!vis.m->IsInt()) throw std::invalid_argument("int"); v = vis.m->GetInt(); }
|
||||||
|
void Reflect(JsonReader &vis, unsigned &v ) { if (!vis.m->IsUint64()) throw std::invalid_argument("unsigned"); v = (unsigned)vis.m->GetUint64(); }
|
||||||
|
void Reflect(JsonReader &vis, long &v ) { if (!vis.m->IsInt64()) throw std::invalid_argument("long"); v = (long)vis.m->GetInt64(); }
|
||||||
|
void Reflect(JsonReader &vis, unsigned long &v ) { if (!vis.m->IsUint64()) throw std::invalid_argument("unsigned long"); v = (unsigned long)vis.m->GetUint64(); }
|
||||||
|
void Reflect(JsonReader &vis, long long &v ) { if (!vis.m->IsInt64()) throw std::invalid_argument("long long"); v = vis.m->GetInt64(); }
|
||||||
|
void Reflect(JsonReader &vis, unsigned long long &v) { if (!vis.m->IsUint64()) throw std::invalid_argument("unsigned long long"); v = vis.m->GetUint64(); }
|
||||||
|
void Reflect(JsonReader &vis, double &v ) { if (!vis.m->IsDouble()) throw std::invalid_argument("double"); v = vis.m->GetDouble(); }
|
||||||
|
void Reflect(JsonReader &vis, const char *&v ) { if (!vis.m->IsString()) throw std::invalid_argument("string"); v = Intern(vis.GetString()); }
|
||||||
|
void Reflect(JsonReader &vis, std::string &v ) { if (!vis.m->IsString()) throw std::invalid_argument("string"); v = vis.GetString(); }
|
||||||
|
|
||||||
|
void Reflect(JsonWriter &vis, bool &v ) { vis.m->Bool(v); }
|
||||||
|
void Reflect(JsonWriter &vis, unsigned char &v ) { vis.m->Int(v); }
|
||||||
|
void Reflect(JsonWriter &vis, short &v ) { vis.m->Int(v); }
|
||||||
|
void Reflect(JsonWriter &vis, unsigned short &v ) { vis.m->Int(v); }
|
||||||
|
void Reflect(JsonWriter &vis, int &v ) { vis.m->Int(v); }
|
||||||
|
void Reflect(JsonWriter &vis, unsigned &v ) { vis.m->Uint64(v); }
|
||||||
|
void Reflect(JsonWriter &vis, long &v ) { vis.m->Int64(v); }
|
||||||
|
void Reflect(JsonWriter &vis, unsigned long &v ) { vis.m->Uint64(v); }
|
||||||
|
void Reflect(JsonWriter &vis, long long &v ) { vis.m->Int64(v); }
|
||||||
|
void Reflect(JsonWriter &vis, unsigned long long &v) { vis.m->Uint64(v); }
|
||||||
|
void Reflect(JsonWriter &vis, double &v ) { vis.m->Double(v); }
|
||||||
|
void Reflect(JsonWriter &vis, const char *&v ) { vis.String(v); }
|
||||||
|
void Reflect(JsonWriter &vis, std::string &v ) { vis.String(v.c_str(), v.size()); }
|
||||||
|
|
||||||
|
void Reflect(BinaryReader &vis, bool &v ) { v = vis.Get<bool>(); }
|
||||||
|
void Reflect(BinaryReader &vis, unsigned char &v ) { v = vis.Get<unsigned char>(); }
|
||||||
|
void Reflect(BinaryReader &vis, short &v ) { v = (short)vis.VarInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, unsigned short &v ) { v = (unsigned short)vis.VarUInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, int &v ) { v = (int)vis.VarInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, unsigned &v ) { v = (unsigned)vis.VarUInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, long &v ) { v = (long)vis.VarInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, unsigned long &v ) { v = (unsigned long)vis.VarUInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, long long &v ) { v = vis.VarInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, unsigned long long &v) { v = vis.VarUInt(); }
|
||||||
|
void Reflect(BinaryReader &vis, double &v ) { v = vis.Get<double>(); }
|
||||||
|
void Reflect(BinaryReader &vis, const char *&v ) { v = Intern(vis.GetString()); }
|
||||||
|
void Reflect(BinaryReader &vis, std::string &v ) { v = vis.GetString(); }
|
||||||
|
|
||||||
|
void Reflect(BinaryWriter &vis, bool &v ) { vis.Pack(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned char &v ) { vis.Pack(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, short &v ) { vis.VarInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned short &v ) { vis.VarUInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, int &v ) { vis.VarInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned &v ) { vis.VarUInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, long &v ) { vis.VarInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned long &v ) { vis.VarUInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, long long &v ) { vis.VarInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned long long &v) { vis.VarUInt(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, double &v ) { vis.Pack(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, const char *&v ) { vis.String(v); }
|
||||||
|
void Reflect(BinaryWriter &vis, std::string &v ) { vis.String(v.c_str(), v.size()); }
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
void Reflect(JsonWriter &vis, std::string_view &data) {
|
||||||
if (data.empty())
|
if (data.empty())
|
||||||
vis.String("");
|
vis.String("");
|
||||||
else
|
else
|
||||||
vis.String(&data[0], (rapidjson::SizeType)data.size());
|
vis.String(&data[0], (rapidjson::SizeType)data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader &vis, const char *&v) {
|
void Reflect(JsonReader &vis, JsonNull &v) {}
|
||||||
const char *str = vis.GetString();
|
void Reflect(JsonWriter &vis, JsonNull &v) { vis.m->Null(); }
|
||||||
v = Intern(str);
|
|
||||||
}
|
|
||||||
void Reflect(Writer &vis, const char *&v) { vis.String(v); }
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, JsonNull &v) {
|
|
||||||
assert(vis.Format() == SerializeFormat::Json);
|
|
||||||
vis.GetNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reflect(Writer &vis, JsonNull &v) { vis.Null(); }
|
|
||||||
|
|
||||||
// std::unordered_map
|
|
||||||
template <typename V>
|
template <typename V>
|
||||||
void Reflect(Reader &vis, std::unordered_map<Usr, V> &map) {
|
void Reflect(JsonReader &vis, std::unordered_map<Usr, V> &v) {
|
||||||
vis.IterArray([&](Reader &entry) {
|
vis.IterArray([&]() {
|
||||||
V val;
|
V val;
|
||||||
Reflect(entry, val);
|
Reflect(vis, val);
|
||||||
auto usr = val.usr;
|
v[val.usr] = std::move(val);
|
||||||
map[usr] = std::move(val);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
template <typename V>
|
template <typename V>
|
||||||
void Reflect(Writer &vis, std::unordered_map<Usr, V> &map) {
|
void Reflect(JsonWriter &vis, std::unordered_map<Usr, V> &v) {
|
||||||
std::vector<std::pair<uint64_t, V>> xs(map.begin(), map.end());
|
// Determinism
|
||||||
|
std::vector<std::pair<uint64_t, V>> xs(v.begin(), v.end());
|
||||||
std::sort(xs.begin(), xs.end(),
|
std::sort(xs.begin(), xs.end(),
|
||||||
[](const auto &a, const auto &b) { return a.first < b.first; });
|
[](const auto &a, const auto &b) { return a.first < b.first; });
|
||||||
vis.StartArray(xs.size());
|
vis.StartArray();
|
||||||
for (auto &it : xs)
|
for (auto &it : xs)
|
||||||
Reflect(vis, it.second);
|
Reflect(vis, it.second);
|
||||||
vis.EndArray();
|
vis.EndArray();
|
||||||
}
|
}
|
||||||
|
template <typename V>
|
||||||
|
void Reflect(BinaryReader &vis, std::unordered_map<Usr, V> &v) {
|
||||||
|
for (auto n = vis.VarUInt(); n; n--) {
|
||||||
|
V val;
|
||||||
|
Reflect(vis, val);
|
||||||
|
v[val.usr] = std::move(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename V>
|
||||||
|
void Reflect(BinaryWriter &vis, std::unordered_map<Usr, V> &v) {
|
||||||
|
vis.VarUInt(v.size());
|
||||||
|
for (auto &it : v)
|
||||||
|
Reflect(vis, it.second);
|
||||||
|
}
|
||||||
|
|
||||||
// Used by IndexFile::dependencies.
|
// Used by IndexFile::dependencies.
|
||||||
void Reflect(Reader &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
void Reflect(JsonReader &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
||||||
std::string name;
|
std::string name;
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
for (auto it = vis.m->MemberBegin(); it != vis.m->MemberEnd(); ++it)
|
||||||
auto &vis1 = static_cast<JsonReader&>(vis);
|
v[InternH(it->name.GetString())] = it->value.GetInt64();
|
||||||
for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it)
|
}
|
||||||
v[InternH(it->name.GetString())] = it->value.GetInt64();
|
void Reflect(JsonWriter &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
||||||
} else {
|
vis.StartObject();
|
||||||
vis.IterArray([&](Reader &entry) {
|
for (auto &it : v) {
|
||||||
Reflect(entry, name);
|
vis.m->Key(it.first.val().data()); // llvm 8 -> data()
|
||||||
Reflect(entry, v[InternH(name)]);
|
vis.m->Int64(it.second);
|
||||||
});
|
}
|
||||||
|
vis.EndObject();
|
||||||
|
}
|
||||||
|
void Reflect(BinaryReader &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
||||||
|
std::string name;
|
||||||
|
for (auto n = vis.VarUInt(); n; n--) {
|
||||||
|
Reflect(vis, name);
|
||||||
|
Reflect(vis, v[InternH(name)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
void Reflect(BinaryWriter &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
||||||
if (vis.Format() == SerializeFormat::Json) {
|
std::string key;
|
||||||
auto &vis1 = static_cast<JsonWriter&>(vis);
|
vis.VarUInt(v.size());
|
||||||
vis.StartObject();
|
for (auto &it : v) {
|
||||||
for (auto &it : v) {
|
key = it.first.val().str();
|
||||||
vis1.m().Key(it.first.val().data()); // llvm 8 -> data()
|
Reflect(vis, key);
|
||||||
vis1.m().Int64(it.second);
|
Reflect(vis, it.second);
|
||||||
}
|
|
||||||
vis.EndObject();
|
|
||||||
} else {
|
|
||||||
vis.StartArray(v.size());
|
|
||||||
for (auto &it : v) {
|
|
||||||
std::string key = it.first.val().str();
|
|
||||||
Reflect(vis, key);
|
|
||||||
Reflect(vis, it.second);
|
|
||||||
}
|
|
||||||
vis.EndArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this to indexer.cc
|
template <typename Vis> void Reflect(Vis &vis, IndexInclude &v) {
|
||||||
void Reflect(Reader &vis, IndexInclude &v) {
|
ReflectMemberStart(vis);
|
||||||
REFLECT_MEMBER_START();
|
|
||||||
REFLECT_MEMBER(line);
|
REFLECT_MEMBER(line);
|
||||||
REFLECT_MEMBER(resolved_path);
|
REFLECT_MEMBER(resolved_path);
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
void Reflect(Writer &vis, IndexInclude &v) {
|
void Reflect(JsonWriter &vis, IndexInclude &v) {
|
||||||
REFLECT_MEMBER_START();
|
ReflectMemberStart(vis);
|
||||||
REFLECT_MEMBER(line);
|
REFLECT_MEMBER(line);
|
||||||
if (gTestOutputMode) {
|
if (gTestOutputMode) {
|
||||||
std::string basename = llvm::sys::path::filename(v.resolved_path);
|
std::string basename = llvm::sys::path::filename(v.resolved_path);
|
||||||
@ -205,23 +223,34 @@ void Reflect(Writer &vis, IndexInclude &v) {
|
|||||||
} else {
|
} else {
|
||||||
REFLECT_MEMBER(resolved_path);
|
REFLECT_MEMBER(resolved_path);
|
||||||
}
|
}
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Def> void ReflectHoverAndComments(Reader &vis, Def &def) {
|
template <typename Def>
|
||||||
|
void ReflectHoverAndComments(JsonReader &vis, Def &def) {
|
||||||
ReflectMember(vis, "hover", def.hover);
|
ReflectMember(vis, "hover", def.hover);
|
||||||
ReflectMember(vis, "comments", def.comments);
|
ReflectMember(vis, "comments", def.comments);
|
||||||
}
|
}
|
||||||
|
template <typename Def>
|
||||||
template <typename Def> void ReflectHoverAndComments(Writer &vis, Def &def) {
|
void ReflectHoverAndComments(JsonWriter &vis, Def &def) {
|
||||||
// Don't emit empty hover and comments in JSON test mode.
|
// Don't emit empty hover and comments in JSON test mode.
|
||||||
if (!gTestOutputMode || def.hover[0])
|
if (!gTestOutputMode || def.hover[0])
|
||||||
ReflectMember(vis, "hover", def.hover);
|
ReflectMember(vis, "hover", def.hover);
|
||||||
if (!gTestOutputMode || def.comments[0])
|
if (!gTestOutputMode || def.comments[0])
|
||||||
ReflectMember(vis, "comments", def.comments);
|
ReflectMember(vis, "comments", def.comments);
|
||||||
}
|
}
|
||||||
|
template <typename Def>
|
||||||
|
void ReflectHoverAndComments(BinaryReader &vis, Def &def) {
|
||||||
|
Reflect(vis, def.hover);
|
||||||
|
Reflect(vis, def.comments);
|
||||||
|
}
|
||||||
|
template <typename Def>
|
||||||
|
void ReflectHoverAndComments(BinaryWriter &vis, Def &def) {
|
||||||
|
Reflect(vis, def.hover);
|
||||||
|
Reflect(vis, def.comments);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Def> void ReflectShortName(Reader &vis, Def &def) {
|
template <typename Def> void ReflectShortName(JsonReader &vis, Def &def) {
|
||||||
if (gTestOutputMode) {
|
if (gTestOutputMode) {
|
||||||
std::string short_name;
|
std::string short_name;
|
||||||
ReflectMember(vis, "short_name", short_name);
|
ReflectMember(vis, "short_name", short_name);
|
||||||
@ -234,8 +263,7 @@ template <typename Def> void ReflectShortName(Reader &vis, Def &def) {
|
|||||||
ReflectMember(vis, "short_name_size", def.short_name_size);
|
ReflectMember(vis, "short_name_size", def.short_name_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <typename Def> void ReflectShortName(JsonWriter &vis, Def &def) {
|
||||||
template <typename Def> void ReflectShortName(Writer &vis, Def &def) {
|
|
||||||
if (gTestOutputMode) {
|
if (gTestOutputMode) {
|
||||||
std::string_view short_name(def.detailed_name + def.short_name_offset,
|
std::string_view short_name(def.detailed_name + def.short_name_offset,
|
||||||
def.short_name_size);
|
def.short_name_size);
|
||||||
@ -245,9 +273,17 @@ template <typename Def> void ReflectShortName(Writer &vis, Def &def) {
|
|||||||
ReflectMember(vis, "short_name_size", def.short_name_size);
|
ReflectMember(vis, "short_name_size", def.short_name_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <typename Def> void ReflectShortName(BinaryReader &vis, Def &def) {
|
||||||
|
Reflect(vis, def.short_name_offset);
|
||||||
|
Reflect(vis, def.short_name_size);
|
||||||
|
}
|
||||||
|
template <typename Def> void ReflectShortName(BinaryWriter &vis, Def &def) {
|
||||||
|
Reflect(vis, def.short_name_offset);
|
||||||
|
Reflect(vis, def.short_name_size);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &vis, IndexFunc &v) {
|
template <typename TVisitor> void Reflect1(TVisitor &vis, IndexFunc &v) {
|
||||||
REFLECT_MEMBER_START();
|
ReflectMemberStart(vis);
|
||||||
REFLECT_MEMBER2("usr", v.usr);
|
REFLECT_MEMBER2("usr", v.usr);
|
||||||
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
|
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
|
||||||
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
|
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
|
||||||
@ -264,11 +300,15 @@ template <typename TVisitor> void Reflect(TVisitor &vis, IndexFunc &v) {
|
|||||||
REFLECT_MEMBER2("declarations", v.declarations);
|
REFLECT_MEMBER2("declarations", v.declarations);
|
||||||
REFLECT_MEMBER2("derived", v.derived);
|
REFLECT_MEMBER2("derived", v.derived);
|
||||||
REFLECT_MEMBER2("uses", v.uses);
|
REFLECT_MEMBER2("uses", v.uses);
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
|
void Reflect(JsonReader &vis, IndexFunc &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(JsonWriter &vis, IndexFunc &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(BinaryReader &vis, IndexFunc &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(BinaryWriter &vis, IndexFunc &v) { Reflect1(vis, v); }
|
||||||
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &vis, IndexType &v) {
|
template <typename TVisitor> void Reflect1(TVisitor &vis, IndexType &v) {
|
||||||
REFLECT_MEMBER_START();
|
ReflectMemberStart(vis);
|
||||||
REFLECT_MEMBER2("usr", v.usr);
|
REFLECT_MEMBER2("usr", v.usr);
|
||||||
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
|
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
|
||||||
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
|
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
|
||||||
@ -287,11 +327,15 @@ template <typename TVisitor> void Reflect(TVisitor &vis, IndexType &v) {
|
|||||||
REFLECT_MEMBER2("derived", v.derived);
|
REFLECT_MEMBER2("derived", v.derived);
|
||||||
REFLECT_MEMBER2("instances", v.instances);
|
REFLECT_MEMBER2("instances", v.instances);
|
||||||
REFLECT_MEMBER2("uses", v.uses);
|
REFLECT_MEMBER2("uses", v.uses);
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
|
void Reflect(JsonReader &vis, IndexType &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(JsonWriter &vis, IndexType &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(BinaryReader &vis, IndexType &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(BinaryWriter &vis, IndexType &v) { Reflect1(vis, v); }
|
||||||
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &vis, IndexVar &v) {
|
template <typename TVisitor> void Reflect1(TVisitor &vis, IndexVar &v) {
|
||||||
REFLECT_MEMBER_START();
|
ReflectMemberStart(vis);
|
||||||
REFLECT_MEMBER2("usr", v.usr);
|
REFLECT_MEMBER2("usr", v.usr);
|
||||||
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
|
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
|
||||||
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
|
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
|
||||||
@ -305,16 +349,16 @@ template <typename TVisitor> void Reflect(TVisitor &vis, IndexVar &v) {
|
|||||||
|
|
||||||
REFLECT_MEMBER2("declarations", v.declarations);
|
REFLECT_MEMBER2("declarations", v.declarations);
|
||||||
REFLECT_MEMBER2("uses", v.uses);
|
REFLECT_MEMBER2("uses", v.uses);
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
|
void Reflect(JsonReader &vis, IndexVar &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(JsonWriter &vis, IndexVar &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(BinaryReader &vis, IndexVar &v) { Reflect1(vis, v); }
|
||||||
|
void Reflect(BinaryWriter &vis, IndexVar &v) { Reflect1(vis, v); }
|
||||||
|
|
||||||
// IndexFile
|
// IndexFile
|
||||||
bool ReflectMemberStart(Writer &vis, IndexFile &v) {
|
template <typename TVisitor> void Reflect1(TVisitor &vis, IndexFile &v) {
|
||||||
vis.StartObject();
|
ReflectMemberStart(vis);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &vis, IndexFile &v) {
|
|
||||||
REFLECT_MEMBER_START();
|
|
||||||
if (!gTestOutputMode) {
|
if (!gTestOutputMode) {
|
||||||
REFLECT_MEMBER(mtime);
|
REFLECT_MEMBER(mtime);
|
||||||
REFLECT_MEMBER(language);
|
REFLECT_MEMBER(language);
|
||||||
@ -328,15 +372,19 @@ template <typename TVisitor> void Reflect(TVisitor &vis, IndexFile &v) {
|
|||||||
REFLECT_MEMBER(usr2func);
|
REFLECT_MEMBER(usr2func);
|
||||||
REFLECT_MEMBER(usr2type);
|
REFLECT_MEMBER(usr2type);
|
||||||
REFLECT_MEMBER(usr2var);
|
REFLECT_MEMBER(usr2var);
|
||||||
REFLECT_MEMBER_END();
|
ReflectMemberEnd(vis);
|
||||||
}
|
}
|
||||||
|
void ReflectFile(JsonReader &vis, IndexFile &v) { Reflect1(vis, v); }
|
||||||
|
void ReflectFile(JsonWriter &vis, IndexFile &v) { Reflect1(vis, v); }
|
||||||
|
void ReflectFile(BinaryReader &vis, IndexFile &v) { Reflect1(vis, v); }
|
||||||
|
void ReflectFile(BinaryWriter &vis, IndexFile &v) { Reflect1(vis, v); }
|
||||||
|
|
||||||
void Reflect(Reader &vis, SerializeFormat &v) {
|
void Reflect(JsonReader &vis, SerializeFormat &v) {
|
||||||
v = vis.GetString()[0] == 'j' ? SerializeFormat::Json
|
v = vis.GetString()[0] == 'j' ? SerializeFormat::Json
|
||||||
: SerializeFormat::Binary;
|
: SerializeFormat::Binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Writer &vis, SerializeFormat &v) {
|
void Reflect(JsonWriter &vis, SerializeFormat &v) {
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case SerializeFormat::Binary:
|
case SerializeFormat::Binary:
|
||||||
vis.String("binary");
|
vis.String("binary");
|
||||||
@ -378,7 +426,7 @@ std::string Serialize(SerializeFormat format, IndexFile &file) {
|
|||||||
int minor = IndexFile::kMinorVersion;
|
int minor = IndexFile::kMinorVersion;
|
||||||
Reflect(writer, major);
|
Reflect(writer, major);
|
||||||
Reflect(writer, minor);
|
Reflect(writer, minor);
|
||||||
Reflect(writer, file);
|
ReflectFile(writer, file);
|
||||||
return writer.Take();
|
return writer.Take();
|
||||||
}
|
}
|
||||||
case SerializeFormat::Json: {
|
case SerializeFormat::Json: {
|
||||||
@ -394,7 +442,7 @@ std::string Serialize(SerializeFormat format, IndexFile &file) {
|
|||||||
output.Put(c);
|
output.Put(c);
|
||||||
output.Put('\n');
|
output.Put('\n');
|
||||||
}
|
}
|
||||||
Reflect(json_writer, file);
|
ReflectFile(json_writer, file);
|
||||||
return output.GetString();
|
return output.GetString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,7 +472,7 @@ Deserialize(SerializeFormat format, const std::string &path,
|
|||||||
throw std::invalid_argument("Invalid version");
|
throw std::invalid_argument("Invalid version");
|
||||||
file = std::make_unique<IndexFile>(sys::fs::UniqueID(0, 0), path,
|
file = std::make_unique<IndexFile>(sys::fs::UniqueID(0, 0), path,
|
||||||
file_content);
|
file_content);
|
||||||
Reflect(reader, *file);
|
ReflectFile(reader, *file);
|
||||||
} catch (std::invalid_argument &e) {
|
} 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;
|
return nullptr;
|
||||||
@ -450,7 +498,7 @@ Deserialize(SerializeFormat format, const std::string &path,
|
|||||||
file_content);
|
file_content);
|
||||||
JsonReader json_reader{&reader};
|
JsonReader json_reader{&reader};
|
||||||
try {
|
try {
|
||||||
Reflect(json_reader, *file);
|
ReflectFile(json_reader, *file);
|
||||||
} catch (std::invalid_argument &e) {
|
} catch (std::invalid_argument &e) {
|
||||||
LOG_S(INFO) << "'" << path << "': failed to deserialize "
|
LOG_S(INFO) << "'" << path << "': failed to deserialize "
|
||||||
<< json_reader.GetPath() << "." << e.what();
|
<< json_reader.GetPath() << "." << e.what();
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <llvm/Support/Compiler.h>
|
#include <llvm/Support/Compiler.h>
|
||||||
|
|
||||||
#include <macro_map.h>
|
#include <macro_map.h>
|
||||||
|
#include <rapidjson/fwd.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -28,159 +29,208 @@ enum class SerializeFormat { Binary, Json };
|
|||||||
|
|
||||||
struct JsonNull {};
|
struct JsonNull {};
|
||||||
|
|
||||||
class Reader {
|
struct JsonReader {
|
||||||
public:
|
rapidjson::Value *m;
|
||||||
virtual ~Reader();
|
std::vector<const char *> path_;
|
||||||
virtual SerializeFormat Format() const = 0;
|
|
||||||
|
|
||||||
virtual bool IsBool() = 0;
|
JsonReader(rapidjson::Value *m) : m(m) {}
|
||||||
virtual bool IsNull() = 0;
|
void StartObject() {}
|
||||||
virtual bool IsInt() = 0;
|
void EndObject() {}
|
||||||
virtual bool IsInt64() = 0;
|
void IterArray(std::function<void()> fn);
|
||||||
virtual bool IsUInt64() = 0;
|
void Member(const char *name, std::function<void()> fn);
|
||||||
virtual bool IsDouble() = 0;
|
bool IsNull();
|
||||||
virtual bool IsString() = 0;
|
std::string GetString();
|
||||||
|
std::string GetPath() const;
|
||||||
virtual void GetNull() = 0;
|
|
||||||
virtual bool GetBool() = 0;
|
|
||||||
virtual uint8_t GetUInt8() = 0;
|
|
||||||
virtual int GetInt() = 0;
|
|
||||||
virtual uint32_t GetUInt32() = 0;
|
|
||||||
virtual int64_t GetInt64() = 0;
|
|
||||||
virtual uint64_t GetUInt64() = 0;
|
|
||||||
virtual double GetDouble() = 0;
|
|
||||||
virtual const char *GetString() = 0;
|
|
||||||
|
|
||||||
virtual bool HasMember(const char *x) = 0;
|
|
||||||
virtual std::unique_ptr<Reader> operator[](const char *x) = 0;
|
|
||||||
|
|
||||||
virtual void IterArray(std::function<void(Reader &)> fn) = 0;
|
|
||||||
virtual void Member(const char *name, std::function<void()> fn) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Writer {
|
struct JsonWriter {
|
||||||
public:
|
using W =
|
||||||
virtual ~Writer();
|
rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<char>,
|
||||||
virtual SerializeFormat Format() const = 0;
|
rapidjson::UTF8<char>, rapidjson::CrtAllocator, 0>;
|
||||||
|
|
||||||
virtual void Null() = 0;
|
W *m;
|
||||||
virtual void Bool(bool x) = 0;
|
|
||||||
virtual void Int(int x) = 0;
|
JsonWriter(W *m) : m(m) {}
|
||||||
virtual void Int64(int64_t x) = 0;
|
void StartArray();
|
||||||
virtual void UInt8(uint8_t x) = 0;
|
void EndArray();
|
||||||
virtual void UInt32(uint32_t x) = 0;
|
void StartObject();
|
||||||
virtual void UInt64(uint64_t x) = 0;
|
void EndObject();
|
||||||
virtual void Double(double x) = 0;
|
void Key(const char *name);
|
||||||
virtual void String(const char *x) = 0;
|
void Null();
|
||||||
virtual void String(const char *x, size_t len) = 0;
|
void Int(int v);
|
||||||
virtual void StartArray(size_t) = 0;
|
void String(const char *s);
|
||||||
virtual void EndArray() = 0;
|
void String(const char *s, size_t len);
|
||||||
virtual void StartObject() = 0;
|
};
|
||||||
virtual void EndObject() = 0;
|
|
||||||
virtual void Key(const char *name) = 0;
|
struct BinaryReader {
|
||||||
|
const char *p_;
|
||||||
|
|
||||||
|
BinaryReader(std::string_view buf) : p_(buf.data()) {}
|
||||||
|
template <typename T> T Get() {
|
||||||
|
T ret;
|
||||||
|
memcpy(&ret, p_, sizeof(T));
|
||||||
|
p_ += sizeof(T);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
uint64_t VarUInt() {
|
||||||
|
auto x = *reinterpret_cast<const uint8_t *>(p_++);
|
||||||
|
if (x < 253)
|
||||||
|
return x;
|
||||||
|
if (x == 253)
|
||||||
|
return Get<uint16_t>();
|
||||||
|
if (x == 254)
|
||||||
|
return Get<uint32_t>();
|
||||||
|
return Get<uint64_t>();
|
||||||
|
}
|
||||||
|
int64_t VarInt() {
|
||||||
|
uint64_t x = VarUInt();
|
||||||
|
return int64_t(x >> 1 ^ -(x & 1));
|
||||||
|
}
|
||||||
|
const char *GetString() {
|
||||||
|
const char *ret = p_;
|
||||||
|
while (*p_)
|
||||||
|
p_++;
|
||||||
|
p_++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BinaryWriter {
|
||||||
|
std::string buf_;
|
||||||
|
|
||||||
|
template <typename T> void Pack(T x) {
|
||||||
|
auto i = buf_.size();
|
||||||
|
buf_.resize(i + sizeof(x));
|
||||||
|
memcpy(buf_.data() + i, &x, sizeof(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
void VarUInt(uint64_t n) {
|
||||||
|
if (n < 253)
|
||||||
|
Pack<uint8_t>(n);
|
||||||
|
else if (n < 65536) {
|
||||||
|
Pack<uint8_t>(253);
|
||||||
|
Pack<uint16_t>(n);
|
||||||
|
} else if (n < 4294967296) {
|
||||||
|
Pack<uint8_t>(254);
|
||||||
|
Pack<uint32_t>(n);
|
||||||
|
} else {
|
||||||
|
Pack<uint8_t>(255);
|
||||||
|
Pack<uint64_t>(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); }
|
||||||
|
std::string Take() { return std::move(buf_); }
|
||||||
|
|
||||||
|
void String(const char *x) { String(x, strlen(x)); }
|
||||||
|
void String(const char *x, size_t len) {
|
||||||
|
auto i = buf_.size();
|
||||||
|
buf_.resize(i + len + 1);
|
||||||
|
memcpy(buf_.data() + i, x, len);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexFile;
|
struct IndexFile;
|
||||||
|
|
||||||
#define REFLECT_MEMBER_START() ReflectMemberStart(vis)
|
|
||||||
#define REFLECT_MEMBER_END() ReflectMemberEnd(vis);
|
|
||||||
#define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name)
|
#define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name)
|
||||||
#define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v)
|
#define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v)
|
||||||
|
|
||||||
#define MAKE_REFLECT_TYPE_PROXY(type_name) \
|
#define REFLECT_UNDERLYING(T) \
|
||||||
MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t<type_name>)
|
LLVM_ATTRIBUTE_UNUSED inline void Reflect(JsonReader &vis, T &v) { \
|
||||||
#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \
|
std::underlying_type_t<T> v0; \
|
||||||
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &vis, type &v) { \
|
::ccls::Reflect(vis, v0); \
|
||||||
as_type value0; \
|
v = static_cast<T>(v0); \
|
||||||
::ccls::Reflect(vis, value0); \
|
|
||||||
v = static_cast<type>(value0); \
|
|
||||||
} \
|
} \
|
||||||
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &vis, type &v) { \
|
LLVM_ATTRIBUTE_UNUSED inline void Reflect(JsonWriter &vis, T &v) { \
|
||||||
auto value0 = static_cast<as_type>(v); \
|
auto v0 = static_cast<std::underlying_type_t<T>>(v); \
|
||||||
::ccls::Reflect(vis, value0); \
|
::ccls::Reflect(vis, v0); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REFLECT_UNDERLYING_B(T) \
|
||||||
|
REFLECT_UNDERLYING(T) \
|
||||||
|
LLVM_ATTRIBUTE_UNUSED inline void Reflect(BinaryReader &vis, T &v) { \
|
||||||
|
std::underlying_type_t<T> v0; \
|
||||||
|
::ccls::Reflect(vis, v0); \
|
||||||
|
v = static_cast<T>(v0); \
|
||||||
|
} \
|
||||||
|
LLVM_ATTRIBUTE_UNUSED inline void Reflect(BinaryWriter &vis, T &v) { \
|
||||||
|
auto v0 = static_cast<std::underlying_type_t<T>>(v); \
|
||||||
|
::ccls::Reflect(vis, v0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
|
#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
|
||||||
|
|
||||||
#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
|
#define REFLECT_STRUCT(type, ...) \
|
||||||
template <typename TVisitor> void Reflect(TVisitor &vis, type &v) { \
|
template <typename Vis> void Reflect(Vis &vis, type &v) { \
|
||||||
REFLECT_MEMBER_START(); \
|
ReflectMemberStart(vis); \
|
||||||
REFLECT_MEMBER_END(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MAKE_REFLECT_STRUCT(type, ...) \
|
|
||||||
template <typename TVisitor> void Reflect(TVisitor &vis, type &v) { \
|
|
||||||
REFLECT_MEMBER_START(); \
|
|
||||||
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
|
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
|
||||||
REFLECT_MEMBER_END(); \
|
ReflectMemberEnd(vis); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
// Config has many fields, we need to support at least its number of fields.
|
|
||||||
#define NUM_VA_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N
|
|
||||||
#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name);
|
#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name);
|
||||||
|
|
||||||
// Reflects the struct so it is serialized as an array instead of an object.
|
void Reflect(JsonReader &vis, bool &v);
|
||||||
// This currently only supports writers.
|
void Reflect(JsonReader &vis, unsigned char &v);
|
||||||
#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \
|
void Reflect(JsonReader &vis, short &v);
|
||||||
inline void Reflect(Writer &vis, type &v) { \
|
void Reflect(JsonReader &vis, unsigned short &v);
|
||||||
vis.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \
|
void Reflect(JsonReader &vis, int &v);
|
||||||
MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \
|
void Reflect(JsonReader &vis, unsigned &v);
|
||||||
vis.EndArray(); \
|
void Reflect(JsonReader &vis, long &v);
|
||||||
}
|
void Reflect(JsonReader &vis, unsigned long &v);
|
||||||
|
void Reflect(JsonReader &vis, long long &v);
|
||||||
|
void Reflect(JsonReader &vis, unsigned long long &v);
|
||||||
|
void Reflect(JsonReader &vis, double &v);
|
||||||
|
void Reflect(JsonReader &vis, const char *&v);
|
||||||
|
void Reflect(JsonReader &vis, std::string &v);
|
||||||
|
|
||||||
//// Elementary types
|
void Reflect(JsonWriter &vis, bool &v);
|
||||||
|
void Reflect(JsonWriter &vis, unsigned char &v);
|
||||||
|
void Reflect(JsonWriter &vis, short &v);
|
||||||
|
void Reflect(JsonWriter &vis, unsigned short &v);
|
||||||
|
void Reflect(JsonWriter &vis, int &v);
|
||||||
|
void Reflect(JsonWriter &vis, unsigned &v);
|
||||||
|
void Reflect(JsonWriter &vis, long &v);
|
||||||
|
void Reflect(JsonWriter &vis, unsigned long &v);
|
||||||
|
void Reflect(JsonWriter &vis, long long &v);
|
||||||
|
void Reflect(JsonWriter &vis, unsigned long long &v);
|
||||||
|
void Reflect(JsonWriter &vis, double &v);
|
||||||
|
void Reflect(JsonWriter &vis, const char *&v);
|
||||||
|
void Reflect(JsonWriter &vis, std::string &v);
|
||||||
|
|
||||||
void Reflect(Reader &vis, uint8_t &v);
|
void Reflect(BinaryReader &vis, bool &v);
|
||||||
void Reflect(Writer &vis, uint8_t &v);
|
void Reflect(BinaryReader &vis, unsigned char &v);
|
||||||
|
void Reflect(BinaryReader &vis, short &v);
|
||||||
|
void Reflect(BinaryReader &vis, unsigned short &v);
|
||||||
|
void Reflect(BinaryReader &vis, int &v);
|
||||||
|
void Reflect(BinaryReader &vis, unsigned &v);
|
||||||
|
void Reflect(BinaryReader &vis, long &v);
|
||||||
|
void Reflect(BinaryReader &vis, unsigned long &v);
|
||||||
|
void Reflect(BinaryReader &vis, long long &v);
|
||||||
|
void Reflect(BinaryReader &vis, unsigned long long &v);
|
||||||
|
void Reflect(BinaryReader &vis, double &v);
|
||||||
|
void Reflect(BinaryReader &vis, const char *&v);
|
||||||
|
void Reflect(BinaryReader &vis, std::string &v);
|
||||||
|
|
||||||
void Reflect(Reader &vis, short &v);
|
void Reflect(BinaryWriter &vis, bool &v);
|
||||||
void Reflect(Writer &vis, short &v);
|
void Reflect(BinaryWriter &vis, unsigned char &v);
|
||||||
|
void Reflect(BinaryWriter &vis, short &v);
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned short &v);
|
||||||
|
void Reflect(BinaryWriter &vis, int &v);
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned &v);
|
||||||
|
void Reflect(BinaryWriter &vis, long &v);
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned long &v);
|
||||||
|
void Reflect(BinaryWriter &vis, long long &v);
|
||||||
|
void Reflect(BinaryWriter &vis, unsigned long long &v);
|
||||||
|
void Reflect(BinaryWriter &vis, double &v);
|
||||||
|
void Reflect(BinaryWriter &vis, const char *&v);
|
||||||
|
void Reflect(BinaryWriter &vis, std::string &v);
|
||||||
|
|
||||||
void Reflect(Reader &vis, unsigned short &v);
|
void Reflect(JsonReader &vis, JsonNull &v);
|
||||||
void Reflect(Writer &vis, unsigned short &v);
|
void Reflect(JsonWriter &vis, JsonNull &v);
|
||||||
|
|
||||||
void Reflect(Reader &vis, int &v);
|
void Reflect(JsonReader &vis, SerializeFormat &v);
|
||||||
void Reflect(Writer &vis, int &v);
|
void Reflect(JsonWriter &vis, SerializeFormat &v);
|
||||||
|
|
||||||
void Reflect(Reader &vis, unsigned &v);
|
void Reflect(JsonWriter &vis, std::string_view &v);
|
||||||
void Reflect(Writer &vis, unsigned &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, long &v);
|
|
||||||
void Reflect(Writer &vis, long &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, unsigned long &v);
|
|
||||||
void Reflect(Writer &vis, unsigned long &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, long long &v);
|
|
||||||
void Reflect(Writer &vis, long long &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, unsigned long long &v);
|
|
||||||
void Reflect(Writer &vis, unsigned long long &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, double &v);
|
|
||||||
void Reflect(Writer &vis, double &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, bool &v);
|
|
||||||
void Reflect(Writer &vis, bool &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, std::string &v);
|
|
||||||
void Reflect(Writer &vis, std::string &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, std::string_view &v);
|
|
||||||
void Reflect(Writer &vis, std::string_view &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, const char *&v);
|
|
||||||
void Reflect(Writer &vis, const char *&v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, JsonNull &v);
|
|
||||||
void Reflect(Writer &vis, JsonNull &v);
|
|
||||||
|
|
||||||
void Reflect(Reader &vis, SerializeFormat &v);
|
|
||||||
void Reflect(Writer &vis, SerializeFormat &v);
|
|
||||||
|
|
||||||
//// Type constructors
|
//// Type constructors
|
||||||
|
|
||||||
@ -188,109 +238,154 @@ void Reflect(Writer &vis, SerializeFormat &v);
|
|||||||
// properties (in `key: value` context). Reflect std::optional<T> is used for a
|
// properties (in `key: value` context). Reflect std::optional<T> is used for a
|
||||||
// different purpose, whether an object is nullable (possibly in `value`
|
// different purpose, whether an object is nullable (possibly in `value`
|
||||||
// context).
|
// context).
|
||||||
template <typename T> void Reflect(Reader &vis, std::optional<T> &v) {
|
template <typename T> void Reflect(JsonReader &vis, std::optional<T> &v) {
|
||||||
if (vis.IsNull()) {
|
if (!vis.IsNull()) {
|
||||||
vis.GetNull();
|
v.emplace();
|
||||||
return;
|
|
||||||
}
|
|
||||||
T val;
|
|
||||||
Reflect(vis, val);
|
|
||||||
v = std::move(val);
|
|
||||||
}
|
|
||||||
template <typename T> void Reflect(Writer &vis, std::optional<T> &v) {
|
|
||||||
if (v) {
|
|
||||||
if (vis.Format() != SerializeFormat::Json)
|
|
||||||
vis.UInt8(1);
|
|
||||||
Reflect(vis, *v);
|
Reflect(vis, *v);
|
||||||
} else
|
}
|
||||||
|
}
|
||||||
|
template <typename T> void Reflect(JsonWriter &vis, std::optional<T> &v) {
|
||||||
|
if (v)
|
||||||
|
Reflect(vis, *v);
|
||||||
|
else
|
||||||
vis.Null();
|
vis.Null();
|
||||||
}
|
}
|
||||||
|
template <typename T> void Reflect(BinaryReader &vis, std::optional<T> &v) {
|
||||||
|
if (*vis.p_++) {
|
||||||
|
v.emplace();
|
||||||
|
Reflect(vis, *v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename T> void Reflect(BinaryWriter &vis, std::optional<T> &v) {
|
||||||
|
if (v) {
|
||||||
|
vis.Pack<unsigned char>(1);
|
||||||
|
Reflect(vis, *v);
|
||||||
|
} else {
|
||||||
|
vis.Pack<unsigned char>(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The same as std::optional
|
// The same as std::optional
|
||||||
template <typename T> void Reflect(Reader &vis, Maybe<T> &v) {
|
template <typename T> void Reflect(JsonReader &vis, Maybe<T> &v) {
|
||||||
if (vis.IsNull()) {
|
if (!vis.IsNull())
|
||||||
vis.GetNull();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
T val;
|
|
||||||
Reflect(vis, val);
|
|
||||||
v = std::move(val);
|
|
||||||
}
|
|
||||||
template <typename T> void Reflect(Writer &vis, Maybe<T> &v) {
|
|
||||||
if (v) {
|
|
||||||
if (vis.Format() != SerializeFormat::Json)
|
|
||||||
vis.UInt8(1);
|
|
||||||
Reflect(vis, *v);
|
Reflect(vis, *v);
|
||||||
} else
|
}
|
||||||
|
template <typename T> void Reflect(JsonWriter &vis, Maybe<T> &v) {
|
||||||
|
if (v)
|
||||||
|
Reflect(vis, *v);
|
||||||
|
else
|
||||||
vis.Null();
|
vis.Null();
|
||||||
}
|
}
|
||||||
|
template <typename T> void Reflect(BinaryReader &vis, Maybe<T> &v) {
|
||||||
|
if (*vis.p_++)
|
||||||
|
Reflect(vis, *v);
|
||||||
|
}
|
||||||
|
template <typename T> void Reflect(BinaryWriter &vis, Maybe<T> &v) {
|
||||||
|
if (v) {
|
||||||
|
vis.Pack<unsigned char>(1);
|
||||||
|
Reflect(vis, *v);
|
||||||
|
} else {
|
||||||
|
vis.Pack<unsigned char>(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReflectMember(Writer &vis, const char *name, std::optional<T> &v) {
|
void ReflectMember(JsonWriter &vis, const char *name, std::optional<T> &v) {
|
||||||
// For TypeScript std::optional property key?: value in the spec,
|
// For TypeScript std::optional property key?: value in the spec,
|
||||||
// We omit both key and value if value is std::nullopt (null) for JsonWriter
|
// We omit both key and value if value is std::nullopt (null) for JsonWriter
|
||||||
// to reduce output. But keep it for other serialization formats.
|
// to reduce output. But keep it for other serialization formats.
|
||||||
if (v || vis.Format() != SerializeFormat::Json) {
|
if (v) {
|
||||||
vis.Key(name);
|
vis.Key(name);
|
||||||
Reflect(vis, v);
|
Reflect(vis, *v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <typename T>
|
||||||
|
void ReflectMember(BinaryWriter &vis, const char *, std::optional<T> &v) {
|
||||||
|
Reflect(vis, v);
|
||||||
|
}
|
||||||
|
|
||||||
// The same as std::optional
|
// The same as std::optional
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReflectMember(Writer &vis, const char *name, Maybe<T> &v) {
|
void ReflectMember(JsonWriter &vis, const char *name, Maybe<T> &v) {
|
||||||
if (v.Valid() || vis.Format() != SerializeFormat::Json) {
|
if (v.Valid()) {
|
||||||
vis.Key(name);
|
vis.Key(name);
|
||||||
Reflect(vis, v);
|
Reflect(vis, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <typename T>
|
||||||
|
void ReflectMember(BinaryWriter &vis, const char *, Maybe<T> &v) {
|
||||||
|
Reflect(vis, v);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename L, typename R>
|
template <typename L, typename R>
|
||||||
void Reflect(Reader &vis, std::pair<L, R> &v) {
|
void Reflect(JsonReader &vis, std::pair<L, R> &v) {
|
||||||
vis.Member("L", [&]() { Reflect(vis, v.first); });
|
vis.Member("L", [&]() { Reflect(vis, v.first); });
|
||||||
vis.Member("R", [&]() { Reflect(vis, v.second); });
|
vis.Member("R", [&]() { Reflect(vis, v.second); });
|
||||||
}
|
}
|
||||||
template <typename L, typename R>
|
template <typename L, typename R>
|
||||||
void Reflect(Writer &vis, std::pair<L, R> &v) {
|
void Reflect(JsonWriter &vis, std::pair<L, R> &v) {
|
||||||
vis.StartObject();
|
vis.StartObject();
|
||||||
ReflectMember(vis, "L", v.first);
|
ReflectMember(vis, "L", v.first);
|
||||||
ReflectMember(vis, "R", v.second);
|
ReflectMember(vis, "R", v.second);
|
||||||
vis.EndObject();
|
vis.EndObject();
|
||||||
}
|
}
|
||||||
|
template <typename L, typename R>
|
||||||
|
void Reflect(BinaryReader &vis, std::pair<L, R> &v) {
|
||||||
|
Reflect(vis, v.first);
|
||||||
|
Reflect(vis, v.second);
|
||||||
|
}
|
||||||
|
template <typename L, typename R>
|
||||||
|
void Reflect(BinaryWriter &vis, std::pair<L, R> &v) {
|
||||||
|
Reflect(vis, v.first);
|
||||||
|
Reflect(vis, v.second);
|
||||||
|
}
|
||||||
|
|
||||||
// std::vector
|
// std::vector
|
||||||
template <typename T> void Reflect(Reader &vis, std::vector<T> &vs) {
|
template <typename T> void Reflect(JsonReader &vis, std::vector<T> &v) {
|
||||||
vis.IterArray([&](Reader &entry) {
|
vis.IterArray([&]() {
|
||||||
T entry_value;
|
v.emplace_back();
|
||||||
Reflect(entry, entry_value);
|
Reflect(vis, v.back());
|
||||||
vs.push_back(std::move(entry_value));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
template <typename T> void Reflect(Writer &vis, std::vector<T> &vs) {
|
template <typename T> void Reflect(JsonWriter &vis, std::vector<T> &v) {
|
||||||
vis.StartArray(vs.size());
|
vis.StartArray();
|
||||||
for (auto &v : vs)
|
for (auto &it : v)
|
||||||
Reflect(vis, v);
|
Reflect(vis, it);
|
||||||
vis.EndArray();
|
vis.EndArray();
|
||||||
}
|
}
|
||||||
|
template <typename T> void Reflect(BinaryReader &vis, std::vector<T> &v) {
|
||||||
|
for (auto n = vis.VarUInt(); n; n--) {
|
||||||
|
v.emplace_back();
|
||||||
|
Reflect(vis, v.back());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename T> void Reflect(BinaryWriter &vis, std::vector<T> &v) {
|
||||||
|
vis.VarUInt(v.size());
|
||||||
|
for (auto &it : v)
|
||||||
|
Reflect(vis, it);
|
||||||
|
}
|
||||||
|
|
||||||
// ReflectMember
|
// ReflectMember
|
||||||
|
|
||||||
inline bool ReflectMemberStart(Reader &vis) { return false; }
|
template <typename T> void ReflectMemberStart(T &) {}
|
||||||
inline bool ReflectMemberStart(Writer &vis) {
|
inline void ReflectMemberStart(JsonWriter &vis) { vis.StartObject(); }
|
||||||
vis.StartObject();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ReflectMemberEnd(Reader &vis) {}
|
template <typename T> void ReflectMemberEnd(T &) {}
|
||||||
inline void ReflectMemberEnd(Writer &vis) { vis.EndObject(); }
|
inline void ReflectMemberEnd(JsonWriter &vis) { vis.EndObject(); }
|
||||||
|
|
||||||
template <typename T> void ReflectMember(Reader &vis, const char *name, T &v) {
|
template <typename T> void ReflectMember(JsonReader &vis, const char *name, T &v) {
|
||||||
vis.Member(name, [&]() { Reflect(vis, v); });
|
vis.Member(name, [&]() { Reflect(vis, v); });
|
||||||
}
|
}
|
||||||
template <typename T> void ReflectMember(Writer &vis, const char *name, T &v) {
|
template <typename T> void ReflectMember(JsonWriter &vis, const char *name, T &v) {
|
||||||
vis.Key(name);
|
vis.Key(name);
|
||||||
Reflect(vis, v);
|
Reflect(vis, v);
|
||||||
}
|
}
|
||||||
|
template <typename T> void ReflectMember(BinaryReader &vis, const char *, T &v) {
|
||||||
|
Reflect(vis, v);
|
||||||
|
}
|
||||||
|
template <typename T> void ReflectMember(BinaryWriter &vis, const char *, T &v) {
|
||||||
|
Reflect(vis, v);
|
||||||
|
}
|
||||||
|
|
||||||
// API
|
// API
|
||||||
|
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
// Copyright 2017-2018 ccls Authors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "serializer.hh"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
namespace ccls {
|
|
||||||
class BinaryReader : public Reader {
|
|
||||||
const char *p_;
|
|
||||||
|
|
||||||
template <typename T> T Get() {
|
|
||||||
T ret;
|
|
||||||
memcpy(&ret, p_, sizeof(T));
|
|
||||||
p_ += sizeof(T);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t VarUInt() {
|
|
||||||
auto x = *reinterpret_cast<const uint8_t *>(p_++);
|
|
||||||
if (x < 253)
|
|
||||||
return x;
|
|
||||||
if (x == 253)
|
|
||||||
return Get<uint16_t>();
|
|
||||||
if (x == 254)
|
|
||||||
return Get<uint32_t>();
|
|
||||||
return Get<uint64_t>();
|
|
||||||
}
|
|
||||||
int64_t VarInt() {
|
|
||||||
uint64_t x = VarUInt();
|
|
||||||
return int64_t(x >> 1 ^ -(x & 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
BinaryReader(std::string_view buf) : p_(buf.data()) {}
|
|
||||||
virtual ~BinaryReader();
|
|
||||||
SerializeFormat Format() const override { return SerializeFormat::Binary; }
|
|
||||||
|
|
||||||
bool IsBool() override { return true; }
|
|
||||||
// Abuse how the function is called in serializer.h
|
|
||||||
bool IsNull() override { return !*p_++; }
|
|
||||||
bool IsInt() override { return true; }
|
|
||||||
bool IsInt64() override { return true; }
|
|
||||||
bool IsUInt64() override { return true; }
|
|
||||||
bool IsDouble() override { return true; }
|
|
||||||
bool IsString() override { return true; }
|
|
||||||
|
|
||||||
void GetNull() override {}
|
|
||||||
bool GetBool() override { return Get<bool>(); }
|
|
||||||
int GetInt() override { return VarInt(); }
|
|
||||||
int64_t GetInt64() override { return VarInt(); }
|
|
||||||
uint8_t GetUInt8() override { return Get<uint8_t>(); }
|
|
||||||
uint32_t GetUInt32() override { return VarUInt(); }
|
|
||||||
uint64_t GetUInt64() override { return VarUInt(); }
|
|
||||||
double GetDouble() override { return Get<double>(); }
|
|
||||||
const char *GetString() override {
|
|
||||||
const char *ret = p_;
|
|
||||||
while (*p_)
|
|
||||||
p_++;
|
|
||||||
p_++;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasMember(const char *x) override { return true; }
|
|
||||||
std::unique_ptr<Reader> operator[](const char *x) override { return {}; }
|
|
||||||
|
|
||||||
void IterArray(std::function<void(Reader &)> fn) override {
|
|
||||||
for (auto n = VarUInt(); n; n--)
|
|
||||||
fn(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Member(const char *, std::function<void()> fn) override { fn(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinaryWriter : public Writer {
|
|
||||||
std::string buf_;
|
|
||||||
|
|
||||||
template <typename T> void Pack(T x) {
|
|
||||||
auto i = buf_.size();
|
|
||||||
buf_.resize(i + sizeof(x));
|
|
||||||
memcpy(buf_.data() + i, &x, sizeof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
void VarUInt(uint64_t n) {
|
|
||||||
if (n < 253)
|
|
||||||
Pack<uint8_t>(n);
|
|
||||||
else if (n < 65536) {
|
|
||||||
Pack<uint8_t>(253);
|
|
||||||
Pack<uint16_t>(n);
|
|
||||||
} else if (n < 4294967296) {
|
|
||||||
Pack<uint8_t>(254);
|
|
||||||
Pack<uint32_t>(n);
|
|
||||||
} else {
|
|
||||||
Pack<uint8_t>(255);
|
|
||||||
Pack<uint64_t>(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void VarInt(int64_t n) { VarUInt(uint64_t(n) << 1 ^ n >> 63); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~BinaryWriter();
|
|
||||||
SerializeFormat Format() const override { return SerializeFormat::Binary; }
|
|
||||||
std::string Take() { return std::move(buf_); }
|
|
||||||
|
|
||||||
void Null() override { Pack(uint8_t(0)); }
|
|
||||||
void Bool(bool x) override { Pack(x); }
|
|
||||||
void Int(int x) override { VarInt(x); }
|
|
||||||
void Int64(int64_t x) override { VarInt(x); }
|
|
||||||
void UInt8(uint8_t x) override { Pack(x); }
|
|
||||||
void UInt32(uint32_t x) override { VarUInt(x); }
|
|
||||||
void UInt64(uint64_t x) override { VarUInt(x); }
|
|
||||||
void Double(double x) override { Pack(x); }
|
|
||||||
void String(const char *x) override { String(x, strlen(x)); }
|
|
||||||
void String(const char *x, size_t len) override {
|
|
||||||
auto i = buf_.size();
|
|
||||||
buf_.resize(i + len + 1);
|
|
||||||
memcpy(buf_.data() + i, x, len);
|
|
||||||
}
|
|
||||||
void StartArray(size_t n) override { VarUInt(n); }
|
|
||||||
void EndArray() override {}
|
|
||||||
void StartObject() override {}
|
|
||||||
void EndObject() override {}
|
|
||||||
void Key(const char *name) override {}
|
|
||||||
};
|
|
||||||
} // namespace ccls
|
|
@ -1,108 +0,0 @@
|
|||||||
// Copyright 2017-2018 ccls Authors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "serializer.hh"
|
|
||||||
|
|
||||||
#include <rapidjson/document.h>
|
|
||||||
#include <rapidjson/prettywriter.h>
|
|
||||||
|
|
||||||
namespace ccls {
|
|
||||||
class JsonReader : public Reader {
|
|
||||||
rapidjson::GenericValue<rapidjson::UTF8<>> *m_;
|
|
||||||
std::vector<const char *> path_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
JsonReader(rapidjson::GenericValue<rapidjson::UTF8<>> *m) : m_(m) {}
|
|
||||||
virtual ~JsonReader();
|
|
||||||
SerializeFormat Format() const override { return SerializeFormat::Json; }
|
|
||||||
rapidjson::GenericValue<rapidjson::UTF8<>> &m() { return *m_; }
|
|
||||||
|
|
||||||
bool IsBool() override { return m_->IsBool(); }
|
|
||||||
bool IsNull() override { return m_->IsNull(); }
|
|
||||||
bool IsInt() override { return m_->IsInt(); }
|
|
||||||
bool IsInt64() override { return m_->IsInt64(); }
|
|
||||||
bool IsUInt64() override { return m_->IsUint64(); }
|
|
||||||
bool IsDouble() override { return m_->IsDouble(); }
|
|
||||||
bool IsString() override { return m_->IsString(); }
|
|
||||||
|
|
||||||
void GetNull() override {}
|
|
||||||
bool GetBool() override { return m_->GetBool(); }
|
|
||||||
int GetInt() override { return m_->GetInt(); }
|
|
||||||
int64_t GetInt64() override { return m_->GetInt64(); }
|
|
||||||
uint8_t GetUInt8() override { return uint8_t(m_->GetInt()); }
|
|
||||||
uint32_t GetUInt32() override { return uint32_t(m_->GetUint64()); }
|
|
||||||
uint64_t GetUInt64() override { return m_->GetUint64(); }
|
|
||||||
double GetDouble() override { return m_->GetDouble(); }
|
|
||||||
const char *GetString() override { return m_->GetString(); }
|
|
||||||
|
|
||||||
bool HasMember(const char *x) override { return m_->HasMember(x); }
|
|
||||||
std::unique_ptr<Reader> operator[](const char *x) override {
|
|
||||||
auto &sub = (*m_)[x];
|
|
||||||
return std::unique_ptr<JsonReader>(new JsonReader(&sub));
|
|
||||||
}
|
|
||||||
|
|
||||||
void IterArray(std::function<void(Reader &)> fn) override {
|
|
||||||
if (!m_->IsArray())
|
|
||||||
throw std::invalid_argument("array");
|
|
||||||
// Use "0" to indicate any element for now.
|
|
||||||
path_.push_back("0");
|
|
||||||
for (auto &entry : m_->GetArray()) {
|
|
||||||
auto saved = m_;
|
|
||||||
m_ = &entry;
|
|
||||||
fn(*this);
|
|
||||||
m_ = saved;
|
|
||||||
}
|
|
||||||
path_.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Member(const char *name, std::function<void()> fn) override {
|
|
||||||
path_.push_back(name);
|
|
||||||
auto it = m_->FindMember(name);
|
|
||||||
if (it != m_->MemberEnd()) {
|
|
||||||
auto saved = m_;
|
|
||||||
m_ = &it->value;
|
|
||||||
fn();
|
|
||||||
m_ = saved;
|
|
||||||
}
|
|
||||||
path_.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetPath() const {
|
|
||||||
std::string ret;
|
|
||||||
for (auto &t : path_) {
|
|
||||||
ret += '/';
|
|
||||||
ret += t;
|
|
||||||
}
|
|
||||||
ret.pop_back();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonWriter : public Writer {
|
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> *m_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
JsonWriter(rapidjson::Writer<rapidjson::StringBuffer> *m) : m_(m) {}
|
|
||||||
virtual ~JsonWriter();
|
|
||||||
SerializeFormat Format() const override { return SerializeFormat::Json; }
|
|
||||||
rapidjson::Writer<rapidjson::StringBuffer> &m() { return *m_; }
|
|
||||||
|
|
||||||
void Null() override { m_->Null(); }
|
|
||||||
void Bool(bool x) override { m_->Bool(x); }
|
|
||||||
void Int(int x) override { m_->Int(x); }
|
|
||||||
void Int64(int64_t x) override { m_->Int64(x); }
|
|
||||||
void UInt8(uint8_t x) override { m_->Int(x); }
|
|
||||||
void UInt32(uint32_t x) override { m_->Uint64(x); }
|
|
||||||
void UInt64(uint64_t x) override { m_->Uint64(x); }
|
|
||||||
void Double(double x) override { m_->Double(x); }
|
|
||||||
void String(const char *x) override { m_->String(x); }
|
|
||||||
void String(const char *x, size_t len) override { m_->String(x, len); }
|
|
||||||
void StartArray(size_t) override { m_->StartArray(); }
|
|
||||||
void EndArray() override { m_->EndArray(); }
|
|
||||||
void StartObject() override { m_->StartObject(); }
|
|
||||||
void EndObject() override { m_->EndObject(); }
|
|
||||||
void Key(const char *name) override { m_->Key(name); }
|
|
||||||
};
|
|
||||||
} // namespace ccls
|
|
Loading…
Reference in New Issue
Block a user