ccls/serializer.cc
2017-02-24 22:08:14 -08:00

274 lines
6.1 KiB
C++

#include "serializer.h"
#include "indexer.h"
#if false
template<typename T>
void Emit(Reader& a, const char* key, T& v) {
static_assert(false); // Must be specialized.
}
template<typename T>
void Emit(Writer& a, const char* key, T& v) {
static_assert(false); // Must be specialized.
}
template<>
void Emit(Reader& r, const char* key, int& v) {
v = r[key].GetInt();
}
template<>
void Emit(Writer& w, const char* key, int &v) {
w.Key(key);
w.Int(v);
}
void StartObject(Reader& r) {}
void StartObject(Writer& w) {
w.StartObject();
}
void EndObject(Reader& r) {}
void EndObject(Writer& w) {
w.EndObject();
}
void StartArray(Reader& r) {}
void StartArray(Writer& w) {
w.StartArray();
}
void EndArray(Reader& r) {}
void EndArray(Writer& w) {
w.EndArray();
}
struct Object {
//Location l;
int a = 0, b = 0, c = 0;
};
/*
void EmitKey(Reader& r, const char* key) {
w.Key(key);
}
void EmitKey(Writer& w, const char* key) {
w = w[key];
}
*/
template<typename S>
void Serialize(S& stream, Object& obj) {
StartObject(stream);
Emit(stream, "a", obj.a);
Emit(stream, "b", obj.b);
Emit(stream, "b", obj.c);
EndObject(stream);
}
/*
template <typename C, typename T>
C& operator&(C& stream, T& t) {
t.serialize(stream);
}
*/
int main(int argc, char** argv) {
rapidjson::StringBuffer output;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(output);
writer.SetFormatOptions(
rapidjson::PrettyFormatOptions::kFormatSingleLineArray);
writer.SetIndent(' ', 2);
Object foo;
foo.a = 10;
Serialize(writer, foo);
std::cout << output.GetString() << std::endl;
std::cout << "----" << std::endl;
rapidjson::Document doc;
//doc = doc["foo"];
doc.Parse(output.GetString());
Object foo2;
Serialize(doc, foo2);
std::cin.get();
//Reader r;
//foo.Serialize(r);
return 0;
}
#endif
void Serialize(Writer& writer, const char* key, Location location) {
if (key) writer.Key(key);
std::string s = location.ToString();
writer.String(s.c_str());
}
void Serialize(Writer& writer, const char* key, optional<Location> location) {
if (location)
Serialize(writer, key, location.value());
}
void Serialize(Writer& writer, const char* key, const std::vector<Location>& locs) {
if (locs.size() == 0)
return;
if (key) writer.Key(key);
writer.StartArray();
for (const Location& loc : locs)
Serialize(writer, nullptr, loc);
writer.EndArray();
}
template<typename T>
void Serialize(Writer& writer, const char* key, LocalId<T> id) {
if (key) writer.Key(key);
writer.Uint64(id.local_id);
}
template<typename T>
void Serialize(Writer& writer, const char* key, optional<LocalId<T>> id) {
if (id) {
Serialize(writer, key, id.value());
}
}
template<typename T>
void Serialize(Writer& writer, const char* key, const std::vector<LocalId<T>>& ids) {
if (ids.size() == 0)
return;
if (key) writer.Key(key);
writer.StartArray();
for (LocalId<T> id : ids)
Serialize(writer, nullptr, id);
writer.EndArray();
}
template<typename T>
void Serialize(Writer& writer, const char* key, Ref<T> ref) {
if (key) writer.Key(key);
std::string s = std::to_string(ref.id.local_id) + "@" + ref.loc.ToString();
writer.String(s.c_str());
}
template<typename T>
void Serialize(Writer& writer, const char* key, const std::vector<Ref<T>>& refs) {
if (refs.size() == 0)
return;
if (key) writer.Key(key);
writer.StartArray();
for (Ref<T> ref : refs)
Serialize(writer, nullptr, ref);
writer.EndArray();
}
void Serialize(Writer& writer, const char* key, const std::string& value) {
if (value.size() == 0)
return;
if (key) writer.Key(key);
writer.String(value.c_str());
}
void Serialize(Writer& writer, const char* key, uint64_t value) {
if (key) writer.Key(key);
writer.Uint64(value);
}
void Serialize(Writer& writer, IndexedFile* file) {
auto it = file->usr_to_type_id.find("");
if (it != file->usr_to_type_id.end()) {
file->Resolve(it->second)->def.short_name = "<fundamental>";
assert(file->Resolve(it->second)->uses.size() == 0);
}
#define SERIALIZE(name, value) Serialize(writer, name, def.value)
writer.StartObject();
// Types
writer.Key("types");
writer.StartArray();
for (IndexedTypeDef& def : file->types) {
if (def.is_system_def) continue;
writer.StartObject();
SERIALIZE("id", def.id);
SERIALIZE("usr", def.usr);
SERIALIZE("short_name", def.short_name);
SERIALIZE("qualified_name", def.qualified_name);
SERIALIZE("definition", def.definition);
SERIALIZE("alias_of", def.alias_of);
SERIALIZE("parents", def.parents);
SERIALIZE("derived", derived);
SERIALIZE("types", def.types);
SERIALIZE("funcs", def.funcs);
SERIALIZE("vars", def.vars);
SERIALIZE("uses", uses);
writer.EndObject();
}
writer.EndArray();
// Functions
writer.Key("functions");
writer.StartArray();
for (IndexedFuncDef& def : file->funcs) {
if (def.is_system_def) continue;
writer.StartObject();
SERIALIZE("id", def.id);
SERIALIZE("usr", def.usr);
SERIALIZE("short_name", def.short_name);
SERIALIZE("qualified_name", def.qualified_name);
SERIALIZE("declarations", declarations);
SERIALIZE("definition", def.definition);
SERIALIZE("declaring_type", def.declaring_type);
SERIALIZE("base", def.base);
SERIALIZE("derived", derived);
SERIALIZE("locals", def.locals);
SERIALIZE("callers", callers);
SERIALIZE("callees", def.callees);
SERIALIZE("uses", uses);
writer.EndObject();
}
writer.EndArray();
// Variables
writer.Key("variables");
writer.StartArray();
for (IndexedVarDef& def : file->vars) {
if (def.is_system_def) continue;
writer.StartObject();
SERIALIZE("id", def.id);
SERIALIZE("usr", def.usr);
SERIALIZE("short_name", def.short_name);
SERIALIZE("qualified_name", def.qualified_name);
SERIALIZE("declaration", def.declaration);
SERIALIZE("definition", def.definition);
SERIALIZE("variable_type", def.variable_type);
SERIALIZE("declaring_type", def.declaring_type);
SERIALIZE("uses", uses);
writer.EndObject();
}
writer.EndArray();
writer.EndObject();
#undef WRITE
}