Skip to content

Commit 76dfcad

Browse files
authored
Merge pull request #10508 from github/redsun82/swift-early-toposort
Swift: move toposort in `schema.py`
2 parents ce979d8 + a50f3f7 commit 76dfcad

File tree

8 files changed

+4259
-4271
lines changed

8 files changed

+4259
-4271
lines changed

swift/codegen/generators/cppgen.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from typing import Dict
1717

1818
import inflection
19-
from toposort import toposort_flatten
2019

2120
from swift.codegen.lib import cpp, schema
2221

@@ -71,13 +70,9 @@ def _get_class(self, name: str) -> cpp.Class:
7170
)
7271

7372
def get_classes(self):
74-
grouped = {pathlib.Path(): {}}
73+
ret = {pathlib.Path(): []}
7574
for k, cls in self._classmap.items():
76-
grouped.setdefault(cls.dir, {}).update({k: cls})
77-
ret = {}
78-
for dir, map in grouped.items():
79-
inheritance_graph = {k: {b for b in cls.bases if b in map} for k, cls in map.items()}
80-
ret[dir] = [self._get_class(cls) for cls in toposort_flatten(inheritance_graph)]
75+
ret.setdefault(cls.dir, []).append(self._get_class(cls.name))
8176
return ret
8277

8378

swift/codegen/generators/qlgen.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import itertools
2929

3030
import inflection
31-
from toposort import toposort_flatten
3231

3332
from swift.codegen.lib import schema, ql
3433

@@ -263,9 +262,7 @@ def generate(opts, renderer):
263262

264263
imports = {}
265264

266-
inheritance_graph = {name: cls.bases for name, cls in data.classes.items()}
267-
toposorted_names = toposort_flatten(inheritance_graph)
268-
db_classes = [classes[name] for name in toposorted_names if not classes[name].ipa]
265+
db_classes = [cls for cls in classes.values() if not cls.ipa]
269266
renderer.render(ql.DbClasses(db_classes), out / "Raw.qll")
270267

271268
classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name))
@@ -286,8 +283,7 @@ def generate(opts, renderer):
286283
include_file = stub_out.with_suffix(".qll")
287284
renderer.render(ql.ImportList(list(imports.values())), include_file)
288285

289-
toposorted_classes = [classes[name] for name in toposorted_names]
290-
renderer.render(ql.GetParentImplementation(toposorted_classes), out / 'ParentChild.qll')
286+
renderer.render(ql.GetParentImplementation(list(classes.values())), out / 'ParentChild.qll')
291287

292288
for c in data.classes.values():
293289
if _should_skip_qltest(c, data.classes):

swift/codegen/lib/schema.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import re
55
from dataclasses import dataclass, field
66
from typing import List, Set, Union, Dict, ClassVar, Optional
7+
from toposort import toposort_flatten
78

89
import yaml
910

@@ -167,4 +168,17 @@ def load(path):
167168
cls.bases = [root_class_name]
168169
classes[root_class_name].derived.add(name)
169170

170-
return Schema(classes=classes, includes=set(data.get("_includes", [])))
171+
groups = {}
172+
173+
for name, cls in classes.items():
174+
groups.setdefault(cls.dir, []).append(name)
175+
176+
sorted_classes = {}
177+
178+
for dir in sorted(groups):
179+
group = groups[dir]
180+
inheritance = {name: classes[name].bases for name in group}
181+
for name in toposort_flatten(inheritance):
182+
sorted_classes[name] = classes[name]
183+
184+
return Schema(classes=sorted_classes, includes=set(data.get("_includes", [])))

swift/codegen/test/test_cppgen.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,23 +56,6 @@ def test_two_class_hierarchy(generate):
5656
]
5757

5858

59-
def test_complex_hierarchy_topologically_ordered(generate):
60-
a = cpp.Class(name="A")
61-
b = cpp.Class(name="B")
62-
c = cpp.Class(name="C", bases=[a])
63-
d = cpp.Class(name="D", bases=[a])
64-
e = cpp.Class(name="E", bases=[b, c, d], final=True, trap_name="Es")
65-
f = cpp.Class(name="F", bases=[c], final=True, trap_name="Fs")
66-
assert generate([
67-
schema.Class(name="F", bases=["C"]),
68-
schema.Class(name="B", derived={"E"}),
69-
schema.Class(name="D", bases=["A"], derived={"E"}),
70-
schema.Class(name="C", bases=["A"], derived={"E", "F"}),
71-
schema.Class(name="E", bases=["B", "C", "D"]),
72-
schema.Class(name="A", derived={"C", "D"}),
73-
]) == [a, b, c, d, e, f]
74-
75-
7659
@pytest.mark.parametrize("type,expected", [
7760
("a", "a"),
7861
("string", "std::string"),
@@ -154,8 +137,8 @@ def test_classes_with_dirs(generate_grouped):
154137
assert generate_grouped([
155138
schema.Class(name="A"),
156139
schema.Class(name="B", dir=pathlib.Path("foo")),
157-
schema.Class(name="C", bases=["CBase"], dir=pathlib.Path("bar")),
158140
schema.Class(name="CBase", derived={"C"}, dir=pathlib.Path("bar")),
141+
schema.Class(name="C", bases=["CBase"], dir=pathlib.Path("bar")),
159142
schema.Class(name="D", dir=pathlib.Path("foo/bar/baz")),
160143
]) == {
161144
".": [cpp.Class(name="A", trap_name="As", final=True)],

swift/codegen/test/test_qlgen.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ def test_hierarchy_imports(generate_import_list):
177177

178178
def test_hierarchy_children(generate_children_implementations):
179179
assert generate_children_implementations([
180-
schema.Class("D", bases=["B", "C"]),
181-
schema.Class("C", bases=["A"], derived={"D"}),
182-
schema.Class("B", bases=["A"], derived={"D"}),
183180
schema.Class("A", derived={"B", "C"}),
181+
schema.Class("B", bases=["A"], derived={"D"}),
182+
schema.Class("C", bases=["A"], derived={"D"}),
183+
schema.Class("D", bases=["B", "C"]),
184184
]) == ql.GetParentImplementation(
185185
classes=[ql.Class(name="A"),
186186
ql.Class(name="B", bases=["A"], imports=[

0 commit comments

Comments
 (0)