qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: qemu-devel@nongnu.org
Cc: mdroth@linux.vnet.ibm.com, kwolf@pond.sub.org
Subject: [PATCH 4/6] qapi: Proper intermediate representation for modules
Date: Wed, 20 Nov 2019 19:25:49 +0100	[thread overview]
Message-ID: <20191120182551.23795-5-armbru@redhat.com> (raw)
In-Reply-To: <20191120182551.23795-1-armbru@redhat.com>

Modules are represented only by their names so far.  Introduce class
QAPISchemaModule.  So far, it merely wraps the name.  The next patch
will put it to more interesting use.

Once again, arrays spice up the patch a bit.  For any other type,
@info points to the definition, which lets us map from @info to
module.  For arrays, there is no definition, and @info points to the
first use instead.  We have to use the element type's module instead,
which is only available after .check().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 scripts/qapi/schema.py | 63 ++++++++++++++++++++++++++++--------------
 1 file changed, 43 insertions(+), 20 deletions(-)

diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
index cfb574c85d..0f2e0dcfce 100644
--- a/scripts/qapi/schema.py
+++ b/scripts/qapi/schema.py
@@ -50,9 +50,6 @@ class QAPISchemaEntity(object):
 
     def check(self, schema):
         assert not self._checked
-        if self.info:
-            self._module = os.path.relpath(self.info.fname,
-                                           os.path.dirname(schema.fname))
         seen = {}
         for f in self.features:
             f.check_clash(self.info, seen)
@@ -68,6 +65,13 @@ class QAPISchemaEntity(object):
         if self.doc:
             self.doc.check()
 
+    def _set_module(self, schema, info):
+        assert self._checked
+        self._module = schema.module_by_fname(info and info.fname)
+
+    def set_module(self, schema):
+        self._set_module(schema, self.info)
+
     @property
     def ifcond(self):
         assert self._checked
@@ -75,7 +79,7 @@ class QAPISchemaEntity(object):
 
     @property
     def module(self):
-        assert self._checked
+        assert self._module or not self.info
         return self._module
 
     def is_implicit(self):
@@ -135,15 +139,19 @@ class QAPISchemaVisitor(object):
         pass
 
 
+class QAPISchemaModule(object):
+    def __init__(self, name):
+        self.name = name
+
+
 class QAPISchemaInclude(QAPISchemaEntity):
-
-    def __init__(self, fname, info):
+    def __init__(self, sub_module, info):
         QAPISchemaEntity.__init__(self, None, info, None)
-        self.fname = fname
+        self._sub_module = sub_module
 
     def visit(self, visitor):
         QAPISchemaEntity.visit(self, visitor)
-        visitor.visit_include(self.fname, self.info)
+        visitor.visit_include(self._sub_module.name, self.info)
 
 
 class QAPISchemaType(QAPISchemaEntity):
@@ -276,16 +284,14 @@ class QAPISchemaArrayType(QAPISchemaType):
             self.info and self.info.defn_meta)
         assert not isinstance(self.element_type, QAPISchemaArrayType)
 
+    def set_module(self, schema):
+        self._set_module(schema, self.element_type.info)
+
     @property
     def ifcond(self):
         assert self._checked
         return self.element_type.ifcond
 
-    @property
-    def module(self):
-        assert self._checked
-        return self.element_type.module
-
     def is_implicit(self):
         return True
 
@@ -783,6 +789,10 @@ class QAPISchema(object):
         self.docs = parser.docs
         self._entity_list = []
         self._entity_dict = {}
+        self._module_dict = {}
+        self._schema_dir = os.path.dirname(fname)
+        self._make_module(None) # built-ins
+        self._make_module(fname)
         self._predefining = True
         self._def_predefineds()
         self._predefining = False
@@ -826,14 +836,26 @@ class QAPISchema(object):
                 info, "%s uses unknown type '%s'" % (what, name))
         return typ
 
+    def _module_name(self, fname):
+        if fname is None:
+            return None
+        return os.path.relpath(fname, self._schema_dir)
+
+    def _make_module(self, fname):
+        name = self._module_name(fname)
+        if not name in self._module_dict:
+            self._module_dict[name] = QAPISchemaModule(name)
+        return self._module_dict[name]
+
+    def module_by_fname(self, fname):
+        name = self._module_name(fname)
+        assert name in self._module_dict
+        return self._module_dict[name]
+
     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.fname))
-        self._def_entity(QAPISchemaInclude(fname, info))
+        self._def_entity(QAPISchemaInclude(self._make_module(include), info))
 
     def _def_builtin_type(self, name, json_type, c_type):
         self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
@@ -1065,15 +1087,16 @@ class QAPISchema(object):
             ent.check(self)
             ent.connect_doc()
             ent.check_doc()
+        for ent in self._entity_list:
+            ent.set_module(self)
 
     def visit(self, visitor):
         visitor.visit_begin(self)
         module = None
-        visitor.visit_module(module)
         for entity in self._entity_list:
             if visitor.visit_needed(entity):
                 if entity.module != module:
                     module = entity.module
-                    visitor.visit_module(module)
+                    visitor.visit_module(module.name)
                 entity.visit(visitor)
         visitor.visit_end()
-- 
2.21.0



  parent reply	other threads:[~2019-11-20 18:27 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-20 18:25 [PATCH 0/6] qapi: Module fixes and cleanups Markus Armbruster
2019-11-20 18:25 ` [PATCH 1/6] qapi: Tweak "command returns a nice type" check for clarity Markus Armbruster
2019-11-20 19:08   ` Eric Blake
2019-11-20 18:25 ` [PATCH 2/6] tests/Makefile.include: Fix missing test-qapi-emit-events.[ch] Markus Armbruster
2019-11-20 19:16   ` Eric Blake
2019-11-20 18:25 ` [PATCH 3/6] qapi: Generate command registration stuff into separate files Markus Armbruster
2019-11-20 19:26   ` Eric Blake
2019-11-27 16:12     ` Markus Armbruster
2019-11-20 18:25 ` Markus Armbruster [this message]
2019-11-20 20:31   ` [PATCH 4/6] qapi: Proper intermediate representation for modules Eric Blake
2019-11-20 18:25 ` [PATCH 5/6] qapi: Fix code generation for empty modules Markus Armbruster
2019-11-20 20:35   ` Eric Blake
2019-11-20 18:25 ` [PATCH 6/6] qapi: Simplify QAPISchemaModularCVisitor Markus Armbruster
2019-11-20 20:54   ` Eric Blake
2019-11-20 19:40 ` [PATCH 0/6] qapi: Module fixes and cleanups Markus Armbruster
2019-11-20 23:58 ` no-reply
2019-11-21  6:27 ` Markus Armbruster
2019-11-29  9:59 ` [PATCH 7/6] Makefile: Make Makefile depend on generated qga files, too Markus Armbruster
2019-12-03 22:33   ` Eric Blake
2019-12-04  6:56     ` Markus Armbruster
2019-12-04 12:58       ` Eric Blake
2019-12-04 13:19         ` Markus Armbruster
2019-12-03  9:01 ` [PATCH 0/6] qapi: Module fixes and cleanups Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191120182551.23795-5-armbru@redhat.com \
    --to=armbru@redhat.com \
    --cc=kwolf@pond.sub.org \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).