Add PHP namespacing support to Thrift
Summary: "php_namespace Whoa" at the top of your Thrift file, then all your defined class names start with "Whoa_"
Reviewed By: aditya
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664908 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 90d7de8..953bb55 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -102,7 +102,7 @@
*/
void t_cpp_generator::generate_typedef(t_typedef* ttypedef) {
f_types_ <<
- indent() << "typedef " << type_name(ttypedef->get_type(), true) << " " << ttypedef->get_symbolic() << ";" << endl <<
+ indent() << "typedef " << type_name(ttypedef->get_type(), false, true) << " " << ttypedef->get_symbolic() << ";" << endl <<
endl;
}
@@ -1947,32 +1947,36 @@
* @param ttype The type
* @return String of the type name, i.e. std::set<type>
*/
-string t_cpp_generator::type_name(t_type* ttype, bool in_typedef) {
+string t_cpp_generator::type_name(t_type* ttype, bool arg, bool in_typedef) {
if (ttype->is_base_type()) {
return base_type_name(((t_base_type*)ttype)->get_base());
}
// Check for a custom overloaded C++ name
if (ttype->is_container()) {
+ string cname;
+
t_container* tcontainer = (t_container*) ttype;
if (tcontainer->has_cpp_name()) {
- return tcontainer->get_cpp_name();
+ cname = tcontainer->get_cpp_name();
+ } else if (ttype->is_map()) {
+ t_map* tmap = (t_map*) ttype;
+ cname = "std::map<" +
+ type_name(tmap->get_key_type(), in_typedef) + ", " +
+ type_name(tmap->get_val_type(), in_typedef) + "> ";
+ } else if (ttype->is_set()) {
+ t_set* tset = (t_set*) ttype;
+ cname = "std::set<" + type_name(tset->get_elem_type(), in_typedef) + "> ";
+ } else if (ttype->is_list()) {
+ t_list* tlist = (t_list*) ttype;
+ cname = "std::vector<" + type_name(tlist->get_elem_type(), in_typedef) + "> ";
}
- }
- // Use std:: types for containers
- if (ttype->is_map()) {
- t_map* tmap = (t_map*) ttype;
- return "std::map<" +
- type_name(tmap->get_key_type(), in_typedef) + ", " +
- type_name(tmap->get_val_type(), in_typedef) + "> ";
- }
- if (ttype->is_set()) {
- t_set* tset = (t_set*) ttype;
- return "std::set<" + type_name(tset->get_elem_type(), in_typedef) + "> ";
- }
- if (ttype->is_list()) {
- t_list* tlist = (t_list*) ttype;
- return "std::vector<" + type_name(tlist->get_elem_type(), in_typedef) + "> ";
+
+ if (arg) {
+ return "const " + cname + "&";
+ } else {
+ return cname;
+ }
}
string class_prefix;
@@ -1981,15 +1985,22 @@
}
// Check if it needs to be namespaced
+ string pname;
t_program* program = ttype->get_program();
if (program != NULL && program != program_) {
- return
+ pname =
class_prefix +
namespace_prefix(program->get_cpp_namespace()) +
ttype->get_name();
+ } else {
+ pname = class_prefix + ttype->get_name();
}
- return class_prefix + ttype->get_name();
+ if (arg) {
+ return "const " + pname + "&";
+ } else {
+ return pname;
+ }
}
/**
diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h
index f0c7ec2..83780ed 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.h
+++ b/compiler/cpp/src/generate/t_cpp_generator.h
@@ -127,7 +127,7 @@
std::string namespace_prefix(std::string ns);
std::string namespace_open(std::string ns);
std::string namespace_close(std::string ns);
- std::string type_name(t_type* ttype, bool in_typedef=false);
+ std::string type_name(t_type* ttype, bool arg=false, bool in_typedef=false);
std::string base_type_name(t_base_type::t_base tbase);
std::string declare_field(t_field* tfield, bool init=false);
std::string function_signature(t_function* tfunction, std::string prefix="");
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index cb2573c..bc348c4 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -71,7 +71,7 @@
*/
void t_php_generator::generate_enum(t_enum* tenum) {
f_types_ <<
- "$GLOBALS['E_" << tenum->get_name() << "'] = array(" << endl;
+ "$GLOBALS['" << php_namespace(tenum->get_program()) << "E_" << tenum->get_name() << "'] = array(" << endl;
vector<t_enum_value*> constants = tenum->get_constants();
vector<t_enum_value*>::iterator c_iter;
@@ -95,7 +95,7 @@
// code but you can't do things like an 'extract' on it, which is a bit of
// a downer.
f_types_ <<
- "final class " << tenum->get_name() << " {" << endl;
+ "final class " << php_namespace(tenum->get_program()) << tenum->get_name() << " {" << endl;
indent_up();
value = -1;
@@ -165,7 +165,7 @@
} else if (type->is_enum()) {
indent(f_consts_) << value->get_integer();
} else if (type->is_struct() || type->is_xception()) {
- f_consts_ << "new " << type->get_name() << "(array(" << endl;
+ f_consts_ << "new " << php_namespace(type->get_program()) << type->get_name() << "(array(" << endl;
indent_up();
const vector<t_field*>& fields = ((t_struct*)type)->get_members();
vector<t_field*>::const_iterator f_iter;
@@ -268,7 +268,7 @@
vector<t_field*>::const_iterator m_iter;
out <<
- "class " << tstruct->get_name();
+ "class " << php_namespace(tstruct->get_program()) << tstruct->get_name();
if (is_exception) {
out << " extends Exception";
}
@@ -1213,7 +1213,7 @@
t_struct* tstruct,
string prefix) {
out <<
- indent() << "$" << prefix << " = new " << tstruct->get_name() << "();" << endl <<
+ indent() << "$" << prefix << " = new " << php_namespace(tstruct->get_program()) << tstruct->get_name() << "();" << endl <<
indent() << "$xfer += $" << prefix << "->read($input);" << endl;
}
@@ -1665,7 +1665,7 @@
result += " = array()";
} else if (type->is_struct() || type->is_xception()) {
if (obj) {
- result += " = new " + type->get_name() + "()";
+ result += " = new " + php_namespace(type->get_program()) + type->get_name() + "()";
} else {
result += " = null";
}
diff --git a/compiler/cpp/src/generate/t_php_generator.h b/compiler/cpp/src/generate/t_php_generator.h
index e276eb4..ddea1a2 100644
--- a/compiler/cpp/src/generate/t_php_generator.h
+++ b/compiler/cpp/src/generate/t_php_generator.h
@@ -130,6 +130,11 @@
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
+ std::string php_namespace(t_program* p) {
+ std::string ns = p->get_php_namespace();
+ return ns.size() ? (ns + "_") : "";
+ }
+
private:
/**
diff --git a/compiler/cpp/src/parse/t_program.h b/compiler/cpp/src/parse/t_program.h
index b0eb60e..9a86621 100644
--- a/compiler/cpp/src/parse/t_program.h
+++ b/compiler/cpp/src/parse/t_program.h
@@ -114,6 +114,14 @@
return cpp_includes_;
}
+ void set_php_namespace(std::string php_namespace) {
+ php_namespace_ = php_namespace;
+ }
+
+ const std::string& get_php_namespace() const {
+ return php_namespace_;
+ }
+
void set_java_package(std::string java_package) {
java_package_ = java_package;
}
@@ -154,6 +162,9 @@
// C++ extra includes
std::vector<std::string> cpp_includes_;
+ // PHP namespace
+ std::string php_namespace_;
+
// Java package
std::string java_package_;
diff --git a/compiler/cpp/src/thrift.l b/compiler/cpp/src/thrift.l
index 44927fa..324c5ea 100644
--- a/compiler/cpp/src/thrift.l
+++ b/compiler/cpp/src/thrift.l
@@ -58,6 +58,7 @@
"cpp_include" { return tok_cpp_include; }
"cpp_type" { return tok_cpp_type; }
"java_package" { return tok_java_package; }
+"php_namespace" { return tok_php_namespace; }
"include" { return tok_include; }
"void" { return tok_void; }
diff --git a/compiler/cpp/src/thrift.y b/compiler/cpp/src/thrift.y
index 9dee535..8dbe621 100644
--- a/compiler/cpp/src/thrift.y
+++ b/compiler/cpp/src/thrift.y
@@ -64,6 +64,7 @@
%token tok_cpp_namespace
%token tok_cpp_include
%token tok_cpp_type
+%token tok_php_namespace
%token tok_java_package
/**
@@ -198,6 +199,13 @@
g_program->add_cpp_include($2);
}
}
+| tok_php_namespace tok_identifier
+ {
+ pdebug("Header -> tok_php_namespace tok_identifier");
+ if (g_parse_mode == PROGRAM) {
+ g_program->set_php_namespace($2);
+ }
+ }
| tok_java_package tok_identifier
{
pdebug("Header -> tok_java_package tok_identifier");