qapi: Fix code generation for empty modules

When a sub-module doesn't contain any definitions, we don't generate
code for it, but we do generate the #include.

We generate code only for modules that get visited.
QAPISchema.visit() visits only modules that have definitions.  It can
visit modules multiple times.

Clean this up as follows.  Collect entities in their QAPISchemaModule.
Have QAPISchema.visit() call QAPISchemaModule.visit() for each module.
Have QAPISchemaModule.visit() call .visit_module() for itself, and
QAPISchemaEntity.visit() for each of its entities.  This way, we visit
each module exactly once.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20191120182551.23795-6-armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
Markus Armbruster 2019-11-20 19:25:50 +01:00
parent a9f1dd7ee0
commit 3e7fb5811b
4 changed files with 26 additions and 29 deletions

View file

@ -68,6 +68,7 @@ class QAPISchemaEntity(object):
def _set_module(self, schema, info):
assert self._checked
self._module = schema.module_by_fname(info and info.fname)
self._module.add_entity(self)
def set_module(self, schema):
self._set_module(schema, self.info)
@ -77,11 +78,6 @@ class QAPISchemaEntity(object):
assert self._checked
return self._ifcond
@property
def module(self):
assert self._module or not self.info
return self._module
def is_implicit(self):
return not self.info
@ -142,6 +138,16 @@ class QAPISchemaVisitor(object):
class QAPISchemaModule(object):
def __init__(self, name):
self.name = name
self._entity_list = []
def add_entity(self, ent):
self._entity_list.append(ent)
def visit(self, visitor):
visitor.visit_module(self.name)
for entity in self._entity_list:
if visitor.visit_needed(entity):
entity.visit(visitor)
class QAPISchemaInclude(QAPISchemaEntity):
@ -1093,10 +1099,6 @@ class QAPISchema(object):
def visit(self, visitor):
visitor.visit_begin(self)
module = None
for entity in self._entity_list:
if visitor.visit_needed(entity):
if entity.module != module:
module = entity.module
visitor.visit_module(module.name)
entity.visit(visitor)
for mod in self._module_dict.values():
mod.visit(visitor)
visitor.visit_end()