THRIFT-2862 Enable RTTI and/or build macros for generated code
Client: Haxe
Patch: Jens Geyer
This closes #293
diff --git a/compiler/cpp/src/generate/t_haxe_generator.cc b/compiler/cpp/src/generate/t_haxe_generator.cc
index 504bea9..26dd83b 100644
--- a/compiler/cpp/src/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/generate/t_haxe_generator.cc
@@ -55,6 +55,12 @@
iter = parsed_options.find("callbacks");
callbacks_ = (iter != parsed_options.end());
+ iter = parsed_options.find("rtti");
+ rtti_ = (iter != parsed_options.end());
+
+ iter = parsed_options.find("buildmacro");
+ buildmacro_ = (iter != parsed_options.end()) ? (iter->second) : "";
+
out_dir_base_ = "gen-haxe";
}
@@ -138,38 +144,30 @@
*/
void generate_deserialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
-
void generate_deserialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-
void generate_deserialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-
void generate_deserialize_set_element(std::ofstream& out, t_set* tset, std::string prefix = "");
-
void generate_deserialize_map_element(std::ofstream& out, t_map* tmap, std::string prefix = "");
-
void generate_deserialize_list_element(std::ofstream& out,
t_list* tlist,
std::string prefix = "");
void generate_serialize_field(std::ofstream& out, t_field* tfield, std::string prefix = "");
-
void generate_serialize_struct(std::ofstream& out, t_struct* tstruct, std::string prefix = "");
-
void generate_serialize_container(std::ofstream& out, t_type* ttype, std::string prefix = "");
-
+ void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
+ void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
void generate_serialize_map_element(std::ofstream& out,
t_map* tmap,
std::string iter,
std::string map);
- void generate_serialize_set_element(std::ofstream& out, t_set* tmap, std::string iter);
-
- void generate_serialize_list_element(std::ofstream& out, t_list* tlist, std::string iter);
-
void generate_haxe_doc(std::ofstream& out, t_doc* tdoc);
-
void generate_haxe_doc(std::ofstream& out, t_function* tdoc);
+ void generate_rtti_decoration(std::ofstream& out);
+ void generate_macro_decoration(std::ofstream& out);
+
/**
* Helper rendering functions
*/
@@ -216,6 +214,8 @@
private:
bool callbacks_;
+ bool rtti_;
+ string buildmacro_;
/**
* File streams
@@ -388,6 +388,8 @@
// Add haxe imports
f_enum << string() + "import org.apache.thrift.helper.*;" << endl << endl;
+ generate_rtti_decoration(f_enum);
+ generate_macro_decoration(f_enum);
indent(f_enum) << "class " << get_cap_name(tenum->get_name()) << " ";
scope_up(f_enum);
@@ -449,6 +451,8 @@
f_consts << haxe_type_imports();
+ generate_rtti_decoration(f_consts);
+ generate_macro_decoration(f_consts);
indent(f_consts) << "class " << get_cap_name(program_name_) << "Constants {" << endl << endl;
indent_up();
vector<t_const*>::iterator c_iter;
@@ -700,6 +704,8 @@
string clsname = get_cap_name(tstruct->get_name());
+ generate_rtti_decoration(out);
+ generate_macro_decoration(out);
indent(out) << "class " << clsname << " ";
if (is_exception) {
@@ -1576,6 +1582,8 @@
}
generate_haxe_doc(f_service_, tservice);
+ //generate_rtti_decoration(f_service_); - not yet, because of https://github.com/HaxeFoundation/haxe/issues/3626
+ generate_macro_decoration(f_service_);
f_service_ << indent() << "interface " << get_cap_name(service_name_) << extends_iface << " {"
<< endl << endl;
indent_up();
@@ -1618,6 +1626,8 @@
extends_client = " extends " + extends + "Impl";
}
+ generate_rtti_decoration(f_service_);
+ // build macro is inherited from interface
indent(f_service_) << "class " << get_cap_name(service_name_) << "Impl" << extends_client
<< " implements " << get_cap_name(service_name_) << " {" << endl << endl;
indent_up();
@@ -1834,6 +1844,8 @@
}
// Generate the header portion
+ generate_rtti_decoration(f_service_);
+ generate_macro_decoration(f_service_);
indent(f_service_) << "class " << get_cap_name(service_name_) << "Processor" << extends_processor
<< " implements TProcessor {" << endl << endl;
indent_up();
@@ -2835,6 +2847,27 @@
}
/**
+ * Enables RTTI for a class or interface
+ */
+void t_haxe_generator::generate_rtti_decoration(ofstream& out) {
+ if (rtti_) {
+ out << "@:rtti" << endl;
+ }
+}
+
+/**
+ * Adds build macros to a class or interface
+ */
+void t_haxe_generator::generate_macro_decoration(ofstream& out) {
+ if (!buildmacro_.empty()) {
+ out << "#if ! macro" << endl;
+ out << "@:build( " << buildmacro_ << ")" << endl; // current class/interface
+ out << "@:autoBuild( " << buildmacro_ << ")" << endl; // inherited classes/interfaces
+ out << "#end" << endl;
+ }
+}
+
+/**
* Emits a haxeDoc comment if the provided object has a doc in Thrift
*/
void t_haxe_generator::generate_haxe_doc(ofstream& out, t_doc* tdoc) {
@@ -2889,4 +2922,7 @@
THRIFT_REGISTER_GENERATOR(
haxe,
"Haxe",
- " callbacks: Use onError()/onSuccess() callbacks for service methods (like AS3)\n")
+ " callbacks Use onError()/onSuccess() callbacks for service methods (like AS3)\n" \
+ " rtti Enable @:rtti for generated classes and interfaces\n" \
+ " buildmacro=my.macros.Class.method(args)\n" \
+ " Add @:build macro calls to generated classes and interfaces\n")
diff --git a/test/haxe/src/TestMacro.hx b/test/haxe/src/TestMacro.hx
new file mode 100644
index 0000000..0129d3f
--- /dev/null
+++ b/test/haxe/src/TestMacro.hx
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package ;
+
+import haxe.macro.Context;
+import haxe.macro.Expr;
+
+/****
+ * If you call the Thrift compiler this way (e.g. by changing the prebuild command)
+ *
+ * thrift -r -gen haxe:buildmacro=TestMacro.handle() ../ThriftTest.thrift
+ *
+ * the TestMacro.handle() function implemented below is called for each generated class
+ * and interface. Use "thrift --help" to get more info about other available options.
+ */
+class TestMacro
+{
+ public static function handle( ) : Array< Field> {
+ trace('TestMacro called for ' + Context.getLocalType());
+ return Context.getBuildFields();
+ }
+
+}