From 7cfce4b4d079a1f6b6f3f182ce59efd833d71b76 Mon Sep 17 00:00:00 2001 From: Kwabena N Amponsah Date: Sun, 22 Sep 2024 00:38:29 +0000 Subject: [PATCH] #12 Fix class sorting --- cppwg/input/class_info.py | 22 +++++++- cppwg/input/module_info.py | 51 +++++++++++-------- .../wrapper/primitives/primitives.main.cpp | 4 +- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/cppwg/input/class_info.py b/cppwg/input/class_info.py index ffd686f..01651f9 100644 --- a/cppwg/input/class_info.py +++ b/cppwg/input/class_info.py @@ -30,9 +30,29 @@ def __init__(self, name: str, class_config: Optional[Dict[str, Any]] = None): self.py_names: List[str] = None self.base_decls: Optional[List["declaration_t"]] = None # noqa: F821 + def is_child_of(self, other: "ClassInfo") -> bool: # noqa: F821 + """ + Check if the class is a child of the specified class. + + Parameters + ---------- + other : ClassInfo + The other class to check + + Returns + ------- + bool + True if the class is a child of the specified class, False otherwise + """ + if not self.base_decls: + return False + if not other.decls: + return False + return any(base in other.decls for base in self.base_decls) + def update_from_ns(self, ns: "namespace_t") -> None: # noqa: F821 """ - Update the class information from the source namespace. + Update class with information from the source namespace. Adds the class declarations and base class declarations. diff --git a/cppwg/input/module_info.py b/cppwg/input/module_info.py index 0fe9edd..5ab5a85 100644 --- a/cppwg/input/module_info.py +++ b/cppwg/input/module_info.py @@ -1,7 +1,6 @@ """Module information structure.""" import os -from functools import cmp_to_key from typing import Any, Dict, List, Optional from cppwg.input.base_info import BaseInfo @@ -79,34 +78,44 @@ def is_decl_in_source_path(self, decl: "declaration_t") -> bool: # noqa: F821 def sort_classes(self) -> None: """Sort the class info collection in inheritance order.""" + self.class_info_collection.sort(key=lambda x: x.name) - def compare(class_info_0: "ClassInfo", class_info_1: "ClassInfo"): # noqa: F821 - # Sort classes with no declarations to the bottom - if class_info_0.decls == class_info_1.decls: - return 0 - if class_info_0.decls is None: - return 1 - if class_info_1.decls is None: - return -1 + order_changed = True + while order_changed: + order_changed = False - # 1 if class_0 is a child of class_1 - child_0 = int( - any(base in class_info_1.decls for base in class_info_0.base_decls) - ) + i = 0 + n = len(self.class_info_collection) + while i < n - 1: + cls_i = self.class_info_collection[i] + ii = i # destination of cls_i + child_pos = [] # positions of cls_i's children - # 1 if class_1 is a child of class 0 - child_1 = int( - any(base in class_info_0.decls for base in class_info_1.base_decls) - ) + for j in range(i + 1, n): + cls_j = self.class_info_collection[j] + if cls_i.is_child_of(cls_j): + ii = j + elif cls_j.is_child_of(cls_i): + child_pos.append(j) - return child_0 - child_1 + if ii <= i: + i += 1 + continue # no change in cls_i's position - self.class_info_collection.sort(key=lambda x: x.name) - self.class_info_collection.sort(key=cmp_to_key(compare)) + cls_i = self.class_info_collection.pop(i) + self.class_info_collection.insert(ii, cls_i) + + for j, idx in enumerate(child_pos): + if j > ii: + break # children already positioned after cls_i + cls_j = self.class_info_collection.pop(j - 1 - idx) + self.class_info_collection.insert(ii + idx, cls_j) + + order_changed = True def update_from_ns(self, ns: "namespace_t") -> None: # noqa: F821 """ - Update class info objects with information from the source namespace. + Update module with information from the source namespace. Parameters ---------- diff --git a/examples/shapes/wrapper/primitives/primitives.main.cpp b/examples/shapes/wrapper/primitives/primitives.main.cpp index f90aac5..b691509 100644 --- a/examples/shapes/wrapper/primitives/primitives.main.cpp +++ b/examples/shapes/wrapper/primitives/primitives.main.cpp @@ -5,8 +5,8 @@ #include "wrapper_header_collection.hpp" #include "Shape2.cppwg.hpp" #include "Shape3.cppwg.hpp" -#include "Cuboid.cppwg.hpp" #include "Rectangle.cppwg.hpp" +#include "Cuboid.cppwg.hpp" namespace py = pybind11; @@ -14,6 +14,6 @@ PYBIND11_MODULE(_pyshapes_primitives, m) { register_Shape2_class(m); register_Shape3_class(m); - register_Cuboid_class(m); register_Rectangle_class(m); + register_Cuboid_class(m); }