[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v13 10/14] qapi: Track enum values by QAPISchemaMemb
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v13 10/14] qapi: Track enum values by QAPISchemaMember, not string |
Date: |
Fri, 20 Nov 2015 10:24:56 -0700 |
Rather than using just an array of strings, make enum.values be
an array of the new QAPISchemaMember type. Creating an enum
requires wrapping strings, and visiting an enum requires getting
at the name of each value. But using this type means we can
share the existing code for C name clash detection (although the
code is not yet active until a later commit removes the earlier
ad hoc parser checks). The ._pretty_owner() method needs to
learn about one more implicit type name: the generated enum
associated with a simple union.
Signed-off-by: Eric Blake <address@hidden>
---
v13: new patch
---
scripts/qapi.py | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2748464..d1239c2 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -901,13 +901,17 @@ class QAPISchemaEnumType(QAPISchemaType):
def __init__(self, name, info, values, prefix):
QAPISchemaType.__init__(self, name, info)
for v in values:
- assert isinstance(v, str)
+ assert isinstance(v, QAPISchemaMember)
+ v.set_owner(name)
assert prefix is None or isinstance(prefix, str)
self.values = values
self.prefix = prefix
def check(self, schema):
- assert len(set(self.values)) == len(self.values)
+ # Check for collisions on the generated C enum values
+ seen = {}
+ for v in self.values:
+ v.check_clash(self.info, seen)
def is_implicit(self):
# See QAPISchema._make_implicit_enum_type()
@@ -917,15 +921,18 @@ class QAPISchemaEnumType(QAPISchemaType):
return c_name(self.name)
def c_null(self):
- return c_enum_const(self.name, (self.values + ['_MAX'])[0],
- self.prefix)
+ if self.values:
+ value = self.values[0].name
+ else:
+ value = '_MAX'
+ return c_enum_const(self.name, value, self.prefix)
def json_type(self):
return 'string'
def visit(self, visitor):
visitor.visit_enum_type(self.name, self.info,
- self.values, self.prefix)
+ [v.name for v in self.values], self.prefix)
class QAPISchemaArrayType(QAPISchemaType):
@@ -1049,6 +1056,8 @@ class QAPISchemaMember(object):
else:
assert owner.endswith('-wrapper')
return '(branch of %s)' % owner[:-8]
+ if owner.endswith('Kind'):
+ return '(branch of %s)' % owner[:-4]
return '(%s of %s)' % (self.role, owner)
def describe(self):
@@ -1094,12 +1103,13 @@ class QAPISchemaObjectTypeVariants(object):
self.tag_member = seen[c_name(self.tag_name)]
assert self.tag_name == self.tag_member.name
assert isinstance(self.tag_member.type, QAPISchemaEnumType)
+ tag_values = [v.name for v in self.tag_member.type.values]
for v in self.variants:
v.check(schema)
# Union names must match enum values; alternate names are
# checked separately. Use 'seen' to tell the two apart.
if seen:
- assert v.name in self.tag_member.type.values
+ assert v.name in tag_values
assert isinstance(v.type, QAPISchemaObjectType)
v.type.check(schema)
@@ -1257,15 +1267,16 @@ class QAPISchema(object):
self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None,
[], None)
self._def_entity(self.the_empty_object_type)
- self._def_entity(QAPISchemaEnumType('QType', None,
- ['none', 'qnull', 'qint',
- 'qstring', 'qdict', 'qlist',
- 'qfloat', 'qbool'],
+ qtype_values = [QAPISchemaMember(name) for name in
+ ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist',
+ 'qfloat', 'qbool']]
+ self._def_entity(QAPISchemaEnumType('QType', None, qtype_values,
'QTYPE'))
def _make_implicit_enum_type(self, name, info, values):
name = name + 'Kind' # Use namespace reserved by add_name()
- self._def_entity(QAPISchemaEnumType(name, info, values, None))
+ self._def_entity(QAPISchemaEnumType(
+ name, info, [QAPISchemaMember(v) for v in values], None))
return name
def _make_array_type(self, element_type, info):
@@ -1288,7 +1299,8 @@ class QAPISchema(object):
name = expr['enum']
data = expr['data']
prefix = expr.get('prefix')
- self._def_entity(QAPISchemaEnumType(name, info, data, prefix))
+ self._def_entity(QAPISchemaEnumType(
+ name, info, [QAPISchemaMember(v) for v in data], prefix))
def _make_member(self, name, typ, info):
optional = False
--
2.4.3
- [Qemu-devel] [PATCH v13 00/14] qapi member collision (post-introspection cleanups, subset D), Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 05/14] qapi: Inline _make_implicit_tag(), Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 03/14] qapi: Convert QType into QAPI built-in enum type, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 07/14] qapi: Simplify visits of optional fields, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 08/14] qapi: Shorter visits of optional fields, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 10/14] qapi: Track enum values by QAPISchemaMember, not string,
Eric Blake <=
- [Qemu-devel] [PATCH v13 11/14] qapi: Populate info['name'] for each entity, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 09/14] qapi: Prepare new QAPISchemaMember base class, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 14/14] qapi: Detect base class loops, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 04/14] qapi: Simplify visiting of alternate types, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 12/14] qapi: Enforce (or whitelist) case conventions on qapi members, Eric Blake, 2015/11/20
- [Qemu-devel] [PATCH v13 01/14] qobject: Simplify QObject, Eric Blake, 2015/11/20