diff options
Diffstat (limited to 'scripts/qapi/schema.py')
| -rw-r--r-- | scripts/qapi/schema.py | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 207e4d71f3..231ebf61ba 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -259,7 +259,7 @@ class QAPISchemaType(QAPISchemaEntity): return not self.c_type().endswith(POINTER_SUFFIX) def check(self, schema): - QAPISchemaEntity.check(self, schema) + super().check(schema) for feat in self.features: if feat.is_special(): raise QAPISemError( @@ -465,9 +465,10 @@ class QAPISchemaObjectType(QAPISchemaType): # on behalf of info, which is not necessarily self.info def check_clash(self, info, seen): assert self._checked - assert not self.variants # not implemented for m in self.members: m.check_clash(info, seen) + if self.variants: + self.variants.check_clash(info, seen) def connect_doc(self, doc=None): super().connect_doc(doc) @@ -486,6 +487,10 @@ class QAPISchemaObjectType(QAPISchemaType): assert self.members is not None return not self.members and not self.variants + def has_conditional_members(self): + assert self.members is not None + return any(m.ifcond.is_present() for m in self.members) + def c_name(self): assert self.name != 'q_empty' return super().c_name() @@ -652,8 +657,7 @@ class QAPISchemaVariants: self.info, "branch '%s' is not a value of %s" % (v.name, self.tag_member.type.describe())) - if (not isinstance(v.type, QAPISchemaObjectType) - or v.type.variants): + if not isinstance(v.type, QAPISchemaObjectType): raise QAPISemError( self.info, "%s cannot use %s" @@ -697,6 +701,7 @@ class QAPISchemaMember: def describe(self, info): role = self.role + meta = 'type' defined_in = self.defined_in assert defined_in @@ -708,13 +713,17 @@ class QAPISchemaMember: # Implicit type created for a command's dict 'data' assert role == 'member' role = 'parameter' + meta = 'command' + defined_in = defined_in[:-4] elif defined_in.endswith('-base'): # Implicit type created for a union's dict 'base' role = 'base ' + role + defined_in = defined_in[:-5] else: assert False - elif defined_in != info.defn_name: - return "%s '%s' of type '%s'" % (role, self.name, defined_in) + + if defined_in != info.defn_name: + return "%s '%s' of %s '%s'" % (role, self.name, meta, defined_in) return "%s '%s'" % (role, self.name) @@ -817,6 +826,11 @@ class QAPISchemaCommand(QAPISchemaEntity): self.info, "command's 'data' can take %s only with 'boxed': true" % self.arg_type.describe()) + self.arg_type.check(schema) + if self.arg_type.has_conditional_members() and not self.boxed: + raise QAPISemError( + self.info, + "conditional command arguments require 'boxed': true") if self._ret_type_name: self.ret_type = schema.resolve_type( self._ret_type_name, self.info, "command's 'returns'") @@ -872,6 +886,11 @@ class QAPISchemaEvent(QAPISchemaEntity): self.info, "event's 'data' can take %s only with 'boxed': true" % self.arg_type.describe()) + self.arg_type.check(schema) + if self.arg_type.has_conditional_members() and not self.boxed: + raise QAPISemError( + self.info, + "conditional event arguments require 'boxed': true") def connect_doc(self, doc=None): super().connect_doc(doc) |