aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi/schema.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qapi/schema.py')
-rw-r--r--scripts/qapi/schema.py101
1 files changed, 22 insertions, 79 deletions
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index 3d72c7dfc9..004d7095ff 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -321,8 +321,8 @@ class QAPISchemaEnumType(QAPISchemaType):
m.connect_doc(doc)
def is_implicit(self):
- # See QAPISchema._make_implicit_enum_type() and ._def_predefineds()
- return self.name.endswith('Kind') or self.name == 'QType'
+ # See QAPISchema._def_predefineds()
+ return self.name == 'QType'
def c_type(self):
return c_name(self.name)
@@ -393,8 +393,7 @@ class QAPISchemaObjectType(QAPISchemaType):
def __init__(self, name, info, doc, ifcond, features,
base, local_members, variants):
# struct has local_members, optional base, and no variants
- # flat union has base, variants, and no local_members
- # simple union has local_members, variants, and no base
+ # union has base, variants, and no local_members
super().__init__(name, info, doc, ifcond, features)
self.meta = 'union' if variants else 'struct'
assert base is None or isinstance(base, str)
@@ -465,15 +464,6 @@ class QAPISchemaObjectType(QAPISchemaType):
for m in self.local_members:
m.connect_doc(doc)
- @property
- def ifcond(self):
- assert self._checked
- if isinstance(self._ifcond, QAPISchemaType):
- # Simple union wrapper type inherits from wrapped type;
- # see _make_implicit_object_type()
- return self._ifcond.ifcond
- return self._ifcond
-
def is_implicit(self):
# See QAPISchema._make_implicit_object_type(), as well as
# _def_predefineds()
@@ -576,10 +566,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
class QAPISchemaVariants:
def __init__(self, tag_name, info, tag_member, variants):
- # Flat unions pass tag_name but not tag_member.
- # Simple unions and alternates pass tag_member but not tag_name.
- # After check(), tag_member is always set, and tag_name remains
- # a reliable witness of being used by a flat union.
+ # Unions pass tag_name but not tag_member.
+ # Alternates pass tag_member but not tag_name.
+ # After check(), tag_member is always set.
assert bool(tag_member) != bool(tag_name)
assert (isinstance(tag_name, str) or
isinstance(tag_member, QAPISchemaObjectTypeMember))
@@ -595,7 +584,7 @@ class QAPISchemaVariants:
v.set_defined_in(name)
def check(self, schema, seen):
- if not self.tag_member: # flat union
+ if self._tag_name: # union
self.tag_member = seen.get(c_name(self._tag_name))
base = "'base'"
# Pointing to the base type when not implicit would be
@@ -625,11 +614,11 @@ class QAPISchemaVariants:
self.info,
"discriminator member '%s' of %s must not be conditional"
% (self._tag_name, base))
- else: # simple union
+ else: # alternate
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
assert not self.tag_member.optional
assert not self.tag_member.ifcond.is_present()
- if self._tag_name: # flat union
+ if self._tag_name: # union
# branches that are not explicitly covered get an empty type
cases = {v.name for v in self.variants}
for m in self.tag_member.type.members:
@@ -707,18 +696,10 @@ class QAPISchemaMember:
assert role == 'member'
role = 'parameter'
elif defined_in.endswith('-base'):
- # Implicit type created for a flat union's dict 'base'
+ # Implicit type created for a union's dict 'base'
role = 'base ' + role
else:
- # Implicit type created for a simple union's branch
- assert defined_in.endswith('-wrapper')
- # Unreachable and not implemented
assert False
- elif defined_in.endswith('Kind'):
- # See QAPISchema._make_implicit_enum_type()
- # Implicit enum created for simple union's branches
- assert role == 'value'
- role = 'branch'
elif defined_in != info.defn_name:
return "%s '%s' of type '%s'" % (role, self.name, defined_in)
return "%s '%s'" % (role, self.name)
@@ -1004,15 +985,6 @@ class QAPISchema:
QAPISchemaIfCond(v.get('if')))
for v in values]
- def _make_implicit_enum_type(self, name, info, ifcond, values):
- # See also QAPISchemaObjectTypeMember.describe()
- name = name + 'Kind' # reserved by check_defn_name_str()
- self._def_entity(QAPISchemaEnumType(
- name, info, None, ifcond, None,
- self._make_enum_members(values, info),
- None))
- return name
-
def _make_array_type(self, element_type, info):
name = element_type + 'List' # reserved by check_defn_name_str()
if not self.lookup_type(name):
@@ -1026,17 +998,9 @@ class QAPISchema:
name = 'q_obj_%s-%s' % (name, role)
typ = self.lookup_entity(name, QAPISchemaObjectType)
if typ:
- # The implicit object type has multiple users. This is
- # either a duplicate definition (which will be flagged
- # later), or an implicit wrapper type used for multiple
- # simple unions. In the latter case, ifcond should be the
- # disjunction of its user's ifconds. Not implemented.
- # Instead, we always pass the wrapped type's ifcond, which
- # is trivially the same for all users. It's also
- # necessary for the wrapper to compile. But it's not
- # tight: the disjunction need not imply it. We may end up
- # compiling useless wrapper types.
- # TODO kill simple unions or implement the disjunction
+ # The implicit object type has multiple users. This can
+ # only be a duplicate definition, which will be flagged
+ # later.
pass
else:
self._def_entity(QAPISchemaObjectType(
@@ -1084,49 +1048,28 @@ class QAPISchema:
def _make_variant(self, case, typ, ifcond, info):
return QAPISchemaVariant(case, info, typ, ifcond)
- def _make_simple_variant(self, case, typ, ifcond, info):
- if isinstance(typ, list):
- assert len(typ) == 1
- typ = self._make_array_type(typ[0], info)
- typ = self._make_implicit_object_type(
- typ, info, self.lookup_type(typ),
- 'wrapper', [self._make_member('data', typ, None, None, info)])
- return QAPISchemaVariant(case, info, typ, ifcond)
-
def _def_union_type(self, expr, info, doc):
name = expr['union']
+ base = expr['base']
+ tag_name = expr['discriminator']
data = expr['data']
- base = expr.get('base')
ifcond = QAPISchemaIfCond(expr.get('if'))
features = self._make_features(expr.get('features'), info)
- tag_name = expr.get('discriminator')
- tag_member = None
if isinstance(base, dict):
base = self._make_implicit_object_type(
name, info, ifcond,
'base', self._make_members(base, info))
- if tag_name:
- variants = [
- self._make_variant(key, value['type'],
- QAPISchemaIfCond(value.get('if')),
- info)
- for (key, value) in data.items()]
- members = []
- else:
- variants = [
- self._make_simple_variant(key, value['type'],
- QAPISchemaIfCond(value.get('if')),
- info)
- for (key, value) in data.items()]
- enum = [{'name': v.name, 'if': v.ifcond.ifcond} for v in variants]
- typ = self._make_implicit_enum_type(name, info, ifcond, enum)
- tag_member = QAPISchemaObjectTypeMember('type', info, typ, False)
- members = [tag_member]
+ variants = [
+ self._make_variant(key, value['type'],
+ QAPISchemaIfCond(value.get('if')),
+ info)
+ for (key, value) in data.items()]
+ members = []
self._def_entity(
QAPISchemaObjectType(name, info, doc, ifcond, features,
base, members,
QAPISchemaVariants(
- tag_name, info, tag_member, variants)))
+ tag_name, info, None, variants)))
def _def_alternate_type(self, expr, info, doc):
name = expr['alternate']