-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathshow_class_hierarchies.py
executable file
·98 lines (78 loc) · 2.88 KB
/
show_class_hierarchies.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python3
import re
import glob
from collections import defaultdict
class Header:
''' Parse a header file and extract class name and base class name '''
def __init__(self, filename):
self.class_name = None
self.base_class_name = None
for line in open(filename):
if m := re.match(r'\s*class (?P<name>[\w_]+) : public (?P<base>[\w_]+)', line):
self.class_name = m.group('name')
self.base_class_name = m.group('base')
continue
if m := re.match(r'\s*class (?P<name>[\w_]+)', line):
self.class_name = m.group('name')
self.base_class_name = None
continue
class Hierarchy:
''' Build a hierarchy of classes '''
def __init__(self):
self.base_class_names = set()
self.children = defaultdict(list)
def add(self, h):
if h.base_class_name is None and h.class_name is not None:
self.base_class_names.add(h.class_name)
self.children[h.base_class_name].append(h.class_name)
def get_children_(self, base_class_name):
children_list = self.children[base_class_name]
if not children_list:
return [[base_class_name]]
else:
result = []
for child in children_list:
children2 = self.get_children_(child)
for child2 in children2:
result.append([base_class_name] + child2)
return result
def make_hierarchy(self, base_class_name):
hierarchy = []
children_ = self.children[base_class_name]
if not children_:
hierarchy.append([base_class_name])
else:
for child in children_:
chains = self.get_children_(child)
for chain in chains:
hierarchy.append([base_class_name] + chain)
return hierarchy
def print(self):
for base_class_name in self.base_class_names:
hierarchy = self.make_hierarchy(base_class_name)
print("====================================")
print(f"Hierarchy: {base_class_name}")
print("====================================")
for chain in hierarchy:
print(" <- ".join(chain))
if __name__ == "__main__":
dirs = [
"src/accessor/*.h",
"src/action/*.h",
"src/expression/*.h",
"src/dumper/*.h",
"src/geo/iterator/*.h",
"src/geo/nearest/*.h",
"src/eccodes/accessor/*.h",
"src/eccodes/action/*.h",
"src/eccodes/expression/*.h",
"src/eccodes/dumper/*.h",
"src/eccodes/geo/iterator/*.h",
"src/eccodes/geo/nearest/*.h",
]
for dir in dirs:
hierarchy = Hierarchy()
files = glob.glob(dir)
for fn in files:
hierarchy.add(Header(fn))
hierarchy.print()