[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 05/12] qapi: Track location that created an impli
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PATCH v6 05/12] qapi: Track location that created an implicit type |
Date: |
Thu, 1 Oct 2015 22:31:45 -0600 |
A future patch will enable deferred error detection in the
various QAPISchema*.check() methods (rather than the current
ad hoc parse checks). But that means the user can request
a QAPI entity that will only fail validation after it has
been initialized. Since all errors have to have an
associated 'info' location, we need a location to be
associated with all user-triggered implicit types. The
intuitive info to use is the location of the enclosing
entity that caused the creation of the implicit type.
Note that we do not anticipate builtin types being used in
an error message (as they are not part of the user's QAPI
input, the user can't cause a semantic error in their
behavior), so we exempt those types from requiring info, by
setting a flag to track the completion of _def_predefineds().
No change to the generated code.
RFC: I used a class-level static flag to track whether we expected
'info is None' when creating a QAPISchemaEntity. This is gross,
because the flag will only be set on the first QAPISchema() instance
(it works because none of our client scripts ever instantiate more
than one schema). But the only other thing I could think of would
be passing the QAPISchema instance into the constructor for each
QAPISchemaEntity, which is a lot of churn. Any better ideas on how
best to do the assertion, or should I just drop it?
Signed-off-by: Eric Blake <address@hidden>
---
v6: improve commit message, track implicit enum info, rebase
on new lazy array handling
---
scripts/qapi.py | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 255001a..19cca97 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -792,6 +792,7 @@ class QAPISchemaEntity(object):
def __init__(self, name, info):
assert isinstance(name, str)
self.name = name
+ assert info or not QAPISchema.predefined_initialized
self.info = info
def c_name(self):
@@ -1114,6 +1115,8 @@ class QAPISchemaEvent(QAPISchemaEntity):
class QAPISchema(object):
+ predefined_initialized = False
+
def __init__(self, fname):
try:
self.exprs = check_exprs(QAPISchemaParser(open(fname, "r")).exprs)
@@ -1122,6 +1125,7 @@ class QAPISchema(object):
exit(1)
self._entity_dict = {}
self._def_predefineds()
+ QAPISchema.predefined_initialized = True
self._def_exprs()
self.check()
@@ -1163,9 +1167,9 @@ class QAPISchema(object):
[], None)
self._def_entity(self.the_empty_object_type)
- def _make_implicit_enum_type(self, name, values):
+ def _make_implicit_enum_type(self, name, info, values):
name = name + 'Kind'
- self._def_entity(QAPISchemaEnumType(name, None, values, None))
+ self._def_entity(QAPISchemaEnumType(name, info, values, None))
return name
def _make_array_type(self, element_type, info):
@@ -1174,12 +1178,12 @@ class QAPISchema(object):
self._def_entity(QAPISchemaArrayType(name, info, element_type))
return name
- def _make_implicit_object_type(self, name, role, members):
+ def _make_implicit_object_type(self, name, info, role, members):
if not members:
return None
name = ':obj-%s-%s' % (name, role)
if not self.lookup_entity(name, QAPISchemaObjectType):
- self._def_entity(QAPISchemaObjectType(name, None, None,
+ self._def_entity(QAPISchemaObjectType(name, info, None,
members, None))
return name
@@ -1218,13 +1222,13 @@ class QAPISchema(object):
if isinstance(typ, list):
assert len(typ) == 1
typ = self._make_array_type(typ[0], info)
- typ = self._make_implicit_object_type(typ, 'wrapper',
+ typ = self._make_implicit_object_type(typ, info, 'wrapper',
[self._make_member('data', typ,
info)])
return QAPISchemaObjectTypeVariant(case, typ)
- def _make_tag_enum(self, type_name, variants):
- typ = self._make_implicit_enum_type(type_name,
+ def _make_tag_enum(self, type_name, info, variants):
+ typ = self._make_implicit_enum_type(type_name, info,
[v.name for v in variants])
return QAPISchemaObjectTypeMember('type', typ, False)
@@ -1240,7 +1244,7 @@ class QAPISchema(object):
else:
variants = [self._make_simple_variant(key, value, info)
for (key, value) in data.iteritems()]
- tag_enum = self._make_tag_enum(name, variants)
+ tag_enum = self._make_tag_enum(name, info, variants)
self._def_entity(
QAPISchemaObjectType(name, info, base,
self._make_members(OrderedDict(), info),
@@ -1253,7 +1257,7 @@ class QAPISchema(object):
data = expr['data']
variants = [self._make_variant(key, value)
for (key, value) in data.iteritems()]
- tag_enum = self._make_tag_enum(name, variants)
+ tag_enum = self._make_tag_enum(name, info, variants)
self._def_entity(
QAPISchemaAlternateType(name, info,
QAPISchemaObjectTypeVariants(None,
@@ -1267,7 +1271,7 @@ class QAPISchema(object):
gen = expr.get('gen', True)
success_response = expr.get('success-response', True)
if isinstance(data, OrderedDict):
- data = self._make_implicit_object_type(name, 'arg',
+ data = self._make_implicit_object_type(name, info, 'arg',
self._make_members(data,
info))
if isinstance(rets, list):
@@ -1280,7 +1284,7 @@ class QAPISchema(object):
name = expr['event']
data = expr.get('data')
if isinstance(data, OrderedDict):
- data = self._make_implicit_object_type(name, 'arg',
+ data = self._make_implicit_object_type(name, info, 'arg',
self._make_members(data,
info))
self._def_entity(QAPISchemaEvent(name, info, data))
--
2.4.3
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, (continued)
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Markus Armbruster, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Markus Armbruster, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Markus Armbruster, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Markus Armbruster, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Markus Armbruster, 2015/10/08
- Re: [Qemu-devel] [PATCH v6 02/12] qapi: Don't use info as witness of implicit object type, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v6 05/12] qapi: Track location that created an implicit type,
Eric Blake <=
[Qemu-devel] [PATCH v6 08/12] qapi: Defer duplicate member checks to schema check(), Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v6 11/12] qapi: Detect base class loops, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v6 12/12] RFC: qapi: Hide _info member, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v6 10/12] qapi: Correct error for union branch 'kind' clash, Eric Blake, 2015/10/08