Skip to content

Commit

Permalink
#12 Update class sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
kwabenantim committed Sep 22, 2024
1 parent 3bde9a1 commit fdc44a5
Showing 1 changed file with 41 additions and 39 deletions.
80 changes: 41 additions & 39 deletions cppwg/input/module_info.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Module information structure."""

import os
from pathlib import Path
from typing import Any, Dict, List, Optional

from cppwg.input.base_info import BaseInfo
Expand Down Expand Up @@ -51,7 +52,9 @@ def __init__(self, name: str, module_config: Optional[Dict[str, Any]] = None):

@property
def parent(self) -> "PackageInfo": # noqa: F821
"""Returns the parent package info object."""
"""
Returns the associated package info object.
"""
return self.package_info

def is_decl_in_source_path(self, decl: "declaration_t") -> bool: # noqa: F821
Expand All @@ -73,51 +76,50 @@ def is_decl_in_source_path(self, decl: "declaration_t") -> bool: # noqa: F821

for source_location in self.source_locations:
full_path = os.path.join(self.package_info.source_root, source_location)
if full_path in decl.location.file_name:
if Path(full_path) in Path(decl.location.file_name).parents:
return True

return False

def sort_classes(self) -> None:
"""Sort the class info collection in order of dependence."""
"""
Sort the class info collection in order of dependence.
"""
self.class_info_collection.sort(key=lambda x: x.name)

order_changed = True
while order_changed:
order_changed = False

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

for j in range(i + 1, n):
cls_j = self.class_info_collection[j]
if cls_i.is_child_of(cls_j):
# sort by inheritance
ii = j
elif cls_i.requires(cls_j) and not cls_j.requires(cls_i):
# sort by dependence, ignoring forward declaration cycles
ii = j
elif cls_j.is_child_of(cls_i):
child_pos.append(j)

if ii <= i:
i += 1
continue # no change in cls_i's position

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
i = 0
n = len(self.class_info_collection)
while i < n - 1:
cls_i = self.class_info_collection[i]
ii = i # Tracks destination of cls_i
j_pos = [] # Tracks positions of cls_i's dependents

for j in range(i + 1, n):
cls_j = self.class_info_collection[j]
i_requires_j = cls_i.requires(cls_j)
j_requires_i = cls_j.requires(cls_i)
if cls_i.is_child_of(cls_j) or (i_requires_j and not j_requires_i):
# Position cls_i after all classes it depends on,
# ignoring forward declaration cycles
ii = j
elif cls_j.is_child_of(cls_i) or (j_requires_i and not i_requires_j):
# Collect positions of cls_i's dependents
j_pos.append(j)

if ii <= i:
i += 1
continue # No change in position

# Move cls_i into new position ii
cls_i = self.class_info_collection.pop(i)
self.class_info_collection.insert(ii, cls_i)

# Move dependents into positions after ii
for j, idx in enumerate(j_pos):
if j > ii:
break # Rest of dependents already positioned after ii
cls_j = self.class_info_collection.pop(j - 1 - idx)
self.class_info_collection.insert(ii + idx, cls_j)

def update_from_ns(self, source_ns: "namespace_t") -> None: # noqa: F821
"""
Expand Down

0 comments on commit fdc44a5

Please sign in to comment.