diff --git a/.gitignore b/.gitignore index 7a5c30b4..80d25f4c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ test-suite/djinni/vendor/third-party/proto/ts/*.js /.metals *.db src/source/.metals/* -src/source/.scala-build/* \ No newline at end of file +src/source/.scala-build/* diff --git a/examples/example.djinni b/examples/example.djinni index 0be9057e..282d4e10 100755 --- a/examples/example.djinni +++ b/examples/example.djinni @@ -6,6 +6,14 @@ LevelB = record extends LevelA { fieldB: string; } +LevelB2 = record extends LevelB { + fieldB2: string; +} + +LevelB2C = record extends LevelB2 { + fieldB2C: string; +} + LevelC = record extends LevelB { fieldC: string; } @@ -18,6 +26,15 @@ LevelE = record extends LevelD { fieldE: string; } +LevelD2 = record extends LevelD { + fieldD2: string; +} + LevelF = record extends LevelE { } + +Container = record { + levels: list; + levelA : LevelA; +} \ No newline at end of file diff --git a/examples/generated/android/djinni/java/src/Container.kt b/examples/generated/android/djinni/java/src/Container.kt new file mode 100644 index 00000000..49dd29b6 --- /dev/null +++ b/examples/generated/android/djinni/java/src/Container.kt @@ -0,0 +1,22 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +package djinni.java.src + +import androidx.compose.runtime.Immutable +import java.util.ArrayList + +@Immutable +data class Container( + val levels: ArrayList, + val levelA: LevelA +) { + + override fun toString(): String { + return "Container {" + + "levels=" + levels + + "," + "levelA=" + levelA + + "}" + } + +} diff --git a/examples/generated/android/djinni/java/src/LevelB2.kt b/examples/generated/android/djinni/java/src/LevelB2.kt new file mode 100644 index 00000000..5a6df20e --- /dev/null +++ b/examples/generated/android/djinni/java/src/LevelB2.kt @@ -0,0 +1,23 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +package djinni.java.src + +import androidx.compose.runtime.Immutable + +@Immutable +open class LevelB2( + override val fieldA: String, + override val fieldB: String, + open val fieldB2: String +) : LevelB(fieldA, fieldB) { + + override fun toString(): String { + return "LevelB2 {" + + "fieldA=" + fieldA + + "," + "fieldB=" + fieldB + + "," + "fieldB2=" + fieldB2 + + "}" + } + +} diff --git a/examples/generated/android/djinni/java/src/LevelB2C.kt b/examples/generated/android/djinni/java/src/LevelB2C.kt new file mode 100644 index 00000000..cd339abb --- /dev/null +++ b/examples/generated/android/djinni/java/src/LevelB2C.kt @@ -0,0 +1,25 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +package djinni.java.src + +import androidx.compose.runtime.Immutable + +@Immutable +data class LevelB2C( + override val fieldA: String, + override val fieldB: String, + override val fieldB2: String, + val fieldB2C: String +) : LevelB2(fieldA, fieldB, fieldB2) { + + override fun toString(): String { + return "LevelB2C {" + + "fieldA=" + fieldA + + "," + "fieldB=" + fieldB + + "," + "fieldB2=" + fieldB2 + + "," + "fieldB2C=" + fieldB2C + + "}" + } + +} diff --git a/examples/generated/android/djinni/java/src/LevelD2.kt b/examples/generated/android/djinni/java/src/LevelD2.kt new file mode 100644 index 00000000..2a1fb409 --- /dev/null +++ b/examples/generated/android/djinni/java/src/LevelD2.kt @@ -0,0 +1,27 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +package djinni.java.src + +import androidx.compose.runtime.Immutable + +@Immutable +data class LevelD2( + override val fieldA: String, + override val fieldB: String, + override val fieldC: String, + override val fieldD: String, + val fieldD2: String +) : LevelD(fieldA, fieldB, fieldC, fieldD) { + + override fun toString(): String { + return "LevelD2 {" + + "fieldA=" + fieldA + + "," + "fieldB=" + fieldB + + "," + "fieldC=" + fieldC + + "," + "fieldD=" + fieldD + + "," + "fieldD2=" + fieldD2 + + "}" + } + +} diff --git a/examples/generated/android/jni/NativeContainer.cpp b/examples/generated/android/jni/NativeContainer.cpp new file mode 100644 index 00000000..aabc6d88 --- /dev/null +++ b/examples/generated/android/jni/NativeContainer.cpp @@ -0,0 +1,34 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#include "NativeContainer.h" // my header +#include "Marshal.hpp" +#include "NativeLevelA.h" + +namespace djinni_generated { + +NativeContainer::NativeContainer() = default; + +NativeContainer::~NativeContainer() = default; + +auto NativeContainer::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { + ::djinni::LocalRef r; + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::List<::djinni_generated::NativeLevelA>::fromCpp(jniEnv, c.levels)), + ::djinni::get(::djinni_generated::NativeLevelA::fromCpp(jniEnv, c.levelA)))}; + ::djinni::jniExceptionCheck(jniEnv); + return r; +} + +auto NativeContainer::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { + ::djinni::JniLocalScope jscope(jniEnv, 3); + assert(j != nullptr); + const auto& data = ::djinni::JniClass::get(); + ::transitLib::viewModel::Container model; + model.levels = ::djinni::List<::djinni_generated::NativeLevelA>::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_levels)); + model.levelA = ::djinni_generated::NativeLevelA::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_levelA)); + return model; +} + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeContainer.h b/examples/generated/android/jni/NativeContainer.h new file mode 100644 index 00000000..5c841d9d --- /dev/null +++ b/examples/generated/android/jni/NativeContainer.h @@ -0,0 +1,33 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "ContainerViewModel.h" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeContainer final { +public: + using CppType = ::transitLib::viewModel::Container; + using JniType = jobject; + + using Boxed = NativeContainer; + + ~NativeContainer(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j); + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c); + +private: + NativeContainer(); + friend ::djinni::JniClass; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("djinni/java/src/Container") }; + const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "", "(Ljava/util/ArrayList;Ldjinni/java/src/LevelA;)V") }; + const jfieldID field_levels { ::djinni::jniGetFieldID(clazz.get(), "levels", "Ljava/util/ArrayList;") }; + const jfieldID field_levelA { ::djinni::jniGetFieldID(clazz.get(), "levelA", "Ldjinni/java/src/LevelA;") }; +}; + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelA.cpp b/examples/generated/android/jni/NativeLevelA.cpp index 20173b58..9a35100e 100644 --- a/examples/generated/android/jni/NativeLevelA.cpp +++ b/examples/generated/android/jni/NativeLevelA.cpp @@ -3,6 +3,14 @@ #include "NativeLevelA.h" // my header #include "Marshal.hpp" +#include "NativeLevelB.h" +#include "NativeLevelB2.h" +#include "NativeLevelB2C.h" +#include "NativeLevelC.h" +#include "NativeLevelD.h" +#include "NativeLevelD2.h" +#include "NativeLevelE.h" +#include "NativeLevelF.h" namespace djinni_generated { @@ -11,10 +19,45 @@ NativeLevelA::NativeLevelA() = default; NativeLevelA::~NativeLevelA() = default; auto NativeLevelA::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { - const auto& data = ::djinni::JniClass::get(); - auto r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)))}; - ::djinni::jniExceptionCheck(jniEnv); + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(c)) + { + r = NativeLevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(c)) + { + r = NativeLevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(c)) + { + r = NativeLevelE::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD>(c)) + { + r = NativeLevelD::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelC>(c)) + { + r = NativeLevelC::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2C>(c)) + { + r = NativeLevelB2C::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2>(c)) + { + r = NativeLevelB2::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB>(c)) + { + r = NativeLevelB::fromCpp(jniEnv, myObject); + } + else { + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldA)))}; + ::djinni::jniExceptionCheck(jniEnv); + } return r; } @@ -22,8 +65,8 @@ auto NativeLevelA::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { ::djinni::JniLocalScope jscope(jniEnv, 2); assert(j != nullptr); const auto& data = ::djinni::JniClass::get(); - ::transitLib::viewModel::LevelA model; - model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + std::shared_ptr<::transitLib::viewModel::LevelA> model; + model->fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); return model; } diff --git a/examples/generated/android/jni/NativeLevelA.h b/examples/generated/android/jni/NativeLevelA.h index da6709c4..99f506fb 100644 --- a/examples/generated/android/jni/NativeLevelA.h +++ b/examples/generated/android/jni/NativeLevelA.h @@ -10,7 +10,7 @@ namespace djinni_generated { class NativeLevelA final { public: - using CppType = ::transitLib::viewModel::LevelA; + using CppType = std::shared_ptr<::transitLib::viewModel::LevelA>; using JniType = jobject; using Boxed = NativeLevelA; diff --git a/examples/generated/android/jni/NativeLevelB.cpp b/examples/generated/android/jni/NativeLevelB.cpp index 403e118a..d3978ac7 100644 --- a/examples/generated/android/jni/NativeLevelB.cpp +++ b/examples/generated/android/jni/NativeLevelB.cpp @@ -3,6 +3,13 @@ #include "NativeLevelB.h" // my header #include "Marshal.hpp" +#include "NativeLevelB2.h" +#include "NativeLevelB2C.h" +#include "NativeLevelC.h" +#include "NativeLevelD.h" +#include "NativeLevelD2.h" +#include "NativeLevelE.h" +#include "NativeLevelF.h" namespace djinni_generated { @@ -11,11 +18,42 @@ NativeLevelB::NativeLevelB() = default; NativeLevelB::~NativeLevelB() = default; auto NativeLevelB::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { - const auto& data = ::djinni::JniClass::get(); - auto r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)))}; - ::djinni::jniExceptionCheck(jniEnv); + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(c)) + { + r = NativeLevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(c)) + { + r = NativeLevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(c)) + { + r = NativeLevelE::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD>(c)) + { + r = NativeLevelD::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelC>(c)) + { + r = NativeLevelC::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2C>(c)) + { + r = NativeLevelB2C::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2>(c)) + { + r = NativeLevelB2::fromCpp(jniEnv, myObject); + } + else { + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldB)))}; + ::djinni::jniExceptionCheck(jniEnv); + } return r; } @@ -23,9 +61,9 @@ auto NativeLevelB::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { ::djinni::JniLocalScope jscope(jniEnv, 3); assert(j != nullptr); const auto& data = ::djinni::JniClass::get(); - ::transitLib::viewModel::LevelB model; - model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); - model.fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + std::shared_ptr<::transitLib::viewModel::LevelB> model; + model->fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model->fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); return model; } diff --git a/examples/generated/android/jni/NativeLevelB.h b/examples/generated/android/jni/NativeLevelB.h index 139e3b84..ddd20bf7 100644 --- a/examples/generated/android/jni/NativeLevelB.h +++ b/examples/generated/android/jni/NativeLevelB.h @@ -10,7 +10,7 @@ namespace djinni_generated { class NativeLevelB final { public: - using CppType = ::transitLib::viewModel::LevelB; + using CppType = std::shared_ptr<::transitLib::viewModel::LevelB>; using JniType = jobject; using Boxed = NativeLevelB; diff --git a/examples/generated/android/jni/NativeLevelB2.cpp b/examples/generated/android/jni/NativeLevelB2.cpp new file mode 100644 index 00000000..55a9e3ba --- /dev/null +++ b/examples/generated/android/jni/NativeLevelB2.cpp @@ -0,0 +1,42 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#include "NativeLevelB2.h" // my header +#include "Marshal.hpp" +#include "NativeLevelB2C.h" + +namespace djinni_generated { + +NativeLevelB2::NativeLevelB2() = default; + +NativeLevelB2::~NativeLevelB2() = default; + +auto NativeLevelB2::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2C>(c)) + { + r = NativeLevelB2C::fromCpp(jniEnv, *myObject); + } + else { + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldB2)))}; + ::djinni::jniExceptionCheck(jniEnv); + } + return r; +} + +auto NativeLevelB2::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { + ::djinni::JniLocalScope jscope(jniEnv, 4); + assert(j != nullptr); + const auto& data = ::djinni::JniClass::get(); + std::shared_ptr<::transitLib::viewModel::LevelB2> model; + model->fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model->fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + model->fieldB2 = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB2)); + return model; +} + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelB2.h b/examples/generated/android/jni/NativeLevelB2.h new file mode 100644 index 00000000..5858ab58 --- /dev/null +++ b/examples/generated/android/jni/NativeLevelB2.h @@ -0,0 +1,34 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelB2ViewModel.h" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeLevelB2 final { +public: + using CppType = std::shared_ptr<::transitLib::viewModel::LevelB2>; + using JniType = jobject; + + using Boxed = NativeLevelB2; + + ~NativeLevelB2(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j); + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c); + +private: + NativeLevelB2(); + friend ::djinni::JniClass; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("djinni/java/src/LevelB2") }; + const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") }; + const jfieldID field_fieldA { ::djinni::jniGetFieldID(clazz.get(), "fieldA", "Ljava/lang/String;") }; + const jfieldID field_fieldB { ::djinni::jniGetFieldID(clazz.get(), "fieldB", "Ljava/lang/String;") }; + const jfieldID field_fieldB2 { ::djinni::jniGetFieldID(clazz.get(), "fieldB2", "Ljava/lang/String;") }; +}; + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelB2C.cpp b/examples/generated/android/jni/NativeLevelB2C.cpp new file mode 100644 index 00000000..7dd9bdde --- /dev/null +++ b/examples/generated/android/jni/NativeLevelB2C.cpp @@ -0,0 +1,37 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#include "NativeLevelB2C.h" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeLevelB2C::NativeLevelB2C() = default; + +NativeLevelB2C::~NativeLevelB2C() = default; + +auto NativeLevelB2C::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { + ::djinni::LocalRef r; + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB2)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB2C)))}; + ::djinni::jniExceptionCheck(jniEnv); + return r; +} + +auto NativeLevelB2C::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { + ::djinni::JniLocalScope jscope(jniEnv, 5); + assert(j != nullptr); + const auto& data = ::djinni::JniClass::get(); + ::transitLib::viewModel::LevelB2C model; + model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model.fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + model.fieldB2 = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB2)); + model.fieldB2C = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB2C)); + return model; +} + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelB2C.h b/examples/generated/android/jni/NativeLevelB2C.h new file mode 100644 index 00000000..d7027048 --- /dev/null +++ b/examples/generated/android/jni/NativeLevelB2C.h @@ -0,0 +1,35 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelB2CViewModel.h" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeLevelB2C final { +public: + using CppType = ::transitLib::viewModel::LevelB2C; + using JniType = jobject; + + using Boxed = NativeLevelB2C; + + ~NativeLevelB2C(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j); + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c); + +private: + NativeLevelB2C(); + friend ::djinni::JniClass; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("djinni/java/src/LevelB2C") }; + const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") }; + const jfieldID field_fieldA { ::djinni::jniGetFieldID(clazz.get(), "fieldA", "Ljava/lang/String;") }; + const jfieldID field_fieldB { ::djinni::jniGetFieldID(clazz.get(), "fieldB", "Ljava/lang/String;") }; + const jfieldID field_fieldB2 { ::djinni::jniGetFieldID(clazz.get(), "fieldB2", "Ljava/lang/String;") }; + const jfieldID field_fieldB2C { ::djinni::jniGetFieldID(clazz.get(), "fieldB2C", "Ljava/lang/String;") }; +}; + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelC.cpp b/examples/generated/android/jni/NativeLevelC.cpp index a04292f1..00b7da87 100644 --- a/examples/generated/android/jni/NativeLevelC.cpp +++ b/examples/generated/android/jni/NativeLevelC.cpp @@ -3,6 +3,10 @@ #include "NativeLevelC.h" // my header #include "Marshal.hpp" +#include "NativeLevelD.h" +#include "NativeLevelD2.h" +#include "NativeLevelE.h" +#include "NativeLevelF.h" namespace djinni_generated { @@ -11,12 +15,31 @@ NativeLevelC::NativeLevelC() = default; NativeLevelC::~NativeLevelC() = default; auto NativeLevelC::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { - const auto& data = ::djinni::JniClass::get(); - auto r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldC)))}; - ::djinni::jniExceptionCheck(jniEnv); + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(c)) + { + r = NativeLevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(c)) + { + r = NativeLevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(c)) + { + r = NativeLevelE::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD>(c)) + { + r = NativeLevelD::fromCpp(jniEnv, myObject); + } + else { + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldC)))}; + ::djinni::jniExceptionCheck(jniEnv); + } return r; } @@ -24,10 +47,10 @@ auto NativeLevelC::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { ::djinni::JniLocalScope jscope(jniEnv, 4); assert(j != nullptr); const auto& data = ::djinni::JniClass::get(); - ::transitLib::viewModel::LevelC model; - model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); - model.fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); - model.fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); + std::shared_ptr<::transitLib::viewModel::LevelC> model; + model->fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model->fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + model->fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); return model; } diff --git a/examples/generated/android/jni/NativeLevelC.h b/examples/generated/android/jni/NativeLevelC.h index 67175325..a06ccf74 100644 --- a/examples/generated/android/jni/NativeLevelC.h +++ b/examples/generated/android/jni/NativeLevelC.h @@ -10,7 +10,7 @@ namespace djinni_generated { class NativeLevelC final { public: - using CppType = ::transitLib::viewModel::LevelC; + using CppType = std::shared_ptr<::transitLib::viewModel::LevelC>; using JniType = jobject; using Boxed = NativeLevelC; diff --git a/examples/generated/android/jni/NativeLevelD.cpp b/examples/generated/android/jni/NativeLevelD.cpp index 73a2a163..4f6c2e39 100644 --- a/examples/generated/android/jni/NativeLevelD.cpp +++ b/examples/generated/android/jni/NativeLevelD.cpp @@ -3,6 +3,9 @@ #include "NativeLevelD.h" // my header #include "Marshal.hpp" +#include "NativeLevelD2.h" +#include "NativeLevelE.h" +#include "NativeLevelF.h" namespace djinni_generated { @@ -11,13 +14,28 @@ NativeLevelD::NativeLevelD() = default; NativeLevelD::~NativeLevelD() = default; auto NativeLevelD::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { - const auto& data = ::djinni::JniClass::get(); - auto r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldC)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldD)))}; - ::djinni::jniExceptionCheck(jniEnv); + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(c)) + { + r = NativeLevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(c)) + { + r = NativeLevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(c)) + { + r = NativeLevelE::fromCpp(jniEnv, myObject); + } + else { + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldC)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldD)))}; + ::djinni::jniExceptionCheck(jniEnv); + } return r; } @@ -25,11 +43,11 @@ auto NativeLevelD::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { ::djinni::JniLocalScope jscope(jniEnv, 5); assert(j != nullptr); const auto& data = ::djinni::JniClass::get(); - ::transitLib::viewModel::LevelD model; - model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); - model.fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); - model.fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); - model.fieldD = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldD)); + std::shared_ptr<::transitLib::viewModel::LevelD> model; + model->fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model->fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + model->fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); + model->fieldD = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldD)); return model; } diff --git a/examples/generated/android/jni/NativeLevelD.h b/examples/generated/android/jni/NativeLevelD.h index 48adfb3c..f8a8614e 100644 --- a/examples/generated/android/jni/NativeLevelD.h +++ b/examples/generated/android/jni/NativeLevelD.h @@ -10,7 +10,7 @@ namespace djinni_generated { class NativeLevelD final { public: - using CppType = ::transitLib::viewModel::LevelD; + using CppType = std::shared_ptr<::transitLib::viewModel::LevelD>; using JniType = jobject; using Boxed = NativeLevelD; diff --git a/examples/generated/android/jni/NativeLevelD2.cpp b/examples/generated/android/jni/NativeLevelD2.cpp new file mode 100644 index 00000000..aa2be2f3 --- /dev/null +++ b/examples/generated/android/jni/NativeLevelD2.cpp @@ -0,0 +1,39 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#include "NativeLevelD2.h" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeLevelD2::NativeLevelD2() = default; + +NativeLevelD2::~NativeLevelD2() = default; + +auto NativeLevelD2::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { + ::djinni::LocalRef r; + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldC)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldD)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldD2)))}; + ::djinni::jniExceptionCheck(jniEnv); + return r; +} + +auto NativeLevelD2::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { + ::djinni::JniLocalScope jscope(jniEnv, 6); + assert(j != nullptr); + const auto& data = ::djinni::JniClass::get(); + ::transitLib::viewModel::LevelD2 model; + model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model.fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + model.fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); + model.fieldD = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldD)); + model.fieldD2 = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldD2)); + return model; +} + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelD2.h b/examples/generated/android/jni/NativeLevelD2.h new file mode 100644 index 00000000..1ae89c72 --- /dev/null +++ b/examples/generated/android/jni/NativeLevelD2.h @@ -0,0 +1,36 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelD2ViewModel.h" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeLevelD2 final { +public: + using CppType = ::transitLib::viewModel::LevelD2; + using JniType = jobject; + + using Boxed = NativeLevelD2; + + ~NativeLevelD2(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j); + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c); + +private: + NativeLevelD2(); + friend ::djinni::JniClass; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("djinni/java/src/LevelD2") }; + const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V") }; + const jfieldID field_fieldA { ::djinni::jniGetFieldID(clazz.get(), "fieldA", "Ljava/lang/String;") }; + const jfieldID field_fieldB { ::djinni::jniGetFieldID(clazz.get(), "fieldB", "Ljava/lang/String;") }; + const jfieldID field_fieldC { ::djinni::jniGetFieldID(clazz.get(), "fieldC", "Ljava/lang/String;") }; + const jfieldID field_fieldD { ::djinni::jniGetFieldID(clazz.get(), "fieldD", "Ljava/lang/String;") }; + const jfieldID field_fieldD2 { ::djinni::jniGetFieldID(clazz.get(), "fieldD2", "Ljava/lang/String;") }; +}; + +} // namespace djinni_generated diff --git a/examples/generated/android/jni/NativeLevelE.cpp b/examples/generated/android/jni/NativeLevelE.cpp index ec674a3a..1594e987 100644 --- a/examples/generated/android/jni/NativeLevelE.cpp +++ b/examples/generated/android/jni/NativeLevelE.cpp @@ -3,6 +3,7 @@ #include "NativeLevelE.h" // my header #include "Marshal.hpp" +#include "NativeLevelF.h" namespace djinni_generated { @@ -11,14 +12,21 @@ NativeLevelE::NativeLevelE() = default; NativeLevelE::~NativeLevelE() = default; auto NativeLevelE::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { - const auto& data = ::djinni::JniClass::get(); - auto r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldC)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldD)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldE)))}; - ::djinni::jniExceptionCheck(jniEnv); + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(c)) + { + r = NativeLevelF::fromCpp(jniEnv, *myObject); + } + else { + const auto& data = ::djinni::JniClass::get(); + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldC)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldD)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c->fieldE)))}; + ::djinni::jniExceptionCheck(jniEnv); + } return r; } @@ -26,12 +34,12 @@ auto NativeLevelE::toCpp(JNIEnv* jniEnv, JniType j) -> CppType { ::djinni::JniLocalScope jscope(jniEnv, 6); assert(j != nullptr); const auto& data = ::djinni::JniClass::get(); - ::transitLib::viewModel::LevelE model; - model.fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); - model.fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); - model.fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); - model.fieldD = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldD)); - model.fieldE = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldE)); + std::shared_ptr<::transitLib::viewModel::LevelE> model; + model->fieldA = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldA)); + model->fieldB = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldB)); + model->fieldC = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldC)); + model->fieldD = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldD)); + model->fieldE = ::djinni::String::toCpp(jniEnv, (jstring)jniEnv->GetObjectField(j, data.field_fieldE)); return model; } diff --git a/examples/generated/android/jni/NativeLevelE.h b/examples/generated/android/jni/NativeLevelE.h index 789d0b9d..8f26d7f5 100644 --- a/examples/generated/android/jni/NativeLevelE.h +++ b/examples/generated/android/jni/NativeLevelE.h @@ -10,7 +10,7 @@ namespace djinni_generated { class NativeLevelE final { public: - using CppType = ::transitLib::viewModel::LevelE; + using CppType = std::shared_ptr<::transitLib::viewModel::LevelE>; using JniType = jobject; using Boxed = NativeLevelE; diff --git a/examples/generated/android/jni/NativeLevelF.cpp b/examples/generated/android/jni/NativeLevelF.cpp index aa598880..b438f803 100644 --- a/examples/generated/android/jni/NativeLevelF.cpp +++ b/examples/generated/android/jni/NativeLevelF.cpp @@ -11,13 +11,14 @@ NativeLevelF::NativeLevelF() = default; NativeLevelF::~NativeLevelF() = default; auto NativeLevelF::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef { + ::djinni::LocalRef r; const auto& data = ::djinni::JniClass::get(); - auto r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldC)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldD)), - ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldE)))}; + r = ::djinni::LocalRef{jniEnv->NewObject(data.clazz.get(), data.jconstructor, + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldA)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldB)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldC)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldD)), + ::djinni::get(::djinni::String::fromCpp(jniEnv, c.fieldE)))}; ::djinni::jniExceptionCheck(jniEnv); return r; } diff --git a/examples/generated/cpp/ContainerViewModel.h b/examples/generated/cpp/ContainerViewModel.h new file mode 100644 index 00000000..4a31241b --- /dev/null +++ b/examples/generated/cpp/ContainerViewModel.h @@ -0,0 +1,17 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelAViewModel.h" +#include +#include + +namespace transitLib::viewModel { + +struct Container final { + std::vector> levels; + std::shared_ptr levelA; +}; + +} // namespace transitLib::viewModel diff --git a/examples/generated/cpp/LevelB2CViewModel.h b/examples/generated/cpp/LevelB2CViewModel.h new file mode 100644 index 00000000..6faf517f --- /dev/null +++ b/examples/generated/cpp/LevelB2CViewModel.h @@ -0,0 +1,16 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelB2ViewModel.h" +#include +#include + +namespace transitLib::viewModel { + +struct LevelB2C : public LevelB2 { + std::string fieldB2C; +}; + +} // namespace transitLib::viewModel diff --git a/examples/generated/cpp/LevelB2ViewModel.h b/examples/generated/cpp/LevelB2ViewModel.h new file mode 100644 index 00000000..a5570d6f --- /dev/null +++ b/examples/generated/cpp/LevelB2ViewModel.h @@ -0,0 +1,18 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelBViewModel.h" +#include +#include + +namespace transitLib::viewModel { + +struct LevelB2 : public LevelB { + std::string fieldB2; + + virtual ~LevelB2(){}; +}; + +} // namespace transitLib::viewModel diff --git a/examples/generated/cpp/LevelD2ViewModel.h b/examples/generated/cpp/LevelD2ViewModel.h new file mode 100644 index 00000000..4e7f1998 --- /dev/null +++ b/examples/generated/cpp/LevelD2ViewModel.h @@ -0,0 +1,16 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#pragma once + +#include "LevelDViewModel.h" +#include +#include + +namespace transitLib::viewModel { + +struct LevelD2 : public LevelD { + std::string fieldD2; +}; + +} // namespace transitLib::viewModel diff --git a/examples/generated/objc/SPContainerViewModel+Private.h b/examples/generated/objc/SPContainerViewModel+Private.h new file mode 100644 index 00000000..b41204b9 --- /dev/null +++ b/examples/generated/objc/SPContainerViewModel+Private.h @@ -0,0 +1,24 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPContainerViewModel.h" +#include "ContainerViewModel.h" + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class SPContainerViewModel; + +namespace djinni_generated { + +struct Container +{ + using CppType = ::transitLib::viewModel::Container; + using ObjcType = SPContainerViewModel*; + + using Boxed = Container; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCpp(const CppType& cpp); +}; + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPContainerViewModel+Private.mm b/examples/generated/objc/SPContainerViewModel+Private.mm new file mode 100644 index 00000000..fa98a9e3 --- /dev/null +++ b/examples/generated/objc/SPContainerViewModel+Private.mm @@ -0,0 +1,29 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPContainerViewModel+Private.h" +#import "DJIMarshal+Private.h" +#import "SPLevelAViewModel+Private.h" +#include + +namespace djinni_generated { + +auto Container::toCpp(ObjcType obj) -> CppType +{ + assert(obj); + ::transitLib::viewModel::Container model; + model.levels = ::djinni::List<::djinni_generated::LevelA>::toCpp(obj.levels); + model.levelA = ::djinni_generated::LevelA::toCpp(obj.levelA); + return model; +} + +auto Container::fromCpp(const CppType& cpp) -> ObjcType +{ + ::djinni::LocalRef r; + r = [[SPContainerViewModel alloc] initWithLevels:(::djinni::List<::djinni_generated::LevelA>::fromCpp(cpp.levels)) + levelA:(::djinni_generated::LevelA::fromCpp(cpp.levelA))]; + return r; + +} + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPContainerViewModel.h b/examples/generated/objc/SPContainerViewModel.h new file mode 100644 index 00000000..51457633 --- /dev/null +++ b/examples/generated/objc/SPContainerViewModel.h @@ -0,0 +1,19 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelAViewModel.h" +#import + +@interface SPContainerViewModel : NSObject +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; +- (nonnull instancetype)initWithLevels:(nonnull NSArray *)levels + levelA:(nonnull SPLevelAViewModel *)levelA NS_DESIGNATED_INITIALIZER; ++ (nonnull instancetype)ContainerWithLevels:(nonnull NSArray *)levels + levelA:(nonnull SPLevelAViewModel *)levelA; + +@property (nonatomic, readonly, nonnull) NSArray * levels; + +@property (nonatomic, readonly, nonnull) SPLevelAViewModel * levelA; + +@end diff --git a/examples/generated/objc/SPContainerViewModel.mm b/examples/generated/objc/SPContainerViewModel.mm new file mode 100644 index 00000000..abdd8905 --- /dev/null +++ b/examples/generated/objc/SPContainerViewModel.mm @@ -0,0 +1,33 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPContainerViewModel.h" + + +@implementation SPContainerViewModel + +- (nonnull instancetype)initWithLevels:(nonnull NSArray *)levels + levelA:(nonnull SPLevelAViewModel *)levelA +{ + if (self = [super init]) { + _levels = [levels copy]; + _levelA = levelA; + } + return self; +} + ++ (nonnull instancetype)ContainerWithLevels:(nonnull NSArray *)levels + levelA:(nonnull SPLevelAViewModel *)levelA +{ + return [[self alloc] initWithLevels:levels + levelA:levelA]; +} + +#ifndef DJINNI_DISABLE_DESCRIPTION_METHODS +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@ %p levels:%@ levelA:%@>", self.class, (void *)self, self.levels, self.levelA]; +} + +#endif +@end diff --git a/examples/generated/objc/SPLevelAViewModel+Private.mm b/examples/generated/objc/SPLevelAViewModel+Private.mm index 5000ca8a..839b303e 100644 --- a/examples/generated/objc/SPLevelAViewModel+Private.mm +++ b/examples/generated/objc/SPLevelAViewModel+Private.mm @@ -2,6 +2,14 @@ // This file was generated by Djinni from example.djinni #import "SPLevelAViewModel+Private.h" +#import "SPLevelB2CViewModel+Private.h" +#import "SPLevelB2ViewModel+Private.h" +#import "SPLevelBViewModel+Private.h" +#import "SPLevelCViewModel+Private.h" +#import "SPLevelD2ViewModel+Private.h" +#import "SPLevelDViewModel+Private.h" +#import "SPLevelEViewModel+Private.h" +#import "SPLevelFViewModel+Private.h" #import "DJIMarshal+Private.h" #include @@ -17,7 +25,44 @@ auto LevelA::fromCpp(const CppType& cpp) -> ObjcType { - return [[SPLevelAViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA))]; + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(cpp)) + { + r = LevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(cpp)) + { + r = LevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(cpp)) + { + r = LevelE::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD>(cpp)) + { + r = LevelD::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelC>(cpp)) + { + r = LevelC::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2C>(cpp)) + { + r = LevelB2C::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2>(cpp)) + { + r = LevelB2::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB>(cpp)) + { + r = LevelB::fromCpp(jniEnv, myObject); + } + else { + r = [[SPLevelAViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA))]; + } + return r; + } } // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelB2CViewModel+Private.h b/examples/generated/objc/SPLevelB2CViewModel+Private.h new file mode 100644 index 00000000..91b8e563 --- /dev/null +++ b/examples/generated/objc/SPLevelB2CViewModel+Private.h @@ -0,0 +1,24 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelB2CViewModel.h" +#include "LevelB2CViewModel.h" + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class SPLevelB2CViewModel; + +namespace djinni_generated { + +struct LevelB2C +{ + using CppType = ::transitLib::viewModel::LevelB2C; + using ObjcType = SPLevelB2CViewModel*; + + using Boxed = LevelB2C; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCpp(const CppType& cpp); +}; + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelB2CViewModel+Private.mm b/examples/generated/objc/SPLevelB2CViewModel+Private.mm new file mode 100644 index 00000000..f10e47de --- /dev/null +++ b/examples/generated/objc/SPLevelB2CViewModel+Private.mm @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelB2CViewModel+Private.h" +#import "DJIMarshal+Private.h" +#include + +namespace djinni_generated { + +auto LevelB2C::toCpp(ObjcType obj) -> CppType +{ + assert(obj); + ::transitLib::viewModel::LevelB2C model; + model.fieldA = ::djinni::String::toCpp(obj.fieldA); + model.fieldB = ::djinni::String::toCpp(obj.fieldB); + model.fieldB2 = ::djinni::String::toCpp(obj.fieldB2); + model.fieldB2C = ::djinni::String::toCpp(obj.fieldB2C); + return model; +} + +auto LevelB2C::fromCpp(const CppType& cpp) -> ObjcType +{ + ::djinni::LocalRef r; + r = [[SPLevelB2CViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldB2:(::djinni::String::fromCpp(cpp.fieldB2)) + fieldB2C:(::djinni::String::fromCpp(cpp.fieldB2C))]; + return r; + +} + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelB2CViewModel.h b/examples/generated/objc/SPLevelB2CViewModel.h new file mode 100644 index 00000000..b789b0de --- /dev/null +++ b/examples/generated/objc/SPLevelB2CViewModel.h @@ -0,0 +1,21 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import + +#import "SPLevelB2ViewModel.h" +@interface SPLevelB2CViewModel : SPLevelB2ViewModel +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; +- (nonnull instancetype)initWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2 + fieldB2C:(nonnull NSString *)fieldB2C NS_DESIGNATED_INITIALIZER; ++ (nonnull instancetype)LevelB2CWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2 + fieldB2C:(nonnull NSString *)fieldB2C; + +@property (nonatomic, readonly, nonnull) NSString * fieldB2C; + +@end diff --git a/examples/generated/objc/SPLevelB2CViewModel.mm b/examples/generated/objc/SPLevelB2CViewModel.mm new file mode 100644 index 00000000..6dd01ee8 --- /dev/null +++ b/examples/generated/objc/SPLevelB2CViewModel.mm @@ -0,0 +1,41 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelB2CViewModel.h" + + +@implementation SPLevelB2CViewModel + +- (nonnull instancetype)initWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2 + fieldB2C:(nonnull NSString *)fieldB2C +{ + if (self = [super initWithFieldA:fieldA + fieldB:fieldB + fieldB2:fieldB2]) + { + _fieldB2C = [fieldB2C copy]; + } + return self; +} + ++ (nonnull instancetype)LevelB2CWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2 + fieldB2C:(nonnull NSString *)fieldB2C +{ + return [[self alloc] initWithFieldA:fieldA + fieldB:fieldB + fieldB2:fieldB2 + fieldB2C:fieldB2C]; +} + +#ifndef DJINNI_DISABLE_DESCRIPTION_METHODS +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@ %p fieldA:%@ fieldB:%@ fieldB2:%@ fieldB2C:%@>", self.class, (void *)self, self.fieldA, self.fieldB, self.fieldB2, self.fieldB2C]; +} + +#endif +@end diff --git a/examples/generated/objc/SPLevelB2ViewModel+Private.h b/examples/generated/objc/SPLevelB2ViewModel+Private.h new file mode 100644 index 00000000..ca58e473 --- /dev/null +++ b/examples/generated/objc/SPLevelB2ViewModel+Private.h @@ -0,0 +1,24 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelB2ViewModel.h" +#include "LevelB2ViewModel.h" + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class SPLevelB2ViewModel; + +namespace djinni_generated { + +struct LevelB2 +{ + using CppType = ::transitLib::viewModel::LevelB2; + using ObjcType = SPLevelB2ViewModel*; + + using Boxed = LevelB2; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCpp(const CppType& cpp); +}; + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelB2ViewModel+Private.mm b/examples/generated/objc/SPLevelB2ViewModel+Private.mm new file mode 100644 index 00000000..6b5cd1a4 --- /dev/null +++ b/examples/generated/objc/SPLevelB2ViewModel+Private.mm @@ -0,0 +1,37 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelB2CViewModel+Private.h" +#import "SPLevelB2ViewModel+Private.h" +#import "DJIMarshal+Private.h" +#include + +namespace djinni_generated { + +auto LevelB2::toCpp(ObjcType obj) -> CppType +{ + assert(obj); + ::transitLib::viewModel::LevelB2 model; + model.fieldA = ::djinni::String::toCpp(obj.fieldA); + model.fieldB = ::djinni::String::toCpp(obj.fieldB); + model.fieldB2 = ::djinni::String::toCpp(obj.fieldB2); + return model; +} + +auto LevelB2::fromCpp(const CppType& cpp) -> ObjcType +{ + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2C>(cpp)) + { + r = LevelB2C::fromCpp(jniEnv, *myObject); + } + else { + r = [[SPLevelB2ViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldB2:(::djinni::String::fromCpp(cpp.fieldB2))]; + } + return r; + +} + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelB2ViewModel.h b/examples/generated/objc/SPLevelB2ViewModel.h new file mode 100644 index 00000000..526c6055 --- /dev/null +++ b/examples/generated/objc/SPLevelB2ViewModel.h @@ -0,0 +1,19 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import + +#import "SPLevelBViewModel.h" +@interface SPLevelB2ViewModel : SPLevelBViewModel +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; +- (nonnull instancetype)initWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2; ++ (nonnull instancetype)LevelB2WithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2; + +@property (nonatomic, readonly, nonnull) NSString * fieldB2; + +@end diff --git a/examples/generated/objc/SPLevelB2ViewModel.mm b/examples/generated/objc/SPLevelB2ViewModel.mm new file mode 100644 index 00000000..644d339d --- /dev/null +++ b/examples/generated/objc/SPLevelB2ViewModel.mm @@ -0,0 +1,37 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelB2ViewModel.h" + + +@implementation SPLevelB2ViewModel + +- (nonnull instancetype)initWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2 +{ + if (self = [super initWithFieldA:fieldA + fieldB:fieldB]) + { + _fieldB2 = [fieldB2 copy]; + } + return self; +} + ++ (nonnull instancetype)LevelB2WithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldB2:(nonnull NSString *)fieldB2 +{ + return [[self alloc] initWithFieldA:fieldA + fieldB:fieldB + fieldB2:fieldB2]; +} + +#ifndef DJINNI_DISABLE_DESCRIPTION_METHODS +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@ %p fieldA:%@ fieldB:%@ fieldB2:%@>", self.class, (void *)self, self.fieldA, self.fieldB, self.fieldB2]; +} + +#endif +@end diff --git a/examples/generated/objc/SPLevelBViewModel+Private.mm b/examples/generated/objc/SPLevelBViewModel+Private.mm index 5419670d..251f0522 100644 --- a/examples/generated/objc/SPLevelBViewModel+Private.mm +++ b/examples/generated/objc/SPLevelBViewModel+Private.mm @@ -1,7 +1,14 @@ // AUTOGENERATED FILE - DO NOT MODIFY! // This file was generated by Djinni from example.djinni +#import "SPLevelB2CViewModel+Private.h" +#import "SPLevelB2ViewModel+Private.h" #import "SPLevelBViewModel+Private.h" +#import "SPLevelCViewModel+Private.h" +#import "SPLevelD2ViewModel+Private.h" +#import "SPLevelDViewModel+Private.h" +#import "SPLevelEViewModel+Private.h" +#import "SPLevelFViewModel+Private.h" #import "DJIMarshal+Private.h" #include @@ -18,8 +25,41 @@ auto LevelB::fromCpp(const CppType& cpp) -> ObjcType { - return [[SPLevelBViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) - fieldB:(::djinni::String::fromCpp(cpp.fieldB))]; + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(cpp)) + { + r = LevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(cpp)) + { + r = LevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(cpp)) + { + r = LevelE::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD>(cpp)) + { + r = LevelD::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelC>(cpp)) + { + r = LevelC::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2C>(cpp)) + { + r = LevelB2C::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelB2>(cpp)) + { + r = LevelB2::fromCpp(jniEnv, myObject); + } + else { + r = [[SPLevelBViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB))]; + } + return r; + } } // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelCViewModel+Private.mm b/examples/generated/objc/SPLevelCViewModel+Private.mm index 8e4e9cf2..aab15e22 100644 --- a/examples/generated/objc/SPLevelCViewModel+Private.mm +++ b/examples/generated/objc/SPLevelCViewModel+Private.mm @@ -2,6 +2,10 @@ // This file was generated by Djinni from example.djinni #import "SPLevelCViewModel+Private.h" +#import "SPLevelD2ViewModel+Private.h" +#import "SPLevelDViewModel+Private.h" +#import "SPLevelEViewModel+Private.h" +#import "SPLevelFViewModel+Private.h" #import "DJIMarshal+Private.h" #include @@ -19,9 +23,30 @@ auto LevelC::fromCpp(const CppType& cpp) -> ObjcType { - return [[SPLevelCViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) - fieldB:(::djinni::String::fromCpp(cpp.fieldB)) - fieldC:(::djinni::String::fromCpp(cpp.fieldC))]; + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(cpp)) + { + r = LevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(cpp)) + { + r = LevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(cpp)) + { + r = LevelE::fromCpp(jniEnv, myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD>(cpp)) + { + r = LevelD::fromCpp(jniEnv, myObject); + } + else { + r = [[SPLevelCViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldC:(::djinni::String::fromCpp(cpp.fieldC))]; + } + return r; + } } // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelD2ViewModel+Private.h b/examples/generated/objc/SPLevelD2ViewModel+Private.h new file mode 100644 index 00000000..25cfcefd --- /dev/null +++ b/examples/generated/objc/SPLevelD2ViewModel+Private.h @@ -0,0 +1,24 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelD2ViewModel.h" +#include "LevelD2ViewModel.h" + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class SPLevelD2ViewModel; + +namespace djinni_generated { + +struct LevelD2 +{ + using CppType = ::transitLib::viewModel::LevelD2; + using ObjcType = SPLevelD2ViewModel*; + + using Boxed = LevelD2; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCpp(const CppType& cpp); +}; + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelD2ViewModel+Private.mm b/examples/generated/objc/SPLevelD2ViewModel+Private.mm new file mode 100644 index 00000000..c46c47ed --- /dev/null +++ b/examples/generated/objc/SPLevelD2ViewModel+Private.mm @@ -0,0 +1,34 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelD2ViewModel+Private.h" +#import "DJIMarshal+Private.h" +#include + +namespace djinni_generated { + +auto LevelD2::toCpp(ObjcType obj) -> CppType +{ + assert(obj); + ::transitLib::viewModel::LevelD2 model; + model.fieldA = ::djinni::String::toCpp(obj.fieldA); + model.fieldB = ::djinni::String::toCpp(obj.fieldB); + model.fieldC = ::djinni::String::toCpp(obj.fieldC); + model.fieldD = ::djinni::String::toCpp(obj.fieldD); + model.fieldD2 = ::djinni::String::toCpp(obj.fieldD2); + return model; +} + +auto LevelD2::fromCpp(const CppType& cpp) -> ObjcType +{ + ::djinni::LocalRef r; + r = [[SPLevelD2ViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldC:(::djinni::String::fromCpp(cpp.fieldC)) + fieldD:(::djinni::String::fromCpp(cpp.fieldD)) + fieldD2:(::djinni::String::fromCpp(cpp.fieldD2))]; + return r; + +} + +} // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelD2ViewModel.h b/examples/generated/objc/SPLevelD2ViewModel.h new file mode 100644 index 00000000..43d0ed3a --- /dev/null +++ b/examples/generated/objc/SPLevelD2ViewModel.h @@ -0,0 +1,23 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import + +#import "SPLevelDViewModel.h" +@interface SPLevelD2ViewModel : SPLevelDViewModel +- (nonnull instancetype)init NS_UNAVAILABLE; ++ (nonnull instancetype)new NS_UNAVAILABLE; +- (nonnull instancetype)initWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldC:(nonnull NSString *)fieldC + fieldD:(nonnull NSString *)fieldD + fieldD2:(nonnull NSString *)fieldD2 NS_DESIGNATED_INITIALIZER; ++ (nonnull instancetype)LevelD2WithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldC:(nonnull NSString *)fieldC + fieldD:(nonnull NSString *)fieldD + fieldD2:(nonnull NSString *)fieldD2; + +@property (nonatomic, readonly, nonnull) NSString * fieldD2; + +@end diff --git a/examples/generated/objc/SPLevelD2ViewModel.mm b/examples/generated/objc/SPLevelD2ViewModel.mm new file mode 100644 index 00000000..a9d5c00c --- /dev/null +++ b/examples/generated/objc/SPLevelD2ViewModel.mm @@ -0,0 +1,45 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file was generated by Djinni from example.djinni + +#import "SPLevelD2ViewModel.h" + + +@implementation SPLevelD2ViewModel + +- (nonnull instancetype)initWithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldC:(nonnull NSString *)fieldC + fieldD:(nonnull NSString *)fieldD + fieldD2:(nonnull NSString *)fieldD2 +{ + if (self = [super initWithFieldA:fieldA + fieldB:fieldB + fieldC:fieldC + fieldD:fieldD]) + { + _fieldD2 = [fieldD2 copy]; + } + return self; +} + ++ (nonnull instancetype)LevelD2WithFieldA:(nonnull NSString *)fieldA + fieldB:(nonnull NSString *)fieldB + fieldC:(nonnull NSString *)fieldC + fieldD:(nonnull NSString *)fieldD + fieldD2:(nonnull NSString *)fieldD2 +{ + return [[self alloc] initWithFieldA:fieldA + fieldB:fieldB + fieldC:fieldC + fieldD:fieldD + fieldD2:fieldD2]; +} + +#ifndef DJINNI_DISABLE_DESCRIPTION_METHODS +- (NSString *)description +{ + return [NSString stringWithFormat:@"<%@ %p fieldA:%@ fieldB:%@ fieldC:%@ fieldD:%@ fieldD2:%@>", self.class, (void *)self, self.fieldA, self.fieldB, self.fieldC, self.fieldD, self.fieldD2]; +} + +#endif +@end diff --git a/examples/generated/objc/SPLevelDViewModel+Private.mm b/examples/generated/objc/SPLevelDViewModel+Private.mm index dca3218c..5622de07 100644 --- a/examples/generated/objc/SPLevelDViewModel+Private.mm +++ b/examples/generated/objc/SPLevelDViewModel+Private.mm @@ -1,7 +1,10 @@ // AUTOGENERATED FILE - DO NOT MODIFY! // This file was generated by Djinni from example.djinni +#import "SPLevelD2ViewModel+Private.h" #import "SPLevelDViewModel+Private.h" +#import "SPLevelEViewModel+Private.h" +#import "SPLevelFViewModel+Private.h" #import "DJIMarshal+Private.h" #include @@ -20,10 +23,27 @@ auto LevelD::fromCpp(const CppType& cpp) -> ObjcType { - return [[SPLevelDViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) - fieldB:(::djinni::String::fromCpp(cpp.fieldB)) - fieldC:(::djinni::String::fromCpp(cpp.fieldC)) - fieldD:(::djinni::String::fromCpp(cpp.fieldD))]; + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelD2>(cpp)) + { + r = LevelD2::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(cpp)) + { + r = LevelF::fromCpp(jniEnv, *myObject); + } + else if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelE>(cpp)) + { + r = LevelE::fromCpp(jniEnv, myObject); + } + else { + r = [[SPLevelDViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldC:(::djinni::String::fromCpp(cpp.fieldC)) + fieldD:(::djinni::String::fromCpp(cpp.fieldD))]; + } + return r; + } } // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelEViewModel+Private.mm b/examples/generated/objc/SPLevelEViewModel+Private.mm index fb631fa2..604c444e 100644 --- a/examples/generated/objc/SPLevelEViewModel+Private.mm +++ b/examples/generated/objc/SPLevelEViewModel+Private.mm @@ -2,6 +2,7 @@ // This file was generated by Djinni from example.djinni #import "SPLevelEViewModel+Private.h" +#import "SPLevelFViewModel+Private.h" #import "DJIMarshal+Private.h" #include @@ -21,11 +22,20 @@ auto LevelE::fromCpp(const CppType& cpp) -> ObjcType { - return [[SPLevelEViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) - fieldB:(::djinni::String::fromCpp(cpp.fieldB)) - fieldC:(::djinni::String::fromCpp(cpp.fieldC)) - fieldD:(::djinni::String::fromCpp(cpp.fieldD)) - fieldE:(::djinni::String::fromCpp(cpp.fieldE))]; + ::djinni::LocalRef r; + if (auto myObject = dynamic_pointer_cast<::transitLib::viewModel::LevelF>(cpp)) + { + r = LevelF::fromCpp(jniEnv, *myObject); + } + else { + r = [[SPLevelEViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldC:(::djinni::String::fromCpp(cpp.fieldC)) + fieldD:(::djinni::String::fromCpp(cpp.fieldD)) + fieldE:(::djinni::String::fromCpp(cpp.fieldE))]; + } + return r; + } } // namespace djinni_generated diff --git a/examples/generated/objc/SPLevelFViewModel+Private.mm b/examples/generated/objc/SPLevelFViewModel+Private.mm index c9bb8b10..cc3d1288 100644 --- a/examples/generated/objc/SPLevelFViewModel+Private.mm +++ b/examples/generated/objc/SPLevelFViewModel+Private.mm @@ -21,11 +21,14 @@ auto LevelF::fromCpp(const CppType& cpp) -> ObjcType { - return [[SPLevelFViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) - fieldB:(::djinni::String::fromCpp(cpp.fieldB)) - fieldC:(::djinni::String::fromCpp(cpp.fieldC)) - fieldD:(::djinni::String::fromCpp(cpp.fieldD)) - fieldE:(::djinni::String::fromCpp(cpp.fieldE))]; + ::djinni::LocalRef r; + r = [[SPLevelFViewModel alloc] initWithFieldA:(::djinni::String::fromCpp(cpp.fieldA)) + fieldB:(::djinni::String::fromCpp(cpp.fieldB)) + fieldC:(::djinni::String::fromCpp(cpp.fieldC)) + fieldD:(::djinni::String::fromCpp(cpp.fieldD)) + fieldE:(::djinni::String::fromCpp(cpp.fieldE))]; + return r; + } } // namespace djinni_generated diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index a0692f19..808fabdb 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -23,6 +23,7 @@ import djinni.ast._ import djinni.generatorTools._ import djinni.meta._ import djinni.writer.IndentWriter +import scala.util.matching.Regex import scala.collection.mutable @@ -204,6 +205,14 @@ class CppGenerator(spec: Spec) extends Generator(spec) { val self = marshal.typename(ident, r) val isRecordInherited = isInherited(idl, ident.name) + if (isRecordInherited) { + val childrenRecords = getChildrenRecords(marshal, ident, idl, ident.name) + // for (childRecord <- childrenRecords) { + // println("Found child record: " + getRecordName(childRecord) + " of parent: " + ident.name) + // } + } + + val superRecord = getSuperRecord(idl, r) superRecord match { @@ -242,7 +251,22 @@ class CppGenerator(spec: Spec) extends Generator(spec) { for (f <- r.fields) { writeDoc(w, f.doc) val defaultValue = if (f.defaultValue.isEmpty) "" else " = " + f.defaultValue - w.wl(marshal.fieldType(f.ty) + " " + idCpp.field(f.ident) + defaultValue + ";") + + var fullFieldType = marshal.fieldType(f.ty) + var fieldType = fullFieldType + + if (fullFieldType.contains("vector")) { + val rootTypePattern: Regex = "^(?:std::vector<)?(.+?)(?:>)?$".r + rootTypePattern.findFirstMatchIn(fieldType) match { + case Some(value) => fieldType = value.group(1) + case None => //nothing + } + } + + + val isFieldInherited = isInherited(idl, fieldType) + fullFieldType = if (isFieldInherited) fullFieldType.replace(fieldType,"std::shared_ptr<"+fieldType+">") else fullFieldType + w.wl(fullFieldType + " " + idCpp.field(f.ident) + defaultValue + ";") } if (r.derivingTypes.contains(DerivingType.Eq)) { diff --git a/src/source/JNIGenerator.scala b/src/source/JNIGenerator.scala index ba824231..e0222a33 100644 --- a/src/source/JNIGenerator.scala +++ b/src/source/JNIGenerator.scala @@ -44,6 +44,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { val cppPrefix = cppPrefixOverride.getOrElse(spec.jniIncludeCppPrefix) jniHpp.add("#include " + q(cppPrefix + spec.cppFileIdentStyle(name) + "." + spec.cppHeaderExt)) jniHpp.add("#include " + q(spec.jniBaseLibIncludePrefix + "djinni_support.hpp")) + spec.cppNnHeader match { case Some(nnHdr) => jniHpp.add("#include " + nnHdr) case _ => @@ -106,11 +107,33 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { val fields = superFields ++ r.fields + val isRecordInherited = isInherited(idl, ident.name) + val childrenRecords = getChildrenRecords(jniMarshal, ident, idl, ident.name).reverse + val refs = new JNIRefs(ident.name, prefixOverride) fields.foreach(f => refs.find(f.ty)) + if (isRecordInherited && childrenRecords.nonEmpty) { + for (childRecord <- childrenRecords) { + getRecordIdent(idl, childRecord) match { + case Some(childIdent) => + val childJniHelper = jniMarshal.helperClass(childIdent) + val childJniHelperWithParams = childJniHelper + typeParamsSignature(params) + refs.jniCpp.add(s"#include ${'"'}$childJniHelperWithParams.${spec.cppHeaderExt}${'"'}") + case _ => + //nothing + } + } + } + + val jniHelper = jniMarshal.helperClass(ident) - val cppSelf = cppMarshal.fqTypename(ident, r) + cppTypeArgs(params) + val accessor = if (isRecordInherited) "->" else "." + + var cppSelf = cppMarshal.fqTypename(ident, r) + cppTypeArgs(params) + if (isRecordInherited) { + cppSelf = "std::shared_ptr<"+cppSelf+">" + } def writeJniPrototype(w: IndentWriter) { writeJniTypeParams(w, params) @@ -149,6 +172,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { case Some(value) => value.fields } + val jniHelperWithParams = jniHelper + typeParamsSignature(params) // Defining ctor/dtor in the cpp file reduces build times writeJniTypeParams(w, params) @@ -159,20 +183,65 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { w.wl val fields = superFields ++ r.fields - + writeJniTypeParams(w, params) w.w(s"auto $jniHelperWithParams::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef").braced{ //w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);") + + + w.wl("::djinni::LocalRef r;") + + var hasChildren = false + if (isRecordInherited && childrenRecords.nonEmpty) { + hasChildren = true + var index = 0 + for (childRecord <- childrenRecords) { + getRecordIdent(idl, childRecord) match { + case Some(childIdent) => + val childJniHelper = jniMarshal.helperClass(childIdent) + val childJniHelperWithParams = childJniHelper + typeParamsSignature(params) + + val cppChild = cppMarshal.fqTypename(childIdent, childRecord) + cppTypeArgs(params) + + if (index == 0) { + w.wl(s"if (auto myObject = dynamic_pointer_cast<"+cppChild+">(c))") + } + else { + w.wl(s"else if (auto myObject = dynamic_pointer_cast<"+cppChild+">(c))") + } + + w.braced { + val objectValue = if (isInherited(idl, childIdent)) { + "myObject" + } else { + "*myObject" + } + w.wl(s"r = $childJniHelperWithParams::fromCpp(jniEnv, $objectValue);") + } + + + case _ => + //nothing + } + + + index += 1 + } + + w.wl("else {") + w.increase() + } + if(fields.isEmpty) w.wl("(void)c; // Suppress warnings in release builds for empty records") w.wl(s"const auto& data = ::djinni::JniClass<$jniHelper>::get();") - val call = "auto r = ::djinni::LocalRef{jniEnv->NewObject(" + val call = "r = ::djinni::LocalRef{jniEnv->NewObject(" w.w(call + "data.clazz.get(), data.jconstructor") if(fields.nonEmpty) { w.wl(",") writeAlignedCall(w, " " * call.length(), fields, ")}", f => { val name = idCpp.field(f.ident) val param = jniMarshal.fromCpp(f.ty, - cppMarshal.maybeMove(s"c.$name", f.ty)) + cppMarshal.maybeMove(s"c$accessor$name", f.ty)) s"::djinni::get($param)" }) } @@ -180,6 +249,11 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { w.w(")}") w.wl(";") w.wl(s"::djinni::jniExceptionCheck(jniEnv);") + + if (hasChildren) { + w.decrease() + w.wl("}") + } w.wl(s"return r;") } w.wl @@ -197,7 +271,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { val fieldId = "data.field_" + idJava.field(f.ident) val jniFieldAccess = toJniCall(f.ty, (jt: String) => s"jniEnv->Get${jt}Field(j, $fieldId)") - w.wl(s"model.${idJava.field(f.ident)} = "+jniMarshal.toCpp(f.ty, jniFieldAccess)+";") + w.wl(s"model$accessor${idJava.field(f.ident)} = "+jniMarshal.toCpp(f.ty, jniFieldAccess)+";") } w.wl("return model;") @@ -478,7 +552,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { val moduleNameJava = spec.javaIdentStyle.ty(spec.moduleName + "Module") val includes = s"#include ${q(spec.jniBaseLibIncludePrefix + "djinni_support.hpp")}" :: decls.map(td => s"#include ${q(spec.jniFileIdentStyle(td.ident) + "." + spec.cppHeaderExt)}").toList - + writeJniHppFile(moduleName, "MODULE", List.empty, List.empty, w => { }) writeJniCppFile(moduleName, "MODULE", includes, w => { diff --git a/src/source/ObjcppGenerator.scala b/src/source/ObjcppGenerator.scala index ea7f1648..a8ee091c 100644 --- a/src/source/ObjcppGenerator.scala +++ b/src/source/ObjcppGenerator.scala @@ -345,6 +345,9 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { val fields = superFields ++ r.fields + val isRecordInherited = isInherited(idl, ident.name) + val childrenRecords = getChildrenRecords(objcMarshal, ident, idl, ident.name).reverse + val refs = new ObjcRefs() for (c <- r.consts) refs.find(c.ty) @@ -361,6 +364,20 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { refs.body.add("#include ") refs.body.add("!#import " + q(spec.objcppIncludePrefix + objcppMarshal.privateHeaderName(objcName))) + + if (isRecordInherited && childrenRecords.nonEmpty) { + for (childRecord <- childrenRecords) { + getRecordIdent(idl, childRecord) match { + case Some(childIdent) => + val childObjcHelper = objcppMarshal.helperClass(childIdent) + val objcChildName = childObjcHelper + (if (r.ext.objc) "_base" else "") + refs.body.add("!#import " + q(spec.objcppIncludePrefix + objcppMarshal.privateHeaderName(objcChildName))) + case _ => + //nothing + } + } + } + def checkMutable(tm: MExpr): Boolean = tm.base match { case MOptional => checkMutable(tm.args.head) case MString => true @@ -409,9 +426,59 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { w.braced { if(fields.isEmpty) w.wl("(void)cpp; // Suppress warnings in relase builds for empty records") // val first = if(r.fields.isEmpty) "" else IdentStyle.camelUpper("with_" + r.fields.head.ident.name) - val call = s"return [[$noBaseSelf alloc] init$firstInitializerArg" + w.wl(s"::djinni::LocalRef r;") + + var hasChildren = false + if (isRecordInherited && childrenRecords.nonEmpty) { + hasChildren = true + var index = 0 + for (childRecord <- childrenRecords) { + getRecordIdent(idl, childRecord) match { + case Some(childIdent) => + val childObjcHelper = objcppMarshal.helperClass(childIdent) + + val cppChild = cppMarshal.fqTypename(childIdent, childRecord) + cppTypeArgs(params) + + if (index == 0) { + w.wl(s"if (auto myObject = dynamic_pointer_cast<"+cppChild+">(cpp))") + } + else { + w.wl(s"else if (auto myObject = dynamic_pointer_cast<"+cppChild+">(cpp))") + } + + w.braced { + val objectValue = if (isInherited(idl, childIdent)) { + "myObject" + } else { + "*myObject" + } + w.wl(s"r = $childObjcHelper::fromCpp(jniEnv, $objectValue);") + } + + + case _ => + //nothing + } + + + index += 1 + } + + w.wl("else {") + w.increase() + } + + val call = s"r = [[$noBaseSelf alloc] init$firstInitializerArg" writeAlignedObjcCall(w, call, fields, "]", f => (idObjc.field(f.ident), s"(${objcppMarshal.fromCpp(f.ty, "cpp." + idCpp.field(f.ident))})")) w.wl(";") + + if (hasChildren) { + w.decrease() + w.wl("}") + } + + w.wl(s"return r;") + w.wl } }) }) @@ -438,4 +505,7 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { f(w) }) } + + def cppTypeArgs(params: Seq[TypeParam]): String = + if (params.isEmpty) "" else params.map(p => idCpp.typeParam(p.ident)).mkString("<", ", ", ">") } diff --git a/src/source/generator.scala b/src/source/generator.scala index 778279eb..2599b976 100644 --- a/src/source/generator.scala +++ b/src/source/generator.scala @@ -512,6 +512,77 @@ abstract class Generator(spec: Spec) return false } + def getChildrenRecords(marshal: Marshal, ident: Ident, idl: Seq[TypeDecl], _name: String) : Seq[Record] = { + def recursiveSearchForChildren(idl: Seq[TypeDecl], name: String) : Seq[Record] = { + var foundChildren : Seq[Record] = Seq.empty + val filtered = idl.filter(td => td.ident.name != name) + for (element <- filtered) { + element.body match { + case myRecord: Record => { + myRecord.baseRecord match { + case None => None + case Some(value) => { + if (value == name) { + idl.find(td => td.ident.name == element.ident.name) match { + case Some(dec) => dec.body match { + case record: Record => { + foundChildren = foundChildren :+ record + foundChildren = foundChildren ++ recursiveSearchForChildren(idl, dec.ident.name) + } + case _ => throw new AssertionError("Unreachable. The parser throws an exception when extending a non-interface type.") + } + case _ => throw new AssertionError("Unreachable. The parser throws an exception when extending an interface that doesn't exist.") + } + + + } + } + } + } + case _ => None + } + } + return foundChildren + } + + val childrenRecords = recursiveSearchForChildren(idl, _name) + // println("childrenRecords size "+childrenRecords.length+" for "+_name) + // for (child <- childrenRecords) { + // println("child "+getRecordName(idl, child)) + // } + + return childrenRecords + } + + def getRecordName(idl: Seq[TypeDecl], record : Record) : String = { + for (element <- idl) { + element.body match { + case myRecord: Record => { + if (myRecord == record) { + return element.ident.name + } + } + case _ => return "not found" + } + } + return "not found" + } + + def getRecordIdent(idl: Seq[TypeDecl], record : Record) : Option[Ident] = { + for (element <- idl) { + element.body match { + case myRecord: Record => { + if (myRecord == record) { + return Some(element.ident) + } + } + + case _ => None + } + } + return None + } + // -------------------------------------------------------------------------- // Render type expression