Swift: move toposort in schema.py

This makes the result of code generation independent of the order
in which classes are defined in the schema, and makes additional
topological sorting not required.

Being independent from schema order will be important for reviewing the
move to a pure python schema, as generated code will be left untouched.
This commit is contained in:
Paolo Tranquilli
2022-09-21 10:44:39 +02:00
parent b49487cf42
commit a50f3f752b
8 changed files with 6413 additions and 6425 deletions

View File

@@ -16,7 +16,6 @@ import pathlib
from typing import Dict
import inflection
from toposort import toposort_flatten
from swift.codegen.lib import cpp, schema
@@ -71,13 +70,9 @@ class Processor:
)
def get_classes(self):
grouped = {pathlib.Path(): {}}
ret = {pathlib.Path(): []}
for k, cls in self._classmap.items():
grouped.setdefault(cls.dir, {}).update({k: cls})
ret = {}
for dir, map in grouped.items():
inheritance_graph = {k: {b for b in cls.bases if b in map} for k, cls in map.items()}
ret[dir] = [self._get_class(cls) for cls in toposort_flatten(inheritance_graph)]
ret.setdefault(cls.dir, []).append(self._get_class(cls.name))
return ret

View File

@@ -28,7 +28,6 @@ import typing
import itertools
import inflection
from toposort import toposort_flatten
from swift.codegen.lib import schema, ql
@@ -263,9 +262,7 @@ def generate(opts, renderer):
imports = {}
inheritance_graph = {name: cls.bases for name, cls in data.classes.items()}
toposorted_names = toposort_flatten(inheritance_graph)
db_classes = [classes[name] for name in toposorted_names if not classes[name].ipa]
db_classes = [cls for cls in classes.values() if not cls.ipa]
renderer.render(ql.DbClasses(db_classes), out / "Raw.qll")
classes_by_dir_and_name = sorted(classes.values(), key=lambda cls: (cls.dir, cls.name))
@@ -286,8 +283,7 @@ def generate(opts, renderer):
include_file = stub_out.with_suffix(".qll")
renderer.render(ql.ImportList(list(imports.values())), include_file)
toposorted_classes = [classes[name] for name in toposorted_names]
renderer.render(ql.GetParentImplementation(toposorted_classes), out / 'ParentChild.qll')
renderer.render(ql.GetParentImplementation(list(classes.values())), out / 'ParentChild.qll')
for c in data.classes.values():
if _should_skip_qltest(c, data.classes):