[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v7 08/14] qapi: Track location that created an i
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v7 08/14] qapi: Track location that created an implicit type |
Date: |
Thu, 08 Oct 2015 16:19:38 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) |
Eric Blake <address@hidden> writes:
> A future patch will move some error checking from the parser
> to the various QAPISchema*.check() methods, which run only
> after parsing completes. It will thus be possible to create
> a python instance representing an implicit QAPI type that
> parses fine but will fail validation during check(). Since
> all errors have to have an associated 'info' location, we
> need a location to be associated with those implicit types.
> The intuitive info to use is the location of the enclosing
> entity that caused the creation of the implicit type.
Would you like to mention you already added info to the implicit array
types a couple of patches ago?
>
> 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(),
> and tracking that flag in _def_entity().
>
> No change to the generated code.
>
> Signed-off-by: Eric Blake <address@hidden>
>
> ---
> v7: better commit message and comments, fix info assertion to
> use instance flag rather than ugly leaky abstraction static flag
> v6: improve commit message, track implicit enum info, rebase
> on new lazy array handling
> ---
> scripts/qapi.py | 33 +++++++++++++++++++--------------
> 1 file changed, 19 insertions(+), 14 deletions(-)
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index f5040da..e49f72b 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -795,9 +795,9 @@ class QAPISchemaEntity(object):
> self.name = name
> # For explicitly defined entities, info points to the (explicit)
> # definition. For builtins (and their arrays), info is None.
> - # TODO For other implicitly defined entities, it should point to
> - # a place that triggers implicit definition; there may be more
> - # than one such place.
> + # For other implicitly defined entities, it points to a place
> + # that triggers implicit definition; there may be more than one
> + # such place.
> self.info = info
>
> def c_name(self):
> @@ -1153,7 +1153,9 @@ class QAPISchema(object):
> try:
> self.exprs = check_exprs(QAPISchemaParser(open(fname,
> "r")).exprs)
> self._entity_dict = {}
> + self._predefined_done = False
> self._def_predefineds()
> + self._predefined_done = True
> self._def_exprs()
> self.check()
> except (QAPISchemaError, QAPIExprError), err:
> @@ -1161,6 +1163,9 @@ class QAPISchema(object):
> exit(1)
>
> def _def_entity(self, ent):
> + if self._predefined_done:
> + # Only the predefined types are allowed to not have info
> + assert ent.info
Or possibly
assert ent.info or not self._predefined_done
With self._predefined_done replaced by self._predefining, we'd get
assert ent.info or self._predefining
Pick the bikeshed color you like best :)
> assert ent.name not in self._entity_dict
> self._entity_dict[ent.name] = ent
>
> @@ -1203,9 +1208,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):
> @@ -1214,12 +1219,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
>
> @@ -1259,11 +1264,11 @@ class QAPISchema(object):
> assert len(typ) == 1
> typ = self._make_array_type(typ[0], info)
> typ = self._make_implicit_object_type(
> - typ, 'wrapper', [self._make_member('data', typ, info)])
> + typ, info, 'wrapper', [self._make_member('data', typ, info)])
> return QAPISchemaObjectTypeVariant(case, typ)
>
> - def _make_implicit_tag(self, type_name, variants):
> - typ = self._make_implicit_enum_type(type_name,
> + def _make_implicit_tag(self, type_name, info, variants):
> + typ = self._make_implicit_enum_type(type_name, info,
> [v.name for v in variants])
> return QAPISchemaObjectTypeUnionTag('type', typ, False)
>
> @@ -1279,7 +1284,7 @@ class QAPISchema(object):
> else:
> variants = [self._make_simple_variant(key, value, info)
> for (key, value) in data.iteritems()]
> - tag_enum = self._make_implicit_tag(name, variants)
> + tag_enum = self._make_implicit_tag(name, info, variants)
> self._def_entity(
> QAPISchemaObjectType(name, info, base,
> self._make_members(OrderedDict(), info),
> @@ -1292,7 +1297,7 @@ class QAPISchema(object):
> data = expr['data']
> variants = [self._make_variant(key, value)
> for (key, value) in data.iteritems()]
> - tag_enum = self._make_implicit_tag(name, variants)
> + tag_enum = self._make_implicit_tag(name, info, variants)
> self._def_entity(
> QAPISchemaAlternateType(name, info,
> QAPISchemaObjectTypeVariants(None,
> @@ -1307,7 +1312,7 @@ class QAPISchema(object):
> success_response = expr.get('success-response', True)
> if isinstance(data, OrderedDict):
> data = self._make_implicit_object_type(
> - name, 'arg', self._make_members(data, info))
> + name, info, 'arg', self._make_members(data, info))
> if isinstance(rets, list):
> assert len(rets) == 1
> rets = self._make_array_type(rets[0], info)
> @@ -1319,7 +1324,7 @@ class QAPISchema(object):
> data = expr.get('data')
> if isinstance(data, OrderedDict):
> data = self._make_implicit_object_type(
> - name, 'arg', self._make_members(data, info))
> + name, info, 'arg', self._make_members(data, info))
> self._def_entity(QAPISchemaEvent(name, info, data))
>
> def _def_exprs(self):
Tedious plumbing work, mostly :)
- Re: [Qemu-devel] [PATCH v7 05/14] qapi: Lazy creation of array types, (continued)
[Qemu-devel] [PATCH v7 13/14] qapi: Add test for alternate branch 'kind' clash, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v7 03/14] qapi: Drop redundant alternate-good test, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v7 01/14] qapi: Use predicate callback to determine visit filtering, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v7 08/14] qapi: Track location that created an implicit type, Eric Blake, 2015/10/08
- Re: [Qemu-devel] [PATCH v7 08/14] qapi: Track location that created an implicit type,
Markus Armbruster <=
[Qemu-devel] [PATCH v7 09/14] qapi: Track owner of each object member, Eric Blake, 2015/10/08
[Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Eric Blake, 2015/10/08
- Re: [Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Markus Armbruster, 2015/10/12
- Re: [Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Eric Blake, 2015/10/15
- Re: [Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Eric Blake, 2015/10/13
- Re: [Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Markus Armbruster, 2015/10/13
- Re: [Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Eric Blake, 2015/10/13
- Re: [Qemu-devel] [PATCH v7 11/14] qapi: Move duplicate member checks to schema check(), Markus Armbruster, 2015/10/13