summaryrefslogtreecommitdiffstats
path: root/scripts/qapi/visit.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/qapi/visit.py')
-rw-r--r--scripts/qapi/visit.py122
1 files changed, 88 insertions, 34 deletions
diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py
index cdabc5fa28..339f152152 100644
--- a/scripts/qapi/visit.py
+++ b/scripts/qapi/visit.py
@@ -13,22 +13,43 @@ This work is licensed under the terms of the GNU GPL, version 2.
See the COPYING file in the top-level directory.
"""
-from qapi.common import *
-from qapi.gen import QAPISchemaModularCVisitor, ifcontext
-from qapi.schema import QAPISchemaObjectType
-
-
-def gen_visit_decl(name, scalar=False):
+from typing import List, Optional
+
+from .common import (
+ c_enum_const,
+ c_name,
+ gen_endif,
+ gen_if,
+ indent,
+ mcgen,
+)
+from .gen import QAPISchemaModularCVisitor, ifcontext
+from .schema import (
+ QAPISchema,
+ QAPISchemaEnumMember,
+ QAPISchemaEnumType,
+ QAPISchemaFeature,
+ QAPISchemaObjectType,
+ QAPISchemaObjectTypeMember,
+ QAPISchemaType,
+ QAPISchemaVariants,
+)
+from .source import QAPISourceInfo
+
+
+def gen_visit_decl(name: str, scalar: bool = False) -> str:
c_type = c_name(name) + ' *'
if not scalar:
c_type += '*'
return mcgen('''
-bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_type)sobj, Error **errp);
+
+bool visit_type_%(c_name)s(Visitor *v, const char *name,
+ %(c_type)sobj, Error **errp);
''',
c_name=c_name(name), c_type=c_type)
-def gen_visit_members_decl(name):
+def gen_visit_members_decl(name: str) -> str:
return mcgen('''
bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
@@ -36,7 +57,10 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
c_name=c_name(name))
-def gen_visit_object_members(name, base, members, variants):
+def gen_visit_object_members(name: str,
+ base: Optional[QAPISchemaObjectType],
+ members: List[QAPISchemaObjectTypeMember],
+ variants: Optional[QAPISchemaVariants]) -> str:
ret = mcgen('''
bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
@@ -59,7 +83,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) {
''',
name=memb.name, c_name=c_name(memb.name))
- push_indent()
+ indent.increase()
ret += mcgen('''
if (!visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, errp)) {
return false;
@@ -68,22 +92,24 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
c_type=memb.type.c_name(), name=memb.name,
c_name=c_name(memb.name))
if memb.optional:
- pop_indent()
+ indent.decrease()
ret += mcgen('''
}
''')
ret += gen_endif(memb.ifcond)
if variants:
+ tag_member = variants.tag_member
+ assert isinstance(tag_member.type, QAPISchemaEnumType)
+
ret += mcgen('''
switch (obj->%(c_name)s) {
''',
- c_name=c_name(variants.tag_member.name))
+ c_name=c_name(tag_member.name))
for var in variants.variants:
- case_str = c_enum_const(variants.tag_member.type.name,
- var.name,
- variants.tag_member.type.prefix)
+ case_str = c_enum_const(tag_member.type.name, var.name,
+ tag_member.type.prefix)
ret += gen_if(var.ifcond)
if var.type.name == 'q_empty':
# valid variant and nothing to do
@@ -114,10 +140,11 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
return ret
-def gen_visit_list(name, element_type):
+def gen_visit_list(name: str, element_type: QAPISchemaType) -> str:
return mcgen('''
-bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
+bool visit_type_%(c_name)s(Visitor *v, const char *name,
+ %(c_name)s **obj, Error **errp)
{
bool ok = false;
%(c_name)s *tail;
@@ -147,10 +174,11 @@ out_obj:
c_name=c_name(name), c_elt_type=element_type.c_name())
-def gen_visit_enum(name):
+def gen_visit_enum(name: str) -> str:
return mcgen('''
-bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error **errp)
+bool visit_type_%(c_name)s(Visitor *v, const char *name,
+ %(c_name)s *obj, Error **errp)
{
int value = *obj;
bool ok = visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp);
@@ -161,10 +189,11 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s *obj, Error
c_name=c_name(name))
-def gen_visit_alternate(name, variants):
+def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str:
ret = mcgen('''
-bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
+bool visit_type_%(c_name)s(Visitor *v, const char *name,
+ %(c_name)s **obj, Error **errp)
{
bool ok = false;
@@ -236,10 +265,11 @@ out_obj:
return ret
-def gen_visit_object(name, base, members, variants):
+def gen_visit_object(name: str) -> str:
return mcgen('''
-bool visit_type_%(c_name)s(Visitor *v, const char *name, %(c_name)s **obj, Error **errp)
+bool visit_type_%(c_name)s(Visitor *v, const char *name,
+ %(c_name)s **obj, Error **errp)
{
bool ok = false;
@@ -270,12 +300,12 @@ out_obj:
class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
- def __init__(self, prefix):
+ def __init__(self, prefix: str):
super().__init__(
prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
' * Built-in QAPI visitors', __doc__)
- def _begin_system_module(self, name):
+ def _begin_system_module(self, name: None) -> None:
self._genc.preamble_add(mcgen('''
#include "qemu/osdep.h"
#include "qapi/error.h"
@@ -287,7 +317,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
'''))
- def _begin_user_module(self, name):
+ def _begin_user_module(self, name: str) -> None:
types = self._module_basename('qapi-types', name)
visit = self._module_basename('qapi-visit', name)
self._genc.preamble_add(mcgen('''
@@ -304,18 +334,34 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
''',
types=types))
- def visit_enum_type(self, name, info, ifcond, features, members, prefix):
+ def visit_enum_type(self,
+ name: str,
+ info: QAPISourceInfo,
+ ifcond: List[str],
+ features: List[QAPISchemaFeature],
+ members: List[QAPISchemaEnumMember],
+ prefix: Optional[str]) -> None:
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_decl(name, scalar=True))
self._genc.add(gen_visit_enum(name))
- def visit_array_type(self, name, info, ifcond, element_type):
+ def visit_array_type(self,
+ name: str,
+ info: Optional[QAPISourceInfo],
+ ifcond: List[str],
+ element_type: QAPISchemaType) -> None:
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_decl(name))
self._genc.add(gen_visit_list(name, element_type))
- def visit_object_type(self, name, info, ifcond, features,
- base, members, variants):
+ def visit_object_type(self,
+ name: str,
+ info: Optional[QAPISourceInfo],
+ ifcond: List[str],
+ features: List[QAPISchemaFeature],
+ base: Optional[QAPISchemaObjectType],
+ members: List[QAPISchemaObjectTypeMember],
+ variants: Optional[QAPISchemaVariants]) -> None:
# Nothing to do for the special empty builtin
if name == 'q_empty':
return
@@ -328,15 +374,23 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
if not name.startswith('q_'):
# only explicit types need an allocating visit
self._genh.add(gen_visit_decl(name))
- self._genc.add(gen_visit_object(name, base, members, variants))
-
- def visit_alternate_type(self, name, info, ifcond, features, variants):
+ self._genc.add(gen_visit_object(name))
+
+ def visit_alternate_type(self,
+ name: str,
+ info: QAPISourceInfo,
+ ifcond: List[str],
+ features: List[QAPISchemaFeature],
+ variants: QAPISchemaVariants) -> None:
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_visit_decl(name))
self._genc.add(gen_visit_alternate(name, variants))
-def gen_visit(schema, output_dir, prefix, opt_builtins):
+def gen_visit(schema: QAPISchema,
+ output_dir: str,
+ prefix: str,
+ opt_builtins: bool) -> None:
vis = QAPISchemaGenVisitVisitor(prefix)
schema.visit(vis)
vis.write(output_dir, opt_builtins)