From 7d29dc4cc0bc9ad12f698d373915045ae1d723f2 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Tue, 4 May 2021 22:59:25 +0200 Subject: [PATCH] THRIFT-5408 Support for deprecated/obsolete methods (via annotation) Client: netstd Patch: Jens Geyer --- .../src/thrift/generate/t_netstd_generator.cc | 43 +++++++++++++++++++ .../src/thrift/generate/t_netstd_generator.h | 1 + .../optional_required_default.thrift | 8 ++++ 3 files changed, 52 insertions(+) diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc index 766d2b62fd9..fd218f8f88f 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc @@ -1943,6 +1943,16 @@ void t_netstd_generator::generate_service_interface(ostream& out, t_service* tse } } + auto iter = (*f_iter)->annotations_.find("deprecated"); + if( (*f_iter)->annotations_.end() != iter) { + out << indent() << "[Obsolete"; + // empty annotation values end up with "1" somewhere, ignore these as well + if ((iter->second.length() > 0) && (iter->second != "1")) { + out << "(" << make_csharp_string_literal(iter->second) << ")"; + } + out << "]" << endl; + } + out << indent() << function_signature_async(*f_iter) << ";" << endl << endl; } indent_down(); @@ -2312,6 +2322,11 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service const vector& fields = arg_struct->get_members(); vector::const_iterator f_iter; + bool is_deprecated = (tfunction->annotations_.end() != tfunction->annotations_.find("deprecated")); + if( is_deprecated) { + out << indent() << "#pragma warning disable CS0618,CS0612" << endl; + } + out << indent(); if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { @@ -2346,6 +2361,10 @@ void t_netstd_generator::generate_process_function_async(ostream& out, t_service out << "cancellationToken);" << endl; + if( is_deprecated) { + out << indent() << "#pragma warning restore CS0618,CS0612" << endl; + } + vector::const_iterator x_iter; collect_extensions_types(xs); @@ -2947,6 +2966,30 @@ void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, out << endl; } +string t_netstd_generator::make_csharp_string_literal( string const& value) +{ + if (value.length() == 0) { + return ""; + } + + std::stringstream result; + result << "\""; + for (signed char const c: value) { + if( (c >= 0) && (c < 32)) { // convert ctrl chars, but leave UTF-8 alone + int width = std::max( (int)sizeof(c), 4); + result << "\\x" << std::hex << std::setw(width) << std::setfill('0') << (int)c; + } else if ((c == '\\') || (c == '"')) { + result << "\\" << c; + } else { + result << c; // anything else "as is" + } + } + result << "\""; + + return result.str(); +} + + string t_netstd_generator::make_valid_csharp_identifier(string const& fromName) { string str = fromName; diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h index 8a812a35321..b35550db774 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.h +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h @@ -165,6 +165,7 @@ class t_netstd_generator : public t_oop_generator void init_keywords(); string normalize_name(string name); string make_valid_csharp_identifier(string const& fromName); + string make_csharp_string_literal( string const& value); void prepare_member_name_mapping(t_service* tservice); void prepare_member_name_mapping(t_struct* tstruct); void prepare_member_name_mapping(t_struct* scope, const vector& members, const string& structname); diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift index 1f6c7ee5ead..4a38205dcc7 100644 --- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift +++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift @@ -141,3 +141,11 @@ service foobar { set>> DoItNow( 1 : list>> rd, 2: i32 mitDefault = 42) throws (1: CrashBoomBang cbb) } +service deprecate_everything { + void Foo( ) ( deprecated = "This method has neither 'x' nor \"y\"" ) + void Bar( ) ( deprecated = "Fails to deliver 中文 колбаса" ) + void Baz( ) ( deprecated = "Need this to work with tabs (\t) or Umlauts (äöüÄÖÜß) too" ) + void Deprecated() ( deprecated ) // no comment +} + +