Commit 1af60e92 authored by Miro Knejp's avatar Miro Knejp Committed by Jacob Potter

Fix unreliable code generation around JNI LocalRef unpacking

fixes #107
parent d83a1e7c
......@@ -13,7 +13,7 @@ NativeItemList::~NativeItemList() = default;
auto NativeItemList::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeItemList>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::List<::djinni::String>::fromCpp(jniEnv, c.items).get())};
::djinni::get(::djinni::List<::djinni::String>::fromCpp(jniEnv, c.items)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -37,7 +37,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_textsort_SortItems_createWithListene
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::textsort::SortItems::create_with_listener(::djinni_generated::NativeTextboxListener::toCpp(jniEnv, j_listener));
return ::djinni_generated::NativeSortItems::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeSortItems::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......
......@@ -19,7 +19,7 @@ void NativeTextboxListener::JavaProxy::update(const ::textsort::ItemList & items
::djinni::JniLocalScope jscope(jniEnv, 10);
const auto& data = ::djinni::JniClass<::djinni_generated::NativeTextboxListener>::get();
jniEnv->CallVoidMethod(getGlobalRef(), data.method_update,
::djinni_generated::NativeItemList::fromCpp(jniEnv, items).get());
::djinni::get(::djinni_generated::NativeItemList::fromCpp(jniEnv, items)));
::djinni::jniExceptionCheck(jniEnv);
}
......
......@@ -135,8 +135,8 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w.wl(",")
writeAlignedCall(w, " " * call.length(), r.fields, ")}", f => {
val name = idCpp.field(f.ident)
val get = if(jniMarshal.isJavaHeapObject(f.ty)) ".get()" else ""
jniMarshal.fromCpp(f.ty, s"c.$name") + get
val param = jniMarshal.fromCpp(f.ty, s"c.$name")
s"::djinni::get($param)"
})
}
else
......@@ -261,8 +261,8 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
if(!m.params.isEmpty){
w.wl(",")
writeAlignedCall(w, " " * call.length(), m.params, ")", p => {
val get = if(jniMarshal.isJavaHeapObject(p.ty)) ".get()" else ""
jniMarshal.fromCpp(p.ty, idCpp.local(p.ident)) + get
val param = jniMarshal.fromCpp(p.ty, idCpp.local(p.ident))
s"::djinni::get($param)"
})
}
else
......@@ -315,7 +315,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
val call = if (m.static) s"$cppSelf::$methodName(" else s"ref->$methodName("
writeAlignedCall(w, ret + call, m.params, ")", p => jniMarshal.toCpp(p.ty, "j_" + idJava.local(p.ident)))
w.wl(";")
m.ret.fold()(r => w.wl(s"return ${jniMarshal.fromCpp(r, "r")}" + (if(jniMarshal.isJavaHeapObject(r)) ".release();" else ";")))
m.ret.fold()(r => w.wl(s"return ::djinni::release(${jniMarshal.fromCpp(r, "r")});"))
})
}
}
......
......@@ -312,7 +312,7 @@ namespace djinni
for(const auto& ce : c)
{
auto je = T::Boxed::fromCpp(jniEnv, ce);
jniEnv->CallBooleanMethod(j, data.method_add, je.get());
jniEnv->CallBooleanMethod(j, data.method_add, get(je));
jniExceptionCheck(jniEnv);
}
return j;
......@@ -373,7 +373,7 @@ namespace djinni
for(const auto& ce : c)
{
auto je = T::fromCpp(jniEnv, ce);
jniEnv->CallBooleanMethod(j, data.method_add, je.get());
jniEnv->CallBooleanMethod(j, data.method_add, get(je));
jniExceptionCheck(jniEnv);
}
return j;
......@@ -452,7 +452,7 @@ namespace djinni
{
auto jKey = Key::Boxed::fromCpp(jniEnv, ce.first);
auto jValue = Value::Boxed::fromCpp(jniEnv, ce.second);
jniEnv->CallObjectMethod(j, data.method_put, jKey.get(), jValue.get());
jniEnv->CallObjectMethod(j, data.method_put, get(jKey), get(jValue));
jniExceptionCheck(jniEnv);
}
return j;
......
......@@ -98,6 +98,18 @@ public:
operator PointerType() && = delete;
};
template<class T>
const T& get(const T& x) noexcept { return x; }
template<class T>
typename LocalRef<T>::pointer get(const LocalRef<T>& x) noexcept { return x.get(); }
template<class T>
const T& release(const T& x) noexcept { return x; }
template<class T>
typename LocalRef<T>::pointer release(LocalRef<T>& x) noexcept { return x.release(); }
template<class T>
typename LocalRef<T>::pointer release(LocalRef<T>&& x) noexcept { return x.release(); }
/*
* Exception to indicate that a Java exception is pending in the JVM.
*/
......
map_record = record {
map: map<string, i64>;
imap: map<i32, i32>;
}
map_list_record = record {
......
set_record = record {
set: set<string>;
iset: set<i32>;
}
......@@ -10,8 +10,11 @@
struct MapRecord final {
std::unordered_map<std::string, int64_t> map;
std::unordered_map<int32_t, int32_t> imap;
MapRecord(std::unordered_map<std::string, int64_t> map)
MapRecord(std::unordered_map<std::string, int64_t> map,
std::unordered_map<int32_t, int32_t> imap)
: map(std::move(map))
, imap(std::move(imap))
{}
};
......@@ -3,14 +3,18 @@
#pragma once
#include <cstdint>
#include <string>
#include <unordered_set>
#include <utility>
struct SetRecord final {
std::unordered_set<std::string> set;
std::unordered_set<int32_t> iset;
SetRecord(std::unordered_set<std::string> set)
SetRecord(std::unordered_set<std::string> set,
std::unordered_set<int32_t> iset)
: set(std::move(set))
, iset(std::move(iset))
{}
};
......@@ -12,13 +12,22 @@ public final class MapRecord {
/*package*/ final HashMap<String, Long> mMap;
/*package*/ final HashMap<Integer, Integer> mImap;
public MapRecord(
@Nonnull HashMap<String, Long> map) {
@Nonnull HashMap<String, Long> map,
@Nonnull HashMap<Integer, Integer> imap) {
this.mMap = map;
this.mImap = imap;
}
@Nonnull
public HashMap<String, Long> getMap() {
return mMap;
}
@Nonnull
public HashMap<Integer, Integer> getImap() {
return mImap;
}
}
......@@ -12,13 +12,22 @@ public final class SetRecord {
/*package*/ final HashSet<String> mSet;
/*package*/ final HashSet<Integer> mIset;
public SetRecord(
@Nonnull HashSet<String> set) {
@Nonnull HashSet<String> set,
@Nonnull HashSet<Integer> iset) {
this.mSet = set;
this.mIset = iset;
}
@Nonnull
public HashSet<String> getSet() {
return mSet;
}
@Nonnull
public HashSet<Integer> getIset() {
return mIset;
}
}
......@@ -13,20 +13,20 @@ NativeAssortedPrimitives::~NativeAssortedPrimitives() = default;
auto NativeAssortedPrimitives::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeAssortedPrimitives>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::Bool::fromCpp(jniEnv, c.b),
::djinni::I8::fromCpp(jniEnv, c.eight),
::djinni::I16::fromCpp(jniEnv, c.sixteen),
::djinni::I32::fromCpp(jniEnv, c.thirtytwo),
::djinni::I64::fromCpp(jniEnv, c.sixtyfour),
::djinni::F32::fromCpp(jniEnv, c.fthirtytwo),
::djinni::F64::fromCpp(jniEnv, c.fsixtyfour),
::djinni::Optional<std::experimental::optional, ::djinni::Bool>::fromCpp(jniEnv, c.o_b).get(),
::djinni::Optional<std::experimental::optional, ::djinni::I8>::fromCpp(jniEnv, c.o_eight).get(),
::djinni::Optional<std::experimental::optional, ::djinni::I16>::fromCpp(jniEnv, c.o_sixteen).get(),
::djinni::Optional<std::experimental::optional, ::djinni::I32>::fromCpp(jniEnv, c.o_thirtytwo).get(),
::djinni::Optional<std::experimental::optional, ::djinni::I64>::fromCpp(jniEnv, c.o_sixtyfour).get(),
::djinni::Optional<std::experimental::optional, ::djinni::F32>::fromCpp(jniEnv, c.o_fthirtytwo).get(),
::djinni::Optional<std::experimental::optional, ::djinni::F64>::fromCpp(jniEnv, c.o_fsixtyfour).get())};
::djinni::get(::djinni::Bool::fromCpp(jniEnv, c.b)),
::djinni::get(::djinni::I8::fromCpp(jniEnv, c.eight)),
::djinni::get(::djinni::I16::fromCpp(jniEnv, c.sixteen)),
::djinni::get(::djinni::I32::fromCpp(jniEnv, c.thirtytwo)),
::djinni::get(::djinni::I64::fromCpp(jniEnv, c.sixtyfour)),
::djinni::get(::djinni::F32::fromCpp(jniEnv, c.fthirtytwo)),
::djinni::get(::djinni::F64::fromCpp(jniEnv, c.fsixtyfour)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::Bool>::fromCpp(jniEnv, c.o_b)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::I8>::fromCpp(jniEnv, c.o_eight)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::I16>::fromCpp(jniEnv, c.o_sixteen)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::I32>::fromCpp(jniEnv, c.o_thirtytwo)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::I64>::fromCpp(jniEnv, c.o_sixtyfour)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::F32>::fromCpp(jniEnv, c.o_fthirtytwo)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::F64>::fromCpp(jniEnv, c.o_fsixtyfour)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -20,9 +20,9 @@ NativeClientInterface::JavaProxy::~JavaProxy() = default;
::djinni::JniLocalScope jscope(jniEnv, 10);
const auto& data = ::djinni::JniClass<::djinni_generated::NativeClientInterface>::get();
auto jret = jniEnv->CallObjectMethod(getGlobalRef(), data.method_getRecord,
::djinni::I64::fromCpp(jniEnv, record_id),
::djinni::String::fromCpp(jniEnv, utf8string).get(),
::djinni::Optional<std::experimental::optional, ::djinni::String>::fromCpp(jniEnv, misc).get());
::djinni::get(::djinni::I64::fromCpp(jniEnv, record_id)),
::djinni::get(::djinni::String::fromCpp(jniEnv, utf8string)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::String>::fromCpp(jniEnv, misc)));
::djinni::jniExceptionCheck(jniEnv);
return ::djinni_generated::NativeClientReturnedRecord::toCpp(jniEnv, jret);
}
......
......@@ -13,9 +13,9 @@ NativeClientReturnedRecord::~NativeClientReturnedRecord() = default;
auto NativeClientReturnedRecord::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeClientReturnedRecord>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::I64::fromCpp(jniEnv, c.record_id),
::djinni::String::fromCpp(jniEnv, c.content).get(),
::djinni::Optional<std::experimental::optional, ::djinni::String>::fromCpp(jniEnv, c.misc).get())};
::djinni::get(::djinni::I64::fromCpp(jniEnv, c.record_id)),
::djinni::get(::djinni::String::fromCpp(jniEnv, c.content)),
::djinni::get(::djinni::Optional<std::experimental::optional, ::djinni::String>::fromCpp(jniEnv, c.misc)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,8 +13,8 @@ NativeConstants::~NativeConstants() = default;
auto NativeConstants::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeConstants>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::I32::fromCpp(jniEnv, c.some_integer),
::djinni::String::fromCpp(jniEnv, c.some_string).get())};
::djinni::get(::djinni::I32::fromCpp(jniEnv, c.some_integer)),
::djinni::get(::djinni::String::fromCpp(jniEnv, c.some_string)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -26,7 +26,7 @@ CJNIEXPORT jint JNICALL Java_com_dropbox_djinni_test_CppException_00024CppProxy_
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
const auto& ref = ::djinni::CppProxyHandle<::CppException>::get(nativeRef);
auto r = ref->throw_an_exception();
return ::djinni::I32::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::I32::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -35,7 +35,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_CppException_get(JNIEnv*
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::CppException::get();
return ::djinni_generated::NativeCppException::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeCppException::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......
......@@ -13,7 +13,7 @@ NativeDateRecord::~NativeDateRecord() = default;
auto NativeDateRecord::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeDateRecord>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::Date::fromCpp(jniEnv, c.created_at).get())};
::djinni::get(::djinni::Date::fromCpp(jniEnv, c.created_at)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,7 +13,7 @@ NativeMapDateRecord::~NativeMapDateRecord() = default;
auto NativeMapDateRecord::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeMapDateRecord>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::Map<::djinni::String, ::djinni::Date>::fromCpp(jniEnv, c.dates_by_id).get())};
::djinni::get(::djinni::Map<::djinni::String, ::djinni::Date>::fromCpp(jniEnv, c.dates_by_id)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,7 +13,7 @@ NativeMapListRecord::~NativeMapListRecord() = default;
auto NativeMapListRecord::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeMapListRecord>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::List<::djinni::Map<::djinni::String, ::djinni::I64>>::fromCpp(jniEnv, c.map_list).get())};
::djinni::get(::djinni::List<::djinni::Map<::djinni::String, ::djinni::I64>>::fromCpp(jniEnv, c.map_list)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,16 +13,18 @@ NativeMapRecord::~NativeMapRecord() = default;
auto NativeMapRecord::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeMapRecord>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(jniEnv, c.map).get())};
::djinni::get(::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(jniEnv, c.map)),
::djinni::get(::djinni::Map<::djinni::I32, ::djinni::I32>::fromCpp(jniEnv, c.imap)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
auto NativeMapRecord::toCpp(JNIEnv* jniEnv, JniType j) -> CppType {
::djinni::JniLocalScope jscope(jniEnv, 2);
::djinni::JniLocalScope jscope(jniEnv, 3);
assert(j != nullptr);
const auto& data = ::djinni::JniClass<NativeMapRecord>::get();
return {::djinni::Map<::djinni::String, ::djinni::I64>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mMap))};
return {::djinni::Map<::djinni::String, ::djinni::I64>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mMap)),
::djinni::Map<::djinni::I32, ::djinni::I32>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mImap))};
}
} // namespace djinni_generated
......@@ -25,8 +25,9 @@ private:
friend ::djinni::JniClass<NativeMapRecord>;
const ::djinni::GlobalRef<jclass> clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/MapRecord") };
const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/util/HashMap;)V") };
const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/util/HashMap;Ljava/util/HashMap;)V") };
const jfieldID field_mMap { ::djinni::jniGetFieldID(clazz.get(), "mMap", "Ljava/util/HashMap;") };
const jfieldID field_mImap { ::djinni::jniGetFieldID(clazz.get(), "mImap", "Ljava/util/HashMap;") };
};
} // namespace djinni_generated
......@@ -13,7 +13,7 @@ NativeNestedCollection::~NativeNestedCollection() = default;
auto NativeNestedCollection::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeNestedCollection>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::List<::djinni::Set<::djinni::String>>::fromCpp(jniEnv, c.set_list).get())};
::djinni::get(::djinni::List<::djinni::Set<::djinni::String>>::fromCpp(jniEnv, c.set_list)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,7 +13,7 @@ NativePrimitiveList::~NativePrimitiveList() = default;
auto NativePrimitiveList::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativePrimitiveList>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::List<::djinni::I64>::fromCpp(jniEnv, c.list).get())};
::djinni::get(::djinni::List<::djinni::I64>::fromCpp(jniEnv, c.list)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,8 +13,8 @@ NativeRecordWithDerivings::~NativeRecordWithDerivings() = default;
auto NativeRecordWithDerivings::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeRecordWithDerivings>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::I32::fromCpp(jniEnv, c.key1),
::djinni::String::fromCpp(jniEnv, c.key2).get())};
::djinni::get(::djinni::I32::fromCpp(jniEnv, c.key1)),
::djinni::get(::djinni::String::fromCpp(jniEnv, c.key2)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -14,8 +14,8 @@ NativeRecordWithNestedDerivings::~NativeRecordWithNestedDerivings() = default;
auto NativeRecordWithNestedDerivings::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeRecordWithNestedDerivings>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::I32::fromCpp(jniEnv, c.key),
::djinni_generated::NativeRecordWithDerivings::fromCpp(jniEnv, c.rec).get())};
::djinni::get(::djinni::I32::fromCpp(jniEnv, c.key)),
::djinni::get(::djinni_generated::NativeRecordWithDerivings::fromCpp(jniEnv, c.rec)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
......
......@@ -13,16 +13,18 @@ NativeSetRecord::~NativeSetRecord() = default;
auto NativeSetRecord::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeSetRecord>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::Set<::djinni::String>::fromCpp(jniEnv, c.set).get())};
::djinni::get(::djinni::Set<::djinni::String>::fromCpp(jniEnv, c.set)),
::djinni::get(::djinni::Set<::djinni::I32>::fromCpp(jniEnv, c.iset)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
auto NativeSetRecord::toCpp(JNIEnv* jniEnv, JniType j) -> CppType {
::djinni::JniLocalScope jscope(jniEnv, 2);
::djinni::JniLocalScope jscope(jniEnv, 3);
assert(j != nullptr);
const auto& data = ::djinni::JniClass<NativeSetRecord>::get();
return {::djinni::Set<::djinni::String>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mSet))};
return {::djinni::Set<::djinni::String>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mSet)),
::djinni::Set<::djinni::I32>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mIset))};
}
} // namespace djinni_generated
......@@ -25,8 +25,9 @@ private:
friend ::djinni::JniClass<NativeSetRecord>;
const ::djinni::GlobalRef<jclass> clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/SetRecord") };
const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/util/HashSet;)V") };
const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "<init>", "(Ljava/util/HashSet;Ljava/util/HashSet;)V") };
const jfieldID field_mSet { ::djinni::jniGetFieldID(clazz.get(), "mSet", "Ljava/util/HashSet;") };
const jfieldID field_mIset { ::djinni::jniGetFieldID(clazz.get(), "mIset", "Ljava/util/HashSet;") };
};
} // namespace djinni_generated
......@@ -32,7 +32,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_getSetRecord
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::get_set_record();
return ::djinni_generated::NativeSetRecord::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeSetRecord::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -41,7 +41,7 @@ CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_TestHelpers_checkSetRec
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::check_set_record(::djinni_generated::NativeSetRecord::toCpp(jniEnv, j_rec));
return ::djinni::Bool::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -50,7 +50,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_getPrimitive
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::get_primitive_list();
return ::djinni_generated::NativePrimitiveList::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativePrimitiveList::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -59,7 +59,7 @@ CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_TestHelpers_checkPrimit
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::check_primitive_list(::djinni_generated::NativePrimitiveList::toCpp(jniEnv, j_pl));
return ::djinni::Bool::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -68,7 +68,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_getNestedCol
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::get_nested_collection();
return ::djinni_generated::NativeNestedCollection::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeNestedCollection::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -77,7 +77,7 @@ CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_TestHelpers_checkNested
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::check_nested_collection(::djinni_generated::NativeNestedCollection::toCpp(jniEnv, j_nc));
return ::djinni::Bool::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -86,7 +86,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_getMap(JNIEn
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::get_map();
return ::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -95,7 +95,7 @@ CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_TestHelpers_checkMap(JN
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::check_map(::djinni::Map<::djinni::String, ::djinni::I64>::toCpp(jniEnv, j_m));
return ::djinni::Bool::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -104,7 +104,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_getEmptyMap(
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::get_empty_map();
return ::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -113,7 +113,7 @@ CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_TestHelpers_checkEmptyM
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::check_empty_map(::djinni::Map<::djinni::String, ::djinni::I64>::toCpp(jniEnv, j_m));
return ::djinni::Bool::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -122,7 +122,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_getMapListRe
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::get_map_list_record();
return ::djinni_generated::NativeMapListRecord::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeMapListRecord::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -131,7 +131,7 @@ CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_TestHelpers_checkMapLis
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::check_map_list_record(::djinni_generated::NativeMapListRecord::toCpp(jniEnv, j_m));
return ::djinni::Bool::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -172,7 +172,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_tokenId(JNIE
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::token_id(::djinni_generated::NativeToken::toCpp(jniEnv, j_t));
return ::djinni_generated::NativeToken::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeToken::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -181,7 +181,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_createCppTok
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::create_cpp_token();
return ::djinni_generated::NativeToken::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeToken::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -198,7 +198,7 @@ CJNIEXPORT jlong JNICALL Java_com_dropbox_djinni_test_TestHelpers_cppTokenId(JNI
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::cpp_token_id(::djinni_generated::NativeToken::toCpp(jniEnv, j_t));
return ::djinni::I64::fromCpp(jniEnv, r);
return ::djinni::release(::djinni::I64::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -216,7 +216,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_returnNone(J
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::return_none();
return ::djinni::Optional<std::experimental::optional, ::djinni::I32>::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni::Optional<std::experimental::optional, ::djinni::I32>::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -225,7 +225,7 @@ CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_TestHelpers_assortedPrim
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::assorted_primitives_id(::djinni_generated::NativeAssortedPrimitives::toCpp(jniEnv, j_i));
return ::djinni_generated::NativeAssortedPrimitives::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni_generated::NativeAssortedPrimitives::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......@@ -234,7 +234,7 @@ CJNIEXPORT jbyteArray JNICALL Java_com_dropbox_djinni_test_TestHelpers_idBinary(
try {
DJINNI_FUNCTION_PROLOGUE0(jniEnv);
auto r = ::TestHelpers::id_binary(::djinni::Binary::toCpp(jniEnv, j_b));
return ::djinni::Binary::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni::Binary::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......
......@@ -37,7 +37,7 @@ CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_Token_00024CppProxy_nati
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
const auto& ref = ::djinni::CppProxyHandle<::Token>::get(nativeRef);
auto r = ref->whoami();
return ::djinni::String::fromCpp(jniEnv, r).release();
return ::djinni::release(::djinni::String::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
......
......@@ -10,12 +10,14 @@ namespace djinni_generated {
auto MapRecord::toCpp(ObjcType obj) -> CppType
{
assert(obj);
return {::djinni::Map<::djinni::String, ::djinni::I64>::toCpp(obj.map)};
return {::djinni::Map<::djinni::String, ::djinni::I64>::toCpp(obj.map),
::djinni::Map<::djinni::I32, ::djinni::I32>::toCpp(obj.imap)};
}
auto MapRecord::fromCpp(const CppType& cpp) -> ObjcType
{
return [[DBMapRecord alloc] initWithMap:(::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(cpp.map))];
return [[DBMapRecord alloc] initWithMap:(::djinni::Map<::djinni::String, ::djinni::I64>::fromCpp(cpp.map))
imap:(::djinni::Map<::djinni::I32, ::djinni::I32>::fromCpp(cpp.imap))];
}
} // namespace djinni_generated
......@@ -4,8 +4,11 @@
#import <Foundation/Foundation.h>
@interface DBMapRecord : NSObject
- (nonnull id)initWithMap:(nonnull NSDictionary *)map;
- (nonnull id)initWithMap:(nonnull NSDictionary *)map
imap:(nonnull NSDictionary *)imap;
@property (nonatomic, readonly, nonnull) NSDictionary * map;
@property (nonatomic, readonly, nonnull) NSDictionary * imap;
@end
......@@ -7,9 +7,11 @@
@implementation DBMapRecord
- (id)initWithMap:(nonnull NSDictionary *)map
imap:(nonnull NSDictionary *)imap
{
if (self = [super init]) {
_map = map;
_imap = imap;
}
return self;
}
......
......@@ -10,12 +10,14 @@ namespace djinni_generated {
auto SetRecord::toCpp(ObjcType obj) -> CppType
{
assert(obj);
return {::djinni::Set<::djinni::String>::toCpp(obj.set)};
return {::djinni::Set<::djinni::String>::toCpp(obj.set),
::djinni::Set<::djinni::I32>::toCpp(obj.iset)};
}
auto SetRecord::fromCpp(const CppType& cpp) -> ObjcType
{
return [[DBSetRecord alloc] initWithSet:(::djinni::Set<::djinni::String>::fromCpp(cpp.set))];
return [[DBSetRecord alloc] initWithSet:(::djinni::Set<::djinni::String>::fromCpp(cpp.set))
iset:(::djinni::Set<::djinni::I32>::fromCpp(cpp.iset))];
}
} // namespace djinni_generated
......@@ -4,8 +4,11 @@
#import <Foundation/Foundation.h>
@interface DBSetRecord : NSObject
- (nonnull id)initWithSet:(nonnull NSSet *)set;
- (nonnull id)initWithSet:(nonnull NSSet *)set
iset:(nonnull NSSet *)iset;
@property (nonatomic, readonly, nonnull) NSSet * set;
@property (nonatomic, readonly, nonnull) NSSet * iset;
@end
......@@ -7,9 +7,11 @@
@implementation DBSetRecord
- (id)initWithSet:(nonnull NSSet *)set
iset:(nonnull NSSet *)iset
{
if (self = [super init]) {
_set = set;
_iset = iset;
}
return self;
}
......
......@@ -9,7 +9,7 @@ SetRecord TestHelpers::get_set_record() {
"StringA",
"StringB",
"StringC"
} };
}, {} };
}
bool TestHelpers::check_set_record(const SetRecord & rec) {
......
......@@ -17,10 +17,11 @@ public class SetRecordTest extends TestCase {
public void testJavaSetToCppSet() {
HashSet<String> jSet = new HashSet<String>();
HashSet<Integer> iSet = new HashSet<Integer>();
jSet.add("StringA");
jSet.add("StringB");
jSet.add("StringC");
SetRecord jSetRecord = new SetRecord(jSet);
SetRecord jSetRecord = new SetRecord(jSet, iSet);
assertTrue("checkSetRecord", TestHelpers.checkSetRecord(jSetRecord));
}
}
......@@ -24,21 +24,21 @@
- (void)testCppToObjc
{
MapRecord cppMapRecord([self getCppMap]);
MapRecord cppMapRecord([self getCppMap], {});
DBMapRecord *objcMapRecord = djinni_generated::MapRecord::fromCpp(cppMapRecord);
[self checkObjcMap:objcMapRecord.map];
}
- (void)testObjcToCpp
{
DBMapRecord *objcMapRecord = [[DBMapRecord alloc] initWithMap:[self getObjcMap]];
DBMapRecord *objcMapRecord = [[DBMapRecord alloc] initWithMap:[self getObjcMap] imap:[NSDictionary dictionary]];
MapRecord cppMapRecord = djinni_generated::MapRecord::toCpp(objcMapRecord);
[self checkCppMap:cppMapRecord.map];
}
- (void)testCppToObjcEmpty
{
MapRecord cppMapRecord{ {} };
MapRecord cppMapRecord{ {}, {} };
DBMapRecord *objcMapRecord = djinni_generated::MapRecord::fromCpp(cppMapRecord);
XCTAssertEqual([objcMapRecord.map count], (NSUInteger)0, @"Count 0 expected, actual: %lu", (unsigned long)[objcMapRecord.map count]);
......@@ -46,7 +46,7 @@
- (void)testObjcToCppEmpty
{
DBMapRecord *objcMapRecord = [[DBMapRecord alloc] initWithMap:[[NSDictionary alloc] init]];
DBMapRecord *objcMapRecord = [[DBMapRecord alloc] initWithMap:[NSDictionary dictionary] imap:[NSDictionary dictionary]];
MapRecord cppMapRecord = djinni_generated::MapRecord::toCpp(objcMapRecord);
auto & cppMap = cppMapRecord.map;
XCTAssertEqual(cppMap.size(), (size_t)0, @"Count 0 expected, actual: %zd", cppMap.size());
......@@ -63,7 +63,7 @@
- (void)testObjcMapListToCpp
{
NSArray *objcMapList = [[NSArray alloc] initWithObjects:[self getObjcMap], nil];
NSArray *objcMapList = @[ [self getObjcMap] ];
DBMapListRecord *objcMapListRecord = [[DBMapListRecord alloc] initWithMapList:objcMapList];
auto cppMapListRecord = djinni_generated::MapListRecord::toCpp(objcMapListRecord);
auto & cppMapList = cppMapListRecord.map_list;
......@@ -102,5 +102,4 @@
return @{ @"String1": @1, @"String2": @2, @"String3": @3 };
}
@end
......@@ -11,13 +11,13 @@
- (SetRecord)getCppSetRecord
{
return SetRecord({"StringA", "StringB", "StringC"});
return SetRecord({"StringA", "StringB", "StringC"}, {});
}
- (DBSetRecord *)getObjcSetRecord
{
NSSet *set = [[NSSet alloc] initWithObjects:@"StringA", @"StringB", @"StringC", nil];
DBSetRecord *objcSetRecord = [[DBSetRecord alloc] initWithSet:set];
DBSetRecord *objcSetRecord = [[DBSetRecord alloc] initWithSet:set iset:[NSSet set]];
return objcSetRecord;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment