[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 17/30] qapi: Record 'include' directives in intermedi
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PULL 17/30] qapi: Record 'include' directives in intermediate representation |
Date: |
Thu, 1 Mar 2018 13:42:32 -0600 |
From: Markus Armbruster <address@hidden>
The include directive permits modular QAPI schemata, but the generated
code is monolithic all the same. To permit generating modular code,
the front end needs to pass more information on inclusions to the back
ends. The commit before last added the necessary information to the
parse tree. This commit adds it to the intermediate representation
and its QAPISchemaVisitor. A later commit will use this to to
generate modular code.
New entity QAPISchemaInclude represents inclusions. Call new visitor
method visit_include() for it, so visitors can see the sub-modules a
module includes.
Note that unlike other entities, QAPISchemaInclude has no name, and is
therefore not added to entity_dict.
New QAPISchemaEntity attribute @module names the entity's source file.
Call new visitor method visit_module() when it changes during a visit,
so visitors can keep track of the module being visited.
Signed-off-by: Markus Armbruster <address@hidden>
Reviewed-by: Marc-André Lureau <address@hidden>
Message-Id: <address@hidden>
[eblake: avoid accidental deletion of self._predefining]
Signed-off-by: Eric Blake <address@hidden>
---
scripts/qapi/common.py | 43 +++++++++++++++++++++++++++++---
tests/qapi-schema/comments.out | 1 +
tests/qapi-schema/doc-bad-section.out | 1 +
tests/qapi-schema/doc-good.out | 1 +
tests/qapi-schema/event-case.out | 1 +
tests/qapi-schema/ident-with-escape.out | 1 +
tests/qapi-schema/include-relpath.out | 5 ++++
tests/qapi-schema/include-repetition.out | 10 ++++++++
tests/qapi-schema/include-simple.out | 3 +++
tests/qapi-schema/indented-expr.out | 1 +
tests/qapi-schema/qapi-schema-test.out | 1 +
tests/qapi-schema/test-qapi.py | 7 ++++++
12 files changed, 71 insertions(+), 4 deletions(-)
diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
index 1aa1cd3b9bd..2c5c40ec0a9 100644
--- a/scripts/qapi/common.py
+++ b/scripts/qapi/common.py
@@ -984,8 +984,9 @@ def check_exprs(exprs):
class QAPISchemaEntity(object):
def __init__(self, name, info, doc):
- assert isinstance(name, str)
+ assert name is None or isinstance(name, str)
self.name = name
+ self.module = None
# For explicitly defined entities, info points to the (explicit)
# definition. For builtins (and their arrays), info is None.
# For implicitly defined entities, info points to a place that
@@ -1014,10 +1015,16 @@ class QAPISchemaVisitor(object):
def visit_end(self):
pass
+ def visit_module(self, fname):
+ pass
+
def visit_needed(self, entity):
# Default to visiting everything
return True
+ def visit_include(self, fname, info):
+ pass
+
def visit_builtin_type(self, name, info, json_type):
pass
@@ -1044,6 +1051,16 @@ class QAPISchemaVisitor(object):
pass
+class QAPISchemaInclude(QAPISchemaEntity):
+
+ def __init__(self, fname, info):
+ QAPISchemaEntity.__init__(self, None, info, None)
+ self.fname = fname
+
+ def visit(self, visitor):
+ visitor.visit_include(self.fname, self.info)
+
+
class QAPISchemaType(QAPISchemaEntity):
# Return the C type for common use.
# For the types we commonly box, this is a pointer type.
@@ -1471,6 +1488,7 @@ class QAPISchemaEvent(QAPISchemaEntity):
class QAPISchema(object):
def __init__(self, fname):
+ self._fname = fname
parser = QAPISchemaParser(open(fname, 'r'))
exprs = check_exprs(parser.exprs)
self.docs = parser.docs
@@ -1485,9 +1503,13 @@ class QAPISchema(object):
def _def_entity(self, ent):
# Only the predefined types are allowed to not have info
assert ent.info or self._predefining
- assert ent.name not in self._entity_dict
+ assert ent.name is None or ent.name not in self._entity_dict
self._entity_list.append(ent)
- self._entity_dict[ent.name] = ent
+ if ent.name is not None:
+ self._entity_dict[ent.name] = ent
+ if ent.info:
+ ent.module = os.path.relpath(ent.info['file'],
+ os.path.dirname(self._fname))
def lookup_entity(self, name, typ=None):
ent = self._entity_dict.get(name)
@@ -1498,6 +1520,15 @@ class QAPISchema(object):
def lookup_type(self, name):
return self.lookup_entity(name, QAPISchemaType)
+ def _def_include(self, expr, info, doc):
+ include = expr['include']
+ assert doc is None
+ main_info = info
+ while main_info['parent']:
+ main_info = main_info['parent']
+ fname = os.path.relpath(include, os.path.dirname(main_info['file']))
+ self._def_entity(QAPISchemaInclude(fname, info))
+
def _def_builtin_type(self, name, json_type, c_type):
self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
# TODO As long as we have QAPI_TYPES_BUILTIN to share multiple
@@ -1680,7 +1711,7 @@ class QAPISchema(object):
elif 'event' in expr:
self._def_event(expr, info, doc)
elif 'include' in expr:
- pass
+ self._def_include(expr, info, doc)
else:
assert False
@@ -1690,8 +1721,12 @@ class QAPISchema(object):
def visit(self, visitor):
visitor.visit_begin(self)
+ module = None
for entity in self._entity_list:
if visitor.visit_needed(entity):
+ if entity.module != module:
+ module = entity.module
+ visitor.visit_module(module)
entity.visit(visitor)
visitor.visit_end()
diff --git a/tests/qapi-schema/comments.out b/tests/qapi-schema/comments.out
index 0261ddf202c..8d2f1ce8a2e 100644
--- a/tests/qapi-schema/comments.out
+++ b/tests/qapi-schema/comments.out
@@ -1,4 +1,5 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module comments.json
enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/doc-bad-section.out
b/tests/qapi-schema/doc-bad-section.out
index 23bf8c71aba..cd287215689 100644
--- a/tests/qapi-schema/doc-bad-section.out
+++ b/tests/qapi-schema/doc-bad-section.out
@@ -1,6 +1,7 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module doc-bad-section.json
enum Enum ['one', 'two']
doc symbol=Enum
body=
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index 0c07301f07a..430b5a87db3 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -1,6 +1,7 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module doc-good.json
enum Enum ['one', 'two']
object Base
member base1: Enum optional=False
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 110571b793c..88c0964917a 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -1,5 +1,6 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module event-case.json
event oops None
boxed=False
diff --git a/tests/qapi-schema/ident-with-escape.out
b/tests/qapi-schema/ident-with-escape.out
index 8336aa7629d..ee3b34e623e 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -1,6 +1,7 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module ident-with-escape.json
object q_obj_fooA-arg
member bar1: str optional=False
command fooA q_obj_fooA-arg -> None
diff --git a/tests/qapi-schema/include-relpath.out
b/tests/qapi-schema/include-relpath.out
index 0261ddf202c..ebbabd7a186 100644
--- a/tests/qapi-schema/include-relpath.out
+++ b/tests/qapi-schema/include-relpath.out
@@ -1,4 +1,9 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module include-relpath.json
+include include/relpath.json
+module include/relpath.json
+include include-relpath-sub.json
+module include-relpath-sub.json
enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/include-repetition.out
b/tests/qapi-schema/include-repetition.out
index 0261ddf202c..7235e055bc1 100644
--- a/tests/qapi-schema/include-repetition.out
+++ b/tests/qapi-schema/include-repetition.out
@@ -1,4 +1,14 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module include-repetition.json
+include comments.json
+module comments.json
enum Status ['good', 'bad', 'ugly']
+module include-repetition.json
+include include-repetition-sub.json
+module include-repetition-sub.json
+include comments.json
+include comments.json
+module include-repetition.json
+include comments.json
diff --git a/tests/qapi-schema/include-simple.out
b/tests/qapi-schema/include-simple.out
index 0261ddf202c..006f723eebc 100644
--- a/tests/qapi-schema/include-simple.out
+++ b/tests/qapi-schema/include-simple.out
@@ -1,4 +1,7 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module include-simple.json
+include include-simple-sub.json
+module include-simple-sub.json
enum Status ['good', 'bad', 'ugly']
diff --git a/tests/qapi-schema/indented-expr.out
b/tests/qapi-schema/indented-expr.out
index 34de8be4262..a79935e8c32 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -1,6 +1,7 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module indented-expr.json
command eins None -> None
gen=True success_response=True boxed=False
command zwei None -> None
diff --git a/tests/qapi-schema/qapi-schema-test.out
b/tests/qapi-schema/qapi-schema-test.out
index 50706b01369..012e7fc06a5 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -1,6 +1,7 @@
object q_empty
enum QType ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist', 'qbool']
prefix QTYPE
+module qapi-schema-test.json
object TestStruct
member integer: int optional=False
member boolean: bool optional=False
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 4da14b43af6..67e417e2980 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -16,6 +16,13 @@ from qapi.common import QAPIError, QAPISchema,
QAPISchemaVisitor
class QAPISchemaTestVisitor(QAPISchemaVisitor):
+
+ def visit_module(self, name):
+ print('module %s' % name)
+
+ def visit_include(self, name, info):
+ print('include %s' % name)
+
def visit_enum_type(self, name, info, values, prefix):
print('enum %s %s' % (name, values))
if prefix:
--
2.14.3
- [Qemu-devel] [PULL 05/30] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, (continued)
- [Qemu-devel] [PULL 05/30] qapi: New classes QAPIGenC, QAPIGenH, QAPIGenDoc, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 06/30] qapi: Reduce use of global variables in generators some, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 10/30] qapi: Touch generated files only when they change, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 12/30] qapi/common: Eliminate QAPISchema.exprs, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 13/30] qapi: Lift error reporting from QAPISchema.__init__() to callers, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 15/30] qapi: Record 'include' directives in parse tree, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 11/30] qapi: Improve include file name reporting in error messages, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 08/30] qapi-gen: New common driver for code and doc generators, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 14/30] qapi: Concentrate QAPISchemaParser.exprs updates in .__init__(), Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 16/30] qapi: Generate in source order, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 17/30] qapi: Record 'include' directives in intermediate representation,
Eric Blake <=
- [Qemu-devel] [PULL 18/30] qapi: Rename generated qmp-marshal.c to qmp-commands.c, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 21/30] qapi/common: Fix guardname() for funny filenames, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 20/30] qapi/types qapi/visit: Generate built-in stuff into separate files, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 19/30] qapi: Make code-generating visitors use QAPIGen more, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 22/30] qapi: Generate separate .h, .c for each module, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 24/30] watchdog: Consolidate QAPI into single file, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 26/30] docs/devel/writing-qmp-commands: Update for modular QAPI, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 27/30] docs: Correct outdated information on QAPI, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 30/30] qapi: Don't create useless directory qapi-generated, Eric Blake, 2018/03/01
- [Qemu-devel] [PULL 23/30] Include less of the generated modular QAPI headers, Eric Blake, 2018/03/01