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:
|
public:
|
||||||
std::string dump() const;
|
std::string dump() const;
|
||||||
retdec::config::Class getConfigClass(
|
retdec::common::Class getConfigClass(
|
||||||
llvm::Module* m,
|
llvm::Module* m,
|
||||||
Config* config) const;
|
Config* config) const;
|
||||||
|
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* @file include/retdec/config/classes.h
|
* @file include/retdec/common/class.h
|
||||||
* @brief Decompilation configuration manipulation: classes.
|
* @brief Common class representation.
|
||||||
* @copyright (c) 2017 Avast Software, licensed under the MIT license
|
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef RETDEC_CONFIG_CLASSES_H
|
#ifndef RETDEC_COMMON_CLASS_H
|
||||||
#define RETDEC_CONFIG_CLASSES_H
|
#define RETDEC_COMMON_CLASS_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "retdec/config/base.h"
|
|
||||||
|
|
||||||
namespace retdec {
|
namespace retdec {
|
||||||
namespace config {
|
namespace common {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents C++ class.
|
* Represents C++ class.
|
||||||
@ -22,10 +21,7 @@ namespace config {
|
|||||||
class Class
|
class Class
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Class(const std::string& className);
|
Class(const std::string& className = std::string());
|
||||||
static Class fromJsonValue(const Json::Value& val);
|
|
||||||
|
|
||||||
Json::Value getJsonValue() const;
|
|
||||||
|
|
||||||
/// @name Class get methods.
|
/// @name Class get methods.
|
||||||
/// @{
|
/// @{
|
||||||
@ -42,6 +38,7 @@ class Class
|
|||||||
|
|
||||||
/// @name Class set methods.
|
/// @name Class set methods.
|
||||||
/// @{
|
/// @{
|
||||||
|
void setName(const std::string& name);
|
||||||
void setDemangledName(const std::string& demangledName);
|
void setDemangledName(const std::string& demangledName);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@ -70,12 +67,26 @@ class Class
|
|||||||
/**
|
/**
|
||||||
* A set container with classes.
|
* 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
|
} // namespace retdec
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -8,13 +8,13 @@
|
|||||||
#define RETDEC_CONFIG_CONFIG_H
|
#define RETDEC_CONFIG_CONFIG_H
|
||||||
|
|
||||||
#include "retdec/common/architecture.h"
|
#include "retdec/common/architecture.h"
|
||||||
|
#include "retdec/common/class.h"
|
||||||
#include "retdec/common/file_format.h"
|
#include "retdec/common/file_format.h"
|
||||||
#include "retdec/common/file_type.h"
|
#include "retdec/common/file_type.h"
|
||||||
#include "retdec/common/language.h"
|
#include "retdec/common/language.h"
|
||||||
#include "retdec/common/tool_info.h"
|
#include "retdec/common/tool_info.h"
|
||||||
#include "retdec/common/vtable.h"
|
#include "retdec/common/vtable.h"
|
||||||
#include "retdec/config/base.h"
|
#include "retdec/config/base.h"
|
||||||
#include "retdec/config/classes.h"
|
|
||||||
#include "retdec/config/functions.h"
|
#include "retdec/config/functions.h"
|
||||||
#include "retdec/config/parameters.h"
|
#include "retdec/config/parameters.h"
|
||||||
#include "retdec/config/patterns.h"
|
#include "retdec/config/patterns.h"
|
||||||
@ -86,7 +86,7 @@ class Config
|
|||||||
RegisterContainer registers;
|
RegisterContainer registers;
|
||||||
TypeContainer structures;
|
TypeContainer structures;
|
||||||
common::VtableContainer vtables;
|
common::VtableContainer vtables;
|
||||||
ClassContainer classes;
|
common::ClassContainer classes;
|
||||||
PatternContainer patterns;
|
PatternContainer patterns;
|
||||||
|
|
||||||
private:
|
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();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
retdec::config::Class Class::getConfigClass(
|
retdec::common::Class Class::getConfigClass(
|
||||||
llvm::Module* m,
|
llvm::Module* m,
|
||||||
Config* config) const
|
Config* config) const
|
||||||
{
|
{
|
||||||
retdec::config::Class c(name);
|
retdec::common::Class c(name);
|
||||||
|
|
||||||
auto* demangler = DemanglerProvider::getDemangler(m);
|
auto* demangler = DemanglerProvider::getDemangler(m);
|
||||||
if (demangler)
|
if (demangler)
|
||||||
|
@ -3,6 +3,7 @@ add_library(retdec-common STATIC
|
|||||||
address.cpp
|
address.cpp
|
||||||
architecture.cpp
|
architecture.cpp
|
||||||
calling_convention.cpp
|
calling_convention.cpp
|
||||||
|
class.cpp
|
||||||
file_format.cpp
|
file_format.cpp
|
||||||
file_type.cpp
|
file_type.cpp
|
||||||
language.cpp
|
language.cpp
|
||||||
|
@ -1,30 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* @file src/config/classes.cpp
|
* @file src/common/class.cpp
|
||||||
* @brief Decompilation configuration manipulation: classes.
|
* @brief Common class representation.
|
||||||
* @copyright (c) 2017 Avast Software, licensed under the MIT license
|
* @copyright (c) 2019 Avast Software, licensed under the MIT license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "retdec/config/classes.h"
|
#include "retdec/common/class.h"
|
||||||
#include "retdec/serdes/std.h"
|
|
||||||
#include "retdec/utils/container.h"
|
#include "retdec/utils/container.h"
|
||||||
|
|
||||||
using retdec::utils::hasItem;
|
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 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.
|
* @return Class's ID is its name.
|
||||||
*/
|
*/
|
||||||
@ -103,6 +47,11 @@ const std::vector<std::string>& Class::getSuperClasses() const
|
|||||||
return _superClasses;
|
return _superClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Class::setName(const std::string& name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
void Class::setDemangledName(const std::string& demangledName)
|
void Class::setDemangledName(const std::string& demangledName)
|
||||||
{
|
{
|
||||||
_demangledName = demangledName;
|
_demangledName = demangledName;
|
||||||
@ -187,5 +136,5 @@ bool Class::operator==(const Class& o) const
|
|||||||
return getName() == o.getName();
|
return getName() == o.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace config
|
} // namespace common
|
||||||
} // namespace retdec
|
} // namespace retdec
|
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
add_library(retdec-config STATIC
|
add_library(retdec-config STATIC
|
||||||
base.cpp
|
base.cpp
|
||||||
classes.cpp
|
|
||||||
config.cpp
|
config.cpp
|
||||||
functions.cpp
|
functions.cpp
|
||||||
objects.cpp
|
objects.cpp
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "retdec/config/config.h"
|
#include "retdec/config/config.h"
|
||||||
#include "retdec/serdes/address.h"
|
#include "retdec/serdes/address.h"
|
||||||
#include "retdec/serdes/architecture.h"
|
#include "retdec/serdes/architecture.h"
|
||||||
|
#include "retdec/serdes/class.h"
|
||||||
#include "retdec/serdes/file_format.h"
|
#include "retdec/serdes/file_format.h"
|
||||||
#include "retdec/serdes/file_type.h"
|
#include "retdec/serdes/file_type.h"
|
||||||
#include "retdec/serdes/language.h"
|
#include "retdec/serdes/language.h"
|
||||||
@ -183,7 +184,7 @@ std::string Config::generateJsonString() const
|
|||||||
root[JSON_registers] = registers.getJsonValue();
|
root[JSON_registers] = registers.getJsonValue();
|
||||||
root[JSON_structures] = structures.getJsonValue();
|
root[JSON_structures] = structures.getJsonValue();
|
||||||
root[JSON_vtables] = serdes::serialize(vtables);
|
root[JSON_vtables] = serdes::serialize(vtables);
|
||||||
root[JSON_classes] = classes.getJsonValue();
|
root[JSON_classes] = serdes::serialize(classes);
|
||||||
root[JSON_patterns] = patterns.getJsonValue();
|
root[JSON_patterns] = patterns.getJsonValue();
|
||||||
|
|
||||||
StreamWriterBuilder builder;
|
StreamWriterBuilder builder;
|
||||||
@ -257,7 +258,7 @@ void Config::readJsonString(const std::string& json)
|
|||||||
registers.readJsonValue( root[JSON_registers] );
|
registers.readJsonValue( root[JSON_registers] );
|
||||||
structures.readJsonValue( root[JSON_structures] );
|
structures.readJsonValue( root[JSON_structures] );
|
||||||
serdes::deserialize(root[JSON_vtables], vtables);
|
serdes::deserialize(root[JSON_vtables], vtables);
|
||||||
classes.readJsonValue( root[JSON_classes] );
|
serdes::deserialize(root[JSON_classes], classes);
|
||||||
patterns.readJsonValue( root[JSON_patterns] );
|
patterns.readJsonValue( root[JSON_patterns] );
|
||||||
}
|
}
|
||||||
catch (const InternalException& e)
|
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 *getConfigFunctionByName(const std::string &name) const;
|
||||||
const retdec::config::Function &getConfigFunctionByNameOrEmptyFunction(
|
const retdec::config::Function &getConfigFunctionByNameOrEmptyFunction(
|
||||||
const std::string &name) const;
|
const std::string &name) const;
|
||||||
const retdec::config::Class *getConfigClassByName(const std::string &name) const;
|
const retdec::common::Class *getConfigClassByName(const std::string &name) const;
|
||||||
const retdec::config::Class &getConfigClassByNameOrEmptyClass(
|
const retdec::common::Class &getConfigClassByNameOrEmptyClass(
|
||||||
const std::string &name) const;
|
const std::string &name) const;
|
||||||
std::string getNameOfRegister(const retdec::config::Object ®) const;
|
std::string getNameOfRegister(const retdec::config::Object ®) const;
|
||||||
|
|
||||||
@ -85,9 +85,10 @@ const retdec::config::Function &JSONConfig::Impl::getConfigFunctionByNameOrEmpty
|
|||||||
return f ? *f : emptyFunction;
|
return f ? *f : emptyFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
const retdec::config::Class *JSONConfig::Impl::getConfigClassByName(
|
const retdec::common::Class *JSONConfig::Impl::getConfigClassByName(
|
||||||
const std::string &name) const {
|
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 {
|
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;
|
return !realName.empty() ? realName : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
const retdec::config::Class &JSONConfig::Impl::getConfigClassByNameOrEmptyClass(
|
const retdec::common::Class &JSONConfig::Impl::getConfigClassByNameOrEmptyClass(
|
||||||
const std::string &name) const {
|
const std::string &name) const {
|
||||||
static const retdec::config::Class emptyClass(""s);
|
static const retdec::common::Class emptyClass(""s);
|
||||||
auto c = getConfigClassByName(name);
|
auto c = getConfigClassByName(name);
|
||||||
return c ? *c : emptyClass;
|
return c ? *c : emptyClass;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ add_library(retdec-serdes STATIC
|
|||||||
address.cpp
|
address.cpp
|
||||||
architecture.cpp
|
architecture.cpp
|
||||||
calling_convention.cpp
|
calling_convention.cpp
|
||||||
|
class.cpp
|
||||||
file_format.cpp
|
file_format.cpp
|
||||||
file_type.cpp
|
file_type.cpp
|
||||||
language.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
|
add_executable(retdec-tests-common
|
||||||
address_tests.cpp
|
address_tests.cpp
|
||||||
architecture_tests.cpp
|
architecture_tests.cpp
|
||||||
|
class_tests.cpp
|
||||||
file_format_tests.cpp
|
file_format_tests.cpp
|
||||||
file_type_tests.cpp
|
file_type_tests.cpp
|
||||||
language_tests.cpp
|
language_tests.cpp
|
||||||
|
@ -1,96 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
* @file tests/config/classes_tests.cpp
|
* @file tests/config/classes_tests.cpp
|
||||||
* @brief Tests for the @c classes module.
|
* @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 <gtest/gtest.h>
|
||||||
|
|
||||||
#include "retdec/config/classes.h"
|
#include "retdec/common/class.h"
|
||||||
#include "retdec/config/config.h"
|
|
||||||
|
|
||||||
using namespace ::testing;
|
using namespace ::testing;
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
namespace retdec {
|
namespace retdec {
|
||||||
namespace config {
|
namespace common {
|
||||||
namespace tests {
|
namespace tests {
|
||||||
|
|
||||||
class ClassesTests: public Test {};
|
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()
|
// hasConstructor()
|
||||||
//
|
//
|
||||||
@ -267,5 +193,5 @@ AddSuperClassDoesNotAddSameSuperclassTwice) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tests
|
} // namespace tests
|
||||||
} // namespace config
|
} // namespace common
|
||||||
} // namespace retdec
|
} // namespace retdec
|
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
add_executable(retdec-tests-config
|
add_executable(retdec-tests-config
|
||||||
base_tests.cpp
|
base_tests.cpp
|
||||||
classes_tests.cpp
|
|
||||||
documentation_tests.cpp
|
documentation_tests.cpp
|
||||||
functions_tests.cpp
|
functions_tests.cpp
|
||||||
objects_tests.cpp
|
objects_tests.cpp
|
||||||
|
@ -77,7 +77,7 @@ TEST_F(ConfigTests, SuccessfulReadJsonStringResetsAllConfigData)
|
|||||||
|
|
||||||
TEST_F(ConfigTests, ClassesGetElementByIdReturnsNullPointerWhenThereIsNoSuchClass)
|
TEST_F(ConfigTests, ClassesGetElementByIdReturnsNullPointerWhenThereIsNoSuchClass)
|
||||||
{
|
{
|
||||||
ASSERT_EQ(nullptr, config.classes.getElementById("ClassName"));
|
ASSERT_EQ(config.classes.end(), config.classes.find("ClassName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tests
|
} // namespace tests
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
add_executable(retdec-tests-serdes
|
add_executable(retdec-tests-serdes
|
||||||
calling_convention_tests.cpp
|
calling_convention_tests.cpp
|
||||||
|
class_tests.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(retdec-tests-serdes
|
target_link_libraries(retdec-tests-serdes
|
||||||
retdec-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