From 84ab00868798a65e19d76d3cb5f1552c6b25ceb4 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 17 Mar 2020 12:54:45 +0100 Subject: qapi: Add feature flags to struct members Signed-off-by: Markus Armbruster Reviewed-by: Marc-André Lureau Message-Id: <20200317115459.31821-21-armbru@redhat.com> --- scripts/qapi/expr.py | 3 ++- scripts/qapi/introspect.py | 2 +- scripts/qapi/schema.py | 25 ++++++++++++++++++++----- 3 files changed, 23 insertions(+), 7 deletions(-) (limited to 'scripts/qapi') diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index f9c4448980..2942520399 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -167,8 +167,9 @@ def check_type(value, info, source, allow_optional=True, permit_upper=permit_upper) if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'): raise QAPISemError(info, "%s uses reserved name" % key_source) - check_keys(arg, info, key_source, ['type'], ['if']) + check_keys(arg, info, key_source, ['type'], ['if', 'features']) check_if(arg, info, key_source) + check_features(arg.get('features'), info) check_type(arg['type'], info, key_source, allow_array=True) diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index a3fa9865db..23652be810 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -173,7 +173,7 @@ const QLitObject %(c_name)s = %(c_string)s; obj = {'name': member.name, 'type': self._use_type(member.type)} if member.optional: obj['default'] = None - return _make_tree(obj, member.ifcond, None) + return _make_tree(obj, member.ifcond, member.features) def _gen_variants(self, tag_name, variants): return {'tag': tag_name, diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 59e1f5a395..6ee3677215 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -668,18 +668,31 @@ class QAPISchemaFeature(QAPISchemaMember): class QAPISchemaObjectTypeMember(QAPISchemaMember): - def __init__(self, name, info, typ, optional, ifcond=None): + def __init__(self, name, info, typ, optional, ifcond=None, features=None): super().__init__(name, info, ifcond) assert isinstance(typ, str) assert isinstance(optional, bool) + for f in features or []: + assert isinstance(f, QAPISchemaFeature) + f.set_defined_in(name) self._type_name = typ self.type = None self.optional = optional + self.features = features or [] def check(self, schema): assert self.defined_in self.type = schema.resolve_type(self._type_name, self.info, self.describe) + seen = {} + for f in self.features: + f.check_clash(self.info, seen) + + def connect_doc(self, doc): + super().connect_doc(doc) + if doc: + for f in self.features: + doc.connect_feature(f) class QAPISchemaVariant(QAPISchemaObjectTypeMember): @@ -962,7 +975,7 @@ class QAPISchema: name, info, doc, ifcond, features, self._make_enum_members(data, info), prefix)) - def _make_member(self, name, typ, ifcond, info): + def _make_member(self, name, typ, ifcond, features, info): optional = False if name.startswith('*'): name = name[1:] @@ -970,10 +983,12 @@ class QAPISchema: if isinstance(typ, list): assert len(typ) == 1 typ = self._make_array_type(typ[0], info) - return QAPISchemaObjectTypeMember(name, info, typ, optional, ifcond) + return QAPISchemaObjectTypeMember(name, info, typ, optional, ifcond, + self._make_features(features, info)) def _make_members(self, data, info): - return [self._make_member(key, value['type'], value.get('if'), info) + return [self._make_member(key, value['type'], value.get('if'), + value.get('features'), info) for (key, value) in data.items()] def _def_struct_type(self, expr, info, doc): @@ -996,7 +1011,7 @@ class QAPISchema: 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, info)]) + 'wrapper', [self._make_member('data', typ, None, None, info)]) return QAPISchemaVariant(case, info, typ, ifcond) def _def_union_type(self, expr, info, doc): -- cgit v1.2.3-55-g7522