From 48a93aadb9f807c8b485ffa66b1f936fa213e6f9 Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Mon, 14 Mar 2022 14:29:17 +0100 Subject: [PATCH] Support function generic result type (#1809) Fixes #1708 --- td/generate/DotnetTlDocumentationGenerator.php | 2 +- td/generate/DoxygenTlDocumentationGenerator.php | 2 +- td/generate/JavadocTlDocumentationGenerator.php | 8 ++++---- td/generate/TlDocumentationGenerator.php | 8 +++++--- td/generate/tl_writer_c.h | 2 +- td/generate/tl_writer_cpp.cpp | 2 +- td/generate/tl_writer_cpp.h | 2 +- td/generate/tl_writer_dotnet.h | 2 +- td/generate/tl_writer_h.cpp | 2 +- td/generate/tl_writer_h.h | 2 +- td/generate/tl_writer_hpp.cpp | 2 +- td/generate/tl_writer_hpp.h | 2 +- td/generate/tl_writer_java.cpp | 16 +++++++++++++++- td/generate/tl_writer_java.h | 2 +- td/generate/tl_writer_jni_cpp.cpp | 2 +- td/generate/tl_writer_jni_cpp.h | 2 +- td/generate/tl_writer_jni_h.cpp | 2 +- td/generate/tl_writer_jni_h.h | 2 +- tdtl/td/tl/tl_generate.cpp | 10 +++++----- tdtl/td/tl/tl_writer.h | 2 +- 20 files changed, 45 insertions(+), 29 deletions(-) diff --git a/td/generate/DotnetTlDocumentationGenerator.php b/td/generate/DotnetTlDocumentationGenerator.php index 674cbe13a..da792b362 100644 --- a/td/generate/DotnetTlDocumentationGenerator.php +++ b/td/generate/DotnetTlDocumentationGenerator.php @@ -164,7 +164,7 @@ EOT return "\r\n$shift/// Returns .'; } - protected function addClassDocumentation($class_name, $base_class_name, $description) + protected function addClassDocumentation($class_name, $base_class_name, $return_type, $description) { $this->addDocumentation("public ref class $class_name sealed : $base_class_name {", << diff --git a/td/generate/DoxygenTlDocumentationGenerator.php b/td/generate/DoxygenTlDocumentationGenerator.php index 5acffadf9..dc89536b2 100644 --- a/td/generate/DoxygenTlDocumentationGenerator.php +++ b/td/generate/DoxygenTlDocumentationGenerator.php @@ -389,7 +389,7 @@ EOT return PHP_EOL.$shift.'*'.PHP_EOL.$shift."* Returns $return_type."; } - protected function addClassDocumentation($class_name, $base_class_name, $description) + protected function addClassDocumentation($class_name, $base_class_name, $return_type, $description) { $this->addDocumentation("class $class_name final : public $base_class_name {", << 0) { - return explode(' ', trim($line))[3]; + return preg_split('/( |<|>)/', trim($line))[3]; } return ''; } @@ -157,7 +157,7 @@ EOT EOT ); - $this->addDocumentation(' public abstract static class Function extends Object {', <<addDocumentation(' public abstract static class Function extends Object {', << Returns {@link $return_type $return_type}

"; } - protected function addClassDocumentation($class_name, $base_class_name, $description) + protected function addClassDocumentation($class_name, $base_class_name, $return_type, $description) { - $this->addDocumentation(" public static class $class_name extends $base_class_name {", <<addDocumentation(" public static class $class_name extends ".$base_class_name.(empty($return_type) ? "" : "<".$return_type.">")." {", <<getBaseClassName($is_function); $class_description = $description; + $return_type = ""; if ($is_function) { - $class_description .= $this->getFunctionReturnTypeDescription($this->getTypeName($type), false); + $return_type = $this->getTypeName($type); + $class_description .= $this->getFunctionReturnTypeDescription($return_type, false); } - $this->addClassDocumentation($class_name, $base_class_name, $class_description); + $this->addClassDocumentation($class_name, $base_class_name, $return_type, $class_description); foreach ($known_fields as $name => $field_type) { $may_be_null = stripos($info[$name], 'may be null') !== false; diff --git a/td/generate/tl_writer_c.h b/td/generate/tl_writer_c.h index 37d916ae7..d252e0792 100644 --- a/td/generate/tl_writer_c.h +++ b/td/generate/tl_writer_c.h @@ -303,7 +303,7 @@ class TlWriterCCommon final : public tl::TL_writer { } std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const final { + bool is_proxy, const tl::tl_tree *result) const final { if (is_header_ != 1 || class_name == "") { return ""; } diff --git a/td/generate/tl_writer_cpp.cpp b/td/generate/tl_writer_cpp.cpp index 4a1cd652f..9fae767d3 100644 --- a/td/generate/tl_writer_cpp.cpp +++ b/td/generate/tl_writer_cpp.cpp @@ -493,7 +493,7 @@ std::string TD_TL_writer_cpp::gen_forward_class_declaration(const std::string &c } std::string TD_TL_writer_cpp::gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const { + bool is_proxy, const tl::tl_tree *result) const { return ""; } diff --git a/td/generate/tl_writer_cpp.h b/td/generate/tl_writer_cpp.h index 79856c94c..5785af33d 100644 --- a/td/generate/tl_writer_cpp.h +++ b/td/generate/tl_writer_cpp.h @@ -47,7 +47,7 @@ class TD_TL_writer_cpp : public TD_TL_writer { std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const override; std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const override; + bool is_proxy, const tl::tl_tree *result) const override; std::string gen_class_end() const override; std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const override; diff --git a/td/generate/tl_writer_dotnet.h b/td/generate/tl_writer_dotnet.h index 4e33f2241..1c333f9bd 100644 --- a/td/generate/tl_writer_dotnet.h +++ b/td/generate/tl_writer_dotnet.h @@ -201,7 +201,7 @@ class TlWriterDotNet final : public TL_writer { } std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const final { + bool is_proxy, const tl::tl_tree *result) const final { if (!is_header_) { return ""; } diff --git a/td/generate/tl_writer_h.cpp b/td/generate/tl_writer_h.cpp index 76321d3fa..a7209abc0 100644 --- a/td/generate/tl_writer_h.cpp +++ b/td/generate/tl_writer_h.cpp @@ -255,7 +255,7 @@ std::string TD_TL_writer_h::gen_forward_class_declaration(const std::string &cla } std::string TD_TL_writer_h::gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const { + bool is_proxy, const tl::tl_tree *result) const { return "class " + class_name + (!is_proxy ? " final " : "") + ": public " + base_class_name + " {\n" " public:\n"; diff --git a/td/generate/tl_writer_h.h b/td/generate/tl_writer_h.h index 9f5e77dba..b781b7593 100644 --- a/td/generate/tl_writer_h.h +++ b/td/generate/tl_writer_h.h @@ -34,7 +34,7 @@ class TD_TL_writer_h : public TD_TL_writer { std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const override; std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const override; + bool is_proxy, const tl::tl_tree *result) const override; std::string gen_class_end() const override; std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const override; diff --git a/td/generate/tl_writer_hpp.cpp b/td/generate/tl_writer_hpp.cpp index db3ab755a..56dc0e842 100644 --- a/td/generate/tl_writer_hpp.cpp +++ b/td/generate/tl_writer_hpp.cpp @@ -117,7 +117,7 @@ std::string TD_TL_writer_hpp::gen_forward_class_declaration(const std::string &c } std::string TD_TL_writer_hpp::gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const { + bool is_proxy, const tl::tl_tree *result) const { return ""; } diff --git a/td/generate/tl_writer_hpp.h b/td/generate/tl_writer_hpp.h index c7243799a..d22de001e 100644 --- a/td/generate/tl_writer_hpp.h +++ b/td/generate/tl_writer_hpp.h @@ -34,7 +34,7 @@ class TD_TL_writer_hpp final : public TD_TL_writer { 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) const final; + bool is_proxy, const tl::tl_tree *result) const final; std::string gen_class_end() const final; std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const final; diff --git a/td/generate/tl_writer_java.cpp b/td/generate/tl_writer_java.cpp index f14fdc112..e2dba8abb 100644 --- a/td/generate/tl_writer_java.cpp +++ b/td/generate/tl_writer_java.cpp @@ -206,11 +206,25 @@ std::string TD_TL_writer_java::gen_forward_class_declaration(const std::string & } std::string TD_TL_writer_java::gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const { + bool is_proxy, const tl::tl_tree *result_tl) const { std::string full_class_name = "static class " + class_name; + if (class_name == "Function") { + full_class_name += ""; + } if (class_name != gen_base_tl_class_name()) { full_class_name += " extends " + base_class_name; } + if (result_tl != nullptr && base_class_name == "Function") { + assert(result_tl->get_type() == tl::NODE_TYPE_TYPE); + const tl::tl_tree_type *result_type = static_cast(result_tl); + std::string fetched_type = gen_type_name(result_type); + + if (!fetched_type.empty() && fetched_type[fetched_type.size() - 1] == ' ') { + fetched_type.pop_back(); + } + + full_class_name += "<" + fetched_type + ">"; + } std::string result = " public " + std::string(is_proxy ? "abstract " : "") + full_class_name + " {\n"; if (class_name == gen_base_tl_class_name() || class_name == gen_base_function_class_name()) { result += " public native String toString();\n"; diff --git a/td/generate/tl_writer_java.h b/td/generate/tl_writer_java.h index 40b6ba9e0..7b9065c5d 100644 --- a/td/generate/tl_writer_java.h +++ b/td/generate/tl_writer_java.h @@ -59,7 +59,7 @@ class TD_TL_writer_java final : public tl::TL_writer { 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) const final; + bool is_proxy, const tl::tl_tree *result) const final; std::string gen_class_end() const final; std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const final; diff --git a/td/generate/tl_writer_jni_cpp.cpp b/td/generate/tl_writer_jni_cpp.cpp index 2ef272e0e..18e6ace21 100644 --- a/td/generate/tl_writer_jni_cpp.cpp +++ b/td/generate/tl_writer_jni_cpp.cpp @@ -57,7 +57,7 @@ std::string TD_TL_writer_jni_cpp::gen_base_tl_class_name() const { } std::string TD_TL_writer_jni_cpp::gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const { + bool is_proxy, const tl::tl_tree *result) const { return "\n" "jclass " + class_name + "::Class;\n"; diff --git a/td/generate/tl_writer_jni_cpp.h b/td/generate/tl_writer_jni_cpp.h index e25fd29bc..65518995f 100644 --- a/td/generate/tl_writer_jni_cpp.h +++ b/td/generate/tl_writer_jni_cpp.h @@ -55,7 +55,7 @@ class TD_TL_writer_jni_cpp final : public TD_TL_writer_cpp { std::string gen_base_tl_class_name() const final; std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const final; + bool is_proxy, const tl::tl_tree *result) const final; std::string gen_field_definition(const std::string &class_name, const std::string &type_name, const std::string &field_name) const final; diff --git a/td/generate/tl_writer_jni_h.cpp b/td/generate/tl_writer_jni_h.cpp index 288b5516a..0f860a2ee 100644 --- a/td/generate/tl_writer_jni_h.cpp +++ b/td/generate/tl_writer_jni_h.cpp @@ -126,7 +126,7 @@ std::string TD_TL_writer_jni_h::gen_output_begin() const { } std::string TD_TL_writer_jni_h::gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const { + bool is_proxy, const tl::tl_tree *result) const { if (class_name == gen_base_tl_class_name()) { return "class " + class_name + " {\n" diff --git a/td/generate/tl_writer_jni_h.h b/td/generate/tl_writer_jni_h.h index 335622a80..c5369aa5d 100644 --- a/td/generate/tl_writer_jni_h.h +++ b/td/generate/tl_writer_jni_h.h @@ -35,7 +35,7 @@ class TD_TL_writer_jni_h final : public TD_TL_writer_h { std::string gen_output_begin() const final; std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const final; + bool is_proxy, const tl::tl_tree *result) const final; std::string gen_field_definition(const std::string &class_name, const std::string &type_name, const std::string &field_name) const final; diff --git a/tdtl/td/tl/tl_generate.cpp b/tdtl/td/tl/tl_generate.cpp index 015c09a49..d2d7528ea 100644 --- a/tdtl/td/tl/tl_generate.cpp +++ b/tdtl/td/tl/tl_generate.cpp @@ -245,7 +245,7 @@ static void write_function(tl_outputer &out, const tl_combinator *t, const std:: std::string class_name = w.gen_class_name(t->name); - out.append(w.gen_class_begin(class_name, w.gen_base_function_class_name(), false)); + out.append(w.gen_class_begin(class_name, w.gen_base_function_class_name(), false, t->result)); int required_args = gen_field_definitions(out, t, class_name, w); out.append(w.gen_flags_definitions(t, true)); @@ -302,7 +302,7 @@ static void write_constructor(tl_outputer &out, const tl_combinator *t, const st std::string class_name = w.gen_class_name(t->name); - out.append(w.gen_class_begin(class_name, base_class, is_proxy)); + out.append(w.gen_class_begin(class_name, base_class, is_proxy, t->result)); int required_args = gen_field_definitions(out, t, class_name, w); bool can_be_parsed = false; @@ -386,7 +386,7 @@ void write_class(tl_outputer &out, const tl_type *t, const std::set std::vector empty_vars; bool optimize_one_constructor = (t->simple_constructors == 1); if (!optimize_one_constructor) { - out.append(w.gen_class_begin(class_name, base_class, true)); + out.append(w.gen_class_begin(class_name, base_class, true, nullptr)); out.append(w.gen_get_id(class_name, 0, true)); @@ -648,7 +648,7 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { // write base classes std::vector empty_vars; for (int i = 0; i <= w.get_max_arity(); i++) { - out.append(w.gen_class_begin(w.gen_base_type_class_name(i), w.gen_base_tl_class_name(), true)); + out.append(w.gen_class_begin(w.gen_base_type_class_name(i), w.gen_base_tl_class_name(), true, nullptr)); out.append(w.gen_get_id(w.gen_base_type_class_name(i), 0, true)); @@ -742,7 +742,7 @@ void write_tl(const tl_config &config, tl_outputer &out, const TL_writer &w) { } { - out.append(w.gen_class_begin(w.gen_base_function_class_name(), w.gen_base_tl_class_name(), true)); + out.append(w.gen_class_begin(w.gen_base_function_class_name(), w.gen_base_tl_class_name(), true, nullptr)); out.append(w.gen_get_id(w.gen_base_function_class_name(), 0, true)); diff --git a/tdtl/td/tl/tl_writer.h b/tdtl/td/tl/tl_writer.h index ef99eddc1..e074bb26b 100644 --- a/tdtl/td/tl/tl_writer.h +++ b/tdtl/td/tl/tl_writer.h @@ -89,7 +89,7 @@ class TL_writer { virtual std::string gen_forward_class_declaration(const std::string &class_name, bool is_proxy) const = 0; virtual std::string gen_class_begin(const std::string &class_name, const std::string &base_class_name, - bool is_proxy) const = 0; + bool is_proxy, const tl_tree *result) const = 0; virtual std::string gen_class_end() const = 0; virtual std::string gen_class_alias(const std::string &class_name, const std::string &alias_name) const = 0;