mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-12 21:56:54 +00:00
TypeGraph: Create Mutator and RecursiveMutator base classes
This commit is contained in:
parent
81ae075a68
commit
30678b1dad
@ -23,6 +23,9 @@ namespace oi::detail::type_graph {
|
|||||||
void OI_TYPE_NAME::accept(Visitor& v) { \
|
void OI_TYPE_NAME::accept(Visitor& v) { \
|
||||||
v.visit(*this); \
|
v.visit(*this); \
|
||||||
} \
|
} \
|
||||||
|
Type& OI_TYPE_NAME::accept(Mutator& m) { \
|
||||||
|
return m.visit(*this); \
|
||||||
|
} \
|
||||||
void OI_TYPE_NAME::accept(ConstVisitor& v) const { \
|
void OI_TYPE_NAME::accept(ConstVisitor& v) const { \
|
||||||
v.visit(*this); \
|
v.visit(*this); \
|
||||||
}
|
}
|
||||||
|
@ -67,9 +67,11 @@ enum class Qualifier {
|
|||||||
using QualifierSet = EnumBitset<Qualifier, static_cast<size_t>(Qualifier::Max)>;
|
using QualifierSet = EnumBitset<Qualifier, static_cast<size_t>(Qualifier::Max)>;
|
||||||
|
|
||||||
class Visitor;
|
class Visitor;
|
||||||
|
class Mutator;
|
||||||
class ConstVisitor;
|
class ConstVisitor;
|
||||||
#define DECLARE_ACCEPT \
|
#define DECLARE_ACCEPT \
|
||||||
void accept(Visitor& v) override; \
|
void accept(Visitor& v) override; \
|
||||||
|
Type& accept(Mutator& m) override; \
|
||||||
void accept(ConstVisitor& v) const override;
|
void accept(ConstVisitor& v) const override;
|
||||||
|
|
||||||
// TODO delete copy and move ctors
|
// TODO delete copy and move ctors
|
||||||
@ -83,6 +85,7 @@ class Type {
|
|||||||
public:
|
public:
|
||||||
virtual ~Type() = default;
|
virtual ~Type() = default;
|
||||||
virtual void accept(Visitor& v) = 0;
|
virtual void accept(Visitor& v) = 0;
|
||||||
|
virtual Type& accept(Mutator& m) = 0;
|
||||||
virtual void accept(ConstVisitor& v) const = 0;
|
virtual void accept(ConstVisitor& v) const = 0;
|
||||||
|
|
||||||
virtual const std::string& name() const = 0;
|
virtual const std::string& name() const = 0;
|
||||||
@ -123,6 +126,10 @@ class Member {
|
|||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setType(Type& type) {
|
||||||
|
type_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<Type> type_;
|
std::reference_wrapper<Type> type_;
|
||||||
|
|
||||||
@ -152,6 +159,10 @@ struct Parent {
|
|||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setType(Type& type) {
|
||||||
|
type_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
// uint64_t offset() const {
|
// uint64_t offset() const {
|
||||||
// return offset_;
|
// return offset_;
|
||||||
// }
|
// }
|
||||||
@ -178,6 +189,10 @@ struct TemplateParam {
|
|||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setType(Type& type) {
|
||||||
|
type_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::reference_wrapper<Type> type_;
|
std::reference_wrapper<Type> type_;
|
||||||
|
|
||||||
@ -426,6 +441,10 @@ class Container : public Type {
|
|||||||
return id_;
|
return id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAlign(uint64_t alignment) {
|
||||||
|
align_ = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<TemplateParam> templateParams;
|
std::vector<TemplateParam> templateParams;
|
||||||
const ContainerInfo& containerInfo_;
|
const ContainerInfo& containerInfo_;
|
||||||
|
|
||||||
@ -433,6 +452,7 @@ class Container : public Type {
|
|||||||
std::string name_;
|
std::string name_;
|
||||||
std::string inputName_;
|
std::string inputName_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
|
uint64_t align_ = 0;
|
||||||
NodeId id_ = -1;
|
NodeId id_ = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -506,7 +526,7 @@ class Array : public Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void regenerateName() {
|
void regenerateName() {
|
||||||
name_ = std::string{"OIArray<"} + elementType_.name() + ", " +
|
name_ = std::string{"OIArray<"} + elementType_.get().name() + ", " +
|
||||||
std::to_string(len_) + ">";
|
std::to_string(len_) + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,11 +539,11 @@ class Array : public Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t size() const override {
|
virtual size_t size() const override {
|
||||||
return len_ * elementType_.size();
|
return len_ * elementType_.get().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint64_t align() const override {
|
virtual uint64_t align() const override {
|
||||||
return elementType_.align();
|
return elementType_.get().align();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual NodeId id() const override {
|
virtual NodeId id() const override {
|
||||||
@ -534,12 +554,16 @@ class Array : public Type {
|
|||||||
return elementType_;
|
return elementType_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setElementType(Type& type) {
|
||||||
|
elementType_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
size_t len() const {
|
size_t len() const {
|
||||||
return len_;
|
return len_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type& elementType_;
|
std::reference_wrapper<Type> elementType_;
|
||||||
std::string inputName_;
|
std::string inputName_;
|
||||||
size_t len_;
|
size_t len_;
|
||||||
NodeId id_ = -1;
|
NodeId id_ = -1;
|
||||||
@ -623,11 +647,11 @@ class Typedef : public Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t size() const override {
|
virtual size_t size() const override {
|
||||||
return underlyingType_.size();
|
return underlyingType_.get().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint64_t align() const override {
|
virtual uint64_t align() const override {
|
||||||
return underlyingType_.align();
|
return underlyingType_.get().align();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual NodeId id() const override {
|
virtual NodeId id() const override {
|
||||||
@ -638,10 +662,14 @@ class Typedef : public Type {
|
|||||||
return underlyingType_;
|
return underlyingType_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUnderlyingType(Type& type) {
|
||||||
|
underlyingType_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::string inputName_;
|
std::string inputName_;
|
||||||
Type& underlyingType_;
|
std::reference_wrapper<Type> underlyingType_;
|
||||||
NodeId id_ = -1;
|
NodeId id_ = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -661,7 +689,7 @@ class Pointer : public Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void regenerateName() {
|
void regenerateName() {
|
||||||
name_ = pointeeType_.name() + "*";
|
name_ = pointeeType_.get().name() + "*";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string_view inputName() const override {
|
virtual std::string_view inputName() const override {
|
||||||
@ -688,8 +716,12 @@ class Pointer : public Type {
|
|||||||
return pointeeType_;
|
return pointeeType_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPointeeType(Type& type) {
|
||||||
|
pointeeType_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type& pointeeType_;
|
std::reference_wrapper<Type> pointeeType_;
|
||||||
std::string inputName_;
|
std::string inputName_;
|
||||||
NodeId id_ = -1;
|
NodeId id_ = -1;
|
||||||
|
|
||||||
@ -772,7 +804,7 @@ class DummyAllocator : public Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void regenerateName() {
|
void regenerateName() {
|
||||||
name_ = std::string{"DummyAllocator<"} + type_.name() + ", " +
|
name_ = std::string{"DummyAllocator<"} + type_.get().name() + ", " +
|
||||||
std::to_string(size_) + ", " + std::to_string(align_) + ", " +
|
std::to_string(size_) + ", " + std::to_string(align_) + ", " +
|
||||||
std::to_string(id_) + ">";
|
std::to_string(id_) + ">";
|
||||||
}
|
}
|
||||||
@ -797,8 +829,12 @@ class DummyAllocator : public Type {
|
|||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setAllocType(Type& type) {
|
||||||
|
type_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type& type_;
|
std::reference_wrapper<Type> type_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
uint64_t align_;
|
uint64_t align_;
|
||||||
NodeId id_ = -1;
|
NodeId id_ = -1;
|
||||||
@ -828,19 +864,19 @@ class CaptureKeys : public Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string_view inputName() const override {
|
virtual std::string_view inputName() const override {
|
||||||
return container_.inputName();
|
return container_.get().inputName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void regenerateName() {
|
void regenerateName() {
|
||||||
name_ = "OICaptureKeys<" + container_.name() + ">";
|
name_ = "OICaptureKeys<" + container_.get().name() + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t size() const override {
|
virtual size_t size() const override {
|
||||||
return container_.size();
|
return container_.get().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint64_t align() const override {
|
virtual uint64_t align() const override {
|
||||||
return container_.align();
|
return container_.get().align();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual NodeId id() const override {
|
virtual NodeId id() const override {
|
||||||
@ -855,8 +891,12 @@ class CaptureKeys : public Type {
|
|||||||
return container_;
|
return container_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setContainer(Container& container) {
|
||||||
|
container_ = container;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Container& container_;
|
std::reference_wrapper<Container> container_;
|
||||||
const ContainerInfo& containerInfo_;
|
const ContainerInfo& containerInfo_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
};
|
};
|
||||||
|
@ -32,6 +32,7 @@ namespace oi::detail::type_graph {
|
|||||||
* Visitor
|
* Visitor
|
||||||
*
|
*
|
||||||
* Abstract visitor base class.
|
* Abstract visitor base class.
|
||||||
|
* A visitor simply walks over nodes in a type graph.
|
||||||
*/
|
*/
|
||||||
class Visitor {
|
class Visitor {
|
||||||
public:
|
public:
|
||||||
@ -42,6 +43,21 @@ class Visitor {
|
|||||||
#undef X
|
#undef X
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mutator
|
||||||
|
*
|
||||||
|
* Abstract mutator base class.
|
||||||
|
* A mutator replaces nodes in a type graph with the node returned by visit().
|
||||||
|
*/
|
||||||
|
class Mutator {
|
||||||
|
public:
|
||||||
|
virtual ~Mutator() = default;
|
||||||
|
|
||||||
|
#define X(OI_TYPE_NAME) virtual Type& visit(OI_TYPE_NAME&) = 0;
|
||||||
|
OI_TYPE_LIST
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LazyVisitor
|
* LazyVisitor
|
||||||
*
|
*
|
||||||
@ -115,6 +131,71 @@ class RecursiveVisitor : public Visitor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RecursiveMutator
|
||||||
|
*
|
||||||
|
* Mutator base class which recurses into types by default.
|
||||||
|
*/
|
||||||
|
class RecursiveMutator : public Mutator {
|
||||||
|
public:
|
||||||
|
virtual ~RecursiveMutator() = default;
|
||||||
|
virtual Type& mutate(Type&) = 0;
|
||||||
|
virtual Type& visit(Incomplete& i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Class& c) {
|
||||||
|
for (auto& param : c.templateParams) {
|
||||||
|
param.setType(mutate(param.type()));
|
||||||
|
}
|
||||||
|
for (auto& parent : c.parents) {
|
||||||
|
parent.setType(mutate(parent.type()));
|
||||||
|
}
|
||||||
|
for (auto& mem : c.members) {
|
||||||
|
mem.setType(mutate(mem.type()));
|
||||||
|
}
|
||||||
|
for (auto& child : c.children) {
|
||||||
|
child = dynamic_cast<Class&>(mutate(child));
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Container& c) {
|
||||||
|
for (auto& param : c.templateParams) {
|
||||||
|
param.setType(mutate(param.type()));
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Primitive& p) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Enum& e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Array& a) {
|
||||||
|
a.setElementType(mutate(a.elementType()));
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Typedef& td) {
|
||||||
|
td.setUnderlyingType(mutate(td.underlyingType()));
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Pointer& p) {
|
||||||
|
p.setPointeeType(mutate(p.pointeeType()));
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
virtual Type& visit(Dummy& d) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
virtual Type& visit(DummyAllocator& d) {
|
||||||
|
d.setAllocType(mutate(d.allocType()));
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
virtual Type& visit(CaptureKeys& c) {
|
||||||
|
auto& newContainer = dynamic_cast<Container&>(mutate(c.container()));
|
||||||
|
c.setContainer(newContainer);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ConstVisitor
|
* ConstVisitor
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user