qapi: Use predicate callback to determine visit filtering

Previously, qapi-types and qapi-visit filtered out implicit
objects during visit_object_type() by using 'info' (works since
implicit objects do not [yet] have associated info); meanwhile
qapi-introspect filtered out all schema types on the first pass
by returning a python type from visit_begin(), which was then
used at a distance in QAPISchema.visit() to do the filtering.

Rather than keeping these ad hoc approaches, add a new visitor
callback visit_needed() which returns False to skip a given
entity, and which defaults to True unless overridden. Use the
new mechanism to simplify all three filtering visitors.

No change to the generated code.

Backports commit 25a0d9c977c2f5db914b0a1619759fd77d97b016 from qemu
This commit is contained in:
Eric Blake 2018-02-19 18:49:02 -05:00 committed by Lioncash
parent f371fa9105
commit 9d0c5746ff
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 29 additions and 19 deletions

View file

@ -228,6 +228,10 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self.decl = self._btin + self.decl
self._btin = None
def visit_needed(self, entity):
# Visit everything except implicit objects
return not isinstance(entity, QAPISchemaObjectType) or entity.info
def _gen_type_cleanup(self, name):
self.decl += gen_type_cleanup_decl(name)
self.defn += gen_type_cleanup(name)
@ -249,14 +253,13 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
self._gen_type_cleanup(name)
def visit_object_type(self, name, info, base, members, variants):
if info:
self._fwdecl += gen_fwd_object_or_array(name)
if variants:
assert not members # not implemented
self.decl += gen_union(name, base, variants)
else:
self.decl += gen_struct(name, base, members)
self._gen_type_cleanup(name)
self._fwdecl += gen_fwd_object_or_array(name)
if variants:
assert not members # not implemented
self.decl += gen_union(name, base, variants)
else:
self.decl += gen_struct(name, base, members)
self._gen_type_cleanup(name)
def visit_alternate_type(self, name, info, variants):
self._fwdecl += gen_fwd_object_or_array(name)

View file

@ -332,6 +332,10 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.decl = self._btin + self.decl
self._btin = None
def visit_needed(self, entity):
# Visit everything except implicit objects
return not isinstance(entity, QAPISchemaObjectType) or entity.info
def visit_enum_type(self, name, info, values, prefix):
self.decl += gen_visit_decl(name, scalar=True)
self.defn += gen_visit_enum(name)
@ -348,13 +352,12 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
self.defn += defn
def visit_object_type(self, name, info, base, members, variants):
if info:
self.decl += gen_visit_decl(name)
if variants:
assert not members # not implemented
self.defn += gen_visit_union(name, base, variants)
else:
self.defn += gen_visit_struct(name, base, members)
self.decl += gen_visit_decl(name)
if variants:
assert not members # not implemented
self.defn += gen_visit_union(name, base, variants)
else:
self.defn += gen_visit_struct(name, base, members)
def visit_alternate_type(self, name, info, variants):
self.decl += gen_visit_decl(name)

View file

@ -808,6 +808,10 @@ class QAPISchemaVisitor(object):
def visit_end(self):
pass
def visit_needed(self, entity):
# Default to visiting everything
return True
def visit_builtin_type(self, name, info, json_type):
pass
@ -1300,10 +1304,10 @@ class QAPISchema(object):
ent.check(self)
def visit(self, visitor):
ignore = visitor.visit_begin(self)
for name in sorted(self._entity_dict.keys()):
if not ignore or not isinstance(self._entity_dict[name], ignore):
self._entity_dict[name].visit(visitor)
visitor.visit_begin(self)
for (name, entity) in sorted(self._entity_dict.items()):
if visitor.visit_needed(entity):
entity.visit(visitor)
visitor.visit_end()
#