THRIFT-5703 Haxe 4.30 emits "Local variable retval used without being initialized" on generated code
Client: hx
Patch: Jens Geyer
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index ee65591..166f78e 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -201,6 +201,7 @@
   std::string type_name(t_type* ttype, bool in_container = false, bool in_init = false);
   std::string base_type_name(t_base_type* tbase, bool in_container = false);
   std::string declare_field(t_field* tfield, bool init = false);
+  std::string render_default_value_for_type(t_type* type, bool allow_null);
   std::string function_signature_combined(t_function* tfunction);
   std::string function_signature_normal(t_function* tfunction);
   std::string argument_list(t_struct* tstruct);
@@ -1878,8 +1879,9 @@
 
     string retval = tmp("retval");
     if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) {
-      f_service_ << indent() << "var " << retval << " : " << type_name((*f_iter)->get_returntype()) << ";"
-                 << endl;
+      f_service_ << indent() << "var " << retval << " : " << type_name((*f_iter)->get_returntype())
+                 << " = " << render_default_value_for_type((*f_iter)->get_returntype(),true) 
+                 << ";" << endl;
     }
 
     if ((*f_iter)->is_oneway()) {
@@ -2736,50 +2738,51 @@
  * @param ttype The type
  */
 string t_haxe_generator::declare_field(t_field* tfield, bool init) {
-  // TODO(mcslee): do we ever need to initialize the field?
   string result = "var " + tfield->get_name() + " : " + type_name(tfield->get_type());
   if (init) {
     t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != nullptr) {
       result += " = " + render_const_value_str( ttype, tfield->get_value());
-    } else if (ttype->is_base_type()) {
-      t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
-      switch (tbase) {
-      case t_base_type::TYPE_VOID:
-        throw "NO T_VOID CONSTRUCT";
-      case t_base_type::TYPE_STRING:
-        result += " = null";
-        break;
-      case t_base_type::TYPE_UUID:
-        result += " = uuid.Uuid.NIL";
-        break;
-      case t_base_type::TYPE_BOOL:
-        result += " = false";
-        break;
-      case t_base_type::TYPE_I8:
-      case t_base_type::TYPE_I16:
-      case t_base_type::TYPE_I32:
-      case t_base_type::TYPE_I64:
-        result += " = 0";
-        break;
-      case t_base_type::TYPE_DOUBLE:
-        result += " = (double)0";
-        break;
-      default:
-        throw "unhandled type";
-      }
-
-    } else if (ttype->is_enum()) {
-      result += " = 0";
-    } else if (ttype->is_container()) {
-      result += " = new " + type_name(ttype, false, true) + "()";
     } else {
-      result += " = new " + type_name(ttype, false, true) + "()";
+      result += " = " + render_default_value_for_type( ttype, false);
     }
   }
   return result + ";";
 }
 
+string t_haxe_generator::render_default_value_for_type( t_type* type, bool allow_null) {
+  t_type* ttype = get_true_type(type);
+
+  if (ttype->is_base_type()) {
+    t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
+    switch (tbase) {
+    case t_base_type::TYPE_VOID:
+      throw "NO T_VOID CONSTRUCT";
+    case t_base_type::TYPE_STRING:
+      return "null";
+    case t_base_type::TYPE_UUID:
+      return "uuid.Uuid.NIL";
+    case t_base_type::TYPE_BOOL:
+      return "false";
+    case t_base_type::TYPE_I8:
+    case t_base_type::TYPE_I16:
+    case t_base_type::TYPE_I32:
+    case t_base_type::TYPE_I64:
+      return "0";
+    case t_base_type::TYPE_DOUBLE:
+      return "0.0";
+    default:
+      throw "unhandled type";
+    }
+  } else if (ttype->is_enum()) {
+    return "0";
+  } else if (ttype->is_container()) {
+    return allow_null ? "null" : "new " + type_name(ttype, false, true) + "()";
+  } else {
+    return allow_null ? "null" : "new " + type_name(ttype, false, true) + "()";
+  }
+}
+
 /**
  * Renders a function signature of the form 'type name(args)'
  *