Add write_tl_to_multiple_files to allow C++ autogenerated header splitting.

This commit is contained in:
levlam 2023-06-26 19:25:40 +03:00
parent 014f880e41
commit ac018e21b2
11 changed files with 144 additions and 9 deletions

View File

@ -224,7 +224,7 @@ class TlWriterCCommon final : public tl::TL_writer {
}
std::string gen_output_begin(const std::string &additional_imports) const final {
if (is_header_ == 1) {
return "#pragma once\n"
return "#pragma once\n\n" + additional_imports +
"#ifdef __cplusplus\n"
"extern \"C\" {\n"
"#endif\n"
@ -300,6 +300,10 @@ class TlWriterCCommon final : public tl::TL_writer {
}
}
std::string gen_package_suffix() const final {
return ".h";
}
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final {
if (is_header_ != 1 || class_name == "") {
return "";

View File

@ -206,6 +206,10 @@ class TlWriterDotNet final : public TL_writer {
}
}
std::string gen_package_suffix() const final {
return ".h";
}
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final {
if (!is_header_) {
return "";

View File

@ -51,9 +51,8 @@ std::string TD_TL_writer_h::gen_output_begin(const std::string &additional_impor
ext_include_str +
"#include <cstdint>\n"
"#include <utility>\n"
"#include <vector>\n\n"
"namespace td {\n" +
ext_forward_declaration + "namespace " + tl_name + " {\n\n";
"#include <vector>\n\n" +
additional_imports + "namespace td {\n" + ext_forward_declaration + "namespace " + tl_name + " {\n\n";
}
std::string TD_TL_writer_h::gen_output_begin_once() const {

View File

@ -191,7 +191,7 @@ std::string TD_TL_writer_java::gen_int_const(const tl::tl_tree *tree_c,
}
std::string TD_TL_writer_java::gen_output_begin(const std::string &additional_imports) const {
return "package " + package_name + ";\n\n" + additional_imports;
return "package " + package_name + ";\n\n";
}
std::string TD_TL_writer_java::gen_output_begin_once() const {
@ -218,6 +218,10 @@ std::string TD_TL_writer_java::gen_import_declaration(const std::string &name, b
return "import " + name + ";\n";
}
std::string TD_TL_writer_java::gen_package_suffix() const {
return "";
}
std::string TD_TL_writer_java::gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const {
return "";
}

View File

@ -59,6 +59,8 @@ class TD_TL_writer_java final : public tl::TL_writer {
std::string gen_import_declaration(const std::string &name, bool is_system) const final;
std::string gen_package_suffix() const final;
std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const final;
std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, bool is_proxy,

View File

@ -69,11 +69,9 @@ std::string TD_TL_writer_jni_h::gen_output_begin(const std::string &additional_i
"#include <utility>\n"
"#include <vector>\n\n"
"#include <jni.h>\n\n" +
ext_include_str +
"\n"
ext_include_str + "\n" + additional_imports +
"namespace td {\n" +
forward_declaration("TlStorerToString") +
"namespace td {\n" + forward_declaration("TlStorerToString") +
"\n"
"namespace " +
tl_name + " {\n\n";

View File

@ -125,6 +125,10 @@ std::string TD_TL_writer::gen_import_declaration(const std::string &name, bool i
}
}
std::string TD_TL_writer::gen_package_suffix() const {
return ".h";
}
std::string TD_TL_writer::gen_base_tl_class_name() const {
return base_tl_class_name;
}

View File

@ -46,6 +46,7 @@ class TD_TL_writer : public tl::TL_writer {
std::vector<std::string> get_storers() const override;
std::string gen_import_declaration(const std::string &package_name, bool is_system) const override;
std::string gen_package_suffix() const override;
std::string gen_base_tl_class_name() const override;
std::string gen_base_type_class_name(int arity) const override;
std::string gen_base_function_class_name() const override;

View File

@ -17,6 +17,7 @@
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <set>
#include <string>
#include <vector>
@ -898,5 +899,119 @@ bool write_tl_to_file(const tl_config &config, const std::string &file_name, con
return put_file_contents(file_name, out.get_result(), w.is_documentation_generated());
}
static std::string get_additional_imports(const std::map<std::string, bool> &types, const std::string base_class_name,
const std::string &file_name_prefix, const std::string &file_name_suffix,
const TL_writer &w) {
std::string result =
w.gen_import_declaration(file_name_prefix + "_" + base_class_name + w.gen_package_suffix(), false);
if (w.gen_package_suffix() != file_name_suffix) {
for (std::map<std::string, bool>::const_iterator it = types.begin(); it != types.end(); ++it) {
std::string package_name = file_name_prefix + "_" + w.gen_class_name(it->first) + w.gen_package_suffix();
result += w.gen_import_declaration(package_name, false);
}
}
result += "\n";
return result;
}
bool write_tl_to_multiple_files(const tl_config &config, const std::string &file_name_prefix,
const std::string &file_name_suffix, const TL_writer &w) {
find_complex_types(config, w);
std::map<std::string, tl_string_outputer> outs;
tl_string_outputer *out = &outs["common"];
out->append(w.gen_output_begin(std::string()));
out->append(w.gen_output_begin_once());
out->append(w.gen_output_end());
std::set<std::string> request_types;
std::set<std::string> result_types;
for (std::size_t function = 0; function < config.get_function_count(); function++) {
const tl_combinator *t = config.get_function_by_num(function);
dfs_combinator(t, request_types, w);
dfs_tree(t->result, result_types, w);
}
std::map<std::string, bool> object_types;
for (std::size_t type = 0; type < config.get_type_count(); type++) {
tl_type *t = config.get_type_by_num(type);
if (t->constructors_num == 0 || w.is_built_in_simple_type(t->name) ||
w.is_built_in_complex_type(t->name)) { // built-in dummy or complex types
continue;
}
if (t->flags & FLAG_COMPLEX) {
std::fprintf(stderr, "Can't generate class %s\n", t->name.c_str());
continue;
}
object_types[t->name] = (t->simple_constructors != 1);
out = &outs[w.gen_main_class_name(t)];
auto additional_imports =
get_additional_imports(get_children_types(t, w), "Object", file_name_prefix, file_name_suffix, w);
out->append(w.gen_output_begin(additional_imports));
write_class(*out, t, request_types, result_types, w);
out->append(w.gen_output_end());
}
std::map<std::string, bool> function_types;
for (std::size_t function = 0; function < config.get_function_count(); function++) {
tl_combinator *t = config.get_function_by_num(function);
if (!w.is_combinator_supported(t)) {
// std::fprintf(stderr, "Function %s is too hard to store\n", t->name.c_str());
continue;
}
function_types[t->name] = false;
out = &outs[w.gen_class_name(t->name)];
auto additional_imports =
get_additional_imports(get_children_types(t, w), "Function", file_name_prefix, file_name_suffix, w);
out->append(w.gen_output_begin(additional_imports));
write_function(*out, t, request_types, result_types, w);
out->append(w.gen_output_end());
}
for (std::size_t type = 0; type < config.get_type_count(); type++) {
tl_type *t = config.get_type_by_num(type);
if (t->flags & FLAG_COMPLEX) {
t->flags &= ~FLAG_COMPLEX; // remove temporary flag
}
}
out = &outs["Object"];
out->append(
w.gen_output_begin(get_additional_imports(object_types, "common", file_name_prefix, file_name_suffix, w)));
write_base_object_classes(config, *out, request_types, result_types, w);
out->append(w.gen_output_end());
out = &outs["Function"];
out->append(
w.gen_output_begin(get_additional_imports(function_types, "common", file_name_prefix, file_name_suffix, w)));
write_base_function_class(config, *out, request_types, result_types, w);
out->append(w.gen_output_end());
std::string additional_main_imports;
for (std::map<std::string, tl_string_outputer>::const_iterator it = outs.begin(); it != outs.end(); ++it) {
std::string file_name = file_name_prefix + "_" + it->first + file_name_suffix;
if (!put_file_contents(file_name, it->second.get_result(), w.is_documentation_generated())) {
return false;
}
if (file_name_suffix == w.gen_package_suffix()) {
additional_main_imports += w.gen_import_declaration(file_name, false);
}
}
if (!additional_main_imports.empty()) {
additional_main_imports += "\n";
}
tl_string_outputer main_out;
main_out.append(w.gen_output_begin(additional_main_imports));
main_out.append(w.gen_output_end());
return put_file_contents(file_name_prefix + file_name_suffix, main_out.get_result(), w.is_documentation_generated());
}
} // namespace tl
} // namespace td

View File

@ -21,5 +21,8 @@ tl_config read_tl_config_from_file(const std::string &file_name);
bool write_tl_to_file(const tl_config &config, const std::string &file_name, const TL_writer &w);
bool write_tl_to_multiple_files(const tl_config &config, const std::string &file_name_prefix,
const std::string &file_name_suffix, const TL_writer &w);
} // namespace tl
} // namespace td

View File

@ -88,6 +88,7 @@ class TL_writer {
virtual std::string gen_output_end() const = 0;
virtual std::string gen_import_declaration(const std::string &name, bool is_system) const = 0;
virtual std::string gen_package_suffix() const = 0;
virtual std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const = 0;