Thrift: Make use of get_true_type.

Summary:
We added a helper function for the generators: get_true_type,
which finds the actual type behind a series of typedefs
(though the compiler only supports one layer of typedefs now).
This change uses it everywhere we used to have that loop.
(It was a lot of places.)

Reviewed By: mcslee

Test Plan: test/ManyTypedefs.thrift

Revert Plan: ok


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665220 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index 8af32e2..796c9e0 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -412,10 +412,8 @@
     // TODO(dreiss): When everything else in Thrift is perfect,
     // do more of these in the initializer list.
     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-      t_type* t = (*m_iter)->get_type();
-      while (t->is_typedef()) {
-        t = ((t_typedef*)t)->get_type();
-      }
+      t_type* t = get_true_type((*m_iter)->get_type());
+
       if (!t->is_base_type()) {
         t_const_value* cv = (*m_iter)->get_value();
         if (cv != NULL) {
@@ -1767,10 +1765,7 @@
                                                  t_field* tfield,
                                                  string prefix,
                                                  string suffix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
@@ -1970,10 +1965,7 @@
                                                t_field* tfield,
                                                string prefix,
                                                string suffix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   string name = prefix + tfield->get_name() + suffix;
 
@@ -2327,10 +2319,7 @@
   }
   result += " " + tfield->get_name();
   if (init) {
-    t_type* type = tfield->get_type();
-    while (type->is_typedef()) {
-      type = ((t_typedef*)type)->get_type();
-    }
+    t_type* type = get_true_type(tfield->get_type());
 
     if (type->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
@@ -2416,9 +2405,7 @@
  * @return String of C++ code to definition of that type constant
  */
 string t_cpp_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h
index 858dd22..acc75f6 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.h
+++ b/compiler/cpp/src/generate/t_cpp_generator.h
@@ -143,9 +143,7 @@
   std::string type_to_enum(t_type* ttype);
 
   bool is_complex_type(t_type* ttype) {
-    while (ttype->is_typedef()) {
-      ttype = ((t_typedef*)ttype)->get_type();
-    }
+    ttype = get_true_type(ttype);
 
     return
       ttype->is_container() || 
diff --git a/compiler/cpp/src/generate/t_erl_generator.cc b/compiler/cpp/src/generate/t_erl_generator.cc
index 1b3e7cf..36a37a6 100644
--- a/compiler/cpp/src/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/generate/t_erl_generator.cc
@@ -1059,10 +1059,7 @@
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool inclass) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
@@ -1268,10 +1265,7 @@
 void t_erl_generator::generate_serialize_field(ostream &out, 
                                                t_field* tfield,
                                                string prefix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1454,10 +1448,7 @@
  */
 string t_erl_generator::declare_field(t_field* tfield) {  // TODO
   string result = "@" + tfield->get_name();
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
   if (tfield->get_value() != NULL) {
     result += " = " + render_const_value(type, tfield->get_value());
   } else {
@@ -1562,9 +1553,7 @@
  * Converts the parse type to a Erlang "type" (macro for int constants)
  */
 string t_erl_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_hs_generator.cc b/compiler/cpp/src/generate/t_hs_generator.cc
index c46d70d..614ebe7 100644
--- a/compiler/cpp/src/generate/t_hs_generator.cc
+++ b/compiler/cpp/src/generate/t_hs_generator.cc
@@ -961,9 +961,7 @@
  */
 void t_hs_generator::generate_deserialize_type(ofstream &out,
                                                    t_type* type){
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE";
@@ -1071,10 +1069,7 @@
 void t_hs_generator::generate_serialize_field(ofstream &out,
                                                  t_field* tfield,
                                                  string name) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1257,9 +1252,7 @@
  * Converts the parse type to a Protocol.t_type enum
  */
 string t_hs_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
@@ -1300,9 +1293,7 @@
  * Converts the parse type to an haskell type
  */
 string t_hs_generator::render_hs_type(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
index fdd7202..d4d8fbf 100644
--- a/compiler/cpp/src/generate/t_java_generator.cc
+++ b/compiler/cpp/src/generate/t_java_generator.cc
@@ -392,10 +392,7 @@
     "public " << tstruct->get_name() << "() {" << endl;
   indent_up();
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-    t_type* t = (*m_iter)->get_type();
-    while (t->is_typedef()) {
-      t = ((t_typedef*)t)->get_type();
-    }
+    t_type* t = get_true_type((*m_iter)->get_type());
     if (!t->is_base_type() && (*m_iter)->get_value() != NULL) {
       print_const_value(out, "this." + (*m_iter)->get_name(), t, (*m_iter)->get_value(), true, true);
     }
@@ -1195,10 +1192,7 @@
 void t_java_generator::generate_deserialize_field(ofstream& out,
                                                   t_field* tfield,
                                                   string prefix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
@@ -1411,10 +1405,7 @@
 void t_java_generator::generate_serialize_field(ofstream& out,
                                                 t_field* tfield,
                                                 string prefix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1614,9 +1605,7 @@
  */
 string t_java_generator::type_name(t_type* ttype, bool in_container, bool in_init) {
   // In Java typedefs are just resolved to their real type
-  while (ttype->is_typedef()) {
-    ttype = ((t_typedef*)ttype)->get_type();
-  }
+  ttype = get_true_type(ttype);
 
   if (ttype->is_base_type()) {
     return base_type_name((t_base_type*)ttype, in_container);
@@ -1698,10 +1687,7 @@
   // TODO(mcslee): do we ever need to initialize the field?
   string result = type_name(tfield->get_type()) + " " + tfield->get_name();
   if (init) {
-    t_type* ttype = tfield->get_type();
-    while (ttype->is_typedef()) {
-      ttype = ((t_typedef*)ttype)->get_type();
-    }
+    t_type* ttype = get_true_type(tfield->get_type());
     if (ttype->is_base_type() && tfield->get_value() != NULL) {
       ofstream dummy;
       result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
@@ -1783,9 +1769,7 @@
  * Converts the parse type to a C++ enum string for the given type.
  */
 string t_java_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_java_generator.h b/compiler/cpp/src/generate/t_java_generator.h
index 7266b39..9509d09 100644
--- a/compiler/cpp/src/generate/t_java_generator.h
+++ b/compiler/cpp/src/generate/t_java_generator.h
@@ -137,9 +137,7 @@
   std::string type_to_enum(t_type* ttype);
 
   bool type_can_be_null(t_type* ttype) {
-    while (ttype->is_typedef()) {
-      ttype = ((t_typedef*)ttype)->get_type();
-    }
+    ttype = get_true_type(ttype);
 
     return
       ttype->is_container() || 
diff --git a/compiler/cpp/src/generate/t_ocaml_generator.cc b/compiler/cpp/src/generate/t_ocaml_generator.cc
index 39ad45b..5d51996 100644
--- a/compiler/cpp/src/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/generate/t_ocaml_generator.cc
@@ -1045,9 +1045,7 @@
  */
 void t_ocaml_generator::generate_deserialize_type(ofstream &out,
                                                    t_type* type){
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE";
@@ -1185,10 +1183,7 @@
 void t_ocaml_generator::generate_serialize_field(ofstream &out,
                                                  t_field* tfield,
                                                  string name) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1433,9 +1428,7 @@
  * Converts the parse type to a Protocol.t_type enum
  */
 string t_ocaml_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
@@ -1476,9 +1469,7 @@
  * Converts the parse type to an ocaml type
  */
 string t_ocaml_generator::render_ocaml_type(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_perl_generator.cc b/compiler/cpp/src/generate/t_perl_generator.cc
index 5f8b379..1474deb 100644
--- a/compiler/cpp/src/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/generate/t_perl_generator.cc
@@ -121,9 +121,7 @@
 string t_perl_generator::render_const_value(t_type* type, t_const_value* value) {
   std::ostringstream out;
 
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
 
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
@@ -266,10 +264,7 @@
 
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
     string dval = "undef";
-    t_type* t = (*m_iter)->get_type();
-    while (t->is_typedef()) {
-      t = ((t_typedef*)t)->get_type();
-    }
+    t_type* t = get_true_type((*m_iter)->get_type());
     if ((*m_iter)->get_value() != NULL && !(t->is_struct() || t->is_xception())) {
       dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value());
     }
@@ -281,10 +276,7 @@
   if (members.size() > 0) {
 
     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-      t_type* t = (*m_iter)->get_type();
-      while (t->is_typedef()) {
-        t = ((t_typedef*)t)->get_type();
-      }
+      t_type* t = get_true_type((*m_iter)->get_type());
       if ((*m_iter)->get_value() != NULL && (t->is_struct() || t->is_xception())) {
         indent(out) << "$self->{" << (*m_iter)->get_name() << "} = " << render_const_value(t, (*m_iter)->get_value()) << ";" << endl;
       }
@@ -810,10 +802,7 @@
     const vector<t_field*>& args = (*f_iter)->get_arglist()->get_members();
     vector<t_field*>::const_iterator a_iter;
     for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
-      t_type* atype = (*a_iter)->get_type();
-      while (atype->is_typedef()) {
-        atype = ((t_typedef*)atype)->get_type();
-      }
+      t_type* atype = get_true_type((*a_iter)->get_type());
       string req = "$request->{'" + (*a_iter)->get_name() + "'}";
       f_service_ <<
         indent() << "my $" << (*a_iter)->get_name() << " = (" << req << ") ? " << req << " : undef;" << endl;
@@ -1036,10 +1025,7 @@
                                                   t_field* tfield,
                                                   string prefix,
                                                   bool inclass) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
@@ -1261,10 +1247,7 @@
 void t_perl_generator::generate_serialize_field(ofstream &out,
                                                 t_field* tfield,
                                                 string prefix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1466,10 +1449,7 @@
 string t_perl_generator::declare_field(t_field* tfield, bool init, bool obj) {
   string result = "my $" + tfield->get_name();
   if (init) {
-    t_type* type = tfield->get_type();
-    while (type->is_typedef()) {
-      type = ((t_typedef*)type)->get_type();
-    }
+    t_type* type = get_true_type(tfield->get_type());
     if (type->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
       switch (tbase) {
@@ -1557,9 +1537,7 @@
  * Converts the parse type to a C++ enum string for the given type.
  */
 string t_perl_generator ::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
 
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index 372d1c0..1596a3b 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -156,9 +156,7 @@
  */
 string t_php_generator::render_const_value(t_type* type, t_const_value* value) {
   std::ostringstream out;
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
     switch (tbase) {
@@ -301,10 +299,7 @@
 
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
     string dval = "null";
-    t_type* t = (*m_iter)->get_type();
-    while (t->is_typedef()) {
-      t = ((t_typedef*)t)->get_type();
-    }
+    t_type* t = get_true_type((*m_iter)->get_type());
     if ((*m_iter)->get_value() != NULL && !(t->is_struct() || t->is_xception())) {
       dval = render_const_value((*m_iter)->get_type(), (*m_iter)->get_value());
     }
@@ -321,10 +316,7 @@
     indent_up();
 
     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-      t_type* t = (*m_iter)->get_type();
-      while (t->is_typedef()) {
-        t = ((t_typedef*)t)->get_type();
-      }
+      t_type* t = get_true_type((*m_iter)->get_type());
       if ((*m_iter)->get_value() != NULL && (t->is_struct() || t->is_xception())) {
         indent(out) << "$this->" << (*m_iter)->get_name() << " = " << render_const_value(t, (*m_iter)->get_value()) << ";" << endl;
       }
@@ -909,10 +901,7 @@
     const vector<t_field*>& args = (*f_iter)->get_arglist()->get_members();
     vector<t_field*>::const_iterator a_iter;
     for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) {
-      t_type* atype = (*a_iter)->get_type();
-      while (atype->is_typedef()) {
-        atype = ((t_typedef*)atype)->get_type();
-      }
+      t_type* atype = get_true_type((*a_iter)->get_type());
       string cast = type_to_cast(atype);
       string req = "$request['" + (*a_iter)->get_name() + "']";
       f_service_ <<
@@ -1150,10 +1139,7 @@
                                                  t_field* tfield,
                                                  string prefix,
                                                  bool inclass) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
@@ -1458,10 +1444,7 @@
 void t_php_generator::generate_serialize_field(ofstream &out,
                                                t_field* tfield,
                                                string prefix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1722,10 +1705,7 @@
 string t_php_generator::declare_field(t_field* tfield, bool init, bool obj) {
   string result = "$" + tfield->get_name();
   if (init) {
-    t_type* type = tfield->get_type();
-    while (type->is_typedef()) {
-      type = ((t_typedef*)type)->get_type();
-    }
+    t_type* type = get_true_type(tfield->get_type());
     if (type->is_base_type()) {
       t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
       switch (tbase) {
@@ -1828,9 +1808,7 @@
  * Converts the parse type to a C++ enum string for the given type.
  */
 string t_php_generator ::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_py_generator.cc b/compiler/cpp/src/generate/t_py_generator.cc
index a9e923e..aeabeef 100644
--- a/compiler/cpp/src/generate/t_py_generator.cc
+++ b/compiler/cpp/src/generate/t_py_generator.cc
@@ -1072,10 +1072,7 @@
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool inclass) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   if (type->is_void()) {
     throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " +
@@ -1265,10 +1262,7 @@
 void t_py_generator::generate_serialize_field(ofstream &out,
                                                t_field* tfield,
                                                string prefix) {
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
 
   // Do nothing for void types
   if (type->is_void()) {
@@ -1446,10 +1440,7 @@
  */
 string t_py_generator::declare_field(t_field* tfield) {
   string result = "self." + tfield->get_name();
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
   if (tfield->get_value() != NULL) {
     result += " = " + render_const_value(type, tfield->get_value());
   } else {
@@ -1508,9 +1499,7 @@
  * Converts the parse type to a Python tyoe
  */
 string t_py_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/compiler/cpp/src/generate/t_rb_generator.cc b/compiler/cpp/src/generate/t_rb_generator.cc
index d5b2690..a3f002f 100644
--- a/compiler/cpp/src/generate/t_rb_generator.cc
+++ b/compiler/cpp/src/generate/t_rb_generator.cc
@@ -714,10 +714,7 @@
  */
 string t_rb_generator::declare_field(t_field* tfield) {
   string result = "@" + tfield->get_name();
-  t_type* type = tfield->get_type();
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  t_type* type = get_true_type(tfield->get_type());
   if (tfield->get_value() != NULL) {
     result += " = " + render_const_value(type, tfield->get_value());
   } else {
@@ -781,9 +778,7 @@
  * Converts the parse type to a Ruby tyoe
  */
 string t_rb_generator::type_to_enum(t_type* type) {
-  while (type->is_typedef()) {
-    type = ((t_typedef*)type)->get_type();
-  }
+  type = get_true_type(type);
   
   if (type->is_base_type()) {
     t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
diff --git a/test/ManyTypedefs.thrift b/test/ManyTypedefs.thrift
new file mode 100644
index 0000000..447d7d2b
--- /dev/null
+++ b/test/ManyTypedefs.thrift
@@ -0,0 +1,31 @@
+// This is to make sure you don't mess something up when you change typedef code.
+// Generate it with the old and new thrift and make sure they are the same.
+/*
+rm -rf gen-* orig-*
+mkdir old new
+thrift -cpp -java -php -phpi -py -rb -xsd -perl -ocaml -erl -hs -strict ManyTypedefs.thrift
+mv gen-* old
+../compiler/cpp/thrift -cpp -java -php -phpi -py -rb -xsd -perl -ocaml -erl -hs -strict ManyTypedefs.thrift
+mv gen-* new
+diff -ur old new
+rm -rf old new
+# There should be no output.
+*/
+
+typedef i32 int32
+typedef list<map<int32, string>> biglist
+
+struct struct1 {
+  1: int32 myint;
+  2: biglist mylist;
+}
+
+exception exception1 {
+  1: biglist alist;
+  2: struct1 mystruct;
+}
+
+service AService {
+  struct1 method1(1: int32 myint) throws (1: exception1 exn);
+  biglist method2();
+}