2017-02-23 08:47:07 +00:00
|
|
|
#include "serializer.h"
|
|
|
|
|
2018-01-06 21:46:41 +00:00
|
|
|
#include "serializers/json.h"
|
2018-01-07 00:22:46 +00:00
|
|
|
#include "serializers/msgpack.h"
|
2018-01-06 21:46:41 +00:00
|
|
|
|
2017-03-14 08:33:39 +00:00
|
|
|
#include "indexer.h"
|
|
|
|
|
2017-11-30 03:18:25 +00:00
|
|
|
#include <doctest/doctest.h>
|
2018-01-07 05:08:25 +00:00
|
|
|
#include <loguru.hpp>
|
2017-11-30 03:18:25 +00:00
|
|
|
|
2018-01-19 06:47:44 +00:00
|
|
|
#include <stdexcept>
|
|
|
|
|
2017-04-20 06:02:24 +00:00
|
|
|
namespace {
|
|
|
|
bool gTestOutputMode = false;
|
|
|
|
} // namespace
|
2017-02-24 08:39:25 +00:00
|
|
|
|
2018-01-18 08:43:06 +00:00
|
|
|
//// Elementary types
|
|
|
|
|
2018-01-08 00:06:01 +00:00
|
|
|
void Reflect(Reader& visitor, uint8_t& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsInt())
|
|
|
|
throw std::invalid_argument("uint8_t");
|
2018-01-08 00:06:01 +00:00
|
|
|
value = (uint8_t)visitor.GetInt();
|
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, uint8_t& value) {
|
|
|
|
visitor.Int(value);
|
|
|
|
}
|
|
|
|
|
2017-05-19 07:02:01 +00:00
|
|
|
void Reflect(Reader& visitor, int16_t& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsInt())
|
|
|
|
throw std::invalid_argument("int16_t");
|
2018-01-08 00:06:01 +00:00
|
|
|
value = (int16_t)visitor.GetInt();
|
2017-03-07 09:32:29 +00:00
|
|
|
}
|
2017-05-19 07:02:01 +00:00
|
|
|
void Reflect(Writer& visitor, int16_t& value) {
|
|
|
|
visitor.Int(value);
|
|
|
|
}
|
2018-01-06 19:26:37 +00:00
|
|
|
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Reader& visitor, int& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsInt())
|
|
|
|
throw std::invalid_argument("int");
|
2018-01-07 00:22:46 +00:00
|
|
|
value = visitor.GetInt();
|
2017-05-19 07:02:01 +00:00
|
|
|
}
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Writer& visitor, int& value) {
|
2017-03-07 09:32:29 +00:00
|
|
|
visitor.Int(value);
|
2017-02-23 08:47:07 +00:00
|
|
|
}
|
2018-01-06 19:26:37 +00:00
|
|
|
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Reader& visitor, unsigned& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsInt())
|
|
|
|
throw std::invalid_argument("unsigned");
|
2018-01-18 08:43:06 +00:00
|
|
|
value = visitor.GetUint32();
|
|
|
|
}
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Writer& visitor, unsigned& value) {
|
2018-01-18 08:43:06 +00:00
|
|
|
visitor.Uint32(value);
|
|
|
|
}
|
|
|
|
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Reader& visitor, long& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsInt64())
|
|
|
|
throw std::invalid_argument("long");
|
2018-01-18 19:22:36 +00:00
|
|
|
value = long(visitor.GetInt64());
|
2017-04-20 04:57:44 +00:00
|
|
|
}
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Writer& visitor, long& value) {
|
2017-04-20 04:57:44 +00:00
|
|
|
visitor.Int64(value);
|
|
|
|
}
|
2018-01-06 19:26:37 +00:00
|
|
|
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Reader& visitor, unsigned long& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsUint64())
|
|
|
|
throw std::invalid_argument("unsigned long");
|
2018-01-18 19:22:36 +00:00
|
|
|
value = (unsigned long)visitor.GetUint64();
|
2017-05-19 07:02:01 +00:00
|
|
|
}
|
2018-01-18 18:41:46 +00:00
|
|
|
void Reflect(Writer& visitor, unsigned long& value) {
|
|
|
|
visitor.Uint64(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Reflect(Reader& visitor, long long& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsInt64())
|
|
|
|
throw std::invalid_argument("long long");
|
2018-01-18 18:41:46 +00:00
|
|
|
value = visitor.GetInt64();
|
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, long long& value) {
|
|
|
|
visitor.Int64(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Reflect(Reader& visitor, unsigned long long& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsUint64())
|
|
|
|
throw std::invalid_argument("unsigned long long");
|
2018-01-18 18:41:46 +00:00
|
|
|
value = visitor.GetUint64();
|
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, unsigned long long& value) {
|
2017-05-19 07:02:01 +00:00
|
|
|
visitor.Uint64(value);
|
|
|
|
}
|
2018-01-06 19:26:37 +00:00
|
|
|
|
2018-01-10 06:34:58 +00:00
|
|
|
void Reflect(Reader& visitor, double& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsDouble())
|
|
|
|
throw std::invalid_argument("double");
|
2018-01-10 06:34:58 +00:00
|
|
|
value = visitor.GetDouble();
|
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, double& value) {
|
|
|
|
visitor.Double(value);
|
|
|
|
}
|
|
|
|
|
2017-03-07 09:32:29 +00:00
|
|
|
void Reflect(Reader& visitor, bool& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsBool())
|
|
|
|
throw std::invalid_argument("bool");
|
2018-01-07 00:22:46 +00:00
|
|
|
value = visitor.GetBool();
|
2017-03-07 09:32:29 +00:00
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, bool& value) {
|
|
|
|
visitor.Bool(value);
|
2017-02-23 08:47:07 +00:00
|
|
|
}
|
2018-01-06 19:26:37 +00:00
|
|
|
|
2017-03-07 09:32:29 +00:00
|
|
|
// std::string
|
|
|
|
void Reflect(Reader& visitor, std::string& value) {
|
2018-01-30 00:27:43 +00:00
|
|
|
if (!visitor.IsString())
|
|
|
|
throw std::invalid_argument("std::string");
|
2018-01-19 06:47:44 +00:00
|
|
|
value = visitor.GetString();
|
2017-03-07 09:32:29 +00:00
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, std::string& value) {
|
2017-04-19 05:38:39 +00:00
|
|
|
visitor.String(value.c_str(), (rapidjson::SizeType)value.size());
|
2017-02-23 08:47:07 +00:00
|
|
|
}
|
|
|
|
|
2017-03-08 08:09:15 +00:00
|
|
|
// ReflectMember
|
|
|
|
void ReflectMember(Writer& visitor, const char* name, std::string& value) {
|
|
|
|
visitor.Key(name);
|
|
|
|
Reflect(visitor, value);
|
|
|
|
}
|
|
|
|
|
2017-05-19 07:02:01 +00:00
|
|
|
// TODO: Move this to indexer.cc
|
2017-11-30 03:18:25 +00:00
|
|
|
void Reflect(Reader& visitor, IndexInclude& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-11-30 03:18:25 +00:00
|
|
|
REFLECT_MEMBER(line);
|
|
|
|
REFLECT_MEMBER(resolved_path);
|
|
|
|
REFLECT_MEMBER_END();
|
|
|
|
}
|
|
|
|
void Reflect(Writer& visitor, IndexInclude& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-11-30 03:18:25 +00:00
|
|
|
REFLECT_MEMBER(line);
|
|
|
|
if (gTestOutputMode) {
|
|
|
|
std::string basename = GetBaseName(value.resolved_path);
|
|
|
|
if (!StartsWith(value.resolved_path, "&"))
|
|
|
|
basename = "&" + basename;
|
|
|
|
REFLECT_MEMBER2("resolved_path", basename);
|
|
|
|
} else {
|
|
|
|
REFLECT_MEMBER(resolved_path);
|
|
|
|
}
|
|
|
|
REFLECT_MEMBER_END();
|
|
|
|
}
|
2017-03-07 09:32:29 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-05-12 06:08:15 +00:00
|
|
|
void Reflect(TVisitor& visitor, IndexType& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("id", value.id);
|
2017-12-12 07:56:50 +00:00
|
|
|
REFLECT_MEMBER2("usr", value.usr);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("short_name", value.def.short_name);
|
2017-04-15 04:58:07 +00:00
|
|
|
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
2018-01-07 16:43:53 +00:00
|
|
|
REFLECT_MEMBER2("kind", value.def.kind);
|
2017-12-19 05:20:00 +00:00
|
|
|
REFLECT_MEMBER2("hover", value.def.hover);
|
2017-12-24 02:22:22 +00:00
|
|
|
REFLECT_MEMBER2("comments", value.def.comments);
|
2017-04-05 08:29:15 +00:00
|
|
|
REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling);
|
|
|
|
REFLECT_MEMBER2("definition_extent", value.def.definition_extent);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("alias_of", value.def.alias_of);
|
|
|
|
REFLECT_MEMBER2("parents", value.def.parents);
|
|
|
|
REFLECT_MEMBER2("derived", value.derived);
|
|
|
|
REFLECT_MEMBER2("types", value.def.types);
|
|
|
|
REFLECT_MEMBER2("funcs", value.def.funcs);
|
|
|
|
REFLECT_MEMBER2("vars", value.def.vars);
|
2017-04-21 07:04:56 +00:00
|
|
|
REFLECT_MEMBER2("instances", value.instances);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("uses", value.uses);
|
|
|
|
REFLECT_MEMBER_END();
|
2017-03-01 04:12:57 +00:00
|
|
|
}
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-05-12 06:08:15 +00:00
|
|
|
void Reflect(TVisitor& visitor, IndexFunc& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("id", value.id);
|
2017-12-12 07:56:50 +00:00
|
|
|
REFLECT_MEMBER2("usr", value.usr);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("short_name", value.def.short_name);
|
2017-04-15 04:58:07 +00:00
|
|
|
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
2018-01-07 16:43:53 +00:00
|
|
|
REFLECT_MEMBER2("kind", value.def.kind);
|
2018-01-26 17:28:29 +00:00
|
|
|
REFLECT_MEMBER2("storage", value.def.storage);
|
2017-12-19 05:20:00 +00:00
|
|
|
REFLECT_MEMBER2("hover", value.def.hover);
|
2017-12-24 02:22:22 +00:00
|
|
|
REFLECT_MEMBER2("comments", value.def.comments);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("declarations", value.declarations);
|
2017-04-05 08:29:15 +00:00
|
|
|
REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling);
|
|
|
|
REFLECT_MEMBER2("definition_extent", value.def.definition_extent);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("declaring_type", value.def.declaring_type);
|
|
|
|
REFLECT_MEMBER2("base", value.def.base);
|
|
|
|
REFLECT_MEMBER2("derived", value.derived);
|
|
|
|
REFLECT_MEMBER2("locals", value.def.locals);
|
|
|
|
REFLECT_MEMBER2("callers", value.callers);
|
|
|
|
REFLECT_MEMBER2("callees", value.def.callees);
|
|
|
|
REFLECT_MEMBER_END();
|
2017-03-01 04:12:57 +00:00
|
|
|
}
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-05-12 06:08:15 +00:00
|
|
|
void Reflect(TVisitor& visitor, IndexVar& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("id", value.id);
|
2017-12-12 07:56:50 +00:00
|
|
|
REFLECT_MEMBER2("usr", value.usr);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("short_name", value.def.short_name);
|
2017-04-15 04:58:07 +00:00
|
|
|
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
|
2017-12-19 05:20:00 +00:00
|
|
|
REFLECT_MEMBER2("hover", value.def.hover);
|
2017-12-24 02:22:22 +00:00
|
|
|
REFLECT_MEMBER2("comments", value.def.comments);
|
2018-01-27 05:50:17 +00:00
|
|
|
REFLECT_MEMBER2("declarations", value.declarations);
|
2017-04-05 08:29:15 +00:00
|
|
|
REFLECT_MEMBER2("definition_spelling", value.def.definition_spelling);
|
|
|
|
REFLECT_MEMBER2("definition_extent", value.def.definition_extent);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER2("variable_type", value.def.variable_type);
|
|
|
|
REFLECT_MEMBER2("uses", value.uses);
|
2018-01-28 20:34:31 +00:00
|
|
|
REFLECT_MEMBER2("parent_id", value.def.parent_id);
|
|
|
|
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
|
|
|
|
REFLECT_MEMBER2("kind", value.def.kind);
|
|
|
|
REFLECT_MEMBER2("storage", value.def.storage);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER_END();
|
2017-02-28 08:37:20 +00:00
|
|
|
}
|
|
|
|
|
2017-05-12 06:08:15 +00:00
|
|
|
// IndexFile
|
2018-01-08 04:10:16 +00:00
|
|
|
bool ReflectMemberStart(Writer& visitor, IndexFile& value) {
|
2018-01-13 06:13:08 +00:00
|
|
|
// FIXME
|
2018-01-14 21:18:12 +00:00
|
|
|
auto it = value.id_cache.usr_to_type_id.find(HashUsr(""));
|
2017-03-07 09:32:29 +00:00
|
|
|
if (it != value.id_cache.usr_to_type_id.end()) {
|
|
|
|
value.Resolve(it->second)->def.short_name = "<fundamental>";
|
|
|
|
assert(value.Resolve(it->second)->uses.size() == 0);
|
2017-03-01 04:12:57 +00:00
|
|
|
}
|
|
|
|
|
2018-01-08 04:10:16 +00:00
|
|
|
DefaultReflectMemberStart(visitor);
|
2017-03-07 09:32:29 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename TVisitor>
|
2017-05-12 06:08:15 +00:00
|
|
|
void Reflect(TVisitor& visitor, IndexFile& value) {
|
2018-01-08 04:10:16 +00:00
|
|
|
REFLECT_MEMBER_START();
|
2017-04-20 06:02:24 +00:00
|
|
|
if (!gTestOutputMode) {
|
|
|
|
REFLECT_MEMBER(last_modification_time);
|
2017-11-30 03:47:29 +00:00
|
|
|
REFLECT_MEMBER(language);
|
2017-04-20 07:25:38 +00:00
|
|
|
REFLECT_MEMBER(import_file);
|
2017-04-21 04:06:15 +00:00
|
|
|
REFLECT_MEMBER(args);
|
2017-04-20 06:02:24 +00:00
|
|
|
}
|
2017-05-21 03:46:15 +00:00
|
|
|
REFLECT_MEMBER(includes);
|
2017-11-30 03:18:25 +00:00
|
|
|
if (!gTestOutputMode)
|
|
|
|
REFLECT_MEMBER(dependencies);
|
2017-05-20 21:45:46 +00:00
|
|
|
REFLECT_MEMBER(skipped_by_preprocessor);
|
2017-03-07 18:17:49 +00:00
|
|
|
REFLECT_MEMBER(types);
|
|
|
|
REFLECT_MEMBER(funcs);
|
|
|
|
REFLECT_MEMBER(vars);
|
2017-03-07 09:32:29 +00:00
|
|
|
REFLECT_MEMBER_END();
|
2017-03-01 04:12:57 +00:00
|
|
|
}
|
|
|
|
|
2018-01-09 08:20:51 +00:00
|
|
|
void Reflect(Reader& visitor, std::monostate&) {
|
|
|
|
visitor.GetNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Reflect(Writer& visitor, std::monostate&) {
|
|
|
|
visitor.Null();
|
|
|
|
}
|
|
|
|
|
2018-01-09 06:22:24 +00:00
|
|
|
void Reflect(Reader& visitor, SerializeFormat& value) {
|
|
|
|
std::string fmt = visitor.GetString();
|
|
|
|
value = fmt[0] == 'm' ? SerializeFormat::MessagePack : SerializeFormat::Json;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Reflect(Writer& visitor, SerializeFormat& value) {
|
|
|
|
switch (value) {
|
|
|
|
case SerializeFormat::Json:
|
|
|
|
visitor.String("json");
|
|
|
|
break;
|
|
|
|
case SerializeFormat::MessagePack:
|
|
|
|
visitor.String("msgpack");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-07 02:01:32 +00:00
|
|
|
std::string Serialize(SerializeFormat format, IndexFile& file) {
|
|
|
|
switch (format) {
|
|
|
|
case SerializeFormat::Json: {
|
|
|
|
rapidjson::StringBuffer output;
|
|
|
|
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(output);
|
|
|
|
writer.SetFormatOptions(
|
|
|
|
rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
|
|
|
|
writer.SetIndent(' ', 2);
|
|
|
|
JsonWriter json_writer(&writer);
|
2018-01-28 05:47:37 +00:00
|
|
|
if (!gTestOutputMode) {
|
|
|
|
std::string version = std::to_string(IndexFile::kMajorVersion);
|
|
|
|
for (char c : version)
|
|
|
|
output.Put(c);
|
|
|
|
output.Put('\n');
|
|
|
|
}
|
2018-01-07 02:01:32 +00:00
|
|
|
Reflect(json_writer, file);
|
|
|
|
return output.GetString();
|
|
|
|
}
|
|
|
|
case SerializeFormat::MessagePack: {
|
|
|
|
msgpack::sbuffer buf;
|
|
|
|
msgpack::packer<msgpack::sbuffer> pk(&buf);
|
|
|
|
MessagePackWriter msgpack_writer(&pk);
|
2018-01-28 05:47:37 +00:00
|
|
|
uint64_t magic = IndexFile::kMajorVersion;
|
|
|
|
int version = IndexFile::kMinorVersion;
|
2018-01-28 03:21:35 +00:00
|
|
|
Reflect(msgpack_writer, magic);
|
|
|
|
Reflect(msgpack_writer, version);
|
2018-01-07 02:01:32 +00:00
|
|
|
Reflect(msgpack_writer, file);
|
|
|
|
return std::string(buf.data(), buf.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
2017-03-01 04:12:57 +00:00
|
|
|
}
|
|
|
|
|
2018-01-06 23:29:53 +00:00
|
|
|
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
2018-01-28 05:47:37 +00:00
|
|
|
const std::string& path,
|
2018-01-30 05:34:28 +00:00
|
|
|
const std::string& serialized_index_content,
|
|
|
|
const std::string& file_content,
|
2017-09-22 01:14:57 +00:00
|
|
|
optional<int> expected_version) {
|
2018-01-30 05:34:28 +00:00
|
|
|
if (serialized_index_content.empty())
|
|
|
|
return nullptr;
|
|
|
|
|
2018-01-07 02:01:32 +00:00
|
|
|
std::unique_ptr<IndexFile> file;
|
|
|
|
switch (format) {
|
|
|
|
case SerializeFormat::Json: {
|
|
|
|
rapidjson::Document reader;
|
2018-01-28 05:47:37 +00:00
|
|
|
if (gTestOutputMode)
|
2018-01-30 05:34:28 +00:00
|
|
|
reader.Parse(serialized_index_content.c_str());
|
2018-01-28 05:47:37 +00:00
|
|
|
else {
|
2018-01-30 05:34:28 +00:00
|
|
|
const char* p = strchr(serialized_index_content.c_str(), '\n');
|
2018-01-28 05:47:37 +00:00
|
|
|
if (!p)
|
2018-01-07 02:01:32 +00:00
|
|
|
return nullptr;
|
2018-01-30 05:34:28 +00:00
|
|
|
if (expected_version && atoi(serialized_index_content.c_str()) != *expected_version)
|
2018-01-28 05:47:37 +00:00
|
|
|
return nullptr;
|
|
|
|
reader.Parse(p + 1);
|
2018-01-07 02:01:32 +00:00
|
|
|
}
|
2018-01-28 05:47:37 +00:00
|
|
|
if (reader.HasParseError())
|
|
|
|
return nullptr;
|
2018-01-07 02:01:32 +00:00
|
|
|
|
2018-01-30 05:34:28 +00:00
|
|
|
file = MakeUnique<IndexFile>(path, file_content);
|
2018-01-07 02:01:32 +00:00
|
|
|
JsonReader json_reader{&reader};
|
2018-01-19 06:47:44 +00:00
|
|
|
try {
|
|
|
|
Reflect(json_reader, *file);
|
|
|
|
} catch (std::invalid_argument& e) {
|
2018-01-28 03:21:35 +00:00
|
|
|
LOG_S(INFO) << "'" << path << "': failed to deserialize "
|
2018-01-30 00:27:43 +00:00
|
|
|
<< json_reader.GetPath() << "." << e.what();
|
2018-01-19 06:47:44 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-01-07 02:01:32 +00:00
|
|
|
break;
|
2017-06-14 04:00:51 +00:00
|
|
|
}
|
2017-03-01 04:12:57 +00:00
|
|
|
|
2018-01-07 02:01:32 +00:00
|
|
|
case SerializeFormat::MessagePack: {
|
2018-01-07 04:10:08 +00:00
|
|
|
try {
|
2018-01-28 05:47:37 +00:00
|
|
|
int major, minor;
|
2018-01-30 05:34:28 +00:00
|
|
|
if (serialized_index_content.size() < 8)
|
2018-01-28 03:21:35 +00:00
|
|
|
throw std::invalid_argument("Invalid");
|
2018-01-08 04:10:16 +00:00
|
|
|
msgpack::unpacker upk;
|
2018-01-30 05:34:28 +00:00
|
|
|
upk.reserve_buffer(serialized_index_content.size());
|
|
|
|
memcpy(upk.buffer(), serialized_index_content.data(), serialized_index_content.size());
|
|
|
|
upk.buffer_consumed(serialized_index_content.size());
|
|
|
|
file = MakeUnique<IndexFile>(path, file_content);
|
2018-01-08 04:10:16 +00:00
|
|
|
MessagePackReader reader(&upk);
|
2018-01-28 05:47:37 +00:00
|
|
|
Reflect(reader, major);
|
|
|
|
Reflect(reader, minor);
|
|
|
|
if (major != IndexFile::kMajorVersion ||
|
|
|
|
minor != IndexFile::kMinorVersion)
|
|
|
|
throw std::invalid_argument("Invalid version");
|
2018-01-28 03:21:35 +00:00
|
|
|
Reflect(reader, *file);
|
2018-01-26 17:28:29 +00:00
|
|
|
} catch (std::invalid_argument& e) {
|
2018-01-28 03:21:35 +00:00
|
|
|
LOG_S(INFO) << "Failed to deserialize msgpack '" << path
|
|
|
|
<< "': " << e.what();
|
2018-01-07 04:10:08 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
2018-01-07 02:01:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-04-19 00:05:14 +00:00
|
|
|
|
2017-04-10 00:08:54 +00:00
|
|
|
// Restore non-serialized state.
|
2017-06-14 04:00:51 +00:00
|
|
|
file->path = path;
|
|
|
|
file->id_cache.primary_file = file->path;
|
|
|
|
for (const auto& type : file->types) {
|
2017-12-12 07:56:50 +00:00
|
|
|
file->id_cache.type_id_to_usr[type.id] = type.usr;
|
|
|
|
file->id_cache.usr_to_type_id[type.usr] = type.id;
|
2017-04-10 00:08:54 +00:00
|
|
|
}
|
2017-06-14 04:00:51 +00:00
|
|
|
for (const auto& func : file->funcs) {
|
2017-12-12 07:56:50 +00:00
|
|
|
file->id_cache.func_id_to_usr[func.id] = func.usr;
|
|
|
|
file->id_cache.usr_to_func_id[func.usr] = func.id;
|
2017-04-10 00:08:54 +00:00
|
|
|
}
|
2017-06-14 04:00:51 +00:00
|
|
|
for (const auto& var : file->vars) {
|
2017-12-12 07:56:50 +00:00
|
|
|
file->id_cache.var_id_to_usr[var.id] = var.usr;
|
|
|
|
file->id_cache.usr_to_var_id[var.usr] = var.id;
|
2017-04-10 00:08:54 +00:00
|
|
|
}
|
2017-03-07 09:32:29 +00:00
|
|
|
|
2017-03-01 04:12:57 +00:00
|
|
|
return file;
|
|
|
|
}
|
2017-04-20 06:02:24 +00:00
|
|
|
|
|
|
|
void SetTestOutputMode() {
|
|
|
|
gTestOutputMode = true;
|
2017-05-11 01:44:39 +00:00
|
|
|
}
|
2017-11-30 03:18:25 +00:00
|
|
|
|
|
|
|
TEST_SUITE("Serializer utils") {
|
|
|
|
TEST_CASE("GetBaseName") {
|
|
|
|
REQUIRE(GetBaseName("foo.cc") == "foo.cc");
|
|
|
|
REQUIRE(GetBaseName("foo/foo.cc") == "foo.cc");
|
|
|
|
REQUIRE(GetBaseName("/foo.cc") == "foo.cc");
|
|
|
|
REQUIRE(GetBaseName("///foo.cc") == "foo.cc");
|
|
|
|
REQUIRE(GetBaseName("bar/") == "bar/");
|
|
|
|
REQUIRE(GetBaseName("foobar/bar/") ==
|
|
|
|
"foobar/bar/"); // TODO: Should be bar, but good enough.
|
|
|
|
}
|
|
|
|
}
|