THRIFT-3264 Fix Erlang 16 namespaced types
Client: Erlang
Patch: Nobuaki Sukegawa <nsukeg@gmail.com>
This closes #566
diff --git a/compiler/cpp/src/generate/t_erl_generator.cc b/compiler/cpp/src/generate/t_erl_generator.cc
index 8af5da2..c066636 100644
--- a/compiler/cpp/src/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/generate/t_erl_generator.cc
@@ -56,6 +56,10 @@
legacy_names_ = (parsed_options.find("legacynames") != parsed_options.end());
maps_ = (parsed_options.find("maps") != parsed_options.end());
+ otp16_ = (parsed_options.find("otp16") != parsed_options.end());
+ if (maps_ && otp16_) {
+ throw "argument error: Cannot specify both maps and otp16; maps are not available for Erlang/OTP R16 or older";
+ }
}
/**
@@ -156,6 +160,9 @@
/* if true use maps instead of dicts in generated code */
bool maps_;
+ /* if true use non-namespaced dict and set instead of dict:dict and sets:set */
+ bool otp16_;
+
/**
* add function to export list
*/
@@ -527,11 +534,17 @@
} else if (type->is_map()) {
if (maps_) {
return "#{}";
+ } else if (otp16_) {
+ return "dict()";
} else {
return "dict:dict()";
}
} else if (type->is_set()) {
- return "sets:set()";
+ if (otp16_) {
+ return "set()";
+ } else {
+ return "sets:set()";
+ }
} else if (type->is_list()) {
return "list()";
} else {
@@ -1027,4 +1040,5 @@
erl,
"Erlang",
" legacynames: Output files retain naming conventions of Thrift 0.9.1 and earlier.\n"
- " maps: Generate maps instead of dicts.\n")
+ " maps: Generate maps instead of dicts.\n"
+ " otp16: Generate non-namespaced dict and set instead of dict:dict and sets:set.\n")
diff --git a/configure.ac b/configure.ac
index 9af7f65..0a3fd43 100755
--- a/configure.ac
+++ b/configure.ac
@@ -231,9 +231,16 @@
fi
if test -n "$ERL" -a -n "$ERLC" ; then
have_erlang="yes"
+
+ # otp_release is simply a number (like "17") for OTP17+ while "R16..." for OTP16 or less.
+ # OTP version is currently only used for running tests.
+ if $ERL -eval 'erlang:display(erlang:system_info(otp_release)),halt().' -noshell | grep "^\"R" >/dev/null; then
+ erlang_otp16_or_less="yes"
+ fi
fi
fi
AM_CONDITIONAL(WITH_ERLANG, [test "$have_erlang" = "yes"])
+AM_CONDITIONAL(ERLANG_OTP16, [test "$erlang_otp16_or_less" = "yes"])
AX_THRIFT_LIB(nodejs, [Nodejs], yes)
have_nodejs=no
diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am
index 1f65a24..f48ff0a 100644
--- a/lib/erl/Makefile.am
+++ b/lib/erl/Makefile.am
@@ -21,12 +21,19 @@
THRIFT_FILES = $(wildcard test/*.thrift) \
../../test/ThriftTest.thrift
-.generated: $(THRIFT_FILES)
+if ERLANG_OTP16
+.generated: $(THRIFT) $(THRIFT_FILES)
for f in $(THRIFT_FILES) ; do \
- $(THRIFT) --gen erl -o test $$f ; \
+ $(THRIFT) --gen erl:otp16 -o test $$f ; \
+ done ;
+else
+.generated: $(THRIFT) $(THRIFT_FILES)
+ for f in $(THRIFT_FILES) ; do \
+ $(THRIFT) --gen erl -o test $$f ; \
done ; \
$(THRIFT) --gen erl:maps -o test test/Thrift3214.thrift ; \
touch .generated
+endif
all: .generated
./rebar get-deps
diff --git a/lib/erl/rebar.config b/lib/erl/rebar.config
index 0f5d40e..1ea18a4 100644
--- a/lib/erl/rebar.config
+++ b/lib/erl/rebar.config
@@ -1 +1 @@
-{erl_opts, [debug_info]}.
+{erl_opts, [{platform_define, "^R.*", otp16_or_less}, debug_info]}.
diff --git a/lib/erl/test/test_thrift_3214.erl b/lib/erl/test/test_thrift_3214.erl
index 118e779..0f9544b 100644
--- a/lib/erl/test/test_thrift_3214.erl
+++ b/lib/erl/test/test_thrift_3214.erl
@@ -23,6 +23,7 @@
-include("gen-erl/thrift3214_types.hrl").
-ifdef(TEST).
+-ifndef(otp16_or_less).
-include_lib("eunit/include/eunit.hrl").
record_generation_test_() ->
@@ -56,3 +57,4 @@
].
-endif.
+-endif.