qapi: Don't use info as witness of implicit object type

A future patch will enable error reporting from the various
QAPISchema*.check() methods. But to report an error related
to an implicit type, we'll need to associate a location with
the type (the same location as the top-level entity that is
causing the creation of the implicit type), and once we do
that, keying off of whether foo.info exists is no longer a
viable way to determine if foo is an implicit type.

Instead, add an is_implicit() method to QAPISchemaEntity, and use it.
It can be overridden later for ObjectType and EnumType, when implicit
instances of those classes gain info.

Backports commit 49823c4b4304a3e4aa5d67e089946b12d6a52d64 from qemu
This commit is contained in:
Eric Blake 2018-02-19 18:53:03 -05:00 committed by Lioncash
parent 3d11f7173d
commit dc65960e1f
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 14 additions and 6 deletions

View file

@ -230,7 +230,8 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
def visit_needed(self, entity):
# Visit everything except implicit objects
return not isinstance(entity, QAPISchemaObjectType) or entity.info
return not (entity.is_implicit() and
isinstance(entity, QAPISchemaObjectType))
def _gen_type_cleanup(self, name):
self.decl += gen_type_cleanup_decl(name)

View file

@ -334,7 +334,8 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
def visit_needed(self, entity):
# Visit everything except implicit objects
return not isinstance(entity, QAPISchemaObjectType) or entity.info
return not (entity.is_implicit() and
isinstance(entity, QAPISchemaObjectType))
def visit_enum_type(self, name, info, values, prefix):
self.decl += gen_visit_decl(name, scalar=True)

View file

@ -798,6 +798,9 @@ class QAPISchemaEntity(object):
def check(self, schema):
pass
def is_implicit(self):
return not self.info
def visit(self, visitor):
pass
@ -971,11 +974,11 @@ class QAPISchemaObjectType(QAPISchemaType):
self.members = members
def c_name(self):
assert self.info
assert not self.is_implicit()
return QAPISchemaType.c_name(self)
def c_type(self, is_param=False):
assert self.info
assert not self.is_implicit()
return QAPISchemaType.c_type(self)
def json_type(self):
@ -1042,7 +1045,8 @@ class QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
# This function exists to support ugly simple union special cases
# TODO get rid of them, and drop the function
def simple_union_type(self):
if isinstance(self.type, QAPISchemaObjectType) and not self.type.info:
if (self.type.is_implicit() and
isinstance(self.type, QAPISchemaObjectType)):
assert len(self.type.members) == 1
assert not self.type.variants
return self.type.members[0].type
@ -1161,11 +1165,13 @@ class QAPISchema(object):
self._def_entity(self.the_empty_object_type)
def _make_implicit_enum_type(self, name, values):
name = name + 'Kind'
name = name + 'Kind' # Use namespace reserved by add_name()
self._def_entity(QAPISchemaEnumType(name, None, values, None))
return name
def _make_array_type(self, element_type):
# TODO fooList namespace is not reserved; user can create collisions,
# or abuse our type system with ['fooList'] for 2D array
name = element_type + 'List'
if not self.lookup_type(name):
self._def_entity(QAPISchemaArrayType(name, None, element_type))