mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-04 22:13:19 +00:00
idl: Decouple idl-compiler data structures from grammar structure
Instead of operating on the raw lists of tokens, transform them into typed structures representation, which makes the code by many orders of magnitude simpler to read, understand and extend. This includes sweeping changes throughout the whole source code of the tool, because almost every function was tightly coupled to the way data was passed down from the parser right to the code generation routines. Tested manually by checking that old generated sources are precisely the same as the new generated sources. Signed-off-by: Pavel Solodovnikov <pa.solodovnikov@scylladb.com>
This commit is contained in:
601
idl-compiler.py
601
idl-compiler.py
@@ -26,6 +26,8 @@ import pyparsing as pp
|
||||
from functools import reduce
|
||||
import textwrap
|
||||
from numbers import Number
|
||||
from pprint import pformat
|
||||
from copy import copy
|
||||
|
||||
EXTENSION = '.idl.hh'
|
||||
READ_BUFF = 'input_buffer'
|
||||
@@ -91,6 +93,182 @@ def print_cw(f):
|
||||
#pragma once
|
||||
""")
|
||||
|
||||
class BasicType:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return f"BasicType(name={self.name})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class TemplateType:
|
||||
def __init__(self, name, template_parameters):
|
||||
self.name = name
|
||||
self.template_parameters = template_parameters
|
||||
|
||||
def __str__(self):
|
||||
return f"TemplateType(name={self.name}, args={pformat(self.template_parameters)}"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class EnumValue:
|
||||
def __init__(self, name, initializer=None):
|
||||
self.name = name
|
||||
self.initializer = initializer
|
||||
|
||||
def __str__(self):
|
||||
return f"EnumValue(name={self.name}, initializer={self.initializer})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class EnumDef:
|
||||
def __init__(self, name, underlying_type, members):
|
||||
self.name = name
|
||||
self.underlying_type = underlying_type
|
||||
self.members = members
|
||||
|
||||
def __str__(self):
|
||||
return f"EnumDef(name={self.name}, underlying_type={self.underlying_type}, members={pformat(self.members)})";
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class Attribute:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return f"[[{self.name}]]"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class DataClassMember:
|
||||
def __init__(self, type, name, attribute=None, default_value=None):
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.attribute = attribute
|
||||
self.default_value = default_value
|
||||
|
||||
def __str__(self):
|
||||
return f"DataClassMember(type={self.type}, name={self.name}, attribute={self.attribute}, default_value={self.default_value})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class FunctionClassMember:
|
||||
def __init__(self, type, name, attribute=None, default_value=None):
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.attribute = attribute
|
||||
self.default_value = default_value
|
||||
|
||||
def __str__(self):
|
||||
return f"FunctionClassMember(type={self.type}, name={self.name}, attribute={self.attribute}, default_value={self.default_value})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class ClassTemplateParam:
|
||||
def __init__(self, typename, name):
|
||||
self.typename = typename
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return f"ClassTemplateParam(typename={self.typename}, name={self.name})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class ClassDef:
|
||||
def __init__(self, name, members, final, stub, attribute, template_params):
|
||||
self.name = name
|
||||
self.members = members
|
||||
self.final = final
|
||||
self.stub = stub
|
||||
self.attribute = attribute
|
||||
self.template_params = template_params
|
||||
|
||||
def __str__(self):
|
||||
return f"ClassDef(name={self.name}, members={pformat(self.members)}, final={self.final}, stub={self.stub}, attribute={self.attribute}, template_params={self.template_params})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
class NamespaceDef:
|
||||
def __init__(self, name, members):
|
||||
self.name = name
|
||||
self.members = members
|
||||
|
||||
def __str__(self):
|
||||
return f"NamespaceDef(name={self.name}, members={pformat(self.members)})"
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
def basic_type_parse_action(tokens):
|
||||
return BasicType(name=tokens[0])
|
||||
|
||||
|
||||
def template_type_parse_action(tokens):
|
||||
return TemplateType(name=tokens['template_name'], template_parameters=tokens["template_parameters"].asList())
|
||||
|
||||
|
||||
def enum_value_parse_action(tokens):
|
||||
initializer = None
|
||||
if len(tokens) == 2:
|
||||
initializer = tokens[1]
|
||||
elif len(tokens) == 3:
|
||||
initializer = '-' + tokens[2]
|
||||
return EnumValue(name=tokens[0], initializer=initializer)
|
||||
|
||||
|
||||
def enum_def_parse_action(tokens):
|
||||
return EnumDef(name=tokens['name'], underlying_type=tokens['underlying_type'], members=tokens['enum_values'].asList())
|
||||
|
||||
|
||||
def attribute_parse_action(tokens):
|
||||
return Attribute(name=tokens[0])
|
||||
|
||||
|
||||
def class_member_parse_action(tokens):
|
||||
member_name = tokens['name']
|
||||
attribute = tokens['attribute'][0] if 'attribute' in tokens else None
|
||||
default = tokens['default'][0] if 'default' in tokens else None
|
||||
if not isinstance(member_name, str): # accessor function declaration
|
||||
return FunctionClassMember(type=tokens["type"], name=member_name[0], attribute=attribute, default_value=default)
|
||||
# data member
|
||||
return DataClassMember(type=tokens["type"], name=member_name, attribute=attribute, default_value=default)
|
||||
|
||||
|
||||
def class_def_parse_action(tokens):
|
||||
is_final = 'final' in tokens
|
||||
is_stub = 'stub' in tokens
|
||||
class_members = tokens['members'].asList() if 'members' in tokens else []
|
||||
attribute = tokens['attribute'][0] if 'attribute' in tokens else None
|
||||
template_params = None
|
||||
if 'template' in tokens:
|
||||
template_params = [ClassTemplateParam(typename=tp[0], name=tp[1]) for tp in tokens['template']]
|
||||
return ClassDef(name=tokens['name'], members=class_members, final=is_final, stub=is_stub, attribute=attribute, template_params=template_params)
|
||||
|
||||
|
||||
def namespace_parse_action(tokens):
|
||||
return NamespaceDef(name=tokens['name'], members=tokens['ns_members'].asList())
|
||||
|
||||
|
||||
def parse_file(file_name):
|
||||
|
||||
@@ -102,50 +280,71 @@ def parse_file(file_name):
|
||||
cls = pp.Keyword('class')
|
||||
colon = pp.Literal(":")
|
||||
semi = pp.Literal(";").suppress()
|
||||
langle = pp.Literal("<")
|
||||
rangle = pp.Literal(">")
|
||||
equals = pp.Literal("=")
|
||||
langle = pp.Literal("<").suppress()
|
||||
rangle = pp.Literal(">").suppress()
|
||||
equals = pp.Literal("=").suppress()
|
||||
comma = pp.Literal(",")
|
||||
lparen = pp.Literal("(")
|
||||
rparen = pp.Literal(")")
|
||||
lbrack = pp.Literal("[")
|
||||
rbrack = pp.Literal("]")
|
||||
lbrack = pp.Literal("[").suppress()
|
||||
rbrack = pp.Literal("]").suppress()
|
||||
mins = pp.Literal("-")
|
||||
struct = pp.Keyword('struct')
|
||||
template = pp.Keyword('template')
|
||||
final = pp.Keyword('final')("final")
|
||||
stub = pp.Keyword('stub')("stub")
|
||||
final = pp.Keyword('final')
|
||||
stub = pp.Keyword('stub')
|
||||
with_colon = pp.Word(pp.alphanums + "_" + ":")
|
||||
btype = with_colon
|
||||
type = pp.Forward()
|
||||
nestedParens = pp.nestedExpr('<', '>')
|
||||
|
||||
tmpl = pp.Group(btype("template_name") + langle.suppress() + pp.Group(pp.delimitedList(type)) + rangle.suppress())
|
||||
type << (tmpl | btype)
|
||||
btype = with_colon.copy()
|
||||
btype.setParseAction(basic_type_parse_action)
|
||||
|
||||
type = pp.Forward()
|
||||
|
||||
tmpl = with_colon("template_name") + langle.suppress() + pp.Group(pp.delimitedList(type))("template_parameters") + rangle.suppress()
|
||||
tmpl.setParseAction(template_type_parse_action)
|
||||
|
||||
type <<= tmpl | btype
|
||||
|
||||
enum_lit = pp.Keyword('enum')
|
||||
enum_class = pp.Group(enum_lit + cls)
|
||||
ns = pp.Keyword("namespace")
|
||||
|
||||
enum_init = equals.suppress() + pp.Optional(mins) + number
|
||||
enum_value = pp.Group(identifier + pp.Optional(enum_init))
|
||||
enum_values = pp.Group(lbrace + pp.delimitedList(enum_value) + pp.Optional(comma) + rbrace)
|
||||
enum_init = equals + pp.Optional(mins) + number
|
||||
enum_value = identifier + pp.Optional(enum_init)
|
||||
enum_value.setParseAction(enum_value_parse_action)
|
||||
|
||||
enum_values = lbrace + pp.delimitedList(enum_value) + pp.Optional(comma).suppress() + rbrace
|
||||
enum = enum_class.suppress() + identifier("name") + colon.suppress() + identifier("underlying_type") + enum_values("enum_values") + pp.Optional(semi)
|
||||
enum.setParseAction(enum_def_parse_action)
|
||||
|
||||
content = pp.Forward()
|
||||
|
||||
member_name = pp.Combine(pp.Group(identifier + pp.Optional(lparen + rparen)))
|
||||
attrib = pp.Group(lbrack.suppress() + lbrack.suppress() + pp.SkipTo(']') + rbrack.suppress() + rbrack.suppress())
|
||||
attrib = lbrack + lbrack + pp.SkipTo(']') + rbrack + rbrack
|
||||
attrib.setParseAction(attribute_parse_action)
|
||||
opt_attribute = pp.Optional(attrib)("attribute")
|
||||
namespace = pp.Group(ns("type") + identifier("name") + lbrace + pp.Group(pp.OneOrMore(content))("content") + rbrace)
|
||||
enum = pp.Group(enum_class("type") + identifier("name") + colon.suppress() + identifier("underline_type") + enum_values("enum_values") + pp.Optional(semi).suppress())
|
||||
default_value = equals.suppress() + pp.SkipTo(';')
|
||||
class_member = pp.Group(type("type") + member_name("name") + opt_attribute + pp.Optional(default_value)("default") + semi.suppress())("member")
|
||||
|
||||
default_value = equals + pp.SkipTo(';')
|
||||
member_name = pp.Combine(identifier + pp.Optional(lparen + rparen)("function_marker"))
|
||||
class_member = type("type") + member_name("name") + opt_attribute + pp.Optional(default_value)("default") + semi
|
||||
class_member.setParseAction(class_member_parse_action)
|
||||
|
||||
template_param = pp.Group(identifier("type") + identifier("name"))
|
||||
template_def = pp.Group(template + langle + pp.Group(pp.delimitedList(template_param))("params") + rangle)
|
||||
template_def = template.suppress() + langle + pp.delimitedList(template_param)("params") + rangle
|
||||
class_content = pp.Forward()
|
||||
class_def = pp.Group(pp.Optional(template_def)("template") + (cls | struct)("type") + with_colon("name") + pp.Optional(final) + pp.Optional(stub) + opt_attribute + lbrace + pp.Group(pp.ZeroOrMore(class_content))("members") + rbrace + pp.Optional(semi))
|
||||
content << (enum | class_def | namespace)
|
||||
class_content << (enum | class_def | class_member)
|
||||
for varname in "enum class_def class_member content namespace template_def".split():
|
||||
class_def = pp.Optional(template_def)("template") + (cls | struct).suppress() + with_colon("name") + \
|
||||
pp.Optional(final)("final") + pp.Optional(stub)("stub") + opt_attribute + \
|
||||
lbrace + pp.ZeroOrMore(class_content)("members") + rbrace + pp.Optional(semi)
|
||||
class_content <<= enum | class_def | class_member
|
||||
class_def.setParseAction(class_def_parse_action)
|
||||
|
||||
namespace = ns.suppress() + identifier("name") + lbrace + pp.OneOrMore(content)("ns_members") + rbrace
|
||||
namespace.setParseAction(namespace_parse_action)
|
||||
|
||||
content <<= enum | class_def | namespace
|
||||
|
||||
for varname in ("enum", "class_def", "class_member", "content", "namespace", "template_def"):
|
||||
locals()[varname].setName(varname)
|
||||
|
||||
rt = pp.OneOrMore(content)
|
||||
singleLineComment = "//" + pp.restOfLine
|
||||
rt.ignore(singleLineComment)
|
||||
@@ -192,16 +391,16 @@ struct serializer<$name> {
|
||||
template <typename Input>
|
||||
static void skip(Input& buf);
|
||||
};
|
||||
""").substitute({'name': name, 'sizetype': SIZETYPE, 'tmp_param': template_param}))
|
||||
""").substitute({'name': name, 'tmp_param': template_param}))
|
||||
if config.ns != '':
|
||||
fprintln(hout, "}")
|
||||
|
||||
|
||||
def handle_enum(enum, hout, cout, namespaces, parent_template_param=[]):
|
||||
[ns, ns_open, ns_close] = set_namespace(namespaces)
|
||||
temp_def = ", ".join(map(lambda a: a[0] + " " + a[1], parent_template_param)) if parent_template_param else ""
|
||||
temp_def = ", ".join(map(lambda a: a.typename + " " + a.name, parent_template_param)) if parent_template_param else ""
|
||||
template = "template <" + temp_def + ">" if temp_def else ""
|
||||
name = enum["name"] if ns == "" else ns + "::" + enum["name"]
|
||||
name = enum.name if ns == "" else ns + "::" + enum.name
|
||||
declear_methods(hout, name, temp_def)
|
||||
fprintln(cout, Template("""
|
||||
$template
|
||||
@@ -214,86 +413,69 @@ $template
|
||||
template<typename Input>
|
||||
$name serializer<$name>::read(Input& buf) {
|
||||
return static_cast<$name>(deserialize(buf, boost::type<$type>()));
|
||||
}""").substitute({'name': name, 'size_type': SIZETYPE, 'type': enum['underline_type'], 'template': template}))
|
||||
}""").substitute({'name': name, 'type': enum.underlying_type, 'template': template}))
|
||||
|
||||
|
||||
def join_template(lst):
|
||||
return "<" + ", ".join([param_type(l) for l in lst]) + ">"
|
||||
def join_template(template_params):
|
||||
return "<" + ", ".join([param_type(p) for p in template_params]) + ">"
|
||||
|
||||
|
||||
def param_type(lst):
|
||||
if isinstance(lst, str):
|
||||
return lst
|
||||
if len(lst) == 1:
|
||||
return lst[0]
|
||||
return lst[0] + join_template(lst[1])
|
||||
def param_type(t):
|
||||
if isinstance(t, BasicType):
|
||||
return t.name
|
||||
elif isinstance(t, TemplateType):
|
||||
return t.name + join_template(t.template_parameters)
|
||||
|
||||
|
||||
def flat_template(lst):
|
||||
return ", ".join([param_type(l) for l in lst])
|
||||
|
||||
|
||||
def flat_type(lst):
|
||||
if isinstance(lst, str):
|
||||
return lst
|
||||
if len(lst) == 1:
|
||||
return flat_type(lst[0])
|
||||
return (lst[0] + "__" + "_".join([flat_type(l) for l in lst[1]])).replace('::', '__')
|
||||
|
||||
|
||||
def is_class(obj):
|
||||
return obj["type"] == "class" or obj["type"] == "struct"
|
||||
|
||||
|
||||
def is_enum(obj):
|
||||
try:
|
||||
return not isinstance(obj["type"], str) and "".join(obj["type"]) == 'enumclass'
|
||||
except Exception:
|
||||
return False
|
||||
def flat_type(t):
|
||||
if isinstance(t, BasicType):
|
||||
return t.name
|
||||
elif isinstance(t, TemplateType):
|
||||
return (t.name + "__" + "_".join([flat_type(p) for p in t.template_parameters])).replace('::', '__')
|
||||
|
||||
|
||||
local_types = {}
|
||||
|
||||
|
||||
def list_types(lst):
|
||||
if isinstance(lst, str):
|
||||
return [lst]
|
||||
if len(lst) == 1:
|
||||
return lst
|
||||
lt = reduce(lambda a, b: a + b, [list_types(l) for l in lst[1]])
|
||||
return lt
|
||||
def list_types(t):
|
||||
if isinstance(t, BasicType):
|
||||
return [t.name]
|
||||
elif isinstance(t, TemplateType):
|
||||
return reduce(lambda a, b: a + b, [list_types(p) for p in t.template_parameters])
|
||||
|
||||
|
||||
def list_local_types(lst):
|
||||
return {l for l in list_types(lst) if l in local_types}
|
||||
def list_local_types(t):
|
||||
return {l for l in list_types(t) if l in local_types}
|
||||
|
||||
|
||||
def is_basic_type(lst):
|
||||
if isinstance(lst, str):
|
||||
return lst not in local_types
|
||||
if len(lst) == 1:
|
||||
return isinstance(lst[0], str) and lst[0] not in local_types
|
||||
return False
|
||||
def is_basic_type(t):
|
||||
return isinstance(t, BasicType) and t.name not in local_types
|
||||
|
||||
|
||||
def is_local_type(lst):
|
||||
return isinstance(lst, str) and lst in local_types or len(lst) == 1 and lst[0] in local_types
|
||||
def is_local_type(t):
|
||||
if isinstance(t, str): # e.g. `t` is a local class name
|
||||
return t in local_types
|
||||
return t.name in local_types
|
||||
|
||||
|
||||
def get_template_name(lst):
|
||||
return lst["template_name"] if not isinstance(lst, str) and len(lst) > 1 else None
|
||||
|
||||
|
||||
def is_vector(lst):
|
||||
return get_template_name(lst) == "std::vector"
|
||||
def is_vector(t):
|
||||
return isinstance(t, TemplateType) and t.name == "std::vector"
|
||||
|
||||
|
||||
def is_variant(lst):
|
||||
return get_template_name(lst) == "boost::variant" or get_template_name(lst) == "std::variant"
|
||||
def is_variant(t):
|
||||
return isinstance(t, TemplateType) and (t.name == "boost::variant" or t.name == "std::variant")
|
||||
|
||||
|
||||
def is_optional(lst):
|
||||
return get_template_name(lst) == "std::optional"
|
||||
def is_optional(t):
|
||||
return isinstance(t, TemplateType) and t.name == "std::optional"
|
||||
|
||||
|
||||
created_writers = set()
|
||||
@@ -304,26 +486,28 @@ def get_member_name(name):
|
||||
|
||||
|
||||
def get_members(cls):
|
||||
return [p for p in cls["members"] if not is_class(p) and not is_enum(p)]
|
||||
return [p for p in cls.members if not isinstance(p, ClassDef) and not isinstance(p, EnumDef)]
|
||||
|
||||
|
||||
def is_final(cls):
|
||||
return "final" in cls
|
||||
return cls.final
|
||||
|
||||
|
||||
def get_variant_type(lst):
|
||||
if is_variant(lst):
|
||||
def get_variant_type(t):
|
||||
if is_variant(t):
|
||||
return "variant"
|
||||
return param_type(lst)
|
||||
return param_type(t)
|
||||
|
||||
|
||||
def variant_to_member(typ):
|
||||
return [{"name": get_variant_type(x), "type": x} for x in typ if is_local_type(x) or is_variant(x)]
|
||||
def variant_to_member(template_parameters):
|
||||
return [DataClassMember(name=get_variant_type(x), type=x) for x in template_parameters if is_local_type(x) or is_variant(x)]
|
||||
|
||||
|
||||
def variant_info(info, typ):
|
||||
def variant_info(info, template_parameters):
|
||||
[cls, namespaces, parent_template_param] = info
|
||||
return [{"members": variant_to_member(typ)}, namespaces, parent_template_param]
|
||||
variant_info_cls = copy(cls) # shallow copy of cls
|
||||
variant_info_cls.members = variant_to_member(template_parameters)
|
||||
return [variant_info_cls, namespaces, parent_template_param]
|
||||
|
||||
|
||||
stubs = set()
|
||||
@@ -335,8 +519,8 @@ def is_stub(cls):
|
||||
|
||||
def handle_visitors_state(info, hout, clases=[]):
|
||||
[cls, namespaces, parent_template_param] = info
|
||||
name = "__".join(clases) if clases else cls["name"]
|
||||
frame = "empty_frame" if "final" in cls else "frame"
|
||||
name = "__".join(clases) if clases else cls.name
|
||||
frame = "empty_frame" if cls.final else "frame"
|
||||
fprintln(hout, Template("""
|
||||
template<typename Output>
|
||||
struct state_of_$name {
|
||||
@@ -344,21 +528,21 @@ struct state_of_$name {
|
||||
if clases:
|
||||
local_state = "state_of_" + "__".join(clases[:-1]) + '<Output>'
|
||||
fprintln(hout, Template(" $name _parent;").substitute({'name': local_state}))
|
||||
if "final" in cls:
|
||||
if cls.final:
|
||||
fprintln(hout, Template(" state_of_$name($state parent) : _parent(parent) {}").substitute({'name': name, 'state': local_state}))
|
||||
fprintln(hout, "};")
|
||||
members = get_members(cls)
|
||||
member_class = clases if clases else [cls["name"]]
|
||||
for param in members:
|
||||
if is_local_type(param["type"]):
|
||||
handle_visitors_state(local_types[param_type(param["type"])], hout, member_class + [param["name"]])
|
||||
if is_variant(param["type"]):
|
||||
handle_visitors_state(variant_info(info, param["type"][1]), hout, member_class + [param["name"]])
|
||||
member_class = clases if clases else [cls.name]
|
||||
for m in members:
|
||||
if is_local_type(m.type):
|
||||
handle_visitors_state(local_types[param_type(m.type)], hout, member_class + [m.name])
|
||||
if is_variant(m.type):
|
||||
handle_visitors_state(variant_info(info, m.type.template_parameters), hout, member_class + [m.name])
|
||||
|
||||
|
||||
def get_dependency(cls):
|
||||
members = get_members(cls)
|
||||
return reduce(lambda a, b: a | b, [list_local_types(m["type"]) for m in members], set())
|
||||
return reduce(lambda a, b: a | b, [list_local_types(m.type) for m in members], set())
|
||||
|
||||
|
||||
def optional_add_methods(typ):
|
||||
@@ -388,25 +572,25 @@ def optional_add_methods(typ):
|
||||
|
||||
|
||||
def vector_add_method(current, base_state):
|
||||
typ = current["type"]
|
||||
typ = current.type
|
||||
res = ""
|
||||
if is_basic_type(typ[1]):
|
||||
if is_basic_type(typ.template_parameters[0]):
|
||||
res = res + Template("""
|
||||
void add_$name($type t) {
|
||||
serialize(_out, t);
|
||||
_count++;
|
||||
}""").substitute({'type': param_type(typ[1][0]), 'name': current["name"]})
|
||||
}""").substitute({'type': param_type(typ.template_parameters[0]), 'name': current.name})
|
||||
else:
|
||||
res = res + Template("""
|
||||
writer_of_$type<Output> add() {
|
||||
_count++;
|
||||
return {_out};
|
||||
}""").substitute({'type': flat_type(typ[1][0]), 'name': current["name"]})
|
||||
}""").substitute({'type': flat_type(typ.template_parameters[0]), 'name': current.name})
|
||||
res = res + Template("""
|
||||
void add(${type} v) {
|
||||
serialize(_out, v);
|
||||
_count++;
|
||||
}""").substitute({'type': param_view_type(typ[1][0])})
|
||||
}""").substitute({'type': param_view_type(typ.template_parameters[0])})
|
||||
return res + Template("""
|
||||
after_${basestate}__$name<Output> end_$name() && {
|
||||
_size.set(_out, _count);
|
||||
@@ -420,7 +604,7 @@ def vector_add_method(current, base_state):
|
||||
void rollback(const vector_position& vp) {
|
||||
_out.retract(vp.pos);
|
||||
_count = vp.count;
|
||||
}""").substitute({'name': current["name"], 'basestate': base_state})
|
||||
}""").substitute({'name': current.name, 'basestate': base_state})
|
||||
|
||||
|
||||
def add_param_writer_basic_type(name, base_state, typ, var_type="", var_index=None, root_node=False):
|
||||
@@ -432,14 +616,14 @@ def add_param_writer_basic_type(name, base_state, typ, var_type="", var_index=No
|
||||
return_command = "{ _out, std::move(_state._parent) }" if var_type != "" and not root_node else "{ _out, std::move(_state) }"
|
||||
|
||||
allow_fragmented = False
|
||||
if typ in ['bytes', 'sstring']:
|
||||
typ += '_view'
|
||||
if typ.name in ['bytes', 'sstring']:
|
||||
typename = typ.name + '_view'
|
||||
allow_fragmented = True
|
||||
else:
|
||||
typ = 'const ' + typ + '&'
|
||||
typename = 'const ' + typ.name + '&'
|
||||
|
||||
writer = Template(reindent(4, """
|
||||
after_${base_state}__$name<Output> write_$name$var_type($typ t) && {
|
||||
after_${base_state}__$name<Output> write_$name$var_type($typename t) && {
|
||||
$create_variant_state
|
||||
$set_varient_index
|
||||
serialize(_out, t);
|
||||
@@ -473,16 +657,17 @@ def add_param_writer_object(name, base_state, typ, var_type="", var_index=None,
|
||||
return { _out, $state };
|
||||
}
|
||||
""")).substitute(locals())
|
||||
if not is_stub(typ) and is_local_type(typ):
|
||||
if not is_stub(typ.name) and is_local_type(typ):
|
||||
ret += add_param_writer_basic_type(name, base_state, typ, var_type, var_index, root_node)
|
||||
if is_stub(typ):
|
||||
if is_stub(typ.name):
|
||||
typename = typ.name
|
||||
set_command = "_state.f.end(_out);" if var_type != "" else ""
|
||||
return_command = "{ _out, std::move(_state._parent) }" if var_type != "" and not root_node else "{ _out, std::move(_state) }"
|
||||
ret += Template(reindent(4, """
|
||||
template<typename Serializer>
|
||||
after_${base_state}__${name}<Output> ${name}$var_type(Serializer&& f) && {
|
||||
$set_varient_index
|
||||
f(writer_of_$typ<Output>(_out));
|
||||
f(writer_of_$typename<Output>(_out));
|
||||
$set_command
|
||||
return $return_command;
|
||||
}""")).substitute(locals())
|
||||
@@ -490,9 +675,9 @@ def add_param_writer_object(name, base_state, typ, var_type="", var_index=None,
|
||||
|
||||
|
||||
def add_param_write(current, base_state, vector=False, root_node=False):
|
||||
typ = current["type"]
|
||||
typ = current.type
|
||||
res = ""
|
||||
name = get_member_name(current["name"])
|
||||
name = get_member_name(current.name)
|
||||
if is_basic_type(typ):
|
||||
res = res + add_param_writer_basic_type(name, base_state, typ)
|
||||
elif is_optional(typ):
|
||||
@@ -501,12 +686,12 @@ def add_param_write(current, base_state, vector=False, root_node=False):
|
||||
serialize(_out, false);
|
||||
return { _out, std::move(_state) };
|
||||
}""")).substitute({'type': param_type(typ), 'name': name, 'basestate': base_state})
|
||||
if is_basic_type(typ[1][0]):
|
||||
res = res + add_param_writer_basic_type(name, base_state, typ[1][0], "", "true")
|
||||
elif is_local_type(typ[1][0]):
|
||||
if is_basic_type(typ.template_parameters[0]):
|
||||
res = res + add_param_writer_basic_type(name, base_state, typ.template_parameters[0], "", "true")
|
||||
elif is_local_type(typ.template_parameters[0]):
|
||||
res = res + add_param_writer_object(name, base_state[0][1], typ, "", "true")
|
||||
else:
|
||||
print("non supported optional type ", type[0][1])
|
||||
print("non supported optional type ", typ.template_parameters[0])
|
||||
elif is_vector(typ):
|
||||
set_size = "_size.set(_out, 0);" if vector else "serialize(_out, size_type(0));"
|
||||
|
||||
@@ -523,10 +708,9 @@ def add_param_write(current, base_state, vector=False, root_node=False):
|
||||
elif is_local_type(typ):
|
||||
res = res + add_param_writer_object(name, base_state, typ)
|
||||
elif is_variant(typ):
|
||||
for idx, p in enumerate(typ[1]):
|
||||
for idx, p in enumerate(typ.template_parameters):
|
||||
if is_basic_type(p):
|
||||
varient_type = param_type(p)
|
||||
res = res + add_param_writer_basic_type(name, base_state, varient_type, "_" + varient_type, idx, root_node)
|
||||
res = res + add_param_writer_basic_type(name, base_state, p, "_" + param_type(p), idx, root_node)
|
||||
elif is_variant(p):
|
||||
res = res + add_param_writer_object(name, base_state, p, '_' + "variant", idx, root_node)
|
||||
elif is_local_type(p):
|
||||
@@ -619,9 +803,9 @@ struct $name {
|
||||
|
||||
|
||||
def add_vector_node(hout, member, base_state, parents):
|
||||
if get_template_name(member["type"][1][0]):
|
||||
add_template_writer_node(hout, member["type"][1][0])
|
||||
add_node(hout, base_state + "__" + member["name"], member["type"], base_state, "", parents, vector_add_method(member, base_state), True)
|
||||
if member.type.template_parameters[0].name:
|
||||
add_template_writer_node(hout, member.type.template_parameters[0])
|
||||
add_node(hout, base_state + "__" + member.name, member.type, base_state, "", parents, vector_add_method(member, base_state), True)
|
||||
|
||||
|
||||
optional_nodes = set()
|
||||
@@ -638,17 +822,19 @@ template<typename Output>
|
||||
struct writer_of_$type {
|
||||
Output& _out;
|
||||
$add_method
|
||||
};""")).substitute({'type': full_type, 'add_method': optional_add_methods(typ[1][0])}))
|
||||
};""")).substitute({'type': full_type, 'add_method': optional_add_methods(typ.template_parameters[0])}))
|
||||
|
||||
|
||||
def add_variant_nodes(hout, member, param, base_state, parents, classes):
|
||||
par = base_state + "__" + member["name"]
|
||||
for typ in param[1]:
|
||||
par = base_state + "__" + member.name
|
||||
for typ in param.template_parameters:
|
||||
if is_local_type(typ):
|
||||
handle_visitors_nodes(local_types[param_type(typ)], hout, True, classes + [member["name"], local_types[param_type(typ)][0]["name"]])
|
||||
handle_visitors_nodes(local_types[param_type(typ)], hout, True, classes + [member.name, local_types[param_type(typ)][0].name])
|
||||
if is_variant(typ):
|
||||
name = base_state + "__" + member["name"] + "__variant"
|
||||
new_member = {"type": typ, "name": "variant"}
|
||||
name = base_state + "__" + member.name + "__variant"
|
||||
new_member = copy(member) # shallow copy
|
||||
new_member.type = typ
|
||||
new_member.name = "variant"
|
||||
return_struct = "after_" + par
|
||||
end_method = Template("""
|
||||
$return_struct<Output> end_variant() && {
|
||||
@@ -656,9 +842,9 @@ def add_variant_nodes(hout, member, param, base_state, parents, classes):
|
||||
return { _out, std::move(_state._parent) };
|
||||
}
|
||||
""").substitute({'return_struct': return_struct})
|
||||
add_node(hout, name, None, base_state + "__" + member["name"], "after_", name, end_method)
|
||||
add_variant_nodes(hout, new_member, typ, par, name, classes + [member["name"]])
|
||||
add_node(hout, name, typ, name, "", par, add_param_write({"type": typ, "name": "variant"}, par))
|
||||
add_node(hout, name, None, base_state + "__" + member.name, "after_", name, end_method)
|
||||
add_variant_nodes(hout, new_member, typ, par, name, classes + [member.name])
|
||||
add_node(hout, name, typ, name, "", par, add_param_write(new_member, par))
|
||||
|
||||
|
||||
writers = set()
|
||||
@@ -670,12 +856,12 @@ def add_template_writer_node(hout, typ):
|
||||
|
||||
|
||||
def add_nodes_when_needed(hout, info, member, base_state_name, parents, member_classes):
|
||||
if is_vector(member["type"]):
|
||||
if is_vector(member.type):
|
||||
add_vector_node(hout, member, base_state_name, base_state_name)
|
||||
elif is_variant(member["type"]):
|
||||
add_variant_nodes(hout, member, member["type"], base_state_name, parents, member_classes)
|
||||
elif is_local_type(member["type"]):
|
||||
handle_visitors_nodes(local_types[member["type"]], hout, False, member_classes + [member["name"]])
|
||||
elif is_variant(member.type):
|
||||
add_variant_nodes(hout, member, member.type, base_state_name, parents, member_classes)
|
||||
elif is_local_type(member.type):
|
||||
handle_visitors_nodes(local_types[member.type.name], hout, False, member_classes + [member.name])
|
||||
|
||||
|
||||
def handle_visitors_nodes(info, hout, variant_node=False, clases=[]):
|
||||
@@ -683,9 +869,9 @@ def handle_visitors_nodes(info, hout, variant_node=False, clases=[]):
|
||||
[cls, namespaces, parent_template_param] = info
|
||||
# for root node, only generate once
|
||||
if not clases:
|
||||
if cls["name"] in writers:
|
||||
if cls.name in writers:
|
||||
return
|
||||
writers.add(cls["name"])
|
||||
writers.add(cls.name)
|
||||
|
||||
members = get_members(cls)
|
||||
if clases:
|
||||
@@ -696,15 +882,15 @@ def handle_visitors_nodes(info, hout, variant_node=False, clases=[]):
|
||||
parents = "__".join(clases[:-1])
|
||||
current_name = clases[-1]
|
||||
else:
|
||||
base_state_name = cls["name"]
|
||||
current_name = cls["name"]
|
||||
base_state_name = cls.name
|
||||
current_name = cls.name
|
||||
parents = ""
|
||||
member_classes = clases if clases else [current_name]
|
||||
prefix = "" if clases else "writer_of_"
|
||||
if not members:
|
||||
add_node(hout, base_state_name, None, base_state_name, prefix, parents, add_end_method(parents, current_name, variant_node, clases), False, is_final(cls))
|
||||
return
|
||||
add_node(hout, base_state_name + "__" + get_member_name(members[-1]["name"]), members[-1]["type"], base_state_name, "after_", base_state_name, add_end_method(parents, current_name, variant_node, clases))
|
||||
add_node(hout, base_state_name + "__" + get_member_name(members[-1].name), members[-1].type, base_state_name, "after_", base_state_name, add_end_method(parents, current_name, variant_node, clases))
|
||||
# Create writer and reader for include class
|
||||
if not variant_node:
|
||||
for member in get_dependency(cls):
|
||||
@@ -712,24 +898,21 @@ def handle_visitors_nodes(info, hout, variant_node=False, clases=[]):
|
||||
for ind in reversed(range(1, len(members))):
|
||||
member = members[ind]
|
||||
add_nodes_when_needed(hout, info, member, base_state_name, parents, member_classes)
|
||||
variant_state = base_state_name + "__" + get_member_name(member["name"]) if is_variant(member["type"]) else base_state_name
|
||||
add_node(hout, base_state_name + "__" + get_member_name(members[ind - 1]["name"]), member["type"], variant_state, "after_", base_state_name, add_param_write(member, base_state_name), False)
|
||||
variant_state = base_state_name + "__" + get_member_name(member.name) if is_variant(member.type) else base_state_name
|
||||
add_node(hout, base_state_name + "__" + get_member_name(members[ind - 1].name), member.type, variant_state, "after_", base_state_name, add_param_write(member, base_state_name), False)
|
||||
member = members[0]
|
||||
add_nodes_when_needed(hout, info, member, base_state_name, parents, member_classes)
|
||||
add_node(hout, base_state_name, member["type"], base_state_name, prefix, parents, add_param_write(member, base_state_name, False, not clases), False, is_final(cls))
|
||||
add_node(hout, base_state_name, member.type, base_state_name, prefix, parents, add_param_write(member, base_state_name, False, not clases), False, is_final(cls))
|
||||
|
||||
|
||||
def add_to_types(cls, namespaces, parent_template_param):
|
||||
global local_types
|
||||
global stubs
|
||||
if "attribute" not in cls or cls["attribute"][0][0] != "writable":
|
||||
if not cls.attribute or cls.attribute.name != 'writable':
|
||||
return
|
||||
local_types[cls["name"]] = [cls, namespaces, parent_template_param]
|
||||
if "stub" in cls:
|
||||
stubs.add(cls["name"])
|
||||
for param in cls["members"]:
|
||||
if is_class(param) or is_enum(param):
|
||||
continue
|
||||
local_types[cls.name] = [cls, namespaces, parent_template_param]
|
||||
if cls.stub:
|
||||
stubs.add(cls.name)
|
||||
|
||||
|
||||
def sort_dependencies():
|
||||
@@ -760,14 +943,14 @@ def to_view(val):
|
||||
return val
|
||||
|
||||
|
||||
def param_view_type(lst):
|
||||
if isinstance(lst, str):
|
||||
return to_view(lst)
|
||||
if len(lst) == 1:
|
||||
return to_view(lst[0])
|
||||
if lst[0] == "boost::variant" or lst[0] == "std::variant":
|
||||
return lst[0] + join_template_view(lst[1], ["unknown_variant_type"])
|
||||
return lst[0] + join_template_view(lst[1])
|
||||
def param_view_type(t):
|
||||
if isinstance(t, BasicType):
|
||||
return to_view(t.name)
|
||||
elif isinstance(t, TemplateType):
|
||||
additional_types = []
|
||||
if t.name == "boost::variant" or t.name == "std::variant":
|
||||
additional_types.append("unknown_variant_type")
|
||||
return t.name + join_template_view(t.template_parameters, additional_types)
|
||||
|
||||
|
||||
read_sizes = set()
|
||||
@@ -780,7 +963,7 @@ def add_variant_read_size(hout, typ):
|
||||
return
|
||||
if not is_variant(typ):
|
||||
return
|
||||
for p in typ[1]:
|
||||
for p in typ.template_parameters:
|
||||
if is_variant(p):
|
||||
add_variant_read_size(hout, p)
|
||||
read_sizes.add(t)
|
||||
@@ -801,7 +984,7 @@ $type deserialize(Input& v, boost::type<${type}>) {
|
||||
deserialize(in, boost::type<size_type>());
|
||||
size_type o = deserialize(in, boost::type<size_type>());
|
||||
""").substitute({'type': t}))
|
||||
for index, param in enumerate(typ[1]):
|
||||
for index, param in enumerate(typ.template_parameters):
|
||||
fprintln(hout, Template("""
|
||||
if (o == $ind) {
|
||||
v.skip(sizeof(size_type)*2);
|
||||
@@ -814,28 +997,28 @@ def add_view(hout, info):
|
||||
[cls, namespaces, parent_template_param] = info
|
||||
members = get_members(cls)
|
||||
for m in members:
|
||||
add_variant_read_size(hout, m["type"])
|
||||
add_variant_read_size(hout, m.type)
|
||||
|
||||
fprintln(hout, Template("""struct ${name}_view {
|
||||
utils::input_stream v;
|
||||
""").substitute({'name': cls["name"]}))
|
||||
""").substitute({'name': cls.name}))
|
||||
|
||||
if not is_stub(cls["name"]) and is_local_type(cls["name"]):
|
||||
if not is_stub(cls.name) and is_local_type(cls.name):
|
||||
fprintln(hout, Template(reindent(4, """
|
||||
operator $type() const {
|
||||
auto in = v;
|
||||
return deserialize(in, boost::type<$type>());
|
||||
}
|
||||
""")).substitute({'type': cls["name"]}))
|
||||
""")).substitute({'type': cls.name}))
|
||||
|
||||
skip = "" if is_final(cls) else "ser::skip(in, boost::type<size_type>());"
|
||||
local_names = {}
|
||||
for m in members:
|
||||
name = get_member_name(m["name"])
|
||||
name = get_member_name(m.name)
|
||||
local_names[name] = "this->" + name + "()"
|
||||
full_type = param_view_type(m["type"])
|
||||
if "attribute" in m:
|
||||
deflt = m["default"][0] if "default" in m else param_type(m["type"]) + "()"
|
||||
full_type = param_view_type(m.type)
|
||||
if m.attribute:
|
||||
deflt = m.default_value if m.default_value else param_type(m.type) + "()"
|
||||
if deflt in local_names:
|
||||
deflt = local_names[deflt]
|
||||
deser = Template("(in.size()>0) ? $func(in, boost::type<$typ>()) : $default").substitute(
|
||||
@@ -883,7 +1066,7 @@ struct serializer<${type}_view> {
|
||||
});
|
||||
}
|
||||
};
|
||||
""").substitute({'type': param_type(cls["name"]), 'skip': skip, 'skip_impl': skip_impl}))
|
||||
""").substitute({'type': cls.name, 'skip': skip, 'skip_impl': skip_impl}))
|
||||
|
||||
|
||||
def add_views(hout):
|
||||
@@ -905,28 +1088,25 @@ def add_visitors(hout):
|
||||
|
||||
def handle_class(cls, hout, cout, namespaces=[], parent_template_param=[]):
|
||||
add_to_types(cls, namespaces, parent_template_param)
|
||||
if "stub" in cls:
|
||||
if cls.stub:
|
||||
return
|
||||
[ns, ns_open, ns_close] = set_namespace(namespaces)
|
||||
tpl = "template" in cls
|
||||
template_param_list = (cls["template"][0]["params"].asList() if tpl else [])
|
||||
template_param = ", ".join(map(lambda a: a[0] + " " + a[1], template_param_list + parent_template_param)) if (template_param_list + parent_template_param) else ""
|
||||
template = "template <" + template_param + ">" if tpl else ""
|
||||
template_class_param = "<" + ",".join(map(lambda a: a[1], template_param_list)) + ">" if tpl else ""
|
||||
is_tpl = cls.template_params is not None
|
||||
template_param_list = (cls.template_params if is_tpl else [])
|
||||
template_param = ", ".join(map(lambda a: a.typename + " " + a.name, template_param_list + parent_template_param)) if (template_param_list + parent_template_param) else ""
|
||||
template = "template <" + template_param + ">" if is_tpl else ""
|
||||
template_class_param = "<" + ",".join(map(lambda a: a.name, template_param_list)) + ">" if is_tpl else ""
|
||||
temp_def = template_param if template_param != "" else ""
|
||||
|
||||
if ns == "":
|
||||
name = cls["name"]
|
||||
else:
|
||||
name = ns + "::" + cls["name"]
|
||||
name = cls.name if ns == "" else ns + "::" + cls.name
|
||||
full_name = name + template_class_param
|
||||
for param in cls["members"]:
|
||||
if is_class(param):
|
||||
handle_class(param, hout, cout, namespaces + [cls["name"] + template_class_param], parent_template_param + template_param_list)
|
||||
elif is_enum(param):
|
||||
handle_enum(param, hout, cout, namespaces + [cls["name"] + template_class_param], parent_template_param + template_param_list)
|
||||
for member in cls.members:
|
||||
if isinstance(member, ClassDef):
|
||||
handle_class(member, hout, cout, namespaces + [cls.name + template_class_param], parent_template_param + template_param_list)
|
||||
elif isinstance(member, EnumDef):
|
||||
handle_enum(member, hout, cout, namespaces + [cls.name + template_class_param], parent_template_param + template_param_list)
|
||||
declear_methods(hout, name + template_class_param, temp_def)
|
||||
is_final = "final" in cls
|
||||
is_final = cls.final
|
||||
|
||||
fprintln(cout, Template("""
|
||||
$template
|
||||
@@ -934,11 +1114,11 @@ template <typename Output>
|
||||
void serializer<$name>::write(Output& buf, const $name& obj) {""").substitute({'func': SERIALIZER, 'name': full_name, 'template': template}))
|
||||
if not is_final:
|
||||
fprintln(cout, Template(""" $set_size(buf, obj);""").substitute({'func': SERIALIZER, 'set_size': SETSIZE, 'name': name, 'sizetype': SIZETYPE}))
|
||||
for param in cls["members"]:
|
||||
if is_class(param) or is_enum(param):
|
||||
for member in cls.members:
|
||||
if isinstance(member, ClassDef) or isinstance(member, EnumDef):
|
||||
continue
|
||||
fprintln(cout, Template(""" static_assert(is_equivalent<decltype(obj.$var), $type>::value, "member value has a wrong type");
|
||||
$func(buf, obj.$var);""").substitute({'func': SERIALIZER, 'var': param["name"], 'type': param_type(param["type"])}))
|
||||
$func(buf, obj.$var);""").substitute({'func': SERIALIZER, 'var': member.name, 'type': param_type(member.type)}))
|
||||
fprintln(cout, "}")
|
||||
|
||||
fprintln(cout, Template("""
|
||||
@@ -946,7 +1126,7 @@ $template
|
||||
template <typename Input>
|
||||
$name$temp_param serializer<$name$temp_param>::read(Input& buf) {
|
||||
return seastar::with_serialized_stream(buf, [] (auto& buf) {""").substitute({'func': DESERIALIZER, 'name': name, 'template': template, 'temp_param': template_class_param}))
|
||||
if not cls["members"]:
|
||||
if not cls.members:
|
||||
if not is_final:
|
||||
fprintln(cout, Template(""" $size_type size = $func(buf, boost::type<$size_type>());
|
||||
buf.skip(size - sizeof($size_type));""").substitute({'func': DESERIALIZER, 'size_type': SIZETYPE}))
|
||||
@@ -957,19 +1137,21 @@ $name$temp_param serializer<$name$temp_param>::read(Input& buf) {
|
||||
fprintln(cout, """ auto& in = buf;""")
|
||||
params = []
|
||||
local_names = {}
|
||||
for index, param in enumerate(cls["members"]):
|
||||
if is_class(param) or is_enum(param):
|
||||
for index, param in enumerate(cls.members):
|
||||
if isinstance(param, ClassDef) or isinstance(param, EnumDef):
|
||||
continue
|
||||
local_param = "__local_" + str(index)
|
||||
local_names[param["name"]] = local_param
|
||||
if "attribute" in param:
|
||||
deflt = param["default"][0] if "default" in param else param_type(param["type"]) + "()"
|
||||
local_names[param.name] = local_param
|
||||
if param.attribute:
|
||||
deflt = param_type(param.type) + "()"
|
||||
if param.default_value:
|
||||
deflt = param.default_value
|
||||
if deflt in local_names:
|
||||
deflt = local_names[deflt]
|
||||
fprintln(cout, Template(""" auto $local = (in.size()>0) ?
|
||||
$func(in, boost::type<$typ>()) : $default;""").substitute({'func': DESERIALIZER, 'typ': param_type(param["type"]), 'local': local_param, 'default': deflt}))
|
||||
$func(in, boost::type<$typ>()) : $default;""").substitute({'func': DESERIALIZER, 'typ': param_type(param.type), 'local': local_param, 'default': deflt}))
|
||||
else:
|
||||
fprintln(cout, Template(""" auto $local = $func(in, boost::type<$typ>());""").substitute({'func': DESERIALIZER, 'typ': param_type(param["type"]), 'local': local_param}))
|
||||
fprintln(cout, Template(""" auto $local = $func(in, boost::type<$typ>());""").substitute({'func': DESERIALIZER, 'typ': param_type(param.type), 'local': local_param}))
|
||||
params.append("std::move(" + local_param + ")")
|
||||
fprintln(cout, Template("""
|
||||
$name$temp_param res {$params};
|
||||
@@ -981,39 +1163,39 @@ $name$temp_param serializer<$name$temp_param>::read(Input& buf) {
|
||||
$template
|
||||
template <typename Input>
|
||||
void serializer<$name$temp_param>::skip(Input& buf) {
|
||||
seastar::with_serialized_stream(buf, [] (auto& buf) {""").substitute({'func': DESERIALIZER, 'name': name, 'template': template, 'temp_param': template_class_param}))
|
||||
seastar::with_serialized_stream(buf, [] (auto& buf) {""").substitute({'name': name, 'template': template, 'temp_param': template_class_param}))
|
||||
if not is_final:
|
||||
fprintln(cout, Template(""" $size_type size = $func(buf, boost::type<$size_type>());
|
||||
buf.skip(size - sizeof($size_type));""").substitute({'func': DESERIALIZER, 'size_type': SIZETYPE}))
|
||||
else:
|
||||
for m in get_members(cls):
|
||||
full_type = param_view_type(m["type"])
|
||||
full_type = param_view_type(m.type)
|
||||
fprintln(cout, " ser::skip(buf, boost::type<%s>());" % full_type)
|
||||
fprintln(cout, """ });\n}""")
|
||||
|
||||
|
||||
def handle_objects(tree, hout, cout, namespaces=[]):
|
||||
for obj in tree:
|
||||
if is_class(obj):
|
||||
if isinstance(obj, ClassDef):
|
||||
handle_class(obj, hout, cout, namespaces)
|
||||
elif is_enum(obj):
|
||||
elif isinstance(obj, EnumDef):
|
||||
handle_enum(obj, hout, cout, namespaces)
|
||||
elif obj["type"] == "namespace":
|
||||
handle_objects(obj["content"], hout, cout, namespaces + [obj["name"]])
|
||||
elif isinstance(obj, NamespaceDef):
|
||||
handle_objects(obj.members, hout, cout, namespaces + [obj.name])
|
||||
else:
|
||||
print("unknown type ", obj, obj["type"])
|
||||
print(f"Unknown type: {obj}")
|
||||
|
||||
|
||||
def handle_types(tree, namespaces=[]):
|
||||
for obj in tree:
|
||||
if is_class(obj):
|
||||
if isinstance(obj, ClassDef):
|
||||
add_to_types(obj, namespaces, [])
|
||||
elif is_enum(obj):
|
||||
elif isinstance(obj, EnumDef):
|
||||
pass
|
||||
elif obj["type"] == "namespace":
|
||||
handle_types(obj["content"], namespaces + [obj["name"]])
|
||||
elif isinstance(obj, NamespaceDef):
|
||||
handle_types(obj.members, namespaces + [obj.name])
|
||||
else:
|
||||
print("unknown type ", obj, obj["type"])
|
||||
print(f"Unknown object type: {obj}")
|
||||
|
||||
|
||||
def load_file(name):
|
||||
@@ -1037,7 +1219,6 @@ def load_file(name):
|
||||
data = parse_file(name)
|
||||
if data:
|
||||
handle_types(data)
|
||||
if data:
|
||||
handle_objects(data, hout, cout)
|
||||
add_visitors(cout)
|
||||
if config.ns != '':
|
||||
|
||||
Reference in New Issue
Block a user