Ejemplo n.º 1
0
    def _generate_header(self, cpp_type_meta, cpp_type, type_def: TypeDefBase):
        if cpp_type_meta == CppStruct:
            cpp_type.add_base_class('ISerializable')
            cpp_type.add_member_method(
                '[[nodiscard]] std::string ToJson() const override;')
            cpp_type.add_member_method(
                'void FromJson(const std::string&) override;')

        header_code = LineBuffer(0)

        try:
            cpp_type.write_header(header_code, self.type_registry)
        except Exception as ex:
            print(f"Failed writing header: {type_def.type_name} [{ex}]")
            raise

        # prepend include headers
        if cpp_type_meta in (CppStruct, CppExtendedVariant):
            header_writer = HeaderCodeWriter(header_code)
            header_writer.include_headers.extend(cpp_type.header_includes)

            header_path = self.get_header_file_path(type_def.namespaces,
                                                    type_def.type_name)
            pathlib.Path(header_path.parent).mkdir(parents=True, exist_ok=True)
            with open(header_path, 'w') as header_file:
                header_file.write(header_writer.str())
        else:
            self.type_header_writer.add_to_namespace(
                cpp_type.type_def.namespaces, header_code,
                cpp_type.header_includes)
Ejemplo n.º 2
0
 def write_header(self, buffer: LineBuffer,
                  _type_registry: TypeRegistry) -> None:
     buffer.append(
         f"enum class {self.enum_name()} : {self.type_def.underlying_type}")
     buffer.append('{')
     with IndentedBlock(buffer):
         if self.type_def.members:
             enum_members = self.type_def.members
             for m, i in enum_members.items():
                 comment = f"  //{self.type_def.comments[m]}" if m in self.type_def.comments else ''
                 buffer.append(f"{m} = {i},{comment}")
     buffer.append('};')
Ejemplo n.º 3
0
    def _generate_cpp(self, cpp_type: Union[CppStruct, CppExtendedVariant]):
        cpp_src_code = LineBuffer(0)
        if isinstance(cpp_type, CppStruct):
            cpp_type.add_base_class('ISerializable')
            cpp_type.add_member_method(
                '[[nodiscard]] std::string ToJson() const override;')
            cpp_type.add_member_method(
                'void FromJson(const std::string&) override;')
        cpp_type.write_source(cpp_src_code, self.type_registry)

        # prepend include headers
        header_path = self.get_header_file_path(cpp_type.type_def.namespaces,
                                                cpp_type.type_def.type_name)
        prepend_lines = [f'#include <{header_path}>']
        for include in cpp_type.cpp_includes:
            prepend_lines.append(f"#include <{include}>")
        prepend_lines.append('')
        cpp_src_code.prepend(*prepend_lines)

        cpp_path = self.get_cpp_file_path(cpp_type.type_def)
        pathlib.Path(cpp_path.parent).mkdir(parents=True, exist_ok=True)
        with open(cpp_path, 'w') as header_file:
            header_file.write(cpp_src_code.str())
Ejemplo n.º 4
0
    def write_header(self, buffer: LineBuffer, type_registry: TypeRegistry) -> None:
        var_buffer = LineBuffer(0)
        type_buffer = LineBuffer(0)
        for type_def in self.type_def.members:
            if isinstance(type_def, SimpleAlias):
                cpp_alias = CppSimpleAlias(type_def)
                var_buffer.append(f"{cpp_alias.actual_type()} {type_def.type_name};")
                self.header_includes.update(cpp_alias.get_include_headers(type_registry))
            elif isinstance(type_def, ArrayAlias):
                cpp_array = CppArrayAlias(type_def)
                var_buffer.append(f"{cpp_array.actual_type(type_registry)} {type_def.type_name};")
                self.header_includes.update(cpp_array.get_include_headers(type_registry))
            elif isinstance(type_def, VariantAlias):
                cpp_variant = CppVariantAlias(type_def)
                var_buffer.append(f"{cpp_variant.actual_type(type_registry)} {type_def.type_name};")
                self.header_includes.update(cpp_variant.get_include_headers(type_registry))
            elif isinstance(type_def, EnumType):
                cpp_enum = CppEnum(type_def)
                cpp_enum.write_header(type_buffer, type_registry)
                type_buffer.new_line()
            elif isinstance(type_def, StructType):
                cpp_struct = CppStruct(type_def)
                cpp_struct.write_header(type_buffer, type_registry)
                type_buffer.new_line()
                self.header_includes.update(cpp_struct.header_includes)
            elif isinstance(type_def, ExtendedVariant):
                cpp_struct = CppExtendedVariant(type_def)
                cpp_struct.write_header(type_buffer, type_registry)
                type_buffer.new_line()
                self.header_includes.update(cpp_struct.header_includes)
            elif isinstance(type_def, RefType):
                cpp_ref_alias = CppRefAlias(type_def)
                var_buffer.append(f"{cpp_ref_alias.target_type(type_registry)} {type_def.type_name};")
            else:
                raise TypeError(f"Unsupported struct member type: [{type_def}]")

        # generate struct
        if self.type_def.namespaces:
            buffer.append('namespace ' + '::'.join(self.type_def.namespaces))
            buffer.append('{')
            buffer.indent_up()

        if self.base_classes:
            suffix = ' : ' + ', '.join(self.base_classes)
        else:
            suffix = ''
        buffer.append(f"struct {self.type_def.type_name}{suffix}")
        buffer.append("{")

        if type_buffer:
            with IndentedBlock(buffer):
                buffer.append_buffer(type_buffer)

        if var_buffer:
            with IndentedBlock(buffer):
                buffer.append_buffer(var_buffer)
            buffer.new_line()

        # pre-defined methods
        with IndentedBlock(buffer):
            if self.member_methods:
                for method in self.member_methods:
                    buffer.append(method)
            else:
                buffer.pop()

        buffer.append('};')
        if self.type_def.namespaces:
            buffer.indent_down()
            buffer.append('}  // namespace ' + '::'.join(self.type_def.namespaces))
Ejemplo n.º 5
0
    def write_source(self, buffer: LineBuffer, type_registry: TypeRegistry):
        if self.type_def.namespaces:
            buffer.append('namespace ' + '::'.join(self.type_def.namespaces))
            buffer.append('{')
            buffer.indent_up()

        # internal namespace
        buffer.append(f"namespace internal")
        buffer.append("{")
        with IndentedBlock(buffer):
            # internal ToJson
            tjw = ToJsonWriter(buffer, type_registry, self.type_def)
            tjw.write_function()

            # internal FromJson
            fjw = FromJsonWriter(buffer, type_registry, self.type_def)
            fjw.write_function()

        buffer.append("}")
        buffer.new_line()

        # public ToJson
        buffer.append(f"std::string {self.type_def.type_name}::ToJson() const")
        buffer.append("{")
        with IndentedBlock(buffer):
            buffer.append('return internal::ToJson(*this).dump();')
        buffer.append("}")
        buffer.new_line()

        # public FromJson
        buffer.append(f"void {self.type_def.type_name}::FromJson(std::string const& js)")
        buffer.append("{")
        with IndentedBlock(buffer):
            buffer.append('internal::FromJson(*this, nlohmann::json::parse(js));')
        buffer.append("}")

        if self.type_def.namespaces:
            buffer.indent_down()
            buffer.append('}  // namespace ' + '::'.join(self.type_def.namespaces))
 def write_header(self, buffer: LineBuffer,
                  _type_registry: TypeRegistry) -> None:
     buffer.append(f"using {self.type_name()} = {self.actual_type()};")
Ejemplo n.º 7
0
    def write_header(self, buffer: LineBuffer, type_registry: TypeRegistry) -> None:
        # generate extended struct
        if self.type_def.namespaces:
            buffer.append('namespace ' + '::'.join(self.type_def.namespaces))
            buffer.append('{')
            buffer.indent_up()

        if self.base_classes:
            suffix = ' : ' + ', '.join(self.base_classes)
        else:
            suffix = ''
        variant_members = ['std::monostate']
        for member_type_def in self.type_def.content_variant.member_type_defs:
            if isinstance(member_type_def, SimpleAlias):
                cpp_alias = CppSimpleAlias(member_type_def)
                variant_members.append(cpp_alias.actual_type())
            elif isinstance(member_type_def, ArrayAlias):
                cpp_array = CppArrayAlias(member_type_def)
                variant_members.append(cpp_array.actual_type(type_registry))
            elif isinstance(member_type_def, StructType):
                #     cpp_struct = CppStruct(member_type_def)
                #     variant_members.append(cpp_struct.type_def.type_name)
                pass
            elif isinstance(member_type_def, RefType):
                #     target_type = type_registry.get_ref_target(member_type_def.target_uri)
                #     variant_members.append(target_type.type_name)
                pass
            else:
                raise TypeError(f"Unsupported struct member type: [{member_type_def}]")

        buffer.append(f"struct {self.type_def.type_name}{suffix} : std::variant<{','.join(variant_members)}>")
        buffer.append("{")

        with IndentedBlock(buffer):
            # write type enum
            cpp_enum = CppEnum(self.type_def.type_enum)
            cpp_enum.type_def.type_name = cpp_enum.type_def.type_name.capitalize()
            cpp_enum.write_header(buffer, type_registry)
            buffer.append('')

            cast_expr = f'static_cast<{self.type_def.type_enum.underlying_type}>(MemberType)'
            # write setter
            buffer.append('template <Type MemberType, typename T>')
            buffer.append(f'void SetAs(T value) ')
            buffer.extend_last('{ ')
            buffer.extend_last(f'emplace<{cast_expr}>(value);')
            buffer.extend_last(' }')
            buffer.new_line()

            # write non-const getter
            buffer.append('template <Type MemberType>')
            buffer.append(f'[[nodiscard]] auto& GetAs() ')
            buffer.extend_last('{ ')
            buffer.extend_last(f'return std::get<{cast_expr}>(*this);')
            buffer.extend_last(' }')
            buffer.new_line()

            # write const getter
            buffer.append('template <Type MemberType>')
            buffer.append(f'[[nodiscard]] auto const& GetAs() const ')
            buffer.extend_last('{ ')
            buffer.extend_last(f'return std::get<{cast_expr}>(*this);')
            buffer.extend_last(' }')

            # pre-defined methods
            with IndentedBlock(buffer):
                if self.member_methods:
                    for method in self.member_methods:
                        buffer.append(method)

        buffer.append('};')
        if self.type_def.namespaces:
            buffer.indent_down()
            buffer.append('}  // namespace ' + '::'.join(self.type_def.namespaces))
Ejemplo n.º 8
0
    def write_source(self, buffer: LineBuffer, type_registry: TypeRegistry):
        if self.type_def.namespaces:
            buffer.append('namespace ' + '::'.join(self.type_def.namespaces))
            buffer.append('{')
            buffer.indent_up()

        # internal namespace
        buffer.append(f"namespace internal")
        buffer.append("{")
        with IndentedBlock(buffer):
            fjw = FromJsonWriter(buffer, type_registry, self.type_def)
            fjw.write_function()

            tjw = ToJsonWriter(buffer, type_registry, self.type_def)
            tjw.write_function()

        buffer.append("}")
        buffer.new_line()

        if self.type_def.namespaces:
            buffer.indent_down()
            buffer.append('}  // namespace ' + '::'.join(self.type_def.namespaces))
Ejemplo n.º 9
0
 def write_header(self, buffer: LineBuffer,
                  type_registry: TypeRegistry) -> None:
     buffer.append(
         f"using {self.type_def.type_name} = {self.target_type(type_registry)};"
     )
Ejemplo n.º 10
0
    def get_type_header_buffer(self, namespaces: List[str]) -> LineBuffer:
        ns_key = self._make_ns_key(namespaces)
        if ns_key not in self.include_headers:
            raise NameError(f"No namespace type info: {ns_key}")

        buffer = LineBuffer(0)
        if self.include_headers[ns_key]:
            buffer.new_line()
            for include in self.include_headers[ns_key]:
                buffer.append(f"#include <{include}>")
        buffer.new_line()
        ns_str = "::".join(namespaces)
        buffer.append(f'namespace {ns_str}')
        buffer.append('{')
        with IndentedBlock(buffer):
            for buf in self.buffers[ns_key]:
                buffer.append_buffer(buf)
        buffer.append(f'}} // {ns_str}')

        return buffer
 def str(self):
     final_buffer = LineBuffer(0)
     final_buffer.append('#pragma once')
     if self.include_headers:
         final_buffer.new_line()
         for include in self.include_headers:
             final_buffer.append(f"#include <{include}>")
     final_buffer.new_line()
     final_buffer.append_buffer(self.buffer)
     return final_buffer.str()