mirror of
https://github.com/avast/retdec.git
synced 2024-11-27 14:50:48 +00:00
progress
This commit is contained in:
parent
0505be4929
commit
334ad6083b
@ -23,7 +23,7 @@ class Class
|
||||
{
|
||||
public:
|
||||
std::string dump() const;
|
||||
retdec::config::Class getConfigClass(
|
||||
retdec::common::Class getConfigClass(
|
||||
llvm::Module* m,
|
||||
Config* config) const;
|
||||
|
||||
|
@ -1,19 +1,18 @@
|
||||
/**
|
||||
* @file include/retdec/config/classes.h
|
||||
* @brief Decompilation configuration manipulation: classes.
|
||||
* @copyright (c) 2017 Avast Software, licensed under the MIT license
|
||||
* @file include/retdec/common/class.h
|
||||
* @brief Common class representation.
|
||||
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||
*/
|
||||
|
||||
#ifndef RETDEC_CONFIG_CLASSES_H
|
||||
#define RETDEC_CONFIG_CLASSES_H
|
||||
#ifndef RETDEC_COMMON_CLASS_H
|
||||
#define RETDEC_COMMON_CLASS_H
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "retdec/config/base.h"
|
||||
|
||||
namespace retdec {
|
||||
namespace config {
|
||||
namespace common {
|
||||
|
||||
/**
|
||||
* Represents C++ class.
|
||||
@ -22,10 +21,7 @@ namespace config {
|
||||
class Class
|
||||
{
|
||||
public:
|
||||
explicit Class(const std::string& className);
|
||||
static Class fromJsonValue(const Json::Value& val);
|
||||
|
||||
Json::Value getJsonValue() const;
|
||||
Class(const std::string& className = std::string());
|
||||
|
||||
/// @name Class get methods.
|
||||
/// @{
|
||||
@ -42,6 +38,7 @@ class Class
|
||||
|
||||
/// @name Class set methods.
|
||||
/// @{
|
||||
void setName(const std::string& name);
|
||||
void setDemangledName(const std::string& demangledName);
|
||||
/// @}
|
||||
|
||||
@ -70,12 +67,26 @@ class Class
|
||||
/**
|
||||
* A set container with classes.
|
||||
*/
|
||||
class ClassContainer : public BaseSetContainer<Class>
|
||||
struct ClassCompare
|
||||
{
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator()(const Class& c1, const Class& c2) const
|
||||
{
|
||||
return c1 < c2;
|
||||
}
|
||||
bool operator()(const std::string& id, Class const& c) const
|
||||
{
|
||||
return id < c.getName();
|
||||
}
|
||||
bool operator()(const Class& c, const std::string& id) const
|
||||
{
|
||||
return c.getName() < id;
|
||||
}
|
||||
};
|
||||
using ClassContainer = std::set<Class, ClassCompare>;
|
||||
|
||||
} // namespace config
|
||||
} // namespace common
|
||||
} // namespace retdec
|
||||
|
||||
#endif
|
@ -8,13 +8,13 @@
|
||||
#define RETDEC_CONFIG_CONFIG_H
|
||||
|
||||
#include "retdec/common/architecture.h"
|
||||
#include "retdec/common/class.h"
|
||||
#include "retdec/common/file_format.h"
|
||||
#include "retdec/common/file_type.h"
|
||||
#include "retdec/common/language.h"
|
||||
#include "retdec/common/tool_info.h"
|
||||
#include "retdec/common/vtable.h"
|
||||
#include "retdec/config/base.h"
|
||||
#include "retdec/config/classes.h"
|
||||
#include "retdec/config/functions.h"
|
||||
#include "retdec/config/parameters.h"
|
||||
#include "retdec/config/patterns.h"
|
||||
@ -86,7 +86,7 @@ class Config
|
||||
RegisterContainer registers;
|
||||
TypeContainer structures;
|
||||
common::VtableContainer vtables;
|
||||
ClassContainer classes;
|
||||
common::ClassContainer classes;
|
||||
PatternContainer patterns;
|
||||
|
||||
private:
|
||||
|
26
include/retdec/serdes/class.h
Normal file
26
include/retdec/serdes/class.h
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @file include/retdec/serdes/class.h
|
||||
* @brief Class (de)serialization.
|
||||
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||
*/
|
||||
|
||||
#ifndef RETDEC_SERDES_CLASS_H
|
||||
#define RETDEC_SERDES_CLASS_H
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
namespace retdec {
|
||||
|
||||
namespace common {
|
||||
class Class;
|
||||
} // namespace common
|
||||
|
||||
namespace serdes {
|
||||
|
||||
Json::Value serialize(const common::Class& c);
|
||||
void deserialize(const Json::Value& val, common::Class& c);
|
||||
|
||||
} // namespace serdes
|
||||
} // namespace retdec
|
||||
|
||||
#endif
|
@ -52,11 +52,11 @@ std::string Class::dump() const
|
||||
return out.str();
|
||||
}
|
||||
|
||||
retdec::config::Class Class::getConfigClass(
|
||||
retdec::common::Class Class::getConfigClass(
|
||||
llvm::Module* m,
|
||||
Config* config) const
|
||||
{
|
||||
retdec::config::Class c(name);
|
||||
retdec::common::Class c(name);
|
||||
|
||||
auto* demangler = DemanglerProvider::getDemangler(m);
|
||||
if (demangler)
|
||||
|
@ -3,6 +3,7 @@ add_library(retdec-common STATIC
|
||||
address.cpp
|
||||
architecture.cpp
|
||||
calling_convention.cpp
|
||||
class.cpp
|
||||
file_format.cpp
|
||||
file_type.cpp
|
||||
language.cpp
|
||||
|
@ -1,30 +1,16 @@
|
||||
/**
|
||||
* @file src/config/classes.cpp
|
||||
* @brief Decompilation configuration manipulation: classes.
|
||||
* @copyright (c) 2017 Avast Software, licensed under the MIT license
|
||||
* @file src/common/class.cpp
|
||||
* @brief Common class representation.
|
||||
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||
*/
|
||||
|
||||
#include "retdec/config/classes.h"
|
||||
#include "retdec/serdes/std.h"
|
||||
#include "retdec/common/class.h"
|
||||
#include "retdec/utils/container.h"
|
||||
|
||||
using retdec::utils::hasItem;
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string JSON_name = "name";
|
||||
const std::string JSON_demangledName = "demangledName";
|
||||
const std::string JSON_superClasses = "superClasses";
|
||||
const std::string JSON_virtualMethods = "virtualMethods";
|
||||
const std::string JSON_constructors = "constructors";
|
||||
const std::string JSON_destructors = "destructors";
|
||||
const std::string JSON_methods = "methods";
|
||||
const std::string JSON_vtables = "virtualTables";
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace retdec {
|
||||
namespace config {
|
||||
namespace common {
|
||||
|
||||
//
|
||||
//=============================================================================
|
||||
@ -38,48 +24,6 @@ Class::Class(const std::string& className) :
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads JSON object (associative array) holding class information.
|
||||
* @param val JSON object.
|
||||
*/
|
||||
Class Class::fromJsonValue(const Json::Value& val)
|
||||
{
|
||||
checkJsonValueIsObject(val, "Class");
|
||||
|
||||
Class ret(safeGetString(val, JSON_name));
|
||||
|
||||
ret.setDemangledName(safeGetString(val, JSON_demangledName));
|
||||
serdes::deserialize(val[JSON_superClasses], ret._superClasses);
|
||||
serdes::deserialize(val[JSON_virtualMethods], ret.virtualMethods);
|
||||
serdes::deserialize(val[JSON_constructors], ret.constructors);
|
||||
serdes::deserialize(val[JSON_destructors], ret.destructors);
|
||||
serdes::deserialize(val[JSON_methods], ret.methods);
|
||||
serdes::deserialize(val[JSON_vtables], ret.virtualTables);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns JSON object (associative array) holding class information.
|
||||
* @return JSON object.
|
||||
*/
|
||||
Json::Value Class::getJsonValue() const
|
||||
{
|
||||
Json::Value val;
|
||||
|
||||
if (!getName().empty()) val[JSON_name] = getName();
|
||||
if (!getDemangledName().empty()) val[JSON_demangledName] = getDemangledName();
|
||||
|
||||
val[JSON_superClasses] = serdes::serialize(_superClasses);
|
||||
val[JSON_virtualMethods] = serdes::serialize(virtualMethods);
|
||||
val[JSON_constructors] = serdes::serialize(constructors);
|
||||
val[JSON_destructors] = serdes::serialize(destructors);
|
||||
val[JSON_methods] = serdes::serialize(methods);
|
||||
val[JSON_vtables] = serdes::serialize(virtualTables);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Class's ID is its name.
|
||||
*/
|
||||
@ -103,6 +47,11 @@ const std::vector<std::string>& Class::getSuperClasses() const
|
||||
return _superClasses;
|
||||
}
|
||||
|
||||
void Class::setName(const std::string& name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
void Class::setDemangledName(const std::string& demangledName)
|
||||
{
|
||||
_demangledName = demangledName;
|
||||
@ -187,5 +136,5 @@ bool Class::operator==(const Class& o) const
|
||||
return getName() == o.getName();
|
||||
}
|
||||
|
||||
} // namespace config
|
||||
} // namespace common
|
||||
} // namespace retdec
|
@ -1,7 +1,6 @@
|
||||
|
||||
add_library(retdec-config STATIC
|
||||
base.cpp
|
||||
classes.cpp
|
||||
config.cpp
|
||||
functions.cpp
|
||||
objects.cpp
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "retdec/config/config.h"
|
||||
#include "retdec/serdes/address.h"
|
||||
#include "retdec/serdes/architecture.h"
|
||||
#include "retdec/serdes/class.h"
|
||||
#include "retdec/serdes/file_format.h"
|
||||
#include "retdec/serdes/file_type.h"
|
||||
#include "retdec/serdes/language.h"
|
||||
@ -183,7 +184,7 @@ std::string Config::generateJsonString() const
|
||||
root[JSON_registers] = registers.getJsonValue();
|
||||
root[JSON_structures] = structures.getJsonValue();
|
||||
root[JSON_vtables] = serdes::serialize(vtables);
|
||||
root[JSON_classes] = classes.getJsonValue();
|
||||
root[JSON_classes] = serdes::serialize(classes);
|
||||
root[JSON_patterns] = patterns.getJsonValue();
|
||||
|
||||
StreamWriterBuilder builder;
|
||||
@ -257,7 +258,7 @@ void Config::readJsonString(const std::string& json)
|
||||
registers.readJsonValue( root[JSON_registers] );
|
||||
structures.readJsonValue( root[JSON_structures] );
|
||||
serdes::deserialize(root[JSON_vtables], vtables);
|
||||
classes.readJsonValue( root[JSON_classes] );
|
||||
serdes::deserialize(root[JSON_classes], classes);
|
||||
patterns.readJsonValue( root[JSON_patterns] );
|
||||
}
|
||||
catch (const InternalException& e)
|
||||
|
@ -35,8 +35,8 @@ struct JSONConfig::Impl {
|
||||
const retdec::config::Function *getConfigFunctionByName(const std::string &name) const;
|
||||
const retdec::config::Function &getConfigFunctionByNameOrEmptyFunction(
|
||||
const std::string &name) const;
|
||||
const retdec::config::Class *getConfigClassByName(const std::string &name) const;
|
||||
const retdec::config::Class &getConfigClassByNameOrEmptyClass(
|
||||
const retdec::common::Class *getConfigClassByName(const std::string &name) const;
|
||||
const retdec::common::Class &getConfigClassByNameOrEmptyClass(
|
||||
const std::string &name) const;
|
||||
std::string getNameOfRegister(const retdec::config::Object ®) const;
|
||||
|
||||
@ -85,9 +85,10 @@ const retdec::config::Function &JSONConfig::Impl::getConfigFunctionByNameOrEmpty
|
||||
return f ? *f : emptyFunction;
|
||||
}
|
||||
|
||||
const retdec::config::Class *JSONConfig::Impl::getConfigClassByName(
|
||||
const retdec::common::Class *JSONConfig::Impl::getConfigClassByName(
|
||||
const std::string &name) const {
|
||||
return config.classes.getElementById(name);
|
||||
auto it = config.classes.find(name);
|
||||
return it != config.classes.end() ? &(*it) : nullptr;
|
||||
}
|
||||
|
||||
std::string JSONConfig::Impl::getNameOfRegister(const retdec::config::Object ®) const {
|
||||
@ -105,9 +106,9 @@ std::string JSONConfig::Impl::getNameOfRegister(const retdec::config::Object &re
|
||||
return !realName.empty() ? realName : name;
|
||||
}
|
||||
|
||||
const retdec::config::Class &JSONConfig::Impl::getConfigClassByNameOrEmptyClass(
|
||||
const retdec::common::Class &JSONConfig::Impl::getConfigClassByNameOrEmptyClass(
|
||||
const std::string &name) const {
|
||||
static const retdec::config::Class emptyClass(""s);
|
||||
static const retdec::common::Class emptyClass(""s);
|
||||
auto c = getConfigClassByName(name);
|
||||
return c ? *c : emptyClass;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ add_library(retdec-serdes STATIC
|
||||
address.cpp
|
||||
architecture.cpp
|
||||
calling_convention.cpp
|
||||
class.cpp
|
||||
file_format.cpp
|
||||
file_type.cpp
|
||||
language.cpp
|
||||
|
80
src/serdes/class.cpp
Normal file
80
src/serdes/class.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @file src/serdes/class.h
|
||||
* @brief Class (de)serialization.
|
||||
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "retdec/common/class.h"
|
||||
#include "retdec/serdes/class.h"
|
||||
#include "retdec/serdes/std.h"
|
||||
|
||||
#include "serdes/utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string JSON_name = "name";
|
||||
const std::string JSON_demangledName = "demangledName";
|
||||
const std::string JSON_superClasses = "superClasses";
|
||||
const std::string JSON_virtualMethods = "virtualMethods";
|
||||
const std::string JSON_constructors = "constructors";
|
||||
const std::string JSON_destructors = "destructors";
|
||||
const std::string JSON_methods = "methods";
|
||||
const std::string JSON_vtables = "virtualTables";
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace retdec {
|
||||
namespace serdes {
|
||||
|
||||
Json::Value serialize(const common::Class& c)
|
||||
{
|
||||
Json::Value val;
|
||||
|
||||
if (!c.getName().empty())
|
||||
{
|
||||
val[JSON_name] = c.getName();
|
||||
}
|
||||
if (!c.getDemangledName().empty())
|
||||
{
|
||||
val[JSON_demangledName] = c.getDemangledName();
|
||||
}
|
||||
|
||||
val[JSON_superClasses] = serdes::serialize(c.getSuperClasses());
|
||||
val[JSON_virtualMethods] = serdes::serialize(c.virtualMethods);
|
||||
val[JSON_constructors] = serdes::serialize(c.constructors);
|
||||
val[JSON_destructors] = serdes::serialize(c.destructors);
|
||||
val[JSON_methods] = serdes::serialize(c.methods);
|
||||
val[JSON_vtables] = serdes::serialize(c.virtualTables);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void deserialize(const Json::Value& val, common::Class& c)
|
||||
{
|
||||
if (val.isNull() || !val.isObject())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
c.setName(safeGetString(val, JSON_name));
|
||||
c.setDemangledName(safeGetString(val, JSON_demangledName));
|
||||
|
||||
serdes::deserialize(val[JSON_virtualMethods], c.virtualMethods);
|
||||
serdes::deserialize(val[JSON_constructors], c.constructors);
|
||||
serdes::deserialize(val[JSON_destructors], c.destructors);
|
||||
serdes::deserialize(val[JSON_methods], c.methods);
|
||||
serdes::deserialize(val[JSON_vtables], c.virtualTables);
|
||||
|
||||
std::vector<std::string> superClasses;
|
||||
serdes::deserialize(val[JSON_superClasses], superClasses);
|
||||
for (auto& s : superClasses)
|
||||
{
|
||||
c.addSuperClass(s);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace serdes
|
||||
} // namespace retdec
|
@ -2,6 +2,7 @@
|
||||
add_executable(retdec-tests-common
|
||||
address_tests.cpp
|
||||
architecture_tests.cpp
|
||||
class_tests.cpp
|
||||
file_format_tests.cpp
|
||||
file_type_tests.cpp
|
||||
language_tests.cpp
|
||||
|
@ -1,96 +1,22 @@
|
||||
/**
|
||||
* @file tests/config/classes_tests.cpp
|
||||
* @brief Tests for the @c classes module.
|
||||
* @copyright (c) 2017 Avast Software, licensed under the MIT license
|
||||
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "retdec/config/classes.h"
|
||||
#include "retdec/config/config.h"
|
||||
#include "retdec/common/class.h"
|
||||
|
||||
using namespace ::testing;
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace retdec {
|
||||
namespace config {
|
||||
namespace common {
|
||||
namespace tests {
|
||||
|
||||
class ClassesTests: public Test {};
|
||||
|
||||
//
|
||||
// Parsing
|
||||
//
|
||||
|
||||
TEST_F(ClassesTests,
|
||||
ClassesAreEmptyWhenConfigIsCreated) {
|
||||
Config config;
|
||||
ASSERT_TRUE(config.classes.empty());
|
||||
}
|
||||
|
||||
TEST_F(ClassesTests,
|
||||
NoClassesAreParsedCorrectly) {
|
||||
Config config;
|
||||
|
||||
config.readJsonString(R"({
|
||||
"classes" : []
|
||||
})");
|
||||
|
||||
ASSERT_TRUE(config.classes.empty());
|
||||
}
|
||||
|
||||
TEST_F(ClassesTests,
|
||||
ClassIsParsedCorrectlyFromJSONWhenClassIsFullySpecified) {
|
||||
Config config;
|
||||
|
||||
config.readJsonString(R"({
|
||||
"classes" : [
|
||||
{
|
||||
"name" : "A",
|
||||
"constructors" : [ "Actor" ],
|
||||
"destructors" : [ "Adtor" ],
|
||||
"methods" : [ "Amethod" ],
|
||||
"superClasses" : [ "Asuper" ],
|
||||
"virtualMethods" : [ "Avirtual" ],
|
||||
"virtualTables" : [ "Avtable" ]
|
||||
}
|
||||
]
|
||||
})");
|
||||
|
||||
ASSERT_EQ(1, config.classes.size());
|
||||
auto cl = *config.classes.begin();
|
||||
EXPECT_EQ("A", cl.getName());
|
||||
EXPECT_EQ(std::set<std::string>({"Actor"}), cl.constructors);
|
||||
EXPECT_EQ(std::set<std::string>({"Adtor"}), cl.destructors);
|
||||
EXPECT_EQ(std::set<std::string>({"Amethod"}), cl.methods);
|
||||
EXPECT_EQ(std::vector<std::string>({"Asuper"}), cl.getSuperClasses());
|
||||
EXPECT_EQ(std::set<std::string>({"Avirtual"}), cl.virtualMethods);
|
||||
EXPECT_EQ(std::set<std::string>({"Avtable"}), cl.virtualTables);
|
||||
}
|
||||
|
||||
TEST_F(ClassesTests,
|
||||
ClassIsParsedCorrectlyFromJSONWhenClassHasOnlyNameSpecified) {
|
||||
Config config;
|
||||
|
||||
config.readJsonString(R"({
|
||||
"classes" : [
|
||||
{
|
||||
"name" : "A"
|
||||
}
|
||||
]
|
||||
})");
|
||||
|
||||
ASSERT_EQ(1, config.classes.size());
|
||||
auto cl = *config.classes.begin();
|
||||
EXPECT_EQ("A", cl.getName());
|
||||
EXPECT_TRUE(cl.constructors.empty());
|
||||
EXPECT_TRUE(cl.destructors.empty());
|
||||
EXPECT_TRUE(cl.methods.empty());
|
||||
EXPECT_TRUE(cl.getSuperClasses().empty());
|
||||
EXPECT_TRUE(cl.virtualMethods.empty());
|
||||
EXPECT_TRUE(cl.virtualTables.empty());
|
||||
}
|
||||
|
||||
//
|
||||
// hasConstructor()
|
||||
//
|
||||
@ -267,5 +193,5 @@ AddSuperClassDoesNotAddSameSuperclassTwice) {
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace config
|
||||
} // namespace common
|
||||
} // namespace retdec
|
@ -1,7 +1,6 @@
|
||||
|
||||
add_executable(retdec-tests-config
|
||||
base_tests.cpp
|
||||
classes_tests.cpp
|
||||
documentation_tests.cpp
|
||||
functions_tests.cpp
|
||||
objects_tests.cpp
|
||||
|
@ -77,7 +77,7 @@ TEST_F(ConfigTests, SuccessfulReadJsonStringResetsAllConfigData)
|
||||
|
||||
TEST_F(ConfigTests, ClassesGetElementByIdReturnsNullPointerWhenThereIsNoSuchClass)
|
||||
{
|
||||
ASSERT_EQ(nullptr, config.classes.getElementById("ClassName"));
|
||||
ASSERT_EQ(config.classes.end(), config.classes.find("ClassName"));
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
add_executable(retdec-tests-serdes
|
||||
calling_convention_tests.cpp
|
||||
class_tests.cpp
|
||||
)
|
||||
target_link_libraries(retdec-tests-serdes
|
||||
retdec-serdes
|
||||
|
77
tests/serdes/class_tests.cpp
Normal file
77
tests/serdes/class_tests.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file tests/serdes/classe_tests.cpp
|
||||
* @brief Tests for the @c classes module.
|
||||
* @copyright (c) 2017 Avast Software, licensed under the MIT license
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#include "retdec/common/class.h"
|
||||
#include "retdec/serdes/class.h"
|
||||
|
||||
using namespace ::testing;
|
||||
|
||||
namespace retdec {
|
||||
namespace serdes {
|
||||
namespace tests {
|
||||
|
||||
class ClassTests : public Test
|
||||
{
|
||||
protected:
|
||||
common::Class cl;
|
||||
};
|
||||
|
||||
TEST_F(ClassTests, ClassIsParsedCorrectlyFromJSONWhenClassIsFullySpecified)
|
||||
{
|
||||
std::istringstream input(R"({
|
||||
"name" : "A",
|
||||
"constructors" : [ "Actor" ],
|
||||
"destructors" : [ "Adtor" ],
|
||||
"methods" : [ "Amethod" ],
|
||||
"superClasses" : [ "Asuper" ],
|
||||
"virtualMethods" : [ "Avirtual" ],
|
||||
"virtualTables" : [ "Avtable" ]
|
||||
})");
|
||||
Json::Value val;
|
||||
std::string errs;
|
||||
Json::CharReaderBuilder rbuilder;
|
||||
bool success = Json::parseFromStream(rbuilder, input, &val, &errs);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
deserialize(val, cl);
|
||||
|
||||
EXPECT_EQ("A", cl.getName());
|
||||
EXPECT_EQ(std::set<std::string>({"Actor"}), cl.constructors);
|
||||
EXPECT_EQ(std::set<std::string>({"Adtor"}), cl.destructors);
|
||||
EXPECT_EQ(std::set<std::string>({"Amethod"}), cl.methods);
|
||||
EXPECT_EQ(std::vector<std::string>({"Asuper"}), cl.getSuperClasses());
|
||||
EXPECT_EQ(std::set<std::string>({"Avirtual"}), cl.virtualMethods);
|
||||
EXPECT_EQ(std::set<std::string>({"Avtable"}), cl.virtualTables);
|
||||
}
|
||||
|
||||
TEST_F(ClassTests, ClassIsParsedCorrectlyFromJSONWhenClassHasOnlyNameSpecified)
|
||||
{
|
||||
std::istringstream input(R"({
|
||||
"name" : "A"
|
||||
})");
|
||||
Json::Value val;
|
||||
std::string errs;
|
||||
Json::CharReaderBuilder rbuilder;
|
||||
bool success = Json::parseFromStream(rbuilder, input, &val, &errs);
|
||||
ASSERT_TRUE(success);
|
||||
|
||||
deserialize(val, cl);
|
||||
|
||||
EXPECT_EQ("A", cl.getName());
|
||||
EXPECT_TRUE(cl.constructors.empty());
|
||||
EXPECT_TRUE(cl.destructors.empty());
|
||||
EXPECT_TRUE(cl.methods.empty());
|
||||
EXPECT_TRUE(cl.getSuperClasses().empty());
|
||||
EXPECT_TRUE(cl.virtualMethods.empty());
|
||||
EXPECT_TRUE(cl.virtualTables.empty());
|
||||
}
|
||||
|
||||
} // namespace tests
|
||||
} // namespace serdes
|
||||
} // namespace retdec
|
Loading…
Reference in New Issue
Block a user