You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by je...@apache.org on 2020/08/05 09:55:52 UTC

[thrift] branch master updated: THRIFT-5261 Support for deprecated methods (via annotation) Client: Delphi Patch: Jens Geyer

This is an automated email from the ASF dual-hosted git repository.

jensg pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/thrift.git


The following commit(s) were added to refs/heads/master by this push:
     new 68c1506  THRIFT-5261 Support for deprecated methods (via annotation) Client: Delphi Patch: Jens Geyer
68c1506 is described below

commit 68c1506715d834c5ab274a622a67bab207936ac7
Author: Jens Geyer <je...@apache.org>
AuthorDate: Tue Aug 4 23:09:14 2020 +0200

    THRIFT-5261 Support for deprecated methods (via annotation)
    Client: Delphi
    Patch: Jens Geyer
    
    This closes #2213
---
 .../cpp/src/thrift/generate/t_delphi_generator.cc  | 65 ++++++++++++++++++----
 lib/delphi/test/keywords/ReservedIncluded.thrift   |  7 +++
 lib/delphi/test/keywords/ReservedKeywords.dpr      |  2 +-
 lib/delphi/test/keywords/ReservedKeywords.dproj    |  4 +-
 lib/delphi/test/keywords/ReservedKeywords.thrift   |  4 ++
 test/AnnotationTest.thrift                         |  8 +++
 6 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 4ffdc82..d3ad76a 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -330,6 +330,7 @@ public:
                               std::string prefix,
                               bool b_no_check_keyword = false);
   std::string make_valid_delphi_identifier(std::string const& fromName);
+  std::string make_pascal_string_literal( std::string value);
   std::string input_arg_prefix(t_type* ttype);
 
   std::string base_type_name(t_base_type* tbase);
@@ -802,6 +803,7 @@ void t_delphi_generator::close_generator() {
   f_all << autogen_comment() << endl;
   generate_delphi_doc(f_all, program_);
   f_all << "unit " << unitname << ";" << endl << endl;
+  f_all << "{$WARN SYMBOL_DEPRECATED OFF}" << endl << endl;
   f_all << "interface" << endl << endl;
   f_all << "uses" << endl;
 
@@ -1052,6 +1054,28 @@ void t_delphi_generator::generate_enum(t_enum* tenum) {
   indent_down();
 }
 
+std::string t_delphi_generator::make_pascal_string_literal(std::string value) {
+  std::stringstream result;
+
+  if (value.length() == 0) {
+    return "";
+  }
+
+  result << "'";
+  for (char const &c: value) {
+    if( (c >= 0) && (c < 32)) {  // convert ctrl chars, but leave UTF-8 alone
+      result << "#" << (int)c;  
+    } else if (c == '\'') {
+      result << "''";   // duplicate any single quotes we find
+    } else {
+      result << c;   // anything else "as is"
+    }
+  }
+  result << "'";
+  
+  return result.str();
+}
+
 std::string t_delphi_generator::make_valid_delphi_identifier(std::string const& fromName) {
   std::string str = fromName;
   if (str.empty()) {
@@ -1959,10 +1983,10 @@ void t_delphi_generator::generate_service_interface(t_service* tservice, bool fo
 }
 
 void t_delphi_generator::generate_guid(std::ostream& out) {
-#ifdef _WIN32	// TODO: add support for non-windows platforms if needed
+#ifdef _WIN32   // TODO: add support for non-windows platforms if needed
   GUID guid;
   if (SUCCEEDED(CoCreateGuid(&guid))) {
-	OLECHAR guid_chars[40];
+    OLECHAR guid_chars[40];
     if (StringFromGUID2(guid, &guid_chars[0], sizeof(guid_chars) / sizeof(guid_chars[0])) > 0) {
       std::wstring guid_wstr(guid_chars);
       std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
@@ -3261,25 +3285,42 @@ string t_delphi_generator::function_signature(t_function* tfunction,
     prefix = full_cls + ".";
   }
 
+  string signature = "";
+  
   if( for_async) {
     if (is_void(ttype)) {
-      return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async("
-             + argument_list(tfunction->get_arglist()) + "): IFuture<Integer>;";  // no IFuture<void> in Delphi
+      signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async("
+                + argument_list(tfunction->get_arglist()) + "): IFuture<Integer>;";  // no IFuture<void> in Delphi
     } else {
-      return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async("
-             + argument_list(tfunction->get_arglist()) + "): IFuture<"
-             + type_name(ttype, false, true, is_xception, true) + ">;";
+      signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "Async("
+                + argument_list(tfunction->get_arglist()) + "): IFuture<"
+                + type_name(ttype, false, true, is_xception, true) + ">;";
     }
   } else {
     if (is_void(ttype)) {
-      return "procedure " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
-             + argument_list(tfunction->get_arglist()) + ");";
+      signature = "procedure " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
+                + argument_list(tfunction->get_arglist()) + ");";
     } else {
-      return "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
-             + argument_list(tfunction->get_arglist()) + "): "
-             + type_name(ttype, false, true, is_xception, true) + ";";
+      signature = "function " + prefix + normalize_name(tfunction->get_name(), true, is_xception) + "("
+                + argument_list(tfunction->get_arglist()) + "): "
+                + type_name(ttype, false, true, is_xception, true) + ";";
+    }
+  }
+
+  // deprecated method? only at intf decl!
+  if( full_cls == "") {
+    auto iter = tfunction->annotations_.find("deprecated");
+    if( tfunction->annotations_.end() != iter) {
+      signature += " deprecated";
+      // empty annotation values end up with "1" somewhere, ignore these as well
+      if ((iter->second.length() > 0) && (iter->second != "1")) {
+        signature += " " + make_pascal_string_literal(iter->second);
+      }
+      signature += ";";
     }
   }
+
+  return signature;
 }
 
 string t_delphi_generator::argument_list(t_struct* tstruct) {
diff --git a/lib/delphi/test/keywords/ReservedIncluded.thrift b/lib/delphi/test/keywords/ReservedIncluded.thrift
index 8b47a50..1d94dd9 100644
--- a/lib/delphi/test/keywords/ReservedIncluded.thrift
+++ b/lib/delphi/test/keywords/ReservedIncluded.thrift
@@ -22,4 +22,11 @@ namespace delphi SysUtils
 
 const i32 integer = 42
 
+service deprecate_included_inner {
+  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
+}
+
 // EOF
diff --git a/lib/delphi/test/keywords/ReservedKeywords.dpr b/lib/delphi/test/keywords/ReservedKeywords.dpr
index 1fbc8c1..3742b19 100644
--- a/lib/delphi/test/keywords/ReservedKeywords.dpr
+++ b/lib/delphi/test/keywords/ReservedKeywords.dpr
@@ -3,7 +3,7 @@ program ReservedKeywords;
 {$APPTYPE CONSOLE}
 
 uses
-  SysUtils, System_;
+  SysUtils, System_, AnnotationTest;
 
 begin
   try
diff --git a/lib/delphi/test/keywords/ReservedKeywords.dproj b/lib/delphi/test/keywords/ReservedKeywords.dproj
index 6bd9544..cc36988 100644
--- a/lib/delphi/test/keywords/ReservedKeywords.dproj
+++ b/lib/delphi/test/keywords/ReservedKeywords.dproj
@@ -65,7 +65,9 @@
 		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
 		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
 		<PropertyGroup>
-			<PreBuildEvent><![CDATA[thrift -r  -gen delphi ReservedKeywords.thrift]]></PreBuildEvent>
+			<PreBuildEvent><![CDATA[if exist gen-delphi del gen-delphi\* /s /q
+thrift -r  -gen delphi ReservedKeywords.thrift
+thrift -r  -gen delphi ..\..\..\..\test\AnnotationTest.thrift]]></PreBuildEvent>
 		</PropertyGroup>
 		<ProjectExtensions>
 			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
diff --git a/lib/delphi/test/keywords/ReservedKeywords.thrift b/lib/delphi/test/keywords/ReservedKeywords.thrift
index 2f49d74..08a4d75 100644
--- a/lib/delphi/test/keywords/ReservedKeywords.thrift
+++ b/lib/delphi/test/keywords/ReservedKeywords.thrift
@@ -134,5 +134,9 @@ struct Thrift4554_Struct {
   4 : optional Thrift4554_Enum Foo
 }
 
+service deprecate_included_outer extends ReservedIncluded.deprecate_included_inner {
+  void FooBarBaz()
+}
+
 
 // EOF
diff --git a/test/AnnotationTest.thrift b/test/AnnotationTest.thrift
index 7e24e1c..9258322 100644
--- a/test/AnnotationTest.thrift
+++ b/test/AnnotationTest.thrift
@@ -70,3 +70,11 @@ service foo_service {
   void foo() ( foo = "bar" )
 } (a.b="c")
 
+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
+}
+
+