mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00:00
TopoSorter: Sort Typedefs before pointers
Also rename visitAfter() to acceptAfter() to match the previous renaming of visit() to accept().
This commit is contained in:
parent
df5ae4e34c
commit
e1496354de
@ -69,7 +69,7 @@ void TopoSorter::visit(Class& c) {
|
||||
// Same as pointers, children do not create a dependency so are delayed until
|
||||
// the end.
|
||||
for (const auto& child : c.children) {
|
||||
visitAfter(child);
|
||||
acceptAfter(child);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ void TopoSorter::visit(Container& c) {
|
||||
sortedTypes_.push_back(c);
|
||||
if (containerAllowsIncompleteParams(c)) {
|
||||
for (const auto& param : c.templateParams) {
|
||||
visitAfter(param.type());
|
||||
acceptAfter(param.type());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,9 +118,16 @@ void TopoSorter::visit(Typedef& td) {
|
||||
}
|
||||
|
||||
void TopoSorter::visit(Pointer& p) {
|
||||
if (dynamic_cast<Typedef*>(&p.pointeeType())) {
|
||||
// Typedefs can not be forward declared, so we must sort them before
|
||||
// pointers which reference them
|
||||
accept(p.pointeeType());
|
||||
return;
|
||||
}
|
||||
|
||||
// Pointers do not create a dependency, but we do still care about the types
|
||||
// they point to, so delay them until the end.
|
||||
visitAfter(p.pointeeType());
|
||||
acceptAfter(p.pointeeType());
|
||||
}
|
||||
|
||||
/*
|
||||
@ -131,13 +138,13 @@ void TopoSorter::visit(Pointer& p) {
|
||||
* program. This means we can delay processing them until after all of the true
|
||||
* dependencies have been sorted.
|
||||
*/
|
||||
void TopoSorter::visitAfter(Type& type) {
|
||||
void TopoSorter::acceptAfter(Type& type) {
|
||||
typesToSort_.push(type);
|
||||
}
|
||||
|
||||
void TopoSorter::visitAfter(Type* type) {
|
||||
void TopoSorter::acceptAfter(Type* type) {
|
||||
if (type) {
|
||||
visitAfter(*type);
|
||||
acceptAfter(*type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,8 +52,8 @@ class TopoSorter : public RecursiveVisitor {
|
||||
std::vector<std::reference_wrapper<Type>> sortedTypes_;
|
||||
std::queue<std::reference_wrapper<Type>> typesToSort_;
|
||||
|
||||
void visitAfter(Type& type);
|
||||
void visitAfter(Type* type);
|
||||
void acceptAfter(Type& type);
|
||||
void acceptAfter(Type* type);
|
||||
};
|
||||
|
||||
} // namespace type_graph
|
||||
|
@ -209,10 +209,16 @@ aliasA
|
||||
|
||||
TEST(TopoSorterTest, Pointers) {
|
||||
// Pointers do not require pointee types to be defined first
|
||||
auto myclass = Class{0, Class::Kind::Class, "MyClass", 69};
|
||||
auto mypointer = Pointer{1, myclass};
|
||||
auto classA = Class{0, Class::Kind::Class, "ClassA", 69};
|
||||
auto mypointer = Pointer{1, classA};
|
||||
|
||||
test({mypointer}, "MyClass");
|
||||
auto myclass = Class{2, Class::Kind::Class, "MyClass", 69};
|
||||
myclass.members.push_back(Member{mypointer, "ptr", 0});
|
||||
|
||||
test({myclass}, R"(
|
||||
MyClass
|
||||
ClassA
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(TopoSorterTest, PointerCycle) {
|
||||
@ -238,6 +244,22 @@ ClassA
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TopoSorterTest, PointerToTypedef) {
|
||||
auto classA = Class{0, Class::Kind::Class, "ClassA", 8};
|
||||
auto aliasA = Typedef{1, "aliasA", classA};
|
||||
|
||||
auto mypointer = Pointer{1, aliasA};
|
||||
|
||||
auto myclass = Class{2, Class::Kind::Class, "MyClass", 69};
|
||||
myclass.members.push_back(Member{mypointer, "ptrToTypedef", 0});
|
||||
|
||||
test({myclass}, R"(
|
||||
ClassA
|
||||
aliasA
|
||||
MyClass
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(TopoSorterTest, TwoDeep) {
|
||||
auto myunion = Class{0, Class::Kind::Union, "MyUnion", 7};
|
||||
auto mystruct = Class{1, Class::Kind::Struct, "MyStruct", 13};
|
||||
|
Loading…
Reference in New Issue
Block a user