qapi/parser: add QAPIExpression type
This patch creates a new type, QAPIExpression, which represents a parsed expression complete with QAPIDoc and QAPISourceInfo. This patch turns parser.exprs into a list of QAPIExpression instead, and adjusts expr.py to match. This allows the types we specify in parser.py to be "remembered" all the way through expr.py and into schema.py. Several assertions around packing and unpacking this data can be removed as a result. It also corrects a harmless typing error. Before the patch, check_exprs() allegedly takes a List[_JSONObject]. It actually takes a list of dicts of the form {'expr': E, 'info': I, 'doc': D} where E is of type _ExprValue, I is of type QAPISourceInfo, and D is of type QAPIDoc. Key 'doc' is optional. This is not a _JSONObject! Passes type checking anyway, because _JSONObject is Dict[str, object]. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20230215000011.1725012-5-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Commit message amended to point out the typing fix]
This commit is contained in:
parent
c60caf8086
commit
420110591c
|
@ -43,7 +43,7 @@ from typing import (
|
|||
|
||||
from .common import c_name
|
||||
from .error import QAPISemError
|
||||
from .parser import QAPIDoc
|
||||
from .parser import QAPIExpression
|
||||
from .source import QAPISourceInfo
|
||||
|
||||
|
||||
|
@ -228,12 +228,11 @@ def check_keys(value: _JSONObject,
|
|||
pprint(unknown), pprint(allowed)))
|
||||
|
||||
|
||||
def check_flags(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_flags(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Ensure flag members (if present) have valid values.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError:
|
||||
When certain flags have an invalid value, or when
|
||||
|
@ -242,18 +241,18 @@ def check_flags(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
for key in ('gen', 'success-response'):
|
||||
if key in expr and expr[key] is not False:
|
||||
raise QAPISemError(
|
||||
info, "flag '%s' may only use false value" % key)
|
||||
expr.info, "flag '%s' may only use false value" % key)
|
||||
for key in ('boxed', 'allow-oob', 'allow-preconfig', 'coroutine'):
|
||||
if key in expr and expr[key] is not True:
|
||||
raise QAPISemError(
|
||||
info, "flag '%s' may only use true value" % key)
|
||||
expr.info, "flag '%s' may only use true value" % key)
|
||||
if 'allow-oob' in expr and 'coroutine' in expr:
|
||||
# This is not necessarily a fundamental incompatibility, but
|
||||
# we don't have a use case and the desired semantics isn't
|
||||
# obvious. The simplest solution is to forbid it until we get
|
||||
# a use case for it.
|
||||
raise QAPISemError(info, "flags 'allow-oob' and 'coroutine' "
|
||||
"are incompatible")
|
||||
raise QAPISemError(
|
||||
expr.info, "flags 'allow-oob' and 'coroutine' are incompatible")
|
||||
|
||||
|
||||
def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
|
||||
|
@ -446,12 +445,11 @@ def check_features(features: Optional[object],
|
|||
check_if(feat, info, source)
|
||||
|
||||
|
||||
def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_enum(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Normalize and validate this expression as an ``enum`` definition.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError: When ``expr`` is not a valid ``enum``.
|
||||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
|
@ -459,6 +457,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
name = expr['enum']
|
||||
members = expr['data']
|
||||
prefix = expr.get('prefix')
|
||||
info = expr.info
|
||||
|
||||
if not isinstance(members, list):
|
||||
raise QAPISemError(info, "'data' must be an array")
|
||||
|
@ -485,12 +484,11 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
check_features(member.get('features'), info)
|
||||
|
||||
|
||||
def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_struct(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Normalize and validate this expression as a ``struct`` definition.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError: When ``expr`` is not a valid ``struct``.
|
||||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
|
@ -498,16 +496,15 @@ def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
name = cast(str, expr['struct']) # Checked in check_exprs
|
||||
members = expr['data']
|
||||
|
||||
check_type(members, info, "'data'", allow_dict=name)
|
||||
check_type(expr.get('base'), info, "'base'")
|
||||
check_type(members, expr.info, "'data'", allow_dict=name)
|
||||
check_type(expr.get('base'), expr.info, "'base'")
|
||||
|
||||
|
||||
def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_union(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Normalize and validate this expression as a ``union`` definition.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError: when ``expr`` is not a valid ``union``.
|
||||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
|
@ -516,6 +513,7 @@ def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
base = expr['base']
|
||||
discriminator = expr['discriminator']
|
||||
members = expr['data']
|
||||
info = expr.info
|
||||
|
||||
check_type(base, info, "'base'", allow_dict=name)
|
||||
check_name_is_str(discriminator, info, "'discriminator'")
|
||||
|
@ -530,17 +528,17 @@ def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
check_type(value['type'], info, source, allow_array=not base)
|
||||
|
||||
|
||||
def check_alternate(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_alternate(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Normalize and validate this expression as an ``alternate`` definition.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError: When ``expr`` is not a valid ``alternate``.
|
||||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
"""
|
||||
members = expr['data']
|
||||
info = expr.info
|
||||
|
||||
if not members:
|
||||
raise QAPISemError(info, "'data' must not be empty")
|
||||
|
@ -556,12 +554,11 @@ def check_alternate(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
check_type(value['type'], info, source, allow_array=True)
|
||||
|
||||
|
||||
def check_command(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_command(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Normalize and validate this expression as a ``command`` definition.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError: When ``expr`` is not a valid ``command``.
|
||||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
|
@ -571,17 +568,16 @@ def check_command(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
boxed = expr.get('boxed', False)
|
||||
|
||||
if boxed and args is None:
|
||||
raise QAPISemError(info, "'boxed': true requires 'data'")
|
||||
check_type(args, info, "'data'", allow_dict=not boxed)
|
||||
check_type(rets, info, "'returns'", allow_array=True)
|
||||
raise QAPISemError(expr.info, "'boxed': true requires 'data'")
|
||||
check_type(args, expr.info, "'data'", allow_dict=not boxed)
|
||||
check_type(rets, expr.info, "'returns'", allow_array=True)
|
||||
|
||||
|
||||
def check_event(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
||||
def check_event(expr: QAPIExpression) -> None:
|
||||
"""
|
||||
Normalize and validate this expression as an ``event`` definition.
|
||||
|
||||
:param expr: The expression to validate.
|
||||
:param info: QAPI schema source file information.
|
||||
|
||||
:raise QAPISemError: When ``expr`` is not a valid ``event``.
|
||||
:return: None, ``expr`` is normalized in-place as needed.
|
||||
|
@ -590,11 +586,11 @@ def check_event(expr: _JSONObject, info: QAPISourceInfo) -> None:
|
|||
boxed = expr.get('boxed', False)
|
||||
|
||||
if boxed and args is None:
|
||||
raise QAPISemError(info, "'boxed': true requires 'data'")
|
||||
check_type(args, info, "'data'", allow_dict=not boxed)
|
||||
raise QAPISemError(expr.info, "'boxed': true requires 'data'")
|
||||
check_type(args, expr.info, "'data'", allow_dict=not boxed)
|
||||
|
||||
|
||||
def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
|
||||
def check_exprs(exprs: List[QAPIExpression]) -> List[QAPIExpression]:
|
||||
"""
|
||||
Validate and normalize a list of parsed QAPI schema expressions.
|
||||
|
||||
|
@ -606,21 +602,9 @@ def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
|
|||
:raise QAPISemError: When any expression fails validation.
|
||||
:return: The same list of expressions (now modified).
|
||||
"""
|
||||
for expr_elem in exprs:
|
||||
# Expression
|
||||
assert isinstance(expr_elem['expr'], dict)
|
||||
for key in expr_elem['expr'].keys():
|
||||
assert isinstance(key, str)
|
||||
expr: _JSONObject = expr_elem['expr']
|
||||
|
||||
# QAPISourceInfo
|
||||
assert isinstance(expr_elem['info'], QAPISourceInfo)
|
||||
info: QAPISourceInfo = expr_elem['info']
|
||||
|
||||
# Optional[QAPIDoc]
|
||||
tmp = expr_elem.get('doc')
|
||||
assert tmp is None or isinstance(tmp, QAPIDoc)
|
||||
doc: Optional[QAPIDoc] = tmp
|
||||
for expr in exprs:
|
||||
info = expr.info
|
||||
doc = expr.doc
|
||||
|
||||
if 'include' in expr:
|
||||
continue
|
||||
|
@ -652,24 +636,24 @@ def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
|
|||
if meta == 'enum':
|
||||
check_keys(expr, info, meta,
|
||||
['enum', 'data'], ['if', 'features', 'prefix'])
|
||||
check_enum(expr, info)
|
||||
check_enum(expr)
|
||||
elif meta == 'union':
|
||||
check_keys(expr, info, meta,
|
||||
['union', 'base', 'discriminator', 'data'],
|
||||
['if', 'features'])
|
||||
normalize_members(expr.get('base'))
|
||||
normalize_members(expr['data'])
|
||||
check_union(expr, info)
|
||||
check_union(expr)
|
||||
elif meta == 'alternate':
|
||||
check_keys(expr, info, meta,
|
||||
['alternate', 'data'], ['if', 'features'])
|
||||
normalize_members(expr['data'])
|
||||
check_alternate(expr, info)
|
||||
check_alternate(expr)
|
||||
elif meta == 'struct':
|
||||
check_keys(expr, info, meta,
|
||||
['struct', 'data'], ['base', 'if', 'features'])
|
||||
normalize_members(expr['data'])
|
||||
check_struct(expr, info)
|
||||
check_struct(expr)
|
||||
elif meta == 'command':
|
||||
check_keys(expr, info, meta,
|
||||
['command'],
|
||||
|
@ -677,17 +661,17 @@ def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
|
|||
'gen', 'success-response', 'allow-oob',
|
||||
'allow-preconfig', 'coroutine'])
|
||||
normalize_members(expr.get('data'))
|
||||
check_command(expr, info)
|
||||
check_command(expr)
|
||||
elif meta == 'event':
|
||||
check_keys(expr, info, meta,
|
||||
['event'], ['data', 'boxed', 'if', 'features'])
|
||||
normalize_members(expr.get('data'))
|
||||
check_event(expr, info)
|
||||
check_event(expr)
|
||||
else:
|
||||
assert False, 'unexpected meta type'
|
||||
|
||||
check_if(expr, info, meta)
|
||||
check_features(expr.get('features'), info)
|
||||
check_flags(expr, info)
|
||||
check_flags(expr)
|
||||
|
||||
return exprs
|
||||
|
|
|
@ -21,6 +21,7 @@ from typing import (
|
|||
TYPE_CHECKING,
|
||||
Dict,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Set,
|
||||
Union,
|
||||
|
@ -37,15 +38,24 @@ if TYPE_CHECKING:
|
|||
from .schema import QAPISchemaFeature, QAPISchemaMember
|
||||
|
||||
|
||||
#: Represents a single Top Level QAPI schema expression.
|
||||
TopLevelExpr = Dict[str, object]
|
||||
|
||||
# Return value alias for get_expr().
|
||||
_ExprValue = Union[List[object], Dict[str, object], str, bool]
|
||||
|
||||
# FIXME: Consolidate and centralize definitions for TopLevelExpr,
|
||||
# _ExprValue, _JSONValue, and _JSONObject; currently scattered across
|
||||
# several modules.
|
||||
|
||||
# FIXME: Consolidate and centralize definitions for _ExprValue,
|
||||
# JSONValue, and _JSONObject; currently scattered across several
|
||||
# modules.
|
||||
|
||||
|
||||
class QAPIExpression(Dict[str, object]):
|
||||
# pylint: disable=too-few-public-methods
|
||||
def __init__(self,
|
||||
data: Mapping[str, object],
|
||||
info: QAPISourceInfo,
|
||||
doc: Optional['QAPIDoc'] = None):
|
||||
super().__init__(data)
|
||||
self.info = info
|
||||
self.doc: Optional['QAPIDoc'] = doc
|
||||
|
||||
|
||||
class QAPIParseError(QAPISourceError):
|
||||
|
@ -100,7 +110,7 @@ class QAPISchemaParser:
|
|||
self.line_pos = 0
|
||||
|
||||
# Parser output:
|
||||
self.exprs: List[Dict[str, object]] = []
|
||||
self.exprs: List[QAPIExpression] = []
|
||||
self.docs: List[QAPIDoc] = []
|
||||
|
||||
# Showtime!
|
||||
|
@ -147,8 +157,7 @@ class QAPISchemaParser:
|
|||
"value of 'include' must be a string")
|
||||
incl_fname = os.path.join(os.path.dirname(self._fname),
|
||||
include)
|
||||
self.exprs.append({'expr': {'include': incl_fname},
|
||||
'info': info})
|
||||
self._add_expr(OrderedDict({'include': incl_fname}), info)
|
||||
exprs_include = self._include(include, info, incl_fname,
|
||||
self._included)
|
||||
if exprs_include:
|
||||
|
@ -165,17 +174,18 @@ class QAPISchemaParser:
|
|||
for name, value in pragma.items():
|
||||
self._pragma(name, value, info)
|
||||
else:
|
||||
expr_elem = {'expr': expr,
|
||||
'info': info}
|
||||
if cur_doc:
|
||||
if not cur_doc.symbol:
|
||||
raise QAPISemError(
|
||||
cur_doc.info, "definition documentation required")
|
||||
expr_elem['doc'] = cur_doc
|
||||
self.exprs.append(expr_elem)
|
||||
if cur_doc and not cur_doc.symbol:
|
||||
raise QAPISemError(
|
||||
cur_doc.info, "definition documentation required")
|
||||
self._add_expr(expr, info, cur_doc)
|
||||
cur_doc = None
|
||||
self.reject_expr_doc(cur_doc)
|
||||
|
||||
def _add_expr(self, expr: Mapping[str, object],
|
||||
info: QAPISourceInfo,
|
||||
doc: Optional['QAPIDoc'] = None) -> None:
|
||||
self.exprs.append(QAPIExpression(expr, info, doc))
|
||||
|
||||
@staticmethod
|
||||
def reject_expr_doc(doc: Optional['QAPIDoc']) -> None:
|
||||
if doc and doc.symbol:
|
||||
|
@ -784,7 +794,7 @@ class QAPIDoc:
|
|||
% feature.name)
|
||||
self.features[feature.name].connect(feature)
|
||||
|
||||
def check_expr(self, expr: TopLevelExpr) -> None:
|
||||
def check_expr(self, expr: QAPIExpression) -> None:
|
||||
if self.has_section('Returns') and 'command' not in expr:
|
||||
raise QAPISemError(self.info,
|
||||
"'Returns:' is only valid for commands")
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
from collections import OrderedDict
|
||||
import os
|
||||
import re
|
||||
from typing import Optional
|
||||
from typing import List, Optional
|
||||
|
||||
from .common import (
|
||||
POINTER_SUFFIX,
|
||||
|
@ -29,7 +29,7 @@ from .common import (
|
|||
)
|
||||
from .error import QAPIError, QAPISemError, QAPISourceError
|
||||
from .expr import check_exprs
|
||||
from .parser import QAPISchemaParser
|
||||
from .parser import QAPIExpression, QAPISchemaParser
|
||||
|
||||
|
||||
class QAPISchemaIfCond:
|
||||
|
@ -964,10 +964,11 @@ class QAPISchema:
|
|||
name = self._module_name(fname)
|
||||
return self._module_dict[name]
|
||||
|
||||
def _def_include(self, expr, info, doc):
|
||||
def _def_include(self, expr: QAPIExpression):
|
||||
include = expr['include']
|
||||
assert doc is None
|
||||
self._def_entity(QAPISchemaInclude(self._make_module(include), info))
|
||||
assert expr.doc is None
|
||||
self._def_entity(
|
||||
QAPISchemaInclude(self._make_module(include), expr.info))
|
||||
|
||||
def _def_builtin_type(self, name, json_type, c_type):
|
||||
self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
|
||||
|
@ -1045,14 +1046,15 @@ class QAPISchema:
|
|||
name, info, None, ifcond, None, None, members, None))
|
||||
return name
|
||||
|
||||
def _def_enum_type(self, expr, info, doc):
|
||||
def _def_enum_type(self, expr: QAPIExpression):
|
||||
name = expr['enum']
|
||||
data = expr['data']
|
||||
prefix = expr.get('prefix')
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
info = expr.info
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
self._def_entity(QAPISchemaEnumType(
|
||||
name, info, doc, ifcond, features,
|
||||
name, info, expr.doc, ifcond, features,
|
||||
self._make_enum_members(data, info), prefix))
|
||||
|
||||
def _make_member(self, name, typ, ifcond, features, info):
|
||||
|
@ -1072,14 +1074,15 @@ class QAPISchema:
|
|||
value.get('features'), info)
|
||||
for (key, value) in data.items()]
|
||||
|
||||
def _def_struct_type(self, expr, info, doc):
|
||||
def _def_struct_type(self, expr: QAPIExpression):
|
||||
name = expr['struct']
|
||||
base = expr.get('base')
|
||||
data = expr['data']
|
||||
info = expr.info
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
self._def_entity(QAPISchemaObjectType(
|
||||
name, info, doc, ifcond, features, base,
|
||||
name, info, expr.doc, ifcond, features, base,
|
||||
self._make_members(data, info),
|
||||
None))
|
||||
|
||||
|
@ -1089,11 +1092,13 @@ class QAPISchema:
|
|||
typ = self._make_array_type(typ[0], info)
|
||||
return QAPISchemaVariant(case, info, typ, ifcond)
|
||||
|
||||
def _def_union_type(self, expr, info, doc):
|
||||
def _def_union_type(self, expr: QAPIExpression):
|
||||
name = expr['union']
|
||||
base = expr['base']
|
||||
tag_name = expr['discriminator']
|
||||
data = expr['data']
|
||||
assert isinstance(data, dict)
|
||||
info = expr.info
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
if isinstance(base, dict):
|
||||
|
@ -1105,17 +1110,19 @@ class QAPISchema:
|
|||
QAPISchemaIfCond(value.get('if')),
|
||||
info)
|
||||
for (key, value) in data.items()]
|
||||
members = []
|
||||
members: List[QAPISchemaObjectTypeMember] = []
|
||||
self._def_entity(
|
||||
QAPISchemaObjectType(name, info, doc, ifcond, features,
|
||||
QAPISchemaObjectType(name, info, expr.doc, ifcond, features,
|
||||
base, members,
|
||||
QAPISchemaVariants(
|
||||
tag_name, info, None, variants)))
|
||||
|
||||
def _def_alternate_type(self, expr, info, doc):
|
||||
def _def_alternate_type(self, expr: QAPIExpression):
|
||||
name = expr['alternate']
|
||||
data = expr['data']
|
||||
assert isinstance(data, dict)
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
info = expr.info
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
variants = [
|
||||
self._make_variant(key, value['type'],
|
||||
|
@ -1124,11 +1131,11 @@ class QAPISchema:
|
|||
for (key, value) in data.items()]
|
||||
tag_member = QAPISchemaObjectTypeMember('type', info, 'QType', False)
|
||||
self._def_entity(
|
||||
QAPISchemaAlternateType(name, info, doc, ifcond, features,
|
||||
QAPISchemaVariants(
|
||||
None, info, tag_member, variants)))
|
||||
QAPISchemaAlternateType(
|
||||
name, info, expr.doc, ifcond, features,
|
||||
QAPISchemaVariants(None, info, tag_member, variants)))
|
||||
|
||||
def _def_command(self, expr, info, doc):
|
||||
def _def_command(self, expr: QAPIExpression):
|
||||
name = expr['command']
|
||||
data = expr.get('data')
|
||||
rets = expr.get('returns')
|
||||
|
@ -1139,6 +1146,7 @@ class QAPISchema:
|
|||
allow_preconfig = expr.get('allow-preconfig', False)
|
||||
coroutine = expr.get('coroutine', False)
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
info = expr.info
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
if isinstance(data, OrderedDict):
|
||||
data = self._make_implicit_object_type(
|
||||
|
@ -1147,44 +1155,42 @@ class QAPISchema:
|
|||
if isinstance(rets, list):
|
||||
assert len(rets) == 1
|
||||
rets = self._make_array_type(rets[0], info)
|
||||
self._def_entity(QAPISchemaCommand(name, info, doc, ifcond, features,
|
||||
data, rets,
|
||||
self._def_entity(QAPISchemaCommand(name, info, expr.doc, ifcond,
|
||||
features, data, rets,
|
||||
gen, success_response,
|
||||
boxed, allow_oob, allow_preconfig,
|
||||
coroutine))
|
||||
|
||||
def _def_event(self, expr, info, doc):
|
||||
def _def_event(self, expr: QAPIExpression):
|
||||
name = expr['event']
|
||||
data = expr.get('data')
|
||||
boxed = expr.get('boxed', False)
|
||||
ifcond = QAPISchemaIfCond(expr.get('if'))
|
||||
info = expr.info
|
||||
features = self._make_features(expr.get('features'), info)
|
||||
if isinstance(data, OrderedDict):
|
||||
data = self._make_implicit_object_type(
|
||||
name, info, ifcond,
|
||||
'arg', self._make_members(data, info))
|
||||
self._def_entity(QAPISchemaEvent(name, info, doc, ifcond, features,
|
||||
data, boxed))
|
||||
self._def_entity(QAPISchemaEvent(name, info, expr.doc, ifcond,
|
||||
features, data, boxed))
|
||||
|
||||
def _def_exprs(self, exprs):
|
||||
for expr_elem in exprs:
|
||||
expr = expr_elem['expr']
|
||||
info = expr_elem['info']
|
||||
doc = expr_elem.get('doc')
|
||||
for expr in exprs:
|
||||
if 'enum' in expr:
|
||||
self._def_enum_type(expr, info, doc)
|
||||
self._def_enum_type(expr)
|
||||
elif 'struct' in expr:
|
||||
self._def_struct_type(expr, info, doc)
|
||||
self._def_struct_type(expr)
|
||||
elif 'union' in expr:
|
||||
self._def_union_type(expr, info, doc)
|
||||
self._def_union_type(expr)
|
||||
elif 'alternate' in expr:
|
||||
self._def_alternate_type(expr, info, doc)
|
||||
self._def_alternate_type(expr)
|
||||
elif 'command' in expr:
|
||||
self._def_command(expr, info, doc)
|
||||
self._def_command(expr)
|
||||
elif 'event' in expr:
|
||||
self._def_event(expr, info, doc)
|
||||
self._def_event(expr)
|
||||
elif 'include' in expr:
|
||||
self._def_include(expr, info, doc)
|
||||
self._def_include(expr)
|
||||
else:
|
||||
assert False
|
||||
|
||||
|
|
Loading…
Reference in New Issue