diff --git a/example/generated-src/cpp/sort_items.hpp b/example/generated-src/cpp/sort_items.hpp index a01d3936c..687b8249e 100644 --- a/example/generated-src/cpp/sort_items.hpp +++ b/example/generated-src/cpp/sort_items.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include namespace textsort { @@ -15,6 +16,33 @@ class SortItems { public: virtual ~SortItems() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/textsort/SortItems$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "TXSSortItems"; } + /** For the iOS / Android demo */ virtual void sort(sort_order order, const ItemList & items) = 0; diff --git a/example/generated-src/cpp/textbox_listener.hpp b/example/generated-src/cpp/textbox_listener.hpp index 5770120d9..dcc1cb9ee 100644 --- a/example/generated-src/cpp/textbox_listener.hpp +++ b/example/generated-src/cpp/textbox_listener.hpp @@ -3,6 +3,8 @@ #pragma once +#include + namespace textsort { struct ItemList; @@ -11,6 +13,33 @@ class TextboxListener { public: virtual ~TextboxListener() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "TXSTextboxListener"; } + virtual void update(const ItemList & items) = 0; }; diff --git a/example/generated-src/java/com/dropbox/textsort/SortItems.java b/example/generated-src/java/com/dropbox/textsort/SortItems.java index beeef710c..177389bd1 100644 --- a/example/generated-src/java/com/dropbox/textsort/SortItems.java +++ b/example/generated-src/java/com/dropbox/textsort/SortItems.java @@ -41,6 +41,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // SortItems methods + @Override public void sort(SortOrder order, ItemList items) { diff --git a/example/generated-src/objc/TXSSortItems+Private.mm b/example/generated-src/objc/TXSSortItems+Private.mm index 9368ce974..dab7da356 100644 --- a/example/generated-src/objc/TXSSortItems+Private.mm +++ b/example/generated-src/objc/TXSSortItems+Private.mm @@ -32,6 +32,13 @@ - (id)initWithCpp:(const std::shared_ptr<::textsort::SortItems>&)cppRef return self; } +- (const std::shared_ptr<::textsort::SortItems>&) cppRef +{ + return _cppRefHandle.get(); +} + +// TXSSortItems methods + - (void)sort:(TXSSortOrder)order items:(nonnull TXSItemList *)items { try { @@ -61,7 +68,7 @@ + (nonnull TXSItemList *)runSort:(nonnull TXSItemList *)items { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto SortItems::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/example/generated-src/objc/TXSTextboxListener+Private.mm b/example/generated-src/objc/TXSTextboxListener+Private.mm index 18ef89465..276faac4d 100644 --- a/example/generated-src/objc/TXSTextboxListener+Private.mm +++ b/example/generated-src/objc/TXSTextboxListener+Private.mm @@ -17,6 +17,8 @@ { public: using Handle::Handle; + + // TextboxListener methods void update(const ::textsort::ItemList & c_items) override { @autoreleasepool { diff --git a/example/generated-src/objc/TXSTextboxListener.h b/example/generated-src/objc/TXSTextboxListener.h index b57313a8c..f3d8cf426 100644 --- a/example/generated-src/objc/TXSTextboxListener.h +++ b/example/generated-src/objc/TXSTextboxListener.h @@ -5,7 +5,7 @@ #import -@protocol TXSTextboxListener +@protocol TXSTextboxListener - (void)update:(nonnull TXSItemList *)items; diff --git a/example/objc/TextSort.xcodeproj/project.pbxproj b/example/objc/TextSort.xcodeproj/project.pbxproj index 8f534fb5f..f5d1562d3 100644 --- a/example/objc/TextSort.xcodeproj/project.pbxproj +++ b/example/objc/TextSort.xcodeproj/project.pbxproj @@ -150,7 +150,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = TXS; - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0730; ORGANIZATIONNAME = "Dropbox, Inc."; }; buildConfigurationList = 65834DD819AC599E0061AD3F /* Build configuration list for PBXProject "TextSort" */; @@ -236,6 +236,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -301,6 +302,7 @@ GCC_PREFIX_HEADER = "TextSort/TextSort-Prefix.pch"; INFOPLIST_FILE = "TextSort/TextSort-Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = "Dropbox.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = 1; WRAPPER_EXTENSION = app; @@ -316,6 +318,7 @@ GCC_PREFIX_HEADER = "TextSort/TextSort-Prefix.pch"; INFOPLIST_FILE = "TextSort/TextSort-Info.plist"; LIBRARY_SEARCH_PATHS = "$(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = "Dropbox.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = 1; WRAPPER_EXTENSION = app; diff --git a/example/objc/TextSort.xcodeproj/xcshareddata/xcschemes/TextSort.xcscheme b/example/objc/TextSort.xcodeproj/xcshareddata/xcschemes/TextSort.xcscheme index f3120ac80..b5c1ee841 100644 --- a/example/objc/TextSort.xcodeproj/xcshareddata/xcschemes/TextSort.xcscheme +++ b/example/objc/TextSort.xcodeproj/xcshareddata/xcschemes/TextSort.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -38,17 +38,21 @@ ReferencedContainer = "container:TextSort.xcodeproj"> + + - + - + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - Dropbox.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index 119636fd7..298bb1ff5 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -27,28 +27,34 @@ import scala.collection.mutable class CppGenerator(spec: Spec) extends Generator(spec) { val marshal = new CppMarshal(spec) + val jniMarshal = new JNIMarshal(spec) + val objcMarshal = new ObjcMarshal(spec) val writeCppFile = writeCppFileGeneric(spec.cppOutFolder.get, spec.cppNamespace, spec.cppFileIdentStyle, spec.cppIncludePrefix) _ def writeHppFile(name: String, origin: String, includes: Iterable[String], fwds: Iterable[String], f: IndentWriter => Unit, f2: IndentWriter => Unit = (w => {})) = writeHppFileGeneric(spec.cppHeaderOutFolder.get, spec.cppNamespace, spec.cppFileIdentStyle)(name, origin, includes, fwds, f, f2) - class CppRefs(name: String) { + class CppRefs(ident: Ident) { var hpp = mutable.TreeSet[String]() var hppFwds = mutable.TreeSet[String]() var cpp = mutable.TreeSet[String]() + def addInclude(ident: Ident) { + hpp.add(s"#include ${marshal.include(ident)}") + } + def find(ty: TypeRef, forwardDeclareOnly: Boolean) { find(ty.resolved, forwardDeclareOnly) } def find(tm: MExpr, forwardDeclareOnly: Boolean) { tm.args.foreach((x) => find(x, forwardDeclareOnly)) find(tm.base, forwardDeclareOnly) } def find(m: Meta, forwardDeclareOnly : Boolean) = { - for(r <- marshal.hppReferences(m, name, forwardDeclareOnly)) r match { + for(r <- marshal.hppReferences(m, ident.name, forwardDeclareOnly)) r match { case ImportRef(arg) => hpp.add("#include " + arg) case DeclRef(decl, Some(spec.cppNamespace)) => hppFwds.add(decl) case DeclRef(_, _) => } - for(r <- marshal.cppReferences(m, name, forwardDeclareOnly)) r match { + for(r <- marshal.cppReferences(m, ident.name, forwardDeclareOnly)) r match { case ImportRef(arg) => cpp.add("#include " + arg) case DeclRef(_, _) => } @@ -56,7 +62,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { } override def generateEnum(origin: String, ident: Ident, doc: Doc, e: Enum) { - val refs = new CppRefs(ident.name) + val refs = new CppRefs(ident) val self = marshal.typename(ident, e) if (spec.cppEnumHashWorkaround) { @@ -135,7 +141,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { } override def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record) { - val refs = new CppRefs(ident.name) + val refs = new CppRefs(ident) r.fields.foreach(f => refs.find(f.ty, false)) r.consts.foreach(c => refs.find(c.ty, false)) refs.hpp.add("#include ") // Add for std::move @@ -262,8 +268,14 @@ class CppGenerator(spec: Spec) extends Generator(spec) { } - override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { - val refs = new CppRefs(ident.name) + override def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { + val refs = new CppRefs(ident) + if (i.superIdent.isDefined) { + refs.addInclude(i.superIdent.get) + } + + refs.hpp.add("#include ") // needed for std::string jniProxyClassName(); + i.methods.map(m => { m.params.map(p => refs.find(p.ty, true)) m.ret.foreach((x)=>refs.find(x, true)) @@ -273,15 +285,54 @@ class CppGenerator(spec: Spec) extends Generator(spec) { }) val self = marshal.typename(ident, i) + val superNametype = marshal.superTypename(i) val methodNamesInScope = i.methods.map(m => idCpp.method(m.ident)) writeHppFile(ident, origin, refs.hpp, refs.hppFwds, w => { + writeDoc(w, doc) writeCppTypeParams(w, typeParams) - w.w(s"class $self").bracedSemi { + + val extendsDef = if (superNametype.isDefined) " : public " + superNametype.get else "" + w.w(s"class $self$extendsDef").bracedSemi { w.wlOutdent("public:") // Destructor w.wl(s"virtual ~$self() {}") + + // Proxy class name + val jniProxyClassName = if (i.ext.cpp) q(jniMarshal.undecoratedTypename(ident, i) + "$CppProxy") else "nullptr" + w.wl + w.wl("/**") + w.wl(" * Defines the name of the JNI C++ proxy class. Used to convert a") + w.wl(" * C++ implemented object to a Java object when the type of the object being") + w.wl(" * converted is unknown to the JniInterface (see djinni_support.hpp).") + w.wl(" * ") + w.wl(" * The proxy class name is only used for converting Djinni interfaces that") + w.wl(" * are implemented in C++. Java implemented interfaces are converted differently.") + w.wl(" * However, the C++ class of an interface implemented in Java must still have a") + w.wl(" * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile.") + w.wl(" * ") + w.wl(" * @return The name of the class's associated JNI proxy class.") + w.wl(" * ") + w.wl(" * @see JniInterface in djinni_support.hpp") + w.wl(" */") + w.wl(s"virtual const std::string jniProxyClassName() { return $jniProxyClassName; }") + + val objcTypeName = objcMarshal.typename(ident, i) + val objcProxyClassName = q(if (i.ext.objc && i.ext.cpp) objcTypeName + "CppProxy" else objcTypeName) + + w.wl + w.wl("/**") + w.wl(" * Defines the name of the Objective-C type for the class. Used to convert a") + w.wl(" * C++ object to an Objective-C object when the type of the object being") + w.wl(" * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp).") + w.wl(" * ") + w.wl(" * @return The name of the Objective C type associated with the class.") + w.wl(" * ") + w.wl(" * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp") + w.wl(" */") + w.wl(s"virtual const std::string objcProxyClassName() { return $objcProxyClassName; }") + // Constants generateHppConstants(w, i.consts) // Methods @@ -313,5 +364,4 @@ class CppGenerator(spec: Spec) extends Generator(spec) { if (params.isEmpty) return w.wl("template " + params.map(p => "typename " + idCpp.typeParam(p.ident)).mkString("<", ", ", ">")) } - } diff --git a/src/source/CppMarshal.scala b/src/source/CppMarshal.scala index fd991fa2d..53cd05f34 100644 --- a/src/source/CppMarshal.scala +++ b/src/source/CppMarshal.scala @@ -26,6 +26,11 @@ class CppMarshal(spec: Spec) extends Marshal(spec) { case r: Record => withNs(Some(spec.cppNamespace), idCpp.ty(name)) } + def superTypename(ty: TypeDef): Option[String] = ty match { + case i: Interface => if (i.superIdent.isDefined) Some(idCpp.ty(i.superIdent.get.name)) else None + case _ => None + } + def paramType(tm: MExpr, scopeSymbols: Seq[String]): String = toCppParamType(tm, None, scopeSymbols) def paramType(ty: TypeRef, scopeSymbols: Seq[String]): String = paramType(ty.resolved, scopeSymbols) override def paramType(tm: MExpr): String = toCppParamType(tm) diff --git a/src/source/JNIGenerator.scala b/src/source/JNIGenerator.scala index c36234ec0..01e41d7c7 100644 --- a/src/source/JNIGenerator.scala +++ b/src/source/JNIGenerator.scala @@ -47,6 +47,10 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { case _ => } + def addHppInclude(name: String): Unit = { + jniHpp.add("#include " + name) + } + def find(ty: TypeRef) { find(ty.resolved) } def find(tm: MExpr) { tm.args.foreach(find) @@ -175,12 +179,21 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { writeJniFiles(origin, params.nonEmpty, ident, refs, writeJniPrototype, writeJniBody) } - override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { + override def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { val refs = new JNIRefs(ident.name) + + if (i.superIdent.isDefined) { + refs.addHppInclude(jniMarshal.include(i.superIdent.get.name)) + } + i.methods.foreach(m => { m.params.foreach(p => refs.find(p.ty)) m.ret.foreach(refs.find) }) + getInterfaceSuperMethods(i, idl).foreach(m => { + m.params.foreach(p => refs.find(p.ty)) + m.ret.foreach(refs.find) + }) i.consts.foreach(c => { refs.find(c.ty) }) @@ -232,22 +245,33 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { w.wl(s"JavaProxy(JniType j);") w.wl(s"~JavaProxy();") w.wl - for (m <- i.methods) { - val ret = cppMarshal.fqReturnType(m.ret) - val params = m.params.map(p => cppMarshal.fqParamType(p.ty) + " " + idCpp.local(p.ident)) - w.wl(s"$ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")} override;") + + def writeJavaProxyMethodDecls(w: IndentWriter, methods: Seq[Interface.Method]) { + for (m <- methods) { + val ret = cppMarshal.fqReturnType(m.ret) + val params = m.params.map(p => cppMarshal.fqParamType(p.ty) + " " + idCpp.local(p.ident)) + w.wl(s"$ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")} override;") + } } + writeJavaProxyMethodDecls(w, getInterfaceSuperMethods(i, idl)) + writeJavaProxyMethodDecls(w, i.methods) + w.wl w.wlOutdent(s"private:") w.wl(s"friend ::djinni::JniInterface<$cppSelf, ${withNs(Some(spec.jniNamespace), jniSelf)}>;") } w.wl w.wl(s"const ::djinni::GlobalRef clazz { ::djinni::jniFindClass(${q(classLookup)}) };") - for (m <- i.methods) { - val javaMethodName = idJava.method(m.ident) - val javaMethodSig = q(jniMarshal.javaMethodSignature(m.params, m.ret)) - w.wl(s"const jmethodID method_$javaMethodName { ::djinni::jniGetMethodID(clazz.get(), ${q(javaMethodName)}, $javaMethodSig) };") + + def writeJavaProxyJniMethods(w: IndentWriter, methods: Seq[Interface.Method]) { + for (m <- methods) { + val javaMethodName = idJava.method(m.ident) + val javaMethodSig = q(jniMarshal.javaMethodSignature(m.params, m.ret)) + w.wl(s"const jmethodID method_$javaMethodName { ::djinni::jniGetMethodID(clazz.get(), ${q(javaMethodName)}, $javaMethodSig) };") + } } + writeJavaProxyJniMethods(w, getInterfaceSuperMethods(i, idl)) + writeJavaProxyJniMethods(w, i.methods) } } } @@ -269,46 +293,51 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { writeJniTypeParams(w, typeParams) w.wl(s"$jniSelfWithParams::JavaProxy::~JavaProxy() = default;") w.wl - for (m <- i.methods) { - val ret = cppMarshal.fqReturnType(m.ret) - val params = m.params.map(p => cppMarshal.fqParamType(p.ty) + " c_" + idCpp.local(p.ident)) - writeJniTypeParams(w, typeParams) - val methodNameAndSignature: String = s"${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}" - w.w(s"$ret $jniSelfWithParams::JavaProxy::$methodNameAndSignature").braced { - w.wl(s"auto jniEnv = ::djinni::jniGetThreadEnv();") - w.wl(s"::djinni::JniLocalScope jscope(jniEnv, 10);") - w.wl(s"const auto& data = ::djinni::JniClass<${withNs(Some(spec.jniNamespace), jniSelf)}>::get();") - val call = m.ret.fold("jniEnv->CallVoidMethod(")(r => "auto jret = " + toJniCall(r, (jt: String) => s"jniEnv->Call${jt}Method(")) - w.w(call) - val javaMethodName = idJava.method(m.ident) - w.w(s"Handle::get().get(), data.method_$javaMethodName") - if(m.params.nonEmpty){ - w.wl(",") - writeAlignedCall(w, " " * call.length(), m.params, ")", p => { - val param = jniMarshal.fromCpp(p.ty, "c_" + idCpp.local(p.ident)) - s"::djinni::get($param)" + + def writeJavaProxyMethodImpls(w: IndentWriter, methods: Seq[Interface.Method]) { + for (m <- methods) { + val ret = cppMarshal.fqReturnType(m.ret) + val params = m.params.map(p => cppMarshal.fqParamType(p.ty) + " c_" + idCpp.local(p.ident)) + writeJniTypeParams(w, typeParams) + val methodNameAndSignature: String = s"${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}" + w.w(s"$ret $jniSelfWithParams::JavaProxy::$methodNameAndSignature").braced { + w.wl(s"auto jniEnv = ::djinni::jniGetThreadEnv();") + w.wl(s"::djinni::JniLocalScope jscope(jniEnv, 10);") + w.wl(s"const auto& data = ::djinni::JniClass<${withNs(Some(spec.jniNamespace), jniSelf)}>::get();") + val call = m.ret.fold("jniEnv->CallVoidMethod(")(r => "auto jret = " + toJniCall(r, (jt: String) => s"jniEnv->Call${jt}Method(")) + w.w(call) + val javaMethodName = idJava.method(m.ident) + w.w(s"Handle::get().get(), data.method_$javaMethodName") + if(m.params.nonEmpty){ + w.wl(",") + writeAlignedCall(w, " " * call.length(), m.params, ")", p => { + val param = jniMarshal.fromCpp(p.ty, "c_" + idCpp.local(p.ident)) + s"::djinni::get($param)" + }) + } + else + w.w(")") + w.wl(";") + w.wl(s"::djinni::jniExceptionCheck(jniEnv);") + m.ret.fold()(ty => { + (spec.cppNnCheckExpression, isInterface(ty.resolved)) match { + case (Some(check), true) => { + // We have a non-optional interface, assert that we're getting a non-null value + val javaParams = m.params.map(p => javaMarshal.fqParamType(p.ty) + " " + idJava.local(p.ident)) + val javaParamsString: String = javaParams.mkString("(", ",", ")") + val functionString: String = s"${javaMarshal.fqTypename(ident, i)}#$javaMethodName$javaParamsString" + w.wl(s"""DJINNI_ASSERT_MSG(jret, jniEnv, "Got unexpected null return value from function $functionString");""") + w.wl(s"return ${jniMarshal.toCpp(ty, "jret")};") + } + case _ => + } + w.wl(s"return ${jniMarshal.toCpp(ty, "jret")};") }) } - else - w.w(")") - w.wl(";") - w.wl(s"::djinni::jniExceptionCheck(jniEnv);") - m.ret.fold()(ty => { - (spec.cppNnCheckExpression, isInterface(ty.resolved)) match { - case (Some(check), true) => { - // We have a non-optional interface, assert that we're getting a non-null value - val javaParams = m.params.map(p => javaMarshal.fqParamType(p.ty) + " " + idJava.local(p.ident)) - val javaParamsString: String = javaParams.mkString("(", ",", ")") - val functionString: String = s"${javaMarshal.fqTypename(ident, i)}#$javaMethodName$javaParamsString" - w.wl(s"""DJINNI_ASSERT_MSG(jret, jniEnv, "Got unexpected null return value from function $functionString");""") - w.wl(s"return ${jniMarshal.toCpp(ty, "jret")};") - } - case _ => - } - w.wl(s"return ${jniMarshal.toCpp(ty, "jret")};") - }) } } + writeJavaProxyMethodImpls(w, getInterfaceSuperMethods(i, idl)) + writeJavaProxyMethodImpls(w, i.methods) } if (i.ext.cpp) { // Generate CEXPORT functions for JNI to call. @@ -342,30 +371,35 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { nativeHook("nativeDestroy", false, Seq.empty, None, { w.wl(s"delete reinterpret_cast<::djinni::CppProxyHandle<$cppSelf>*>(nativeRef);") }) - for (m <- i.methods) { - val nativeAddon = if (m.static) "" else "native_" - nativeHook(nativeAddon + idJava.method(m.ident), m.static, m.params, m.ret, { - //w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);") - if (!m.static) w.wl(s"const auto& ref = ::djinni::objectFromHandleAddress<$cppSelf>(nativeRef);") - m.params.foreach(p => { - if (isInterface(p.ty.resolved) && spec.cppNnCheckExpression.nonEmpty) { - // We have a non-optional interface in nn mode, assert that we're getting a non-null value - val paramName = idJava.local(p.ident) - val javaMethodName = idJava.method(m.ident) - val javaParams = m.params.map(p => javaMarshal.fqParamType(p.ty) + " " + idJava.local(p.ident)) - val javaParamsString: String = javaParams.mkString("(", ", ", ")") - val functionString: String = s"${javaMarshal.fqTypename(ident, i)}#$javaMethodName$javaParamsString" - w.wl( s"""DJINNI_ASSERT_MSG(j_$paramName, jniEnv, "Got unexpected null parameter '$paramName' to function $functionString");""") - } + + def writeJniMethods(w: IndentWriter, methods: Seq[Interface.Method]) { + for (m <- methods) { + val nativeAddon = if (m.static) "" else "native_" + nativeHook(nativeAddon + idJava.method(m.ident), m.static, m.params, m.ret, { + //w.wl(s"::${spec.jniNamespace}::JniLocalScope jscope(jniEnv, 10);") + if (!m.static) w.wl(s"const auto& ref = ::djinni::objectFromHandleAddress<$cppSelf>(nativeRef);") + m.params.foreach(p => { + if (isInterface(p.ty.resolved) && spec.cppNnCheckExpression.nonEmpty) { + // We have a non-optional interface in nn mode, assert that we're getting a non-null value + val paramName = idJava.local(p.ident) + val javaMethodName = idJava.method(m.ident) + val javaParams = m.params.map(p => javaMarshal.fqParamType(p.ty) + " " + idJava.local(p.ident)) + val javaParamsString: String = javaParams.mkString("(", ", ", ")") + val functionString: String = s"${javaMarshal.fqTypename(ident, i)}#$javaMethodName$javaParamsString" + w.wl( s"""DJINNI_ASSERT_MSG(j_$paramName, jniEnv, "Got unexpected null parameter '$paramName' to function $functionString");""") + } + }) + val methodName = idCpp.method(m.ident) + val ret = m.ret.fold("")(r => "auto r = ") + 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 ::djinni::release(${jniMarshal.fromCpp(r, "r")});")) }) - val methodName = idCpp.method(m.ident) - val ret = m.ret.fold("")(r => "auto r = ") - 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 ::djinni::release(${jniMarshal.fromCpp(r, "r")});")) - }) + } } + writeJniMethods(w, getInterfaceSuperMethods(i, idl)) + writeJniMethods(w, i.methods) } } diff --git a/src/source/JavaGenerator.scala b/src/source/JavaGenerator.scala index d97299a63..5795ed9e4 100644 --- a/src/source/JavaGenerator.scala +++ b/src/source/JavaGenerator.scala @@ -120,16 +120,22 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { }) } - override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { + override def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { val refs = new JavaRefs() - i.methods.map(m => { - m.params.map(p => refs.find(p.ty)) - m.ret.foreach(refs.find) - }) - i.consts.map(c => { - refs.find(c.ty) - }) + def mapRefs(i: Interface) { + i.methods.map(m => { + m.params.map(p => refs.find(p.ty)) + m.ret.foreach(refs.find) + }) + i.consts.map(c => { + refs.find(c.ty) + }) + } + + marshal.superInterfacesForInterface(i, idl).foreach { mapRefs(_) } + mapRefs(i) + if (i.ext.cpp) { refs.java.add("java.util.concurrent.atomic.AtomicBoolean") } @@ -140,7 +146,12 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { writeDoc(w, doc) javaAnnotationHeader.foreach(w.wl) - w.w(s"${javaClassAccessModifierString}abstract class $javaClass$typeParamList").braced { + + val superTypename = marshal.superTypename(i) + + // In java we need to add an "extends Type" to a class to subclass it. + val extendsDef = if (superTypename.isDefined) " extends " + superTypename.get else "" + w.w(s"${javaClassAccessModifierString}abstract class $javaClass$typeParamList$extendsDef").braced { val skipFirst = SkipFirst() generateJavaConstants(w, i.consts) @@ -188,19 +199,16 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { w.wl("destroy();") w.wl("super.finalize();") } - for (m <- i.methods if !m.static) { // Static methods not in CppProxy - val ret = marshal.returnType(m.ret) - val returnStmt = m.ret.fold("")(_ => "return ") - val params = m.params.map(p => marshal.paramType(p.ty) + " " + idJava.local(p.ident)).mkString(", ") - val args = m.params.map(p => idJava.local(p.ident)).mkString(", ") - val meth = idJava.method(m.ident) - w.wl - w.wl(s"@Override") - w.wl(s"public $ret $meth($params)$throwException").braced { - w.wl("assert !this.destroyed.get() : \"trying to use a destroyed object\";") - w.wl(s"${returnStmt}native_$meth(this.nativeRef${preComma(args)});") - } - w.wl(s"private native $ret native_$meth(long _nativeRef${preComma(params)});") + + // For JNI support, Djinni generates a nested class, called CppProxy, which handles the bridging + // between Java and C++. The super interface methods need to be declared within the proxy. + w.wl; w.wl(s"// $javaClass methods") + writeCppProxyMethods(w, i.methods, throwException) + + val superMethods = getInterfaceSuperMethods(i, idl) + if (!superMethods.isEmpty) { + w.wl; w.wl(s"// ${superTypename.getOrElse("Super")} methods") + writeCppProxyMethods(w, superMethods, throwException) } } } @@ -208,6 +216,23 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { }) } + def writeCppProxyMethods(w: IndentWriter, methods: Seq[Interface.Method], throwException: String) { + for (m <- methods if !m.static) { // Static methods not in CppProxy + val ret = marshal.returnType(m.ret) + val returnStmt = m.ret.fold("")(_ => "return ") + val params = m.params.map(p => marshal.paramType(p.ty) + " " + idJava.local(p.ident)).mkString(", ") + val args = m.params.map(p => idJava.local(p.ident)).mkString(", ") + val meth = idJava.method(m.ident) + w.wl + w.wl(s"@Override") + w.wl(s"public $ret $meth($params)$throwException").braced { + w.wl("assert !this.destroyed.get() : \"trying to use a destroyed object\";") + w.wl(s"${returnStmt}native_$meth(this.nativeRef${preComma(args)});") + } + w.wl(s"private native $ret native_$meth(long _nativeRef${preComma(params)});") + } + } + override def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record) { val refs = new JavaRefs() r.fields.foreach(f => refs.find(f.ty)) diff --git a/src/source/JavaMarshal.scala b/src/source/JavaMarshal.scala index 91d765210..e23813e11 100644 --- a/src/source/JavaMarshal.scala +++ b/src/source/JavaMarshal.scala @@ -12,6 +12,11 @@ class JavaMarshal(spec: Spec) extends Marshal(spec) { override def typename(tm: MExpr): String = toJavaType(tm, None) def typename(name: String, ty: TypeDef): String = idJava.ty(name) + def superTypename(ty: TypeDef): Option[String] = ty match { + case i: Interface => if(i.superIdent.isDefined) Some(idJava.ty(i.superIdent.get.name)) else None + case _ => None + } + override def fqTypename(tm: MExpr): String = toJavaType(tm, spec.javaPackage) def fqTypename(name: String, ty: TypeDef): String = withPackage(spec.javaPackage, idJava.ty(name)) diff --git a/src/source/Marshal.scala b/src/source/Marshal.scala index f4fff656e..96897089a 100644 --- a/src/source/Marshal.scala +++ b/src/source/Marshal.scala @@ -3,6 +3,7 @@ package djinni import djinni.ast._ import djinni.generatorTools._ import djinni.meta._ +import scala.collection.mutable.ListBuffer import scala.language.implicitConversions // Generate code for marshalling a specific type from/to C++ including header and type names. @@ -16,6 +17,8 @@ abstract class Marshal(spec: Spec) { // Same as typename() but always fully namespace or package qualified def fqTypename(tm: MExpr): String def fqTypename(ty: TypeRef): String = fqTypename(ty.resolved) + // Typename string of the interface that the type extends + def superTypename(ty: TypeRef): String = typename(ty.resolved) // Type signature for a function parameter def paramType(tm: MExpr): String def paramType(ty: TypeRef): String = paramType(ty.resolved) @@ -36,6 +39,27 @@ abstract class Marshal(spec: Spec) { def fromCpp(tm: MExpr, expr: String): String = "" def fromCpp(ty: TypeRef, expr: String): String = fromCpp(ty.resolved, expr) + def interfaceForIdent(idl: Seq[TypeDecl], ident: Ident): Interface = { + idl.find(td => td.ident.name == ident.name) match { + case Some(superDec) => superDec.body match { + case i: Interface => i + 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.") + } + } + + def superInterfacesForInterface(i: Interface, idl: Seq[TypeDecl]): Seq[Interface] = { + val interfaces = ListBuffer[Interface]() + + var interface = i + while (interface.superIdent.isDefined) { + interface = interfaceForIdent(idl, interface.superIdent.get) + interfaces += interface + } + interfaces + } + implicit def identToString(ident: Ident): String = ident.name protected val idCpp = spec.cppIdentStyle protected val idJava = spec.javaIdentStyle diff --git a/src/source/ObjcGenerator.scala b/src/source/ObjcGenerator.scala index 3d573aad5..ce8e4afa7 100644 --- a/src/source/ObjcGenerator.scala +++ b/src/source/ObjcGenerator.scala @@ -74,7 +74,7 @@ class ObjcGenerator(spec: Spec) extends BaseObjcGenerator(spec) { /** * Generate Interface */ - override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { + override def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { val refs = new ObjcRefs() i.methods.map(m => { m.params.map(p => refs.find(p.ty)) @@ -88,6 +88,10 @@ class ObjcGenerator(spec: Spec) extends BaseObjcGenerator(spec) { refs.header.add("#import ") + if (i.superIdent.isDefined) { + refs.header.add ("#import " + q(spec.objcIncludePrefix + marshal.headerName(i.superIdent.get))) + } + def writeObjcFuncDecl(method: Interface.Method, w: IndentWriter) { val label = if (method.static) "+" else "-" val ret = marshal.returnType(method.ret) @@ -105,7 +109,11 @@ class ObjcGenerator(spec: Spec) extends BaseObjcGenerator(spec) { } w.wl writeDoc(w, doc) - if (i.ext.objc) w.wl(s"@protocol $self") else w.wl(s"@interface $self : NSObject") + + // Top level Djinni protocols need to extend NSObject. Without extending NSObject, protocols can't leverage + // methods like respondsToSelector when the instance variable is of the form id ivarName; + val superTypename = marshal.superTypename(i).getOrElse("NSObject") + if (i.ext.objc) w.wl(s"@protocol $self <$superTypename>") else w.wl(s"@interface $self : $superTypename") for (m <- i.methods) { w.wl writeDoc(w, m.doc) diff --git a/src/source/ObjcMarshal.scala b/src/source/ObjcMarshal.scala index 66edc49fa..6bdd0ed89 100644 --- a/src/source/ObjcMarshal.scala +++ b/src/source/ObjcMarshal.scala @@ -12,6 +12,11 @@ class ObjcMarshal(spec: Spec) extends Marshal(spec) { } def typename(name: String, ty: TypeDef): String = idObjc.ty(name) + def superTypename(ty: TypeDef): Option[String] = ty match { + case i: Interface => if(i.superIdent.isDefined) Some(idObjc.ty(i.superIdent.get.name)) else None + case _ => None + } + override def fqTypename(tm: MExpr): String = typename(tm) def fqTypename(name: String, ty: TypeDef): String = typename(name, ty) diff --git a/src/source/ObjcppGenerator.scala b/src/source/ObjcppGenerator.scala index ab0263f5d..e78d2630c 100644 --- a/src/source/ObjcppGenerator.scala +++ b/src/source/ObjcppGenerator.scala @@ -61,12 +61,16 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { def nnCheck(expr: String): String = spec.cppNnCheckExpression.fold(expr)(check => s"$check($expr)") - override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { + override def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { val refs = new ObjcRefs() i.methods.map(m => { m.params.map(p => refs.find(p.ty)) m.ret.foreach(refs.find) }) + getInterfaceSuperMethods(i, idl).map(m => { + m.params.map(p => refs.find(p.ty)) + m.ret.foreach(refs.find) + }) i.consts.map(c => { refs.find(c.ty) }) @@ -76,6 +80,10 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { refs.privHeader.add("#include ") refs.privHeader.add("!#include " + q(spec.objcppIncludeCppPrefix + spec.cppFileIdentStyle(ident) + "." + spec.cppHeaderExt)) + if (i.superIdent.isDefined) { + refs.privHeader.add("#import " + q(spec.objcppIncludePrefix + objcppMarshal.privateHeaderName(i.superIdent.get.name))); + } + refs.body.add("!#import " + q(spec.objcppIncludeObjcPrefix + headerName(ident))) refs.body.add("!#import " + q(spec.objcppIncludePrefix + objcppMarshal.privateHeaderName(ident.name))) @@ -84,13 +92,6 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { case _ => } - def writeObjcFuncDecl(method: Interface.Method, w: IndentWriter) { - val label = if (method.static) "+" else "-" - val ret = objcMarshal.fqReturnType(method.ret) - val decl = s"$label ($ret)${idObjc.method(method.ident)}" - writeAlignedObjcCall(w, decl, method.params, "", p => (idObjc.field(p.ident), s"(${objcMarshal.paramType(p.ty)})${idObjc.local(p.ident)}")) - } - val helperClass = objcppMarshal.helperClass(ident) writeObjcFile(objcppMarshal.privateHeaderName(ident.name), origin, refs.privHeader, w => { @@ -169,32 +170,19 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { } w.wl("return self;") } - for (m <- i.methods) { - w.wl - writeObjcFuncDecl(m, w) - w.braced { - w.w("try").bracedEnd(" DJINNI_TRANSLATE_EXCEPTIONS()") { - m.params.foreach(p => { - if (isInterface(p.ty.resolved) && spec.cppNnCheckExpression.nonEmpty) { - // We have a non-optional interface, assert that we're getting a non-null value - val paramName = idObjc.local(p.ident) - val stringWriter = new StringWriter() - writeObjcFuncDecl(m, new IndentWriter(stringWriter)) - val singleLineFunctionDecl = stringWriter.toString.replaceAll("\n *", " ") - val exceptionReason = s"Got unexpected null parameter '$paramName' to function $objcSelf $singleLineFunctionDecl" - w.w(s"if ($paramName == nil)").braced { - w.wl(s"""throw std::invalid_argument("$exceptionReason");""") - } - } - }) - val ret = m.ret.fold("")(_ => "auto objcpp_result_ = ") - val call = ret + (if (!m.static) "_cppRefHandle.get()->" else cppSelf + "::") + idCpp.method(m.ident) + "(" - writeAlignedCall(w, call, m.params, ")", p => objcppMarshal.toCpp(p.ty, idObjc.local(p.ident.name))) - - w.wl(";") - m.ret.fold()(r => w.wl(s"return ${objcppMarshal.fromCpp(r, "objcpp_result_")};")) - } - } + w.wl + w.wl(s"- (const std::shared_ptr<$cppSelf>&) cppRef") + w.braced { + w.wl("return _cppRefHandle.get();") + } + + w.wl; w.wl(s"// $objcSelf methods") + writeCppProxyMethods(w, i.methods, objcSelf, cppSelf) + + val superMethods = getInterfaceSuperMethods(i, idl) + if (superMethods.nonEmpty) { + w.wl; w.wl(s"// ${objcppMarshal.superTypename(i).getOrElse("Super")} methods") + writeCppProxyMethods(w, superMethods, objcSelf, cppSelf) } if (i.consts.nonEmpty) { @@ -212,31 +200,14 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { w.bracedSemi { w.wlOutdent("public:") w.wl("using Handle::Handle;") - for (m <- i.methods) { - val ret = cppMarshal.fqReturnType(m.ret) - val params = m.params.map(p => cppMarshal.fqParamType(p.ty) + " c_" + idCpp.local(p.ident)) - w.wl(s"$ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")} override").braced { - w.w("@autoreleasepool").braced { - val ret = m.ret.fold("")(_ => "auto objcpp_result_ = ") - val call = s"[Handle::get() ${idObjc.method(m.ident)}" - writeAlignedObjcCall(w, ret + call, m.params, "]", p => (idObjc.field(p.ident), s"(${objcppMarshal.fromCpp(p.ty, "c_" + idCpp.local(p.ident))})")) - w.wl(";") - m.ret.fold()(ty => { - if (spec.cppNnCheckExpression.nonEmpty && isInterface(ty.resolved)) { - // We have a non-optional interface, so assert that we're getting a non-null value - // before putting it into a non-null pointer - val stringWriter = new StringWriter() - writeObjcFuncDecl(m, new IndentWriter(stringWriter)) - val singleLineFunctionDecl = stringWriter.toString.replaceAll("\n *", " ") - val exceptionReason = s"Got unexpected null return value from function $objcSelf $singleLineFunctionDecl" - w.w(s"if (objcpp_result_ == nil)").braced { - w.wl(s"""throw std::invalid_argument("$exceptionReason");""") - } - } - w.wl(s"return ${objcppMarshal.toCpp(ty, "objcpp_result_")};") - }) - } - } + + w.wl; w.wl(s"// $helperClass methods") + writeObjcProxyMethods(w, i.methods, objcSelf) + + val superMethods = getInterfaceSuperMethods(i, idl) + if (superMethods.nonEmpty) { + w.wl; w.wl(s"// ${cppMarshal.superTypename(i).getOrElse("Super")} methods") + writeObjcProxyMethods(w, superMethods, objcSelf) } } }) @@ -257,7 +228,12 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { if (i.ext.cpp && !i.ext.objc) { // C++ only. In this case we generate a class instead of a protocol, so // we don't have to do any casting at all, just access cppRef directly. - w.wl("return " + nnCheck("objc->_cppRefHandle.get()") + ";") + // + // The cppRef is accessed through a getter to support interface inheritance. + // Accessing the cppRef through a getter ensures that the cppRef of subtypes + // will be returned. Accessing the ivar directly results in accessing the + // supertype's cppRef. + w.wl("return " + nnCheck("[objc cppRef]") + ";") //w.wl(s"return ${spec.cppNnCheckExpression.getOrElse("")}(objc->_cppRefHandle.get());") } else if (i.ext.cpp || i.ext.objc) { // ObjC only, or ObjC and C++. @@ -308,6 +284,72 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { }) } + def writeObjcFuncDecl(method: Interface.Method, w: IndentWriter) { + val label = if (method.static) "+" else "-" + val ret = objcMarshal.fqReturnType(method.ret) + val decl = s"$label ($ret)${idObjc.method(method.ident)}" + writeAlignedObjcCall(w, decl, method.params, "", p => (idObjc.field(p.ident), s"(${objcMarshal.paramType(p.ty)})${idObjc.local(p.ident)}")) + } + + def writeCppProxyMethods(w: IndentWriter, methods: Seq[Interface.Method], objcName: String, cppName: String) { + for (m <- methods) { + w.wl + writeObjcFuncDecl(m, w) + w.braced { + w.w("try").bracedEnd(" DJINNI_TRANSLATE_EXCEPTIONS()") { + m.params.foreach(p => { + if (isInterface(p.ty.resolved) && spec.cppNnCheckExpression.nonEmpty) { + // We have a non-optional interface, assert that we're getting a non-null value + val paramName = idObjc.local(p.ident) + val stringWriter = new StringWriter() + writeObjcFuncDecl(m, new IndentWriter(stringWriter)) + val singleLineFunctionDecl = stringWriter.toString.replaceAll("\n *", " ") + val exceptionReason = s"Got unexpected null parameter '$paramName' to function $objcName $singleLineFunctionDecl" + w.w(s"if ($paramName == nil)").braced { + w.wl(s"""throw std::invalid_argument("$exceptionReason");""") + } + } + }) + val ret = m.ret.fold("")(_ => "auto objcpp_result_ = ") + val call = ret + (if (!m.static) "_cppRefHandle.get()->" else cppName + "::") + idCpp.method(m.ident) + "(" + writeAlignedCall(w, call, m.params, ")", p => objcppMarshal.toCpp(p.ty, idObjc.local(p.ident.name))) + + w.wl(";") + m.ret.fold()(r => w.wl(s"return ${objcppMarshal.fromCpp(r, "objcpp_result_")};")) + } + } + } + } + + def writeObjcProxyMethods(w: IndentWriter, methods: Seq[Interface.Method], objcName: String) { + for (m <- methods) { + val ret = cppMarshal.fqReturnType(m.ret) + val params = m.params.map(p => cppMarshal.fqParamType(p.ty) + " c_" + idCpp.local(p.ident)) + w.wl(s"$ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")} override").braced { + w.w("@autoreleasepool").braced { + val ret = m.ret.fold("")(_ => "auto objcpp_result_ = ") + val call = s"[Handle::get() ${idObjc.method(m.ident)}" + writeAlignedObjcCall(w, ret + call, m.params, "]", p => (idObjc.field(p.ident), s"(${objcppMarshal.fromCpp(p.ty, "c_" + idCpp.local(p.ident))})")) + w.wl(";") + m.ret.fold()(ty => { + if (spec.cppNnCheckExpression.nonEmpty && isInterface(ty.resolved)) { + // We have a non-optional interface, so assert that we're getting a non-null value + // before putting it into a non-null pointer + val stringWriter = new StringWriter() + writeObjcFuncDecl(m, new IndentWriter(stringWriter)) + val singleLineFunctionDecl = stringWriter.toString.replaceAll("\n *", " ") + val exceptionReason = s"Got unexpected null return value from function $objcName $singleLineFunctionDecl" + w.w(s"if (r == nil)").braced { + w.wl(s"""throw std::invalid_argument("$exceptionReason");""") + } + } + w.wl(s"return ${objcppMarshal.toCpp(ty, "objcpp_result_")};") + }) + } + } + } + } + override def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record) { val refs = new ObjcRefs() for (c <- r.consts) diff --git a/src/source/ObjcppMarshal.scala b/src/source/ObjcppMarshal.scala index 8ad5bc42a..20dcd4925 100644 --- a/src/source/ObjcppMarshal.scala +++ b/src/source/ObjcppMarshal.scala @@ -11,6 +11,8 @@ class ObjcppMarshal(spec: Spec) extends Marshal(spec) { override def typename(tm: MExpr): String = throw new AssertionError("not applicable") def typename(name: String, ty: TypeDef): String = throw new AssertionError("not applicable") + def superTypename(ty: TypeDef): Option[String] = objcMarshal.superTypename(ty) + override def fqTypename(tm: MExpr): String = throw new AssertionError("not applicable") def fqTypename(name: String, ty: TypeDef): String = throw new AssertionError("not applicable") diff --git a/src/source/YamlGenerator.scala b/src/source/YamlGenerator.scala index 6b6fe8b83..a2288c4f6 100644 --- a/src/source/YamlGenerator.scala +++ b/src/source/YamlGenerator.scala @@ -171,7 +171,7 @@ class YamlGenerator(spec: Spec) extends Generator(spec) { // unused } - override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { + override def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { // unused } diff --git a/src/source/ast.scala b/src/source/ast.scala index 6d2ca62c8..cf6699e1b 100644 --- a/src/source/ast.scala +++ b/src/source/ast.scala @@ -50,6 +50,14 @@ case class Ext(java: Boolean, cpp: Boolean, objc: Boolean) { def any(): Boolean = { java || cpp || objc } + + override def equals(that: Any): Boolean = that match { + case that: Ext => that.java == this.java && that.objc == this.objc && that.cpp == this.cpp + case _ => false + } + override def hashCode:Int = { + (if (java) 1 << 0 else 0) | (if (cpp) 1 << 1 else 0) | (if (objc) 1 << 2 else 0) + } } case class TypeRef(expr: TypeExpr) { @@ -74,7 +82,7 @@ object Record { } } -case class Interface(ext: Ext, methods: Seq[Interface.Method], consts: Seq[Const]) extends TypeDef +case class Interface(superIdent: Option[Ident], ext: Ext, methods: Seq[Interface.Method], consts: Seq[Const]) extends TypeDef object Interface { case class Method(ident: Ident, params: Seq[Field], ret: Option[TypeRef], doc: Doc, static: Boolean, const: Boolean) } diff --git a/src/source/generator.scala b/src/source/generator.scala index b14564076..5232dd7c9 100644 --- a/src/source/generator.scala +++ b/src/source/generator.scala @@ -22,6 +22,7 @@ import djinni.generatorTools._ import djinni.meta._ import djinni.syntax.Error import djinni.writer.IndentWriter +import scala.collection.mutable.ListBuffer import scala.language.implicitConversions import scala.collection.mutable @@ -338,13 +339,13 @@ abstract class Generator(spec: Spec) assert(td.params.isEmpty) generateEnum(td.origin, td.ident, td.doc, e) case r: Record => generateRecord(td.origin, td.ident, td.doc, td.params, r) - case i: Interface => generateInterface(td.origin, td.ident, td.doc, td.params, i) + case i: Interface => generateInterface(idl, td.origin, td.ident, td.doc, td.params, i) } } def generateEnum(origin: String, ident: Ident, doc: Doc, e: Enum) def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record) - def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) + def generateInterface(idl: Seq[TypeDecl], origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) // -------------------------------------------------------------------------- // Render type expression @@ -394,4 +395,27 @@ abstract class Generator(spec: Spec) w.wl(" */") } } + + // -------------------------------------------------------------------------- + // Interface Inheritance Utils + + def getInterfaceSuperMethods(i: Interface, idl: Seq[TypeDecl]): Seq[Interface.Method] = { + val methods = ListBuffer[Interface.Method](); + + var superIdent = i.superIdent + while (superIdent.isDefined) { + idl.find(td => td.ident.name == superIdent.get.name) match { + case Some(superDec) => superDec.body match { + case i: Interface => { + methods.appendAll(i.methods) + superIdent = i.superIdent + } + 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.") + } + } + methods.filter(m => !m.static) + } + } diff --git a/src/source/parser.scala b/src/source/parser.scala index 0b1c6cea5..94e481d61 100644 --- a/src/source/parser.scala +++ b/src/source/parser.scala @@ -40,13 +40,15 @@ private object IdlParser extends RegexParsers { def idlFile(origin: String): Parser[IdlFile] = rep(importFile) ~ rep(typeDecl(origin)) ^^ { case imp~types => IdlFile(imp, types) } def importFile: Parser[FileRef] = { - - def fileParent:String = if (fileStack.top.getParent() != null) return fileStack.top.getParent() + "/" else return "" + + def fileParent:String = if (fileStack.top.getParent() != null) return fileStack.top.getParent() + "/" else return "" ("@" ~> directive) ~ ("\"" ~> filePath <~ "\"") ^^ { case "import" ~ x => val newPath = fileParent + x - new IdlFileRef(new File(newPath)) + + def importFile = new File(newPath) + new IdlFileRef(importFile.getCanonicalFile) case "extern" ~ x => val newPath = fileParent + x new ExternFileRef(new File(newPath)) @@ -90,7 +92,7 @@ private object IdlParser extends RegexParsers { success(Ext(foundJava, foundCpp, foundObjc)) } - def typeDef: Parser[TypeDef] = record | enum | interface + def typeDef: Parser[TypeDef] = record | enum | interface | interfaceExtends def recordHeader = "record" ~> extRecord def record: Parser[Record] = recordHeader ~ bracesList(field | const) ~ opt(deriving) ^^ { @@ -123,14 +125,23 @@ private object IdlParser extends RegexParsers { case ext~items => { val methods = items collect {case m: Method => m} val consts = items collect {case c: Const => c} - Interface(ext, methods, consts) + Interface(None, ext, methods, consts) + } + } + + def interfaceExtendsHeaders = "interface extends" ~> ident + def interfaceExtends: Parser[Interface] = interfaceExtendsHeaders ~ extInterface ~ bracesList(method | const) ^^ { + case ident~ext~items => { + val methods = items collect {case m: Method => m} + val consts = items collect {case c: Const => c} + Interface(Some(ident), ext, methods, consts) } } def externTypeDecl: Parser[TypeDef] = externEnum | externInterface | externRecord def externEnum: Parser[Enum] = enumHeader ^^ { case _ => Enum(List()) } def externRecord: Parser[Record] = recordHeader ~ opt(deriving) ^^ { case ext~deriving => Record(ext, List(), List(), deriving.getOrElse(Set[DerivingType]())) } - def externInterface: Parser[Interface] = interfaceHeader ^^ { case ext => Interface(ext, List(), List()) } + def externInterface: Parser[Interface] = interfaceHeader ^^ { case ext => Interface(None, ext, List(), List()) } def staticLabel: Parser[Boolean] = ("static ".r | "".r) ^^ { case "static " => true diff --git a/src/source/resolver.scala b/src/source/resolver.scala index aac986b1e..209b904e6 100644 --- a/src/source/resolver.scala +++ b/src/source/resolver.scala @@ -70,7 +70,7 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = { scope = scope.updated(typeParam.ident.name, MParam(typeParam.ident.name)) } - resolve(scope, typeDecl.body) + resolve(idl, scope, typeDecl.body) } for (typeDecl <- idl) { @@ -84,11 +84,11 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = { None } -private def resolve(scope: Scope, typeDef: TypeDef) { +private def resolve(idl: Seq[TypeDecl], scope: Scope, typeDef: TypeDef) { typeDef match { case e: Enum => resolveEnum(scope, e) case r: Record => resolveRecord(scope, r) - case i: Interface => resolveInterface(scope, i) + case i: Interface => resolveInterface(idl, scope, i) } } @@ -263,7 +263,22 @@ private def resolveRecord(scope: Scope, r: Record) { } } -private def resolveInterface(scope: Scope, i: Interface) { +private def resolveInterface(idl: Seq[TypeDecl], scope: Scope, i: Interface) { + // Check that the inherited interface 1) exists, 2) is in fact an interface, and 3) is implemented in the same language + if (i.superIdent.isDefined) { + val superIdent = i.superIdent.get + idl.find(td => td.ident.name == superIdent.name) match { + case Some(superDecl) => superDecl.body match { + case si: Interface => + if (!si.ext.equals(i.ext)) + throw Error(superIdent.loc, "Sub-interface implementation declarations (+j +o +c) must match super-interface.").toException + else None // All good! + case _ => throw Error(superIdent.loc, s"'${superIdent.name}' is not an interface. Interfaces can only extend other interfaces.").toException + } + case None => throw Error(superIdent.loc, s"Unknown interface '${superIdent.name}'").toException + } + } + // Const and static methods are only allowed on +c (only) interfaces if (i.ext.java || i.ext.objc) { for (m <- i.methods) { diff --git a/support-lib/jni/djinni_support.cpp b/support-lib/jni/djinni_support.cpp index e3a9ff515..9d85b7a46 100644 --- a/support-lib/jni/djinni_support.cpp +++ b/support-lib/jni/djinni_support.cpp @@ -546,12 +546,13 @@ void jniDefaultSetPendingFromCurrent(JNIEnv * env, const char * /*ctx*/) noexcep template class ProxyCache; CppProxyClassInfo::CppProxyClassInfo(const char * className) - : clazz(jniFindClass(className)), + : proxyClassName{std::string(className)}, + clazz(jniFindClass(className)), constructor(jniGetMethodID(clazz.get(), "", "(J)V")), idField(jniGetFieldID(clazz.get(), "nativeRef", "J")) { } -CppProxyClassInfo::CppProxyClassInfo() : constructor{}, idField{} { +CppProxyClassInfo::CppProxyClassInfo() : proxyClassName{}, constructor{}, idField{} { } CppProxyClassInfo::~CppProxyClassInfo() { diff --git a/support-lib/jni/djinni_support.hpp b/support-lib/jni/djinni_support.hpp index a4fab781f..7b9e1eb16 100644 --- a/support-lib/jni/djinni_support.hpp +++ b/support-lib/jni/djinni_support.hpp @@ -353,6 +353,7 @@ static const std::shared_ptr & objectFromHandleAddress(jlong handle) { * here, so this object has an invalid state and default constructor. */ struct CppProxyClassInfo { + const std::string proxyClassName; const GlobalRef clazz; const jmethodID constructor; const jfieldID idField; @@ -404,8 +405,10 @@ class JniInterface { * Given a Java object, find or create a C++ version. The cases here are: * 1. Null * 2. The provided Java object is actually a CppProxy (Java-side proxy for a C++ impl) - * 3. The provided Java object has an existing JavaProxy (C++-side proxy for a Java impl) - * 4. The provided Java object needs a new JavaProxy allocated + * 3. The provided Java object is a CppProxy, but is a proxy for a subclass of the class + * associated with this JniInterface. + * 4. The provided Java object has an existing JavaProxy (C++-side proxy for a Java impl) + * 5. The provided Java object needs a new JavaProxy allocated */ std::shared_ptr _fromJava(JNIEnv* jniEnv, jobject j) const { // Case 1 - null @@ -413,16 +416,44 @@ class JniInterface { return nullptr; } - // Case 2 - already a Java proxy; we just need to pull the C++ impl out. (This case + // Case 2 & 3 - already a Java proxy; we just need to pull the C++ impl out. (This case // is only possible if we were constructed with a cppProxyClassName parameter.) - if (m_cppProxyClass - && jniEnv->IsSameObject(jniEnv->GetObjectClass(j), m_cppProxyClass.clazz.get())) { - jlong handle = jniEnv->GetLongField(j, m_cppProxyClass.idField); - jniExceptionCheck(jniEnv); - return objectFromHandleAddress(handle); + if (m_cppProxyClass) { + if (jniEnv->IsSameObject(jniEnv->GetObjectClass(j), m_cppProxyClass.clazz.get())) { + // Case 2 + // + // The provided Java object's class is the same as the JniInterface proxy's class. + // Use the JniInterface proxy's class to get the C++ object associated with the + // provided Java object. + + jlong handle = jniEnv->GetLongField(j, m_cppProxyClass.idField); + jniExceptionCheck(jniEnv); + return objectFromHandleAddress(handle); + } else { + // Case 3 + // + // The provided Java object and the JniInterface proxy's class should have a super + // class in common. If that's the case, attempt to use the provided Java object + // directly to get its associated C++ object. + + jclass superClazz = jniEnv->GetSuperclass(m_cppProxyClass.clazz.get()); + while(superClazz != nullptr) { + if (jniEnv->IsInstanceOf(j, superClazz)) { + jclass clazz = jniEnv->GetObjectClass(j); + jfieldID idField = jniEnv->GetFieldID(clazz, "nativeRef", "J"); + if (!jniEnv->ExceptionCheck()) { + jlong handle = jniEnv->GetLongField(j, idField); + jniExceptionCheck(jniEnv); + return objectFromHandleAddress(handle); + } + jniEnv->ExceptionClear(); + break; + } + superClazz = jniEnv->GetSuperclass(superClazz); + } + } } - - // Cases 3 and 4 - see _getJavaProxy helper below. JavaProxyCache is responsible for + // Cases 4 and 5 - see _getJavaProxy helper below. JavaProxyCache is responsible for // distinguishing between the two cases. Only possible if Self::JavaProxy exists. return _getJavaProxy(j); } @@ -460,14 +491,31 @@ class JniInterface { static std::pair newCppProxy(const std::shared_ptr & cppObj) { const auto & data = JniClass::get(); const auto & jniEnv = jniGetThreadEnv(); - std::unique_ptr> to_encapsulate( - new CppProxyHandle(std::static_pointer_cast(cppObj))); + + auto castCppObj = std::static_pointer_cast(cppObj); + std::unique_ptr> to_encapsulate(new CppProxyHandle(castCppObj)); jlong handle = static_cast(reinterpret_cast(to_encapsulate.get())); - jobject cppProxy = jniEnv->NewObject(data.m_cppProxyClass.clazz.get(), - data.m_cppProxyClass.constructor, - handle); + + jobject cppProxy = nullptr; + if (data.m_cppProxyClass.proxyClassName != castCppObj->jniProxyClassName()) { + // The cppObj is an instance of a subclass of the class associated with this JniInterface + // instance. Create a proxy object from the proxy class name associated with the + // cppObj object, instead of relying on this JniInterface's proxy class info. + CppProxyClassInfo tempProxyClassInfo{castCppObj->jniProxyClassName().c_str()}; + cppProxy = jniEnv->NewObject(tempProxyClassInfo.clazz.get(), + tempProxyClassInfo.constructor, + handle); + } else { + // Use the JniInterface's proxy class info, since the cppObj is the same type + // as the class associated with this JniInterface instance. + cppProxy = jniEnv->NewObject(data.m_cppProxyClass.clazz.get(), + data.m_cppProxyClass.constructor, + handle); + } + jniExceptionCheck(jniEnv); to_encapsulate.release(); + return { cppProxy, cppObj.get() }; } diff --git a/support-lib/objc/DJICppWrapperCache+Private.h b/support-lib/objc/DJICppWrapperCache+Private.h index 425460970..bc0a79594 100644 --- a/support-lib/objc/DJICppWrapperCache+Private.h +++ b/support-lib/objc/DJICppWrapperCache+Private.h @@ -16,8 +16,8 @@ // This header can only be imported to Objective-C++ source code! -#import #include +#include #include "../proxy_cache_interface.hpp" @@ -44,8 +44,9 @@ ObjcType * get_cpp_proxy_impl(const std::shared_ptr & cppRef) { typeid(cppRef), cppRef, [] (const std::shared_ptr & cppRef) -> std::pair { + auto castCppRef = std::static_pointer_cast(cppRef); return { - [[ObjcType alloc] initWithCpp:std::static_pointer_cast(cppRef)], + [((ObjcType *)[objc_getClass(castCppRef->objcProxyClassName().c_str()) alloc]) initWithCpp:castCppRef], cppRef.get() }; } diff --git a/test-suite/djinni/common.djinni b/test-suite/djinni/common.djinni index 5c165f605..9185082f5 100644 --- a/test-suite/djinni/common.djinni +++ b/test-suite/djinni/common.djinni @@ -14,3 +14,4 @@ @import "single_language_interfaces.djinni" @import "extended_record.djinni" @import "varnames.djinni" +@import "interface_inheritance.djinni" diff --git a/test-suite/djinni/interface_inheritance.djinni b/test-suite/djinni/interface_inheritance.djinni new file mode 100644 index 000000000..cb48751ec --- /dev/null +++ b/test-suite/djinni/interface_inheritance.djinni @@ -0,0 +1,44 @@ +interface_inheritance_constant = interface { + const base_method_return_value: string = "base_method"; + const base_override_method_return_value: string = "override_method"; + + const sub_method_return_value: string = "sub_method"; + const sub_override_method_return_value: string = "sub_override_method"; +} + +base_cpp_interface_inheritance = interface +c { + base_method(): string; + override_method(): string; + + static create(): base_cpp_interface_inheritance; +} + +sub_cpp_interface_inheritance = interface extends base_cpp_interface_inheritance +c { + sub_method(): string; + + static create(): sub_cpp_interface_inheritance; +} + +base_objc_java_interface_inheritance = interface +o +j { + base_method(): string; + override_method(): string; +} + +sub_objc_java_interface_inheritance = interface extends base_objc_java_interface_inheritance +o +j { + sub_method(): string; +} + +interface_encapsulator = interface +c { + set_cpp_object(object: base_cpp_interface_inheritance); + get_cpp_object(): base_cpp_interface_inheritance; + sub_cpp_as_base_cpp(): base_cpp_interface_inheritance; + + set_objc_java_object(object: base_objc_java_interface_inheritance); + get_objc_java_object(): base_objc_java_interface_inheritance; + + # Takes a sub interface object through a base interface argument, then cast the argument back to + # the sub interface. Returning null signifies failure. + cast_base_arg_to_sub(subAsBase: base_objc_java_interface_inheritance): sub_objc_java_interface_inheritance; + + static create(): interface_encapsulator; +} diff --git a/test-suite/generated-src/cpp/Conflict.hpp b/test-suite/generated-src/cpp/Conflict.hpp index 1c5e2430b..f081201f4 100644 --- a/test-suite/generated-src/cpp/Conflict.hpp +++ b/test-suite/generated-src/cpp/Conflict.hpp @@ -3,6 +3,8 @@ #pragma once +#include + namespace testsuite { /** @@ -12,6 +14,33 @@ namespace testsuite { class Conflict { public: virtual ~Conflict() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/Conflict$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBConflict"; } }; } // namespace testsuite diff --git a/test-suite/generated-src/cpp/_varname_interface_.hpp b/test-suite/generated-src/cpp/_varname_interface_.hpp index dddbfffad..6b5685a37 100644 --- a/test-suite/generated-src/cpp/_varname_interface_.hpp +++ b/test-suite/generated-src/cpp/_varname_interface_.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include namespace testsuite { @@ -13,6 +14,33 @@ class VarnameInterface { public: virtual ~VarnameInterface() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/VarnameInterface$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBVarnameInterface"; } + virtual VarnameRecord _rmethod_(const VarnameRecord & _r_arg_) = 0; virtual std::shared_ptr _imethod_(const std::shared_ptr & _i_arg_) = 0; diff --git a/test-suite/generated-src/cpp/base_cpp_interface_inheritance.hpp b/test-suite/generated-src/cpp/base_cpp_interface_inheritance.hpp new file mode 100644 index 000000000..0125d5095 --- /dev/null +++ b/test-suite/generated-src/cpp/base_cpp_interface_inheritance.hpp @@ -0,0 +1,49 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include +#include + +namespace testsuite { + +class BaseCppInterfaceInheritance { +public: + virtual ~BaseCppInterfaceInheritance() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/BaseCppInterfaceInheritance$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBBaseCppInterfaceInheritance"; } + + virtual std::string base_method() = 0; + + virtual std::string override_method() = 0; + + static std::shared_ptr create(); +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/base_objc_java_interface_inheritance.hpp b/test-suite/generated-src/cpp/base_objc_java_interface_inheritance.hpp new file mode 100644 index 000000000..e3ca2a2d7 --- /dev/null +++ b/test-suite/generated-src/cpp/base_objc_java_interface_inheritance.hpp @@ -0,0 +1,46 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include + +namespace testsuite { + +class BaseObjcJavaInterfaceInheritance { +public: + virtual ~BaseObjcJavaInterfaceInheritance() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBBaseObjcJavaInterfaceInheritance"; } + + virtual std::string base_method() = 0; + + virtual std::string override_method() = 0; +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/client_interface.hpp b/test-suite/generated-src/cpp/client_interface.hpp index 0b35234cd..78299eeac 100644 --- a/test-suite/generated-src/cpp/client_interface.hpp +++ b/test-suite/generated-src/cpp/client_interface.hpp @@ -18,6 +18,33 @@ class ClientInterface { public: virtual ~ClientInterface() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBClientInterface"; } + /** Returns record of given string */ virtual ClientReturnedRecord get_record(int64_t record_id, const std::string & utf8string, const std::experimental::optional & misc) = 0; diff --git a/test-suite/generated-src/cpp/conflict_user.hpp b/test-suite/generated-src/cpp/conflict_user.hpp index f3eb04432..7d8451e78 100644 --- a/test-suite/generated-src/cpp/conflict_user.hpp +++ b/test-suite/generated-src/cpp/conflict_user.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include #include namespace testsuite { @@ -14,6 +15,33 @@ class ConflictUser { public: virtual ~ConflictUser() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ConflictUser$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBConflictUser"; } + virtual std::shared_ptr<::testsuite::Conflict> Conflict() = 0; virtual bool conflict_arg(const std::unordered_set> & cs) = 0; diff --git a/test-suite/generated-src/cpp/constants_interface.hpp b/test-suite/generated-src/cpp/constants_interface.hpp index 54a7d6c8c..9472d938e 100644 --- a/test-suite/generated-src/cpp/constants_interface.hpp +++ b/test-suite/generated-src/cpp/constants_interface.hpp @@ -16,6 +16,33 @@ class ConstantsInterface { public: virtual ~ConstantsInterface() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ConstantsInterface$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBConstantsInterface"; } + static bool const BOOL_CONSTANT; static int8_t const I8_CONSTANT; diff --git a/test-suite/generated-src/cpp/cpp_exception.hpp b/test-suite/generated-src/cpp/cpp_exception.hpp index a8e7e13c4..afe3b26a6 100644 --- a/test-suite/generated-src/cpp/cpp_exception.hpp +++ b/test-suite/generated-src/cpp/cpp_exception.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace testsuite { @@ -12,6 +13,33 @@ class CppException { public: virtual ~CppException() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/CppException$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBCppException"; } + virtual int32_t throw_an_exception() = 0; static std::shared_ptr get(); diff --git a/test-suite/generated-src/cpp/enum_usage_interface.hpp b/test-suite/generated-src/cpp/enum_usage_interface.hpp index a55e095f1..d3b1343c2 100644 --- a/test-suite/generated-src/cpp/enum_usage_interface.hpp +++ b/test-suite/generated-src/cpp/enum_usage_interface.hpp @@ -4,6 +4,7 @@ #pragma once #include "../../handwritten-src/cpp/optional.hpp" +#include #include #include #include @@ -16,6 +17,33 @@ class EnumUsageInterface { public: virtual ~EnumUsageInterface() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/EnumUsageInterface$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBEnumUsageInterfaceCppProxy"; } + virtual color e(color e) = 0; virtual std::experimental::optional o(std::experimental::optional o) = 0; diff --git a/test-suite/generated-src/cpp/extern_interface_1.hpp b/test-suite/generated-src/cpp/extern_interface_1.hpp index 5c207ff3e..67311487a 100644 --- a/test-suite/generated-src/cpp/extern_interface_1.hpp +++ b/test-suite/generated-src/cpp/extern_interface_1.hpp @@ -6,10 +6,38 @@ #include "client_interface.hpp" #include "client_returned_record.hpp" #include +#include class ExternInterface1 { public: virtual ~ExternInterface1() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ExternInterface1$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBExternInterface1"; } + virtual ::testsuite::ClientReturnedRecord foo(const std::shared_ptr<::testsuite::ClientInterface> & i) = 0; }; diff --git a/test-suite/generated-src/cpp/extern_interface_2.hpp b/test-suite/generated-src/cpp/extern_interface_2.hpp index ef055e165..dcf70706a 100644 --- a/test-suite/generated-src/cpp/extern_interface_2.hpp +++ b/test-suite/generated-src/cpp/extern_interface_2.hpp @@ -5,6 +5,7 @@ #include "test_helpers.hpp" #include +#include struct ExternRecordWithDerivings; @@ -12,5 +13,32 @@ class ExternInterface2 { public: virtual ~ExternInterface2() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBExternInterface2"; } + virtual ExternRecordWithDerivings foo(const std::shared_ptr<::testsuite::TestHelpers> & i) = 0; }; diff --git a/test-suite/generated-src/cpp/first_listener.hpp b/test-suite/generated-src/cpp/first_listener.hpp index 5597c7a3b..3f14441cb 100644 --- a/test-suite/generated-src/cpp/first_listener.hpp +++ b/test-suite/generated-src/cpp/first_listener.hpp @@ -3,6 +3,8 @@ #pragma once +#include + namespace testsuite { /** Used for ObjC multiple inheritance tests */ @@ -10,6 +12,33 @@ class FirstListener { public: virtual ~FirstListener() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBFirstListener"; } + virtual void first() = 0; }; diff --git a/test-suite/generated-src/cpp/interface_encapsulator.hpp b/test-suite/generated-src/cpp/interface_encapsulator.hpp new file mode 100644 index 000000000..04b3a24d5 --- /dev/null +++ b/test-suite/generated-src/cpp/interface_encapsulator.hpp @@ -0,0 +1,65 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include +#include + +namespace testsuite { + +class BaseCppInterfaceInheritance; +class BaseObjcJavaInterfaceInheritance; +class SubObjcJavaInterfaceInheritance; + +class InterfaceEncapsulator { +public: + virtual ~InterfaceEncapsulator() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/InterfaceEncapsulator$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBInterfaceEncapsulator"; } + + virtual void set_cpp_object(const std::shared_ptr & object) = 0; + + virtual std::shared_ptr get_cpp_object() = 0; + + virtual std::shared_ptr sub_cpp_as_base_cpp() = 0; + + virtual void set_objc_java_object(const std::shared_ptr & object) = 0; + + virtual std::shared_ptr get_objc_java_object() = 0; + + /** + * Takes a sub interface object through a base interface argument, then cast the argument back to + * the sub interface. Returning null signifies failure. + */ + virtual std::shared_ptr cast_base_arg_to_sub(const std::shared_ptr & subAsBase) = 0; + + static std::shared_ptr create(); +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/interface_inheritance_constant.cpp b/test-suite/generated-src/cpp/interface_inheritance_constant.cpp new file mode 100644 index 000000000..1cdc18e99 --- /dev/null +++ b/test-suite/generated-src/cpp/interface_inheritance_constant.cpp @@ -0,0 +1,16 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "interface_inheritance_constant.hpp" // my header + +namespace testsuite { + +std::string const InterfaceInheritanceConstant::BASE_METHOD_RETURN_VALUE = {"base_method"}; + +std::string const InterfaceInheritanceConstant::BASE_OVERRIDE_METHOD_RETURN_VALUE = {"override_method"}; + +std::string const InterfaceInheritanceConstant::SUB_METHOD_RETURN_VALUE = {"sub_method"}; + +std::string const InterfaceInheritanceConstant::SUB_OVERRIDE_METHOD_RETURN_VALUE = {"sub_override_method"}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/interface_inheritance_constant.hpp b/test-suite/generated-src/cpp/interface_inheritance_constant.hpp new file mode 100644 index 000000000..0c33cd1e4 --- /dev/null +++ b/test-suite/generated-src/cpp/interface_inheritance_constant.hpp @@ -0,0 +1,50 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include + +namespace testsuite { + +class InterfaceInheritanceConstant { +public: + virtual ~InterfaceInheritanceConstant() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/InterfaceInheritanceConstant$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBInterfaceInheritanceConstantCppProxy"; } + + static std::string const BASE_METHOD_RETURN_VALUE; + + static std::string const BASE_OVERRIDE_METHOD_RETURN_VALUE; + + static std::string const SUB_METHOD_RETURN_VALUE; + + static std::string const SUB_OVERRIDE_METHOD_RETURN_VALUE; +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/java_only_listener.hpp b/test-suite/generated-src/cpp/java_only_listener.hpp index 4d36febb9..474d87349 100644 --- a/test-suite/generated-src/cpp/java_only_listener.hpp +++ b/test-suite/generated-src/cpp/java_only_listener.hpp @@ -3,11 +3,40 @@ #pragma once +#include + namespace testsuite { class JavaOnlyListener { public: virtual ~JavaOnlyListener() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBJavaOnlyListener"; } }; } // namespace testsuite diff --git a/test-suite/generated-src/cpp/listener_caller.hpp b/test-suite/generated-src/cpp/listener_caller.hpp index dd403b7a7..fdccf41d5 100644 --- a/test-suite/generated-src/cpp/listener_caller.hpp +++ b/test-suite/generated-src/cpp/listener_caller.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include namespace testsuite { @@ -20,6 +21,33 @@ class ListenerCaller { public: virtual ~ListenerCaller() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ListenerCaller$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBListenerCaller"; } + static std::shared_ptr init(const std::shared_ptr & first_l, const std::shared_ptr & second_l); virtual void callFirst() = 0; diff --git a/test-suite/generated-src/cpp/objc_only_listener.hpp b/test-suite/generated-src/cpp/objc_only_listener.hpp index 428e4db9e..a0c0d6e99 100644 --- a/test-suite/generated-src/cpp/objc_only_listener.hpp +++ b/test-suite/generated-src/cpp/objc_only_listener.hpp @@ -3,11 +3,40 @@ #pragma once +#include + namespace testsuite { class ObjcOnlyListener { public: virtual ~ObjcOnlyListener() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBObjcOnlyListener"; } }; } // namespace testsuite diff --git a/test-suite/generated-src/cpp/return_one.hpp b/test-suite/generated-src/cpp/return_one.hpp index 728071135..ea0b25e8e 100644 --- a/test-suite/generated-src/cpp/return_one.hpp +++ b/test-suite/generated-src/cpp/return_one.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace testsuite { @@ -13,6 +14,33 @@ class ReturnOne { public: virtual ~ReturnOne() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ReturnOne$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBReturnOne"; } + static std::shared_ptr get_instance(); virtual int8_t return_one() = 0; diff --git a/test-suite/generated-src/cpp/return_two.hpp b/test-suite/generated-src/cpp/return_two.hpp index abb41f9f0..1f9773feb 100644 --- a/test-suite/generated-src/cpp/return_two.hpp +++ b/test-suite/generated-src/cpp/return_two.hpp @@ -5,6 +5,7 @@ #include #include +#include namespace testsuite { @@ -13,6 +14,33 @@ class ReturnTwo { public: virtual ~ReturnTwo() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ReturnTwo$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBReturnTwo"; } + static std::shared_ptr get_instance(); virtual int8_t return_two() = 0; diff --git a/test-suite/generated-src/cpp/reverse_client_interface.hpp b/test-suite/generated-src/cpp/reverse_client_interface.hpp index 955b912a5..031bc5cf2 100644 --- a/test-suite/generated-src/cpp/reverse_client_interface.hpp +++ b/test-suite/generated-src/cpp/reverse_client_interface.hpp @@ -13,6 +13,33 @@ class ReverseClientInterface { public: virtual ~ReverseClientInterface() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/ReverseClientInterface$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBReverseClientInterface"; } + virtual std::string return_str() const = 0; virtual std::string meth_taking_interface(const std::shared_ptr & i) = 0; diff --git a/test-suite/generated-src/cpp/second_listener.hpp b/test-suite/generated-src/cpp/second_listener.hpp index 10ed57b81..3f9d9b3a2 100644 --- a/test-suite/generated-src/cpp/second_listener.hpp +++ b/test-suite/generated-src/cpp/second_listener.hpp @@ -3,6 +3,8 @@ #pragma once +#include + namespace testsuite { /** Used for ObjC multiple inheritance tests */ @@ -10,6 +12,33 @@ class SecondListener { public: virtual ~SecondListener() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBSecondListener"; } + virtual void second() = 0; }; diff --git a/test-suite/generated-src/cpp/sub_cpp_interface_inheritance.hpp b/test-suite/generated-src/cpp/sub_cpp_interface_inheritance.hpp new file mode 100644 index 000000000..0bcf7edf1 --- /dev/null +++ b/test-suite/generated-src/cpp/sub_cpp_interface_inheritance.hpp @@ -0,0 +1,48 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "base_cpp_interface_inheritance.hpp" +#include +#include + +namespace testsuite { + +class SubCppInterfaceInheritance : public BaseCppInterfaceInheritance { +public: + virtual ~SubCppInterfaceInheritance() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/SubCppInterfaceInheritance$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBSubCppInterfaceInheritance"; } + + virtual std::string sub_method() = 0; + + static std::shared_ptr create(); +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/sub_objc_java_interface_inheritance.hpp b/test-suite/generated-src/cpp/sub_objc_java_interface_inheritance.hpp new file mode 100644 index 000000000..b70c52d35 --- /dev/null +++ b/test-suite/generated-src/cpp/sub_objc_java_interface_inheritance.hpp @@ -0,0 +1,45 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "base_objc_java_interface_inheritance.hpp" +#include + +namespace testsuite { + +class SubObjcJavaInterfaceInheritance : public BaseObjcJavaInterfaceInheritance { +public: + virtual ~SubObjcJavaInterfaceInheritance() {} + + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return nullptr; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBSubObjcJavaInterfaceInheritance"; } + + virtual std::string sub_method() = 0; +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/cpp/test_duration.hpp b/test-suite/generated-src/cpp/test_duration.hpp index 028fc5d06..e6e36b4df 100644 --- a/test-suite/generated-src/cpp/test_duration.hpp +++ b/test-suite/generated-src/cpp/test_duration.hpp @@ -14,6 +14,33 @@ class TestDuration { public: virtual ~TestDuration() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/TestDuration$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBTestDuration"; } + static std::string hoursString(std::chrono::duration> dt); static std::string minutesString(std::chrono::duration> dt); diff --git a/test-suite/generated-src/cpp/test_helpers.hpp b/test-suite/generated-src/cpp/test_helpers.hpp index df09e2439..031c54dbd 100644 --- a/test-suite/generated-src/cpp/test_helpers.hpp +++ b/test-suite/generated-src/cpp/test_helpers.hpp @@ -30,6 +30,33 @@ class TestHelpers { public: virtual ~TestHelpers() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/TestHelpers$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBTestHelpers"; } + /** Method with documentation */ static SetRecord get_set_record(); diff --git a/test-suite/generated-src/cpp/user_token.hpp b/test-suite/generated-src/cpp/user_token.hpp index 2bbfa57f9..4266ce254 100644 --- a/test-suite/generated-src/cpp/user_token.hpp +++ b/test-suite/generated-src/cpp/user_token.hpp @@ -11,6 +11,33 @@ class UserToken { public: virtual ~UserToken() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/UserToken$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBUserTokenCppProxy"; } + virtual std::string whoami() = 0; }; diff --git a/test-suite/generated-src/cpp/uses_single_language_listeners.hpp b/test-suite/generated-src/cpp/uses_single_language_listeners.hpp index fd20afee2..cf475b7e3 100644 --- a/test-suite/generated-src/cpp/uses_single_language_listeners.hpp +++ b/test-suite/generated-src/cpp/uses_single_language_listeners.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include namespace testsuite { @@ -18,6 +19,33 @@ class UsesSingleLanguageListeners { public: virtual ~UsesSingleLanguageListeners() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/UsesSingleLanguageListeners$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBUsesSingleLanguageListenersCppProxy"; } + virtual void callForObjC(const std::shared_ptr & l) = 0; virtual std::shared_ptr returnForObjC() = 0; diff --git a/test-suite/generated-src/cpp/wchar_test_helpers.hpp b/test-suite/generated-src/cpp/wchar_test_helpers.hpp index bb585677a..04a750f34 100644 --- a/test-suite/generated-src/cpp/wchar_test_helpers.hpp +++ b/test-suite/generated-src/cpp/wchar_test_helpers.hpp @@ -13,6 +13,33 @@ class WcharTestHelpers { public: virtual ~WcharTestHelpers() {} + /** + * Defines the name of the JNI C++ proxy class. Used to convert a + * C++ implemented object to a Java object when the type of the object being + * converted is unknown to the JniInterface (see djinni_support.hpp). + * + * The proxy class name is only used for converting Djinni interfaces that + * are implemented in C++. Java implemented interfaces are converted differently. + * However, the C++ class of an interface implemented in Java must still have a + * jniProxyClassName method in order for Djinni's JniInterface::fromCpp method to compile. + * + * @return The name of the class's associated JNI proxy class. + * + * @see JniInterface in djinni_support.hpp + */ + virtual const std::string jniProxyClassName() { return "com/dropbox/djinni/test/WcharTestHelpers$CppProxy"; } + + /** + * Defines the name of the Objective-C type for the class. Used to convert a + * C++ object to an Objective-C object when the type of the object being + * converted is unknown to the C++ wrapper cache (see DJICppWrapperCache+Private.hpp). + * + * @return The name of the Objective C type associated with the class. + * + * @see get_cpp_proxy function in DJICppWrapperCache+Private.hpp + */ + virtual const std::string objcProxyClassName() { return "DBWcharTestHelpers"; } + static WcharTestRec get_record(); static std::wstring get_string(); diff --git a/test-suite/generated-src/inFileList.txt b/test-suite/generated-src/inFileList.txt index 4b273f4ab..54b57e1b0 100644 --- a/test-suite/generated-src/inFileList.txt +++ b/test-suite/generated-src/inFileList.txt @@ -16,6 +16,7 @@ djinni/multiple_inheritance.djinni djinni/single_language_interfaces.djinni djinni/extended_record.djinni djinni/varnames.djinni +djinni/interface_inheritance.djinni djinni/date.djinni djinni/date.yaml djinni/duration.djinni diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/BaseCppInterfaceInheritance.java b/test-suite/generated-src/java/com/dropbox/djinni/test/BaseCppInterfaceInheritance.java new file mode 100644 index 000000000..108e65804 --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/BaseCppInterfaceInheritance.java @@ -0,0 +1,61 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +package com.dropbox.djinni.test; + +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class BaseCppInterfaceInheritance { + @Nonnull + public abstract String baseMethod(); + + @Nonnull + public abstract String overrideMethod(); + + @CheckForNull + public static native BaseCppInterfaceInheritance create(); + + private static final class CppProxy extends BaseCppInterfaceInheritance + { + private final long nativeRef; + private final AtomicBoolean destroyed = new AtomicBoolean(false); + + private CppProxy(long nativeRef) + { + if (nativeRef == 0) throw new RuntimeException("nativeRef is zero"); + this.nativeRef = nativeRef; + } + + private native void nativeDestroy(long nativeRef); + public void destroy() + { + boolean destroyed = this.destroyed.getAndSet(true); + if (!destroyed) nativeDestroy(this.nativeRef); + } + protected void finalize() throws java.lang.Throwable + { + destroy(); + super.finalize(); + } + + // BaseCppInterfaceInheritance methods + + @Override + public String baseMethod() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_baseMethod(this.nativeRef); + } + private native String native_baseMethod(long _nativeRef); + + @Override + public String overrideMethod() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_overrideMethod(this.nativeRef); + } + private native String native_overrideMethod(long _nativeRef); + } +} diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritance.java b/test-suite/generated-src/java/com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritance.java new file mode 100644 index 000000000..9a1b240eb --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritance.java @@ -0,0 +1,15 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +package com.dropbox.djinni.test; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class BaseObjcJavaInterfaceInheritance { + @Nonnull + public abstract String baseMethod(); + + @Nonnull + public abstract String overrideMethod(); +} diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/Conflict.java b/test-suite/generated-src/java/com/dropbox/djinni/test/Conflict.java index fbd6ce640..757c3511d 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/Conflict.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/Conflict.java @@ -35,5 +35,7 @@ protected void finalize() throws java.lang.Throwable destroy(); super.finalize(); } + + // Conflict methods } } diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ConflictUser.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ConflictUser.java index 7169b30ff..39c33ac03 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ConflictUser.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ConflictUser.java @@ -37,6 +37,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ConflictUser methods + @Override public Conflict Conflict() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ConstantsInterface.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ConstantsInterface.java index 2c38a374f..c5f4208e0 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ConstantsInterface.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ConstantsInterface.java @@ -97,6 +97,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ConstantsInterface methods + @Override public void dummy() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/CppException.java b/test-suite/generated-src/java/com/dropbox/djinni/test/CppException.java index 362dbb0f5..8d1a01830 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/CppException.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/CppException.java @@ -36,6 +36,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // CppException methods + @Override public int throwAnException() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/EnumUsageInterface.java b/test-suite/generated-src/java/com/dropbox/djinni/test/EnumUsageInterface.java index dcb1322db..679805c5f 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/EnumUsageInterface.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/EnumUsageInterface.java @@ -49,6 +49,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // EnumUsageInterface methods + @Override public Color e(Color e) { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ExternInterface1.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ExternInterface1.java index 01c0dbf94..e5cc981b6 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ExternInterface1.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ExternInterface1.java @@ -31,6 +31,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ExternInterface1 methods + @Override public com.dropbox.djinni.test.ClientReturnedRecord foo(com.dropbox.djinni.test.ClientInterface i) { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/InterfaceEncapsulator.java b/test-suite/generated-src/java/com/dropbox/djinni/test/InterfaceEncapsulator.java new file mode 100644 index 000000000..4e3c16c13 --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/InterfaceEncapsulator.java @@ -0,0 +1,107 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +package com.dropbox.djinni.test; + +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class InterfaceEncapsulator { + public abstract void setCppObject(@CheckForNull BaseCppInterfaceInheritance object); + + @CheckForNull + public abstract BaseCppInterfaceInheritance getCppObject(); + + @CheckForNull + public abstract BaseCppInterfaceInheritance subCppAsBaseCpp(); + + public abstract void setObjcJavaObject(@CheckForNull BaseObjcJavaInterfaceInheritance object); + + @CheckForNull + public abstract BaseObjcJavaInterfaceInheritance getObjcJavaObject(); + + /** + * Takes a sub interface object through a base interface argument, then cast the argument back to + * the sub interface. Returning null signifies failure. + */ + @CheckForNull + public abstract SubObjcJavaInterfaceInheritance castBaseArgToSub(@CheckForNull BaseObjcJavaInterfaceInheritance subAsBase); + + @CheckForNull + public static native InterfaceEncapsulator create(); + + private static final class CppProxy extends InterfaceEncapsulator + { + private final long nativeRef; + private final AtomicBoolean destroyed = new AtomicBoolean(false); + + private CppProxy(long nativeRef) + { + if (nativeRef == 0) throw new RuntimeException("nativeRef is zero"); + this.nativeRef = nativeRef; + } + + private native void nativeDestroy(long nativeRef); + public void destroy() + { + boolean destroyed = this.destroyed.getAndSet(true); + if (!destroyed) nativeDestroy(this.nativeRef); + } + protected void finalize() throws java.lang.Throwable + { + destroy(); + super.finalize(); + } + + // InterfaceEncapsulator methods + + @Override + public void setCppObject(BaseCppInterfaceInheritance object) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + native_setCppObject(this.nativeRef, object); + } + private native void native_setCppObject(long _nativeRef, BaseCppInterfaceInheritance object); + + @Override + public BaseCppInterfaceInheritance getCppObject() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_getCppObject(this.nativeRef); + } + private native BaseCppInterfaceInheritance native_getCppObject(long _nativeRef); + + @Override + public BaseCppInterfaceInheritance subCppAsBaseCpp() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_subCppAsBaseCpp(this.nativeRef); + } + private native BaseCppInterfaceInheritance native_subCppAsBaseCpp(long _nativeRef); + + @Override + public void setObjcJavaObject(BaseObjcJavaInterfaceInheritance object) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + native_setObjcJavaObject(this.nativeRef, object); + } + private native void native_setObjcJavaObject(long _nativeRef, BaseObjcJavaInterfaceInheritance object); + + @Override + public BaseObjcJavaInterfaceInheritance getObjcJavaObject() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_getObjcJavaObject(this.nativeRef); + } + private native BaseObjcJavaInterfaceInheritance native_getObjcJavaObject(long _nativeRef); + + @Override + public SubObjcJavaInterfaceInheritance castBaseArgToSub(BaseObjcJavaInterfaceInheritance subAsBase) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_castBaseArgToSub(this.nativeRef, subAsBase); + } + private native SubObjcJavaInterfaceInheritance native_castBaseArgToSub(long _nativeRef, BaseObjcJavaInterfaceInheritance subAsBase); + } +} diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/InterfaceInheritanceConstant.java b/test-suite/generated-src/java/com/dropbox/djinni/test/InterfaceInheritanceConstant.java new file mode 100644 index 000000000..7f71d1367 --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/InterfaceInheritanceConstant.java @@ -0,0 +1,49 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +package com.dropbox.djinni.test; + +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class InterfaceInheritanceConstant { + @Nonnull + public static final String BASE_METHOD_RETURN_VALUE = "base_method"; + + @Nonnull + public static final String BASE_OVERRIDE_METHOD_RETURN_VALUE = "override_method"; + + @Nonnull + public static final String SUB_METHOD_RETURN_VALUE = "sub_method"; + + @Nonnull + public static final String SUB_OVERRIDE_METHOD_RETURN_VALUE = "sub_override_method"; + + + private static final class CppProxy extends InterfaceInheritanceConstant + { + private final long nativeRef; + private final AtomicBoolean destroyed = new AtomicBoolean(false); + + private CppProxy(long nativeRef) + { + if (nativeRef == 0) throw new RuntimeException("nativeRef is zero"); + this.nativeRef = nativeRef; + } + + private native void nativeDestroy(long nativeRef); + public void destroy() + { + boolean destroyed = this.destroyed.getAndSet(true); + if (!destroyed) nativeDestroy(this.nativeRef); + } + protected void finalize() throws java.lang.Throwable + { + destroy(); + super.finalize(); + } + + // InterfaceInheritanceConstant methods + } +} diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ListenerCaller.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ListenerCaller.java index 934a11b8c..75d0c8dab 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ListenerCaller.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ListenerCaller.java @@ -44,6 +44,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ListenerCaller methods + @Override public void callFirst() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnOne.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnOne.java index a973cd87e..49a58a969 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnOne.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnOne.java @@ -37,6 +37,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ReturnOne methods + @Override public byte returnOne() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnTwo.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnTwo.java index 5e3ed043c..4509dd4ee 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnTwo.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ReturnTwo.java @@ -37,6 +37,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ReturnTwo methods + @Override public byte returnTwo() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/ReverseClientInterface.java b/test-suite/generated-src/java/com/dropbox/djinni/test/ReverseClientInterface.java index 9dea77f2a..66c32ad67 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/ReverseClientInterface.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/ReverseClientInterface.java @@ -43,6 +43,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // ReverseClientInterface methods + @Override public String returnStr() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/SubCppInterfaceInheritance.java b/test-suite/generated-src/java/com/dropbox/djinni/test/SubCppInterfaceInheritance.java new file mode 100644 index 000000000..788b2f75f --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/SubCppInterfaceInheritance.java @@ -0,0 +1,68 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +package com.dropbox.djinni.test; + +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class SubCppInterfaceInheritance extends BaseCppInterfaceInheritance { + @Nonnull + public abstract String subMethod(); + + @CheckForNull + public static native SubCppInterfaceInheritance create(); + + private static final class CppProxy extends SubCppInterfaceInheritance + { + private final long nativeRef; + private final AtomicBoolean destroyed = new AtomicBoolean(false); + + private CppProxy(long nativeRef) + { + if (nativeRef == 0) throw new RuntimeException("nativeRef is zero"); + this.nativeRef = nativeRef; + } + + private native void nativeDestroy(long nativeRef); + public void destroy() + { + boolean destroyed = this.destroyed.getAndSet(true); + if (!destroyed) nativeDestroy(this.nativeRef); + } + protected void finalize() throws java.lang.Throwable + { + destroy(); + super.finalize(); + } + + // SubCppInterfaceInheritance methods + + @Override + public String subMethod() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_subMethod(this.nativeRef); + } + private native String native_subMethod(long _nativeRef); + + // BaseCppInterfaceInheritance methods + + @Override + public String baseMethod() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_baseMethod(this.nativeRef); + } + private native String native_baseMethod(long _nativeRef); + + @Override + public String overrideMethod() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_overrideMethod(this.nativeRef); + } + private native String native_overrideMethod(long _nativeRef); + } +} diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/SubObjcJavaInterfaceInheritance.java b/test-suite/generated-src/java/com/dropbox/djinni/test/SubObjcJavaInterfaceInheritance.java new file mode 100644 index 000000000..e4a499e5f --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/SubObjcJavaInterfaceInheritance.java @@ -0,0 +1,12 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +package com.dropbox.djinni.test; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class SubObjcJavaInterfaceInheritance extends BaseObjcJavaInterfaceInheritance { + @Nonnull + public abstract String subMethod(); +} diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/TestDuration.java b/test-suite/generated-src/java/com/dropbox/djinni/test/TestDuration.java index 4331dde0d..c7a080167 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/TestDuration.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/TestDuration.java @@ -89,5 +89,7 @@ protected void finalize() throws java.lang.Throwable destroy(); super.finalize(); } + + // TestDuration methods } } diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/TestHelpers.java b/test-suite/generated-src/java/com/dropbox/djinni/test/TestHelpers.java index 052461154..52f2c5e1f 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/TestHelpers.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/TestHelpers.java @@ -104,5 +104,7 @@ protected void finalize() throws java.lang.Throwable destroy(); super.finalize(); } + + // TestHelpers methods } } diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/UserToken.java b/test-suite/generated-src/java/com/dropbox/djinni/test/UserToken.java index 659e8b58f..58206a08c 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/UserToken.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/UserToken.java @@ -34,6 +34,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // UserToken methods + @Override public String whoami() { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/UsesSingleLanguageListeners.java b/test-suite/generated-src/java/com/dropbox/djinni/test/UsesSingleLanguageListeners.java index 719afba3c..17565fd4e 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/UsesSingleLanguageListeners.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/UsesSingleLanguageListeners.java @@ -45,6 +45,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // UsesSingleLanguageListeners methods + @Override public void callForObjC(ObjcOnlyListener l) { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/VarnameInterface.java b/test-suite/generated-src/java/com/dropbox/djinni/test/VarnameInterface.java index 57b016f5d..73d461253 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/VarnameInterface.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/VarnameInterface.java @@ -37,6 +37,8 @@ protected void finalize() throws java.lang.Throwable super.finalize(); } + // VarnameInterface methods + @Override public VarnameRecord Rmethod(VarnameRecord RArg) { diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/WcharTestHelpers.java b/test-suite/generated-src/java/com/dropbox/djinni/test/WcharTestHelpers.java index eecbbd107..2bcea2037 100644 --- a/test-suite/generated-src/java/com/dropbox/djinni/test/WcharTestHelpers.java +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/WcharTestHelpers.java @@ -40,5 +40,7 @@ protected void finalize() throws java.lang.Throwable destroy(); super.finalize(); } + + // WcharTestHelpers methods } } diff --git a/test-suite/generated-src/jni/NativeBaseCppInterfaceInheritance.cpp b/test-suite/generated-src/jni/NativeBaseCppInterfaceInheritance.cpp new file mode 100644 index 000000000..862f81a29 --- /dev/null +++ b/test-suite/generated-src/jni/NativeBaseCppInterfaceInheritance.cpp @@ -0,0 +1,51 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "NativeBaseCppInterfaceInheritance.hpp" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeBaseCppInterfaceInheritance::NativeBaseCppInterfaceInheritance() : ::djinni::JniInterface<::testsuite::BaseCppInterfaceInheritance, NativeBaseCppInterfaceInheritance>("com/dropbox/djinni/test/BaseCppInterfaceInheritance$CppProxy") {} + +NativeBaseCppInterfaceInheritance::~NativeBaseCppInterfaceInheritance() = default; + + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_BaseCppInterfaceInheritance_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + delete reinterpret_cast<::djinni::CppProxyHandle<::testsuite::BaseCppInterfaceInheritance>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_BaseCppInterfaceInheritance_00024CppProxy_native_1baseMethod(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::BaseCppInterfaceInheritance>(nativeRef); + auto r = ref->base_method(); + return ::djinni::release(::djinni::String::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_BaseCppInterfaceInheritance_00024CppProxy_native_1overrideMethod(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::BaseCppInterfaceInheritance>(nativeRef); + auto r = ref->override_method(); + return ::djinni::release(::djinni::String::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_BaseCppInterfaceInheritance_create(JNIEnv* jniEnv, jobject /*this*/) +{ + try { + DJINNI_FUNCTION_PROLOGUE0(jniEnv); + auto r = ::testsuite::BaseCppInterfaceInheritance::create(); + return ::djinni::release(::djinni_generated::NativeBaseCppInterfaceInheritance::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeBaseCppInterfaceInheritance.hpp b/test-suite/generated-src/jni/NativeBaseCppInterfaceInheritance.hpp new file mode 100644 index 000000000..48d5d02c4 --- /dev/null +++ b/test-suite/generated-src/jni/NativeBaseCppInterfaceInheritance.hpp @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "base_cpp_interface_inheritance.hpp" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeBaseCppInterfaceInheritance final : ::djinni::JniInterface<::testsuite::BaseCppInterfaceInheritance, NativeBaseCppInterfaceInheritance> { +public: + using CppType = std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>; + using JniType = jobject; + + using Boxed = NativeBaseCppInterfaceInheritance; + + ~NativeBaseCppInterfaceInheritance(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeBaseCppInterfaceInheritance(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::BaseCppInterfaceInheritance, NativeBaseCppInterfaceInheritance>; + +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeBaseObjcJavaInterfaceInheritance.cpp b/test-suite/generated-src/jni/NativeBaseObjcJavaInterfaceInheritance.cpp new file mode 100644 index 000000000..15ef025b4 --- /dev/null +++ b/test-suite/generated-src/jni/NativeBaseObjcJavaInterfaceInheritance.cpp @@ -0,0 +1,34 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "NativeBaseObjcJavaInterfaceInheritance.hpp" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeBaseObjcJavaInterfaceInheritance::NativeBaseObjcJavaInterfaceInheritance() : ::djinni::JniInterface<::testsuite::BaseObjcJavaInterfaceInheritance, NativeBaseObjcJavaInterfaceInheritance>() {} + +NativeBaseObjcJavaInterfaceInheritance::~NativeBaseObjcJavaInterfaceInheritance() = default; + +NativeBaseObjcJavaInterfaceInheritance::JavaProxy::JavaProxy(JniType j) : Handle(::djinni::jniGetThreadEnv(), j) { } + +NativeBaseObjcJavaInterfaceInheritance::JavaProxy::~JavaProxy() = default; + +std::string NativeBaseObjcJavaInterfaceInheritance::JavaProxy::base_method() { + auto jniEnv = ::djinni::jniGetThreadEnv(); + ::djinni::JniLocalScope jscope(jniEnv, 10); + const auto& data = ::djinni::JniClass<::djinni_generated::NativeBaseObjcJavaInterfaceInheritance>::get(); + auto jret = (jstring)jniEnv->CallObjectMethod(Handle::get().get(), data.method_baseMethod); + ::djinni::jniExceptionCheck(jniEnv); + return ::djinni::String::toCpp(jniEnv, jret); +} +std::string NativeBaseObjcJavaInterfaceInheritance::JavaProxy::override_method() { + auto jniEnv = ::djinni::jniGetThreadEnv(); + ::djinni::JniLocalScope jscope(jniEnv, 10); + const auto& data = ::djinni::JniClass<::djinni_generated::NativeBaseObjcJavaInterfaceInheritance>::get(); + auto jret = (jstring)jniEnv->CallObjectMethod(Handle::get().get(), data.method_overrideMethod); + ::djinni::jniExceptionCheck(jniEnv); + return ::djinni::String::toCpp(jniEnv, jret); +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeBaseObjcJavaInterfaceInheritance.hpp b/test-suite/generated-src/jni/NativeBaseObjcJavaInterfaceInheritance.hpp new file mode 100644 index 000000000..7889de98f --- /dev/null +++ b/test-suite/generated-src/jni/NativeBaseObjcJavaInterfaceInheritance.hpp @@ -0,0 +1,48 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "base_objc_java_interface_inheritance.hpp" +#include "djinni_support.hpp" + +namespace djinni_generated { + +class NativeBaseObjcJavaInterfaceInheritance final : ::djinni::JniInterface<::testsuite::BaseObjcJavaInterfaceInheritance, NativeBaseObjcJavaInterfaceInheritance> { +public: + using CppType = std::shared_ptr<::testsuite::BaseObjcJavaInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::BaseObjcJavaInterfaceInheritance>; + using JniType = jobject; + + using Boxed = NativeBaseObjcJavaInterfaceInheritance; + + ~NativeBaseObjcJavaInterfaceInheritance(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeBaseObjcJavaInterfaceInheritance(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::BaseObjcJavaInterfaceInheritance, NativeBaseObjcJavaInterfaceInheritance>; + + class JavaProxy final : ::djinni::JavaProxyHandle, public ::testsuite::BaseObjcJavaInterfaceInheritance + { + public: + JavaProxy(JniType j); + ~JavaProxy(); + + std::string base_method() override; + std::string override_method() override; + + private: + friend ::djinni::JniInterface<::testsuite::BaseObjcJavaInterfaceInheritance, ::djinni_generated::NativeBaseObjcJavaInterfaceInheritance>; + }; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritance") }; + const jmethodID method_baseMethod { ::djinni::jniGetMethodID(clazz.get(), "baseMethod", "()Ljava/lang/String;") }; + const jmethodID method_overrideMethod { ::djinni::jniGetMethodID(clazz.get(), "overrideMethod", "()Ljava/lang/String;") }; +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeInterfaceEncapsulator.cpp b/test-suite/generated-src/jni/NativeInterfaceEncapsulator.cpp new file mode 100644 index 000000000..7608a5f1d --- /dev/null +++ b/test-suite/generated-src/jni/NativeInterfaceEncapsulator.cpp @@ -0,0 +1,91 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "NativeInterfaceEncapsulator.hpp" // my header +#include "NativeBaseCppInterfaceInheritance.hpp" +#include "NativeBaseObjcJavaInterfaceInheritance.hpp" +#include "NativeSubObjcJavaInterfaceInheritance.hpp" + +namespace djinni_generated { + +NativeInterfaceEncapsulator::NativeInterfaceEncapsulator() : ::djinni::JniInterface<::testsuite::InterfaceEncapsulator, NativeInterfaceEncapsulator>("com/dropbox/djinni/test/InterfaceEncapsulator$CppProxy") {} + +NativeInterfaceEncapsulator::~NativeInterfaceEncapsulator() = default; + + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + delete reinterpret_cast<::djinni::CppProxyHandle<::testsuite::InterfaceEncapsulator>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_native_1setCppObject(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_object) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::InterfaceEncapsulator>(nativeRef); + ref->set_cpp_object(::djinni_generated::NativeBaseCppInterfaceInheritance::toCpp(jniEnv, j_object)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_native_1getCppObject(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::InterfaceEncapsulator>(nativeRef); + auto r = ref->get_cpp_object(); + return ::djinni::release(::djinni_generated::NativeBaseCppInterfaceInheritance::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_native_1subCppAsBaseCpp(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::InterfaceEncapsulator>(nativeRef); + auto r = ref->sub_cpp_as_base_cpp(); + return ::djinni::release(::djinni_generated::NativeBaseCppInterfaceInheritance::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_native_1setObjcJavaObject(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_object) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::InterfaceEncapsulator>(nativeRef); + ref->set_objc_java_object(::djinni_generated::NativeBaseObjcJavaInterfaceInheritance::toCpp(jniEnv, j_object)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_native_1getObjcJavaObject(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::InterfaceEncapsulator>(nativeRef); + auto r = ref->get_objc_java_object(); + return ::djinni::release(::djinni_generated::NativeBaseObjcJavaInterfaceInheritance::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_00024CppProxy_native_1castBaseArgToSub(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_subAsBase) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::InterfaceEncapsulator>(nativeRef); + auto r = ref->cast_base_arg_to_sub(::djinni_generated::NativeBaseObjcJavaInterfaceInheritance::toCpp(jniEnv, j_subAsBase)); + return ::djinni::release(::djinni_generated::NativeSubObjcJavaInterfaceInheritance::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_InterfaceEncapsulator_create(JNIEnv* jniEnv, jobject /*this*/) +{ + try { + DJINNI_FUNCTION_PROLOGUE0(jniEnv); + auto r = ::testsuite::InterfaceEncapsulator::create(); + return ::djinni::release(::djinni_generated::NativeInterfaceEncapsulator::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeInterfaceEncapsulator.hpp b/test-suite/generated-src/jni/NativeInterfaceEncapsulator.hpp new file mode 100644 index 000000000..3615c2fca --- /dev/null +++ b/test-suite/generated-src/jni/NativeInterfaceEncapsulator.hpp @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "djinni_support.hpp" +#include "interface_encapsulator.hpp" + +namespace djinni_generated { + +class NativeInterfaceEncapsulator final : ::djinni::JniInterface<::testsuite::InterfaceEncapsulator, NativeInterfaceEncapsulator> { +public: + using CppType = std::shared_ptr<::testsuite::InterfaceEncapsulator>; + using CppOptType = std::shared_ptr<::testsuite::InterfaceEncapsulator>; + using JniType = jobject; + + using Boxed = NativeInterfaceEncapsulator; + + ~NativeInterfaceEncapsulator(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeInterfaceEncapsulator(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::InterfaceEncapsulator, NativeInterfaceEncapsulator>; + +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeInterfaceInheritanceConstant.cpp b/test-suite/generated-src/jni/NativeInterfaceInheritanceConstant.cpp new file mode 100644 index 000000000..92cab3445 --- /dev/null +++ b/test-suite/generated-src/jni/NativeInterfaceInheritanceConstant.cpp @@ -0,0 +1,26 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "NativeInterfaceInheritanceConstant.hpp" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeInterfaceInheritanceConstant::NativeInterfaceInheritanceConstant() : ::djinni::JniInterface<::testsuite::InterfaceInheritanceConstant, NativeInterfaceInheritanceConstant>("com/dropbox/djinni/test/InterfaceInheritanceConstant$CppProxy") {} + +NativeInterfaceInheritanceConstant::~NativeInterfaceInheritanceConstant() = default; + +NativeInterfaceInheritanceConstant::JavaProxy::JavaProxy(JniType j) : Handle(::djinni::jniGetThreadEnv(), j) { } + +NativeInterfaceInheritanceConstant::JavaProxy::~JavaProxy() = default; + + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_InterfaceInheritanceConstant_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + delete reinterpret_cast<::djinni::CppProxyHandle<::testsuite::InterfaceInheritanceConstant>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeInterfaceInheritanceConstant.hpp b/test-suite/generated-src/jni/NativeInterfaceInheritanceConstant.hpp new file mode 100644 index 000000000..7edb1b60d --- /dev/null +++ b/test-suite/generated-src/jni/NativeInterfaceInheritanceConstant.hpp @@ -0,0 +1,44 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "djinni_support.hpp" +#include "interface_inheritance_constant.hpp" + +namespace djinni_generated { + +class NativeInterfaceInheritanceConstant final : ::djinni::JniInterface<::testsuite::InterfaceInheritanceConstant, NativeInterfaceInheritanceConstant> { +public: + using CppType = std::shared_ptr<::testsuite::InterfaceInheritanceConstant>; + using CppOptType = std::shared_ptr<::testsuite::InterfaceInheritanceConstant>; + using JniType = jobject; + + using Boxed = NativeInterfaceInheritanceConstant; + + ~NativeInterfaceInheritanceConstant(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeInterfaceInheritanceConstant(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::InterfaceInheritanceConstant, NativeInterfaceInheritanceConstant>; + + class JavaProxy final : ::djinni::JavaProxyHandle, public ::testsuite::InterfaceInheritanceConstant + { + public: + JavaProxy(JniType j); + ~JavaProxy(); + + + private: + friend ::djinni::JniInterface<::testsuite::InterfaceInheritanceConstant, ::djinni_generated::NativeInterfaceInheritanceConstant>; + }; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/InterfaceInheritanceConstant") }; +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeSubCppInterfaceInheritance.cpp b/test-suite/generated-src/jni/NativeSubCppInterfaceInheritance.cpp new file mode 100644 index 000000000..154942274 --- /dev/null +++ b/test-suite/generated-src/jni/NativeSubCppInterfaceInheritance.cpp @@ -0,0 +1,61 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "NativeSubCppInterfaceInheritance.hpp" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeSubCppInterfaceInheritance::NativeSubCppInterfaceInheritance() : ::djinni::JniInterface<::testsuite::SubCppInterfaceInheritance, NativeSubCppInterfaceInheritance>("com/dropbox/djinni/test/SubCppInterfaceInheritance$CppProxy") {} + +NativeSubCppInterfaceInheritance::~NativeSubCppInterfaceInheritance() = default; + + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_SubCppInterfaceInheritance_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + delete reinterpret_cast<::djinni::CppProxyHandle<::testsuite::SubCppInterfaceInheritance>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_SubCppInterfaceInheritance_00024CppProxy_native_1baseMethod(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::SubCppInterfaceInheritance>(nativeRef); + auto r = ref->base_method(); + return ::djinni::release(::djinni::String::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_SubCppInterfaceInheritance_00024CppProxy_native_1overrideMethod(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::SubCppInterfaceInheritance>(nativeRef); + auto r = ref->override_method(); + return ::djinni::release(::djinni::String::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_SubCppInterfaceInheritance_00024CppProxy_native_1subMethod(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::SubCppInterfaceInheritance>(nativeRef); + auto r = ref->sub_method(); + return ::djinni::release(::djinni::String::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_SubCppInterfaceInheritance_create(JNIEnv* jniEnv, jobject /*this*/) +{ + try { + DJINNI_FUNCTION_PROLOGUE0(jniEnv); + auto r = ::testsuite::SubCppInterfaceInheritance::create(); + return ::djinni::release(::djinni_generated::NativeSubCppInterfaceInheritance::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeSubCppInterfaceInheritance.hpp b/test-suite/generated-src/jni/NativeSubCppInterfaceInheritance.hpp new file mode 100644 index 000000000..046849d7e --- /dev/null +++ b/test-suite/generated-src/jni/NativeSubCppInterfaceInheritance.hpp @@ -0,0 +1,33 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "NativeBaseCppInterfaceInheritance.hpp" +#include "djinni_support.hpp" +#include "sub_cpp_interface_inheritance.hpp" + +namespace djinni_generated { + +class NativeSubCppInterfaceInheritance final : ::djinni::JniInterface<::testsuite::SubCppInterfaceInheritance, NativeSubCppInterfaceInheritance> { +public: + using CppType = std::shared_ptr<::testsuite::SubCppInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::SubCppInterfaceInheritance>; + using JniType = jobject; + + using Boxed = NativeSubCppInterfaceInheritance; + + ~NativeSubCppInterfaceInheritance(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeSubCppInterfaceInheritance(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::SubCppInterfaceInheritance, NativeSubCppInterfaceInheritance>; + +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeSubObjcJavaInterfaceInheritance.cpp b/test-suite/generated-src/jni/NativeSubObjcJavaInterfaceInheritance.cpp new file mode 100644 index 000000000..3f2eba23e --- /dev/null +++ b/test-suite/generated-src/jni/NativeSubObjcJavaInterfaceInheritance.cpp @@ -0,0 +1,42 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "NativeSubObjcJavaInterfaceInheritance.hpp" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativeSubObjcJavaInterfaceInheritance::NativeSubObjcJavaInterfaceInheritance() : ::djinni::JniInterface<::testsuite::SubObjcJavaInterfaceInheritance, NativeSubObjcJavaInterfaceInheritance>() {} + +NativeSubObjcJavaInterfaceInheritance::~NativeSubObjcJavaInterfaceInheritance() = default; + +NativeSubObjcJavaInterfaceInheritance::JavaProxy::JavaProxy(JniType j) : Handle(::djinni::jniGetThreadEnv(), j) { } + +NativeSubObjcJavaInterfaceInheritance::JavaProxy::~JavaProxy() = default; + +std::string NativeSubObjcJavaInterfaceInheritance::JavaProxy::base_method() { + auto jniEnv = ::djinni::jniGetThreadEnv(); + ::djinni::JniLocalScope jscope(jniEnv, 10); + const auto& data = ::djinni::JniClass<::djinni_generated::NativeSubObjcJavaInterfaceInheritance>::get(); + auto jret = (jstring)jniEnv->CallObjectMethod(Handle::get().get(), data.method_baseMethod); + ::djinni::jniExceptionCheck(jniEnv); + return ::djinni::String::toCpp(jniEnv, jret); +} +std::string NativeSubObjcJavaInterfaceInheritance::JavaProxy::override_method() { + auto jniEnv = ::djinni::jniGetThreadEnv(); + ::djinni::JniLocalScope jscope(jniEnv, 10); + const auto& data = ::djinni::JniClass<::djinni_generated::NativeSubObjcJavaInterfaceInheritance>::get(); + auto jret = (jstring)jniEnv->CallObjectMethod(Handle::get().get(), data.method_overrideMethod); + ::djinni::jniExceptionCheck(jniEnv); + return ::djinni::String::toCpp(jniEnv, jret); +} +std::string NativeSubObjcJavaInterfaceInheritance::JavaProxy::sub_method() { + auto jniEnv = ::djinni::jniGetThreadEnv(); + ::djinni::JniLocalScope jscope(jniEnv, 10); + const auto& data = ::djinni::JniClass<::djinni_generated::NativeSubObjcJavaInterfaceInheritance>::get(); + auto jret = (jstring)jniEnv->CallObjectMethod(Handle::get().get(), data.method_subMethod); + ::djinni::jniExceptionCheck(jniEnv); + return ::djinni::String::toCpp(jniEnv, jret); +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativeSubObjcJavaInterfaceInheritance.hpp b/test-suite/generated-src/jni/NativeSubObjcJavaInterfaceInheritance.hpp new file mode 100644 index 000000000..96b96b260 --- /dev/null +++ b/test-suite/generated-src/jni/NativeSubObjcJavaInterfaceInheritance.hpp @@ -0,0 +1,51 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#pragma once + +#include "NativeBaseObjcJavaInterfaceInheritance.hpp" +#include "djinni_support.hpp" +#include "sub_objc_java_interface_inheritance.hpp" + +namespace djinni_generated { + +class NativeSubObjcJavaInterfaceInheritance final : ::djinni::JniInterface<::testsuite::SubObjcJavaInterfaceInheritance, NativeSubObjcJavaInterfaceInheritance> { +public: + using CppType = std::shared_ptr<::testsuite::SubObjcJavaInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::SubObjcJavaInterfaceInheritance>; + using JniType = jobject; + + using Boxed = NativeSubObjcJavaInterfaceInheritance; + + ~NativeSubObjcJavaInterfaceInheritance(); + + static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass::get()._fromJava(jniEnv, j); } + static ::djinni::LocalRef fromCppOpt(JNIEnv* jniEnv, const CppOptType& c) { return {jniEnv, ::djinni::JniClass::get()._toJava(jniEnv, c)}; } + static ::djinni::LocalRef fromCpp(JNIEnv* jniEnv, const CppType& c) { return fromCppOpt(jniEnv, c); } + +private: + NativeSubObjcJavaInterfaceInheritance(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::SubObjcJavaInterfaceInheritance, NativeSubObjcJavaInterfaceInheritance>; + + class JavaProxy final : ::djinni::JavaProxyHandle, public ::testsuite::SubObjcJavaInterfaceInheritance + { + public: + JavaProxy(JniType j); + ~JavaProxy(); + + std::string base_method() override; + std::string override_method() override; + std::string sub_method() override; + + private: + friend ::djinni::JniInterface<::testsuite::SubObjcJavaInterfaceInheritance, ::djinni_generated::NativeSubObjcJavaInterfaceInheritance>; + }; + + const ::djinni::GlobalRef clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/SubObjcJavaInterfaceInheritance") }; + const jmethodID method_baseMethod { ::djinni::jniGetMethodID(clazz.get(), "baseMethod", "()Ljava/lang/String;") }; + const jmethodID method_overrideMethod { ::djinni::jniGetMethodID(clazz.get(), "overrideMethod", "()Ljava/lang/String;") }; + const jmethodID method_subMethod { ::djinni::jniGetMethodID(clazz.get(), "subMethod", "()Ljava/lang/String;") }; +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance+Private.h b/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance+Private.h new file mode 100644 index 000000000..cf9c759ab --- /dev/null +++ b/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance+Private.h @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "base_cpp_interface_inheritance.hpp" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class DBBaseCppInterfaceInheritance; + +namespace djinni_generated { + +class BaseCppInterfaceInheritance +{ +public: + using CppType = std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>; + using ObjcType = DBBaseCppInterfaceInheritance*; + + using Boxed = BaseCppInterfaceInheritance; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + diff --git a/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance+Private.mm b/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance+Private.mm new file mode 100644 index 000000000..1420f1b38 --- /dev/null +++ b/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance+Private.mm @@ -0,0 +1,81 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBBaseCppInterfaceInheritance+Private.h" +#import "DBBaseCppInterfaceInheritance.h" +#import "DJICppWrapperCache+Private.h" +#import "DJIError.h" +#import "DJIMarshal+Private.h" +#include +#include +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@interface DBBaseCppInterfaceInheritance () + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>&)cppRef; + +@end + +@implementation DBBaseCppInterfaceInheritance { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + +- (const std::shared_ptr<::testsuite::BaseCppInterfaceInheritance>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBBaseCppInterfaceInheritance methods + +- (nonnull NSString *)baseMethod { + try { + auto objcpp_result_ = _cppRefHandle.get()->base_method(); + return ::djinni::String::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nonnull NSString *)overrideMethod { + try { + auto objcpp_result_ = _cppRefHandle.get()->override_method(); + return ::djinni::String::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + ++ (nullable DBBaseCppInterfaceInheritance *)create { + try { + auto objcpp_result_ = ::testsuite::BaseCppInterfaceInheritance::create(); + return ::djinni_generated::BaseCppInterfaceInheritance::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +namespace djinni_generated { + +auto BaseCppInterfaceInheritance::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return [objc cppRef]; +} + +auto BaseCppInterfaceInheritance::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + return ::djinni::get_cpp_proxy(cpp); +} + +} // namespace djinni_generated + +@end diff --git a/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance.h b/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance.h new file mode 100644 index 000000000..4ee113942 --- /dev/null +++ b/test-suite/generated-src/objc/DBBaseCppInterfaceInheritance.h @@ -0,0 +1,16 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import +@class DBBaseCppInterfaceInheritance; + + +@interface DBBaseCppInterfaceInheritance : NSObject + +- (nonnull NSString *)baseMethod; + +- (nonnull NSString *)overrideMethod; + ++ (nullable DBBaseCppInterfaceInheritance *)create; + +@end diff --git a/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance+Private.h b/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance+Private.h new file mode 100644 index 000000000..d6b5a828d --- /dev/null +++ b/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance+Private.h @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "base_objc_java_interface_inheritance.hpp" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@protocol DBBaseObjcJavaInterfaceInheritance; + +namespace djinni_generated { + +class BaseObjcJavaInterfaceInheritance +{ +public: + using CppType = std::shared_ptr<::testsuite::BaseObjcJavaInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::BaseObjcJavaInterfaceInheritance>; + using ObjcType = id; + + using Boxed = BaseObjcJavaInterfaceInheritance; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + diff --git a/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance+Private.mm b/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance+Private.mm new file mode 100644 index 000000000..7a342ca14 --- /dev/null +++ b/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance+Private.mm @@ -0,0 +1,58 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBBaseObjcJavaInterfaceInheritance+Private.h" +#import "DBBaseObjcJavaInterfaceInheritance.h" +#import "DJIMarshal+Private.h" +#import "DJIObjcWrapperCache+Private.h" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +namespace djinni_generated { + +class BaseObjcJavaInterfaceInheritance::ObjcProxy final +: public ::testsuite::BaseObjcJavaInterfaceInheritance +, public ::djinni::ObjcProxyCache::Handle +{ +public: + using Handle::Handle; + + // BaseObjcJavaInterfaceInheritance methods + std::string base_method() override + { + @autoreleasepool { + auto objcpp_result_ = [Handle::get() baseMethod]; + return ::djinni::String::toCpp(objcpp_result_); + } + } + std::string override_method() override + { + @autoreleasepool { + auto objcpp_result_ = [Handle::get() overrideMethod]; + return ::djinni::String::toCpp(objcpp_result_); + } + } +}; + +} // namespace djinni_generated + +namespace djinni_generated { + +auto BaseObjcJavaInterfaceInheritance::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return ::djinni::get_objc_proxy(objc); +} + +auto BaseObjcJavaInterfaceInheritance::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + return dynamic_cast(*cpp).Handle::get(); +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance.h b/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance.h new file mode 100644 index 000000000..3b9c69a81 --- /dev/null +++ b/test-suite/generated-src/objc/DBBaseObjcJavaInterfaceInheritance.h @@ -0,0 +1,13 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import + + +@protocol DBBaseObjcJavaInterfaceInheritance + +- (nonnull NSString *)baseMethod; + +- (nonnull NSString *)overrideMethod; + +@end diff --git a/test-suite/generated-src/objc/DBClientInterface+Private.mm b/test-suite/generated-src/objc/DBClientInterface+Private.mm index 3593ff4fc..e6c41a554 100644 --- a/test-suite/generated-src/objc/DBClientInterface+Private.mm +++ b/test-suite/generated-src/objc/DBClientInterface+Private.mm @@ -18,6 +18,8 @@ { public: using Handle::Handle; + + // ClientInterface methods ::testsuite::ClientReturnedRecord get_record(int64_t c_record_id, const std::string & c_utf8string, const std::experimental::optional & c_misc) override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBClientInterface.h b/test-suite/generated-src/objc/DBClientInterface.h index 73c7a883f..00b8f795b 100644 --- a/test-suite/generated-src/objc/DBClientInterface.h +++ b/test-suite/generated-src/objc/DBClientInterface.h @@ -7,7 +7,7 @@ /** Client interface */ -@protocol DBClientInterface +@protocol DBClientInterface /** Returns record of given string */ - (nonnull DBClientReturnedRecord *)getRecord:(int64_t)recordId diff --git a/test-suite/generated-src/objc/DBConflict+Private.mm b/test-suite/generated-src/objc/DBConflict+Private.mm index 4f4d7dae5..69ea9eae4 100644 --- a/test-suite/generated-src/objc/DBConflict+Private.mm +++ b/test-suite/generated-src/objc/DBConflict+Private.mm @@ -29,6 +29,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::Conflict>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::Conflict>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBConflict methods + namespace djinni_generated { auto Conflict::toCpp(ObjcType objc) -> CppType @@ -36,7 +43,7 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::Conflict>&)cppRef if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto Conflict::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBConflictUser+Private.mm b/test-suite/generated-src/objc/DBConflictUser+Private.mm index 937934de1..069e69ed6 100644 --- a/test-suite/generated-src/objc/DBConflictUser+Private.mm +++ b/test-suite/generated-src/objc/DBConflictUser+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::ConflictUser>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::ConflictUser>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBConflictUser methods + - (nullable DBConflict *)Conflict { try { auto objcpp_result_ = _cppRefHandle.get()->Conflict(); @@ -52,7 +59,7 @@ - (BOOL)conflictArg:(nonnull NSSet *)cs { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ConflictUser::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBConstantsInterface+Private.mm b/test-suite/generated-src/objc/DBConstantsInterface+Private.mm index f6e7db467..52950b879 100644 --- a/test-suite/generated-src/objc/DBConstantsInterface+Private.mm +++ b/test-suite/generated-src/objc/DBConstantsInterface+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::ConstantsInterface>&)cppRe return self; } +- (const std::shared_ptr<::testsuite::ConstantsInterface>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBConstantsInterface methods + - (void)dummy { try { _cppRefHandle.get()->dummy(); @@ -94,7 +101,7 @@ + (DBConstantRecord * __nonnull)objectConstant if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ConstantsInterface::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBCppException+Private.mm b/test-suite/generated-src/objc/DBCppException+Private.mm index 6d068a92e..08f779a1a 100644 --- a/test-suite/generated-src/objc/DBCppException+Private.mm +++ b/test-suite/generated-src/objc/DBCppException+Private.mm @@ -30,6 +30,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::CppException>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::CppException>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBCppException methods + - (int32_t)throwAnException { try { auto objcpp_result_ = _cppRefHandle.get()->throw_an_exception(); @@ -51,7 +58,7 @@ + (nullable DBCppException *)get { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto CppException::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBEnumUsageInterface+Private.mm b/test-suite/generated-src/objc/DBEnumUsageInterface+Private.mm index 460b43183..7e3e69658 100644 --- a/test-suite/generated-src/objc/DBEnumUsageInterface+Private.mm +++ b/test-suite/generated-src/objc/DBEnumUsageInterface+Private.mm @@ -32,6 +32,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::EnumUsageInterface>&)cppRe return self; } +- (const std::shared_ptr<::testsuite::EnumUsageInterface>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBEnumUsageInterfaceCppProxy methods + - (DBColor)e:(DBColor)e { try { auto objcpp_result_ = _cppRefHandle.get()->e(::djinni::Enum<::testsuite::color, DBColor>::toCpp(e)); @@ -75,6 +82,8 @@ - (nullable NSNumber *)o:(nullable NSNumber *)o { { public: using Handle::Handle; + + // EnumUsageInterface methods ::testsuite::color e(::testsuite::color c_e) override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBEnumUsageInterface.h b/test-suite/generated-src/objc/DBEnumUsageInterface.h index b1dea8045..e7ecea940 100644 --- a/test-suite/generated-src/objc/DBEnumUsageInterface.h +++ b/test-suite/generated-src/objc/DBEnumUsageInterface.h @@ -5,7 +5,7 @@ #import -@protocol DBEnumUsageInterface +@protocol DBEnumUsageInterface - (DBColor)e:(DBColor)e; diff --git a/test-suite/generated-src/objc/DBExternInterface1+Private.mm b/test-suite/generated-src/objc/DBExternInterface1+Private.mm index 6a85c6f8b..d118b48c1 100644 --- a/test-suite/generated-src/objc/DBExternInterface1+Private.mm +++ b/test-suite/generated-src/objc/DBExternInterface1+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::ExternInterface1>&)cppRef return self; } +- (const std::shared_ptr<::ExternInterface1>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBExternInterface1 methods + - (nonnull DBClientReturnedRecord *)foo:(nullable id)i { try { auto objcpp_result_ = _cppRefHandle.get()->foo(::djinni_generated::ClientInterface::toCpp(i)); @@ -45,7 +52,7 @@ - (nonnull DBClientReturnedRecord *)foo:(nullable id)i { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ExternInterface1::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBExternInterface2+Private.mm b/test-suite/generated-src/objc/DBExternInterface2+Private.mm index 38608286b..98ce0cdb3 100644 --- a/test-suite/generated-src/objc/DBExternInterface2+Private.mm +++ b/test-suite/generated-src/objc/DBExternInterface2+Private.mm @@ -18,6 +18,8 @@ { public: using Handle::Handle; + + // ExternInterface2 methods ::ExternRecordWithDerivings foo(const std::shared_ptr<::testsuite::TestHelpers> & c_i) override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBExternInterface2.h b/test-suite/generated-src/objc/DBExternInterface2.h index e027ebcff..2a19a8ae5 100644 --- a/test-suite/generated-src/objc/DBExternInterface2.h +++ b/test-suite/generated-src/objc/DBExternInterface2.h @@ -6,7 +6,7 @@ #import -@protocol DBExternInterface2 +@protocol DBExternInterface2 - (nonnull DBExternRecordWithDerivings *)foo:(nullable DBTestHelpers *)i; diff --git a/test-suite/generated-src/objc/DBFirstListener+Private.mm b/test-suite/generated-src/objc/DBFirstListener+Private.mm index be17c49e7..2d00bdde9 100644 --- a/test-suite/generated-src/objc/DBFirstListener+Private.mm +++ b/test-suite/generated-src/objc/DBFirstListener+Private.mm @@ -16,6 +16,8 @@ { public: using Handle::Handle; + + // FirstListener methods void first() override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBFirstListener.h b/test-suite/generated-src/objc/DBFirstListener.h index d5da0c67c..76ca07df2 100644 --- a/test-suite/generated-src/objc/DBFirstListener.h +++ b/test-suite/generated-src/objc/DBFirstListener.h @@ -5,7 +5,7 @@ /** Used for ObjC multiple inheritance tests */ -@protocol DBFirstListener +@protocol DBFirstListener - (void)first; diff --git a/test-suite/generated-src/objc/DBInterfaceEncapsulator+Private.h b/test-suite/generated-src/objc/DBInterfaceEncapsulator+Private.h new file mode 100644 index 000000000..674bc403c --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceEncapsulator+Private.h @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "interface_encapsulator.hpp" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class DBInterfaceEncapsulator; + +namespace djinni_generated { + +class InterfaceEncapsulator +{ +public: + using CppType = std::shared_ptr<::testsuite::InterfaceEncapsulator>; + using CppOptType = std::shared_ptr<::testsuite::InterfaceEncapsulator>; + using ObjcType = DBInterfaceEncapsulator*; + + using Boxed = InterfaceEncapsulator; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + diff --git a/test-suite/generated-src/objc/DBInterfaceEncapsulator+Private.mm b/test-suite/generated-src/objc/DBInterfaceEncapsulator+Private.mm new file mode 100644 index 000000000..be3635894 --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceEncapsulator+Private.mm @@ -0,0 +1,109 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBInterfaceEncapsulator+Private.h" +#import "DBInterfaceEncapsulator.h" +#import "DBBaseCppInterfaceInheritance+Private.h" +#import "DBBaseObjcJavaInterfaceInheritance+Private.h" +#import "DBSubObjcJavaInterfaceInheritance+Private.h" +#import "DJICppWrapperCache+Private.h" +#import "DJIError.h" +#include +#include +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@interface DBInterfaceEncapsulator () + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::InterfaceEncapsulator>&)cppRef; + +@end + +@implementation DBInterfaceEncapsulator { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::InterfaceEncapsulator>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + +- (const std::shared_ptr<::testsuite::InterfaceEncapsulator>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBInterfaceEncapsulator methods + +- (void)setCppObject:(nullable DBBaseCppInterfaceInheritance *)object { + try { + _cppRefHandle.get()->set_cpp_object(::djinni_generated::BaseCppInterfaceInheritance::toCpp(object)); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nullable DBBaseCppInterfaceInheritance *)getCppObject { + try { + auto objcpp_result_ = _cppRefHandle.get()->get_cpp_object(); + return ::djinni_generated::BaseCppInterfaceInheritance::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nullable DBBaseCppInterfaceInheritance *)subCppAsBaseCpp { + try { + auto objcpp_result_ = _cppRefHandle.get()->sub_cpp_as_base_cpp(); + return ::djinni_generated::BaseCppInterfaceInheritance::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (void)setObjcJavaObject:(nullable id)object { + try { + _cppRefHandle.get()->set_objc_java_object(::djinni_generated::BaseObjcJavaInterfaceInheritance::toCpp(object)); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nullable id)getObjcJavaObject { + try { + auto objcpp_result_ = _cppRefHandle.get()->get_objc_java_object(); + return ::djinni_generated::BaseObjcJavaInterfaceInheritance::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nullable id)castBaseArgToSub:(nullable id)subAsBase { + try { + auto objcpp_result_ = _cppRefHandle.get()->cast_base_arg_to_sub(::djinni_generated::BaseObjcJavaInterfaceInheritance::toCpp(subAsBase)); + return ::djinni_generated::SubObjcJavaInterfaceInheritance::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + ++ (nullable DBInterfaceEncapsulator *)create { + try { + auto objcpp_result_ = ::testsuite::InterfaceEncapsulator::create(); + return ::djinni_generated::InterfaceEncapsulator::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +namespace djinni_generated { + +auto InterfaceEncapsulator::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return [objc cppRef]; +} + +auto InterfaceEncapsulator::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + return ::djinni::get_cpp_proxy(cpp); +} + +} // namespace djinni_generated + +@end diff --git a/test-suite/generated-src/objc/DBInterfaceEncapsulator.h b/test-suite/generated-src/objc/DBInterfaceEncapsulator.h new file mode 100644 index 000000000..72eac16bf --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceEncapsulator.h @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import +@class DBBaseCppInterfaceInheritance; +@class DBInterfaceEncapsulator; +@protocol DBBaseObjcJavaInterfaceInheritance; +@protocol DBSubObjcJavaInterfaceInheritance; + + +@interface DBInterfaceEncapsulator : NSObject + +- (void)setCppObject:(nullable DBBaseCppInterfaceInheritance *)object; + +- (nullable DBBaseCppInterfaceInheritance *)getCppObject; + +- (nullable DBBaseCppInterfaceInheritance *)subCppAsBaseCpp; + +- (void)setObjcJavaObject:(nullable id)object; + +- (nullable id)getObjcJavaObject; + +/** + * Takes a sub interface object through a base interface argument, then cast the argument back to + * the sub interface. Returning null signifies failure. + */ +- (nullable id)castBaseArgToSub:(nullable id)subAsBase; + ++ (nullable DBInterfaceEncapsulator *)create; + +@end diff --git a/test-suite/generated-src/objc/DBInterfaceInheritanceConstant+Private.h b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant+Private.h new file mode 100644 index 000000000..41ffa23c3 --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant+Private.h @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "interface_inheritance_constant.hpp" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@protocol DBInterfaceInheritanceConstant; + +namespace djinni_generated { + +class InterfaceInheritanceConstant +{ +public: + using CppType = std::shared_ptr<::testsuite::InterfaceInheritanceConstant>; + using CppOptType = std::shared_ptr<::testsuite::InterfaceInheritanceConstant>; + using ObjcType = id; + + using Boxed = InterfaceInheritanceConstant; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + diff --git a/test-suite/generated-src/objc/DBInterfaceInheritanceConstant+Private.mm b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant+Private.mm new file mode 100644 index 000000000..0d6b23369 --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant+Private.mm @@ -0,0 +1,82 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBInterfaceInheritanceConstant+Private.h" +#import "DBInterfaceInheritanceConstant.h" +#import "DJICppWrapperCache+Private.h" +#import "DJIError.h" +#import "DJIMarshal+Private.h" +#import "DJIObjcWrapperCache+Private.h" +#include +#include +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@interface DBInterfaceInheritanceConstantCppProxy : NSObject + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::InterfaceInheritanceConstant>&)cppRef; + +@end + +@implementation DBInterfaceInheritanceConstantCppProxy { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::InterfaceInheritanceConstant>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + +- (const std::shared_ptr<::testsuite::InterfaceInheritanceConstant>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBInterfaceInheritanceConstantCppProxy methods + + +namespace djinni_generated { + +class InterfaceInheritanceConstant::ObjcProxy final +: public ::testsuite::InterfaceInheritanceConstant +, public ::djinni::ObjcProxyCache::Handle +{ +public: + using Handle::Handle; + + // InterfaceInheritanceConstant methods +}; + +} // namespace djinni_generated + +namespace djinni_generated { + +auto InterfaceInheritanceConstant::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + if ([(id)objc isKindOfClass:[DBInterfaceInheritanceConstantCppProxy class]]) { + return ((DBInterfaceInheritanceConstantCppProxy*)objc)->_cppRefHandle.get(); + } + return ::djinni::get_objc_proxy(objc); +} + +auto InterfaceInheritanceConstant::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + if (auto cppPtr = dynamic_cast(cpp.get())) { + return cppPtr->Handle::get(); + } + return ::djinni::get_cpp_proxy(cpp); +} + +} // namespace djinni_generated + +@end diff --git a/test-suite/generated-src/objc/DBInterfaceInheritanceConstant.h b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant.h new file mode 100644 index 000000000..a441f9b00 --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant.h @@ -0,0 +1,13 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import + +extern NSString * __nonnull const DBInterfaceInheritanceConstantBaseMethodReturnValue; +extern NSString * __nonnull const DBInterfaceInheritanceConstantBaseOverrideMethodReturnValue; +extern NSString * __nonnull const DBInterfaceInheritanceConstantSubMethodReturnValue; +extern NSString * __nonnull const DBInterfaceInheritanceConstantSubOverrideMethodReturnValue; + +@protocol DBInterfaceInheritanceConstant + +@end diff --git a/test-suite/generated-src/objc/DBInterfaceInheritanceConstant.mm b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant.mm new file mode 100644 index 000000000..bf53c4e99 --- /dev/null +++ b/test-suite/generated-src/objc/DBInterfaceInheritanceConstant.mm @@ -0,0 +1,13 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBInterfaceInheritanceConstant.h" + + +NSString * __nonnull const DBInterfaceInheritanceConstantBaseMethodReturnValue = @"base_method"; + +NSString * __nonnull const DBInterfaceInheritanceConstantBaseOverrideMethodReturnValue = @"override_method"; + +NSString * __nonnull const DBInterfaceInheritanceConstantSubMethodReturnValue = @"sub_method"; + +NSString * __nonnull const DBInterfaceInheritanceConstantSubOverrideMethodReturnValue = @"sub_override_method"; diff --git a/test-suite/generated-src/objc/DBListenerCaller+Private.mm b/test-suite/generated-src/objc/DBListenerCaller+Private.mm index b403438af..4fd1e18da 100644 --- a/test-suite/generated-src/objc/DBListenerCaller+Private.mm +++ b/test-suite/generated-src/objc/DBListenerCaller+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::ListenerCaller>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::ListenerCaller>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBListenerCaller methods + + (nullable DBListenerCaller *)init:(nullable id)firstL secondL:(nullable id)secondL { try { @@ -59,7 +66,7 @@ - (void)callSecond { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ListenerCaller::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBObjcOnlyListener+Private.mm b/test-suite/generated-src/objc/DBObjcOnlyListener+Private.mm index 184ec1c7a..6ebe49cb3 100644 --- a/test-suite/generated-src/objc/DBObjcOnlyListener+Private.mm +++ b/test-suite/generated-src/objc/DBObjcOnlyListener+Private.mm @@ -16,6 +16,8 @@ { public: using Handle::Handle; + + // ObjcOnlyListener methods }; } // namespace djinni_generated diff --git a/test-suite/generated-src/objc/DBObjcOnlyListener.h b/test-suite/generated-src/objc/DBObjcOnlyListener.h index e79cd9c57..cae84c18d 100644 --- a/test-suite/generated-src/objc/DBObjcOnlyListener.h +++ b/test-suite/generated-src/objc/DBObjcOnlyListener.h @@ -4,6 +4,6 @@ #import -@protocol DBObjcOnlyListener +@protocol DBObjcOnlyListener @end diff --git a/test-suite/generated-src/objc/DBReturnOne+Private.mm b/test-suite/generated-src/objc/DBReturnOne+Private.mm index 1b363b5c6..eaa7479d7 100644 --- a/test-suite/generated-src/objc/DBReturnOne+Private.mm +++ b/test-suite/generated-src/objc/DBReturnOne+Private.mm @@ -30,6 +30,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::ReturnOne>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::ReturnOne>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBReturnOne methods + + (nullable DBReturnOne *)getInstance { try { auto objcpp_result_ = ::testsuite::ReturnOne::get_instance(); @@ -51,7 +58,7 @@ - (int8_t)returnOne { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ReturnOne::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBReturnTwo+Private.mm b/test-suite/generated-src/objc/DBReturnTwo+Private.mm index 1050fb043..9c3d20439 100644 --- a/test-suite/generated-src/objc/DBReturnTwo+Private.mm +++ b/test-suite/generated-src/objc/DBReturnTwo+Private.mm @@ -30,6 +30,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::ReturnTwo>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::ReturnTwo>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBReturnTwo methods + + (nullable DBReturnTwo *)getInstance { try { auto objcpp_result_ = ::testsuite::ReturnTwo::get_instance(); @@ -51,7 +58,7 @@ - (int8_t)returnTwo { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ReturnTwo::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBReverseClientInterface+Private.mm b/test-suite/generated-src/objc/DBReverseClientInterface+Private.mm index 9e5fd500f..229740d1a 100644 --- a/test-suite/generated-src/objc/DBReverseClientInterface+Private.mm +++ b/test-suite/generated-src/objc/DBReverseClientInterface+Private.mm @@ -30,6 +30,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::ReverseClientInterface>&)c return self; } +- (const std::shared_ptr<::testsuite::ReverseClientInterface>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBReverseClientInterface methods + - (nonnull NSString *)returnStr { try { auto objcpp_result_ = _cppRefHandle.get()->return_str(); @@ -65,7 +72,7 @@ + (nullable DBReverseClientInterface *)create { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto ReverseClientInterface::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBSecondListener+Private.mm b/test-suite/generated-src/objc/DBSecondListener+Private.mm index 15ce58f3f..a896d1bde 100644 --- a/test-suite/generated-src/objc/DBSecondListener+Private.mm +++ b/test-suite/generated-src/objc/DBSecondListener+Private.mm @@ -16,6 +16,8 @@ { public: using Handle::Handle; + + // SecondListener methods void second() override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBSecondListener.h b/test-suite/generated-src/objc/DBSecondListener.h index 28a03a42d..3f99836f9 100644 --- a/test-suite/generated-src/objc/DBSecondListener.h +++ b/test-suite/generated-src/objc/DBSecondListener.h @@ -5,7 +5,7 @@ /** Used for ObjC multiple inheritance tests */ -@protocol DBSecondListener +@protocol DBSecondListener - (void)second; diff --git a/test-suite/generated-src/objc/DBSubCppInterfaceInheritance+Private.h b/test-suite/generated-src/objc/DBSubCppInterfaceInheritance+Private.h new file mode 100644 index 000000000..d1ae55bf6 --- /dev/null +++ b/test-suite/generated-src/objc/DBSubCppInterfaceInheritance+Private.h @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "sub_cpp_interface_inheritance.hpp" +#import "DBBaseCppInterfaceInheritance+Private.h" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class DBSubCppInterfaceInheritance; + +namespace djinni_generated { + +class SubCppInterfaceInheritance +{ +public: + using CppType = std::shared_ptr<::testsuite::SubCppInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::SubCppInterfaceInheritance>; + using ObjcType = DBSubCppInterfaceInheritance*; + + using Boxed = SubCppInterfaceInheritance; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + diff --git a/test-suite/generated-src/objc/DBSubCppInterfaceInheritance+Private.mm b/test-suite/generated-src/objc/DBSubCppInterfaceInheritance+Private.mm new file mode 100644 index 000000000..980182136 --- /dev/null +++ b/test-suite/generated-src/objc/DBSubCppInterfaceInheritance+Private.mm @@ -0,0 +1,90 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBSubCppInterfaceInheritance+Private.h" +#import "DBSubCppInterfaceInheritance.h" +#import "DJICppWrapperCache+Private.h" +#import "DJIError.h" +#import "DJIMarshal+Private.h" +#include +#include +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@interface DBSubCppInterfaceInheritance () + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::SubCppInterfaceInheritance>&)cppRef; + +@end + +@implementation DBSubCppInterfaceInheritance { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::SubCppInterfaceInheritance>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + +- (const std::shared_ptr<::testsuite::SubCppInterfaceInheritance>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBSubCppInterfaceInheritance methods + +- (nonnull NSString *)subMethod { + try { + auto objcpp_result_ = _cppRefHandle.get()->sub_method(); + return ::djinni::String::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + ++ (nullable DBSubCppInterfaceInheritance *)create { + try { + auto objcpp_result_ = ::testsuite::SubCppInterfaceInheritance::create(); + return ::djinni_generated::SubCppInterfaceInheritance::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +// DBBaseCppInterfaceInheritance methods + +- (nonnull NSString *)baseMethod { + try { + auto objcpp_result_ = _cppRefHandle.get()->base_method(); + return ::djinni::String::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (nonnull NSString *)overrideMethod { + try { + auto objcpp_result_ = _cppRefHandle.get()->override_method(); + return ::djinni::String::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +namespace djinni_generated { + +auto SubCppInterfaceInheritance::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return [objc cppRef]; +} + +auto SubCppInterfaceInheritance::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + return ::djinni::get_cpp_proxy(cpp); +} + +} // namespace djinni_generated + +@end diff --git a/test-suite/generated-src/objc/DBSubCppInterfaceInheritance.h b/test-suite/generated-src/objc/DBSubCppInterfaceInheritance.h new file mode 100644 index 000000000..a2c1f892b --- /dev/null +++ b/test-suite/generated-src/objc/DBSubCppInterfaceInheritance.h @@ -0,0 +1,15 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBBaseCppInterfaceInheritance.h" +#import +@class DBSubCppInterfaceInheritance; + + +@interface DBSubCppInterfaceInheritance : DBBaseCppInterfaceInheritance + +- (nonnull NSString *)subMethod; + ++ (nullable DBSubCppInterfaceInheritance *)create; + +@end diff --git a/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance+Private.h b/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance+Private.h new file mode 100644 index 000000000..323f54954 --- /dev/null +++ b/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance+Private.h @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#include "sub_objc_java_interface_inheritance.hpp" +#import "DBBaseObjcJavaInterfaceInheritance+Private.h" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@protocol DBSubObjcJavaInterfaceInheritance; + +namespace djinni_generated { + +class SubObjcJavaInterfaceInheritance +{ +public: + using CppType = std::shared_ptr<::testsuite::SubObjcJavaInterfaceInheritance>; + using CppOptType = std::shared_ptr<::testsuite::SubObjcJavaInterfaceInheritance>; + using ObjcType = id; + + using Boxed = SubObjcJavaInterfaceInheritance; + + static CppType toCpp(ObjcType objc); + static ObjcType fromCppOpt(const CppOptType& cpp); + static ObjcType fromCpp(const CppType& cpp) { return fromCppOpt(cpp); } + +private: + class ObjcProxy; +}; + +} // namespace djinni_generated + diff --git a/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance+Private.mm b/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance+Private.mm new file mode 100644 index 000000000..64d85bf7b --- /dev/null +++ b/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance+Private.mm @@ -0,0 +1,67 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBSubObjcJavaInterfaceInheritance+Private.h" +#import "DBSubObjcJavaInterfaceInheritance.h" +#import "DJIMarshal+Private.h" +#import "DJIObjcWrapperCache+Private.h" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +namespace djinni_generated { + +class SubObjcJavaInterfaceInheritance::ObjcProxy final +: public ::testsuite::SubObjcJavaInterfaceInheritance +, public ::djinni::ObjcProxyCache::Handle +{ +public: + using Handle::Handle; + + // SubObjcJavaInterfaceInheritance methods + std::string sub_method() override + { + @autoreleasepool { + auto objcpp_result_ = [Handle::get() subMethod]; + return ::djinni::String::toCpp(objcpp_result_); + } + } + + // BaseObjcJavaInterfaceInheritance methods + std::string base_method() override + { + @autoreleasepool { + auto objcpp_result_ = [Handle::get() baseMethod]; + return ::djinni::String::toCpp(objcpp_result_); + } + } + std::string override_method() override + { + @autoreleasepool { + auto objcpp_result_ = [Handle::get() overrideMethod]; + return ::djinni::String::toCpp(objcpp_result_); + } + } +}; + +} // namespace djinni_generated + +namespace djinni_generated { + +auto SubObjcJavaInterfaceInheritance::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return ::djinni::get_objc_proxy(objc); +} + +auto SubObjcJavaInterfaceInheritance::fromCppOpt(const CppOptType& cpp) -> ObjcType +{ + if (!cpp) { + return nil; + } + return dynamic_cast(*cpp).Handle::get(); +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance.h b/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance.h new file mode 100644 index 000000000..27b066f6f --- /dev/null +++ b/test-suite/generated-src/objc/DBSubObjcJavaInterfaceInheritance.h @@ -0,0 +1,12 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from interface_inheritance.djinni + +#import "DBBaseObjcJavaInterfaceInheritance.h" +#import + + +@protocol DBSubObjcJavaInterfaceInheritance + +- (nonnull NSString *)subMethod; + +@end diff --git a/test-suite/generated-src/objc/DBTestDuration+Private.mm b/test-suite/generated-src/objc/DBTestDuration+Private.mm index 4f374d52b..36c9aa922 100644 --- a/test-suite/generated-src/objc/DBTestDuration+Private.mm +++ b/test-suite/generated-src/objc/DBTestDuration+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::TestDuration>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::TestDuration>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBTestDuration methods + + (nonnull NSString *)hoursString:(NSTimeInterval)dt { try { auto objcpp_result_ = ::testsuite::TestDuration::hoursString(::djinni::Duration<::djinni::I32, ::djinni::Duration_h>::toCpp(dt)); @@ -178,7 +185,7 @@ + (int64_t)unbox:(nullable NSNumber *)dt { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto TestDuration::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBTestHelpers+Private.mm b/test-suite/generated-src/objc/DBTestHelpers+Private.mm index eab020b8b..93ad92d93 100644 --- a/test-suite/generated-src/objc/DBTestHelpers+Private.mm +++ b/test-suite/generated-src/objc/DBTestHelpers+Private.mm @@ -38,6 +38,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::TestHelpers>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::TestHelpers>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBTestHelpers methods + + (nonnull DBSetRecord *)getSetRecord { try { auto objcpp_result_ = ::testsuite::TestHelpers::get_set_record(); @@ -215,7 +222,7 @@ + (nonnull NSData *)idBinary:(nonnull NSData *)b { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto TestHelpers::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBUserToken+Private.mm b/test-suite/generated-src/objc/DBUserToken+Private.mm index d22c729fd..6d3750fbf 100644 --- a/test-suite/generated-src/objc/DBUserToken+Private.mm +++ b/test-suite/generated-src/objc/DBUserToken+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::UserToken>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::UserToken>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBUserTokenCppProxy methods + - (nonnull NSString *)whoami { try { auto objcpp_result_ = _cppRefHandle.get()->whoami(); @@ -46,6 +53,8 @@ - (nonnull NSString *)whoami { { public: using Handle::Handle; + + // UserToken methods std::string whoami() override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBUserToken.h b/test-suite/generated-src/objc/DBUserToken.h index 82c9f3f7c..6cd587b29 100644 --- a/test-suite/generated-src/objc/DBUserToken.h +++ b/test-suite/generated-src/objc/DBUserToken.h @@ -4,7 +4,7 @@ #import -@protocol DBUserToken +@protocol DBUserToken - (nonnull NSString *)whoami; diff --git a/test-suite/generated-src/objc/DBUsesSingleLanguageListeners+Private.mm b/test-suite/generated-src/objc/DBUsesSingleLanguageListeners+Private.mm index 8f26c375f..0bb1848d0 100644 --- a/test-suite/generated-src/objc/DBUsesSingleLanguageListeners+Private.mm +++ b/test-suite/generated-src/objc/DBUsesSingleLanguageListeners+Private.mm @@ -32,6 +32,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::UsesSingleLanguageListener return self; } +- (const std::shared_ptr<::testsuite::UsesSingleLanguageListeners>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBUsesSingleLanguageListenersCppProxy methods + - (void)callForObjC:(nullable id)l { try { _cppRefHandle.get()->callForObjC(::djinni_generated::ObjcOnlyListener::toCpp(l)); @@ -66,6 +73,8 @@ - (nullable DBJavaOnlyListener *)returnForJava { { public: using Handle::Handle; + + // UsesSingleLanguageListeners methods void callForObjC(const std::shared_ptr<::testsuite::ObjcOnlyListener> & c_l) override { @autoreleasepool { diff --git a/test-suite/generated-src/objc/DBUsesSingleLanguageListeners.h b/test-suite/generated-src/objc/DBUsesSingleLanguageListeners.h index cb2bf2278..a60bbc5cc 100644 --- a/test-suite/generated-src/objc/DBUsesSingleLanguageListeners.h +++ b/test-suite/generated-src/objc/DBUsesSingleLanguageListeners.h @@ -10,7 +10,7 @@ * Generating and compiling this makes sure other languages don't break * on references to interfaces they don't need. */ -@protocol DBUsesSingleLanguageListeners +@protocol DBUsesSingleLanguageListeners - (void)callForObjC:(nullable id)l; diff --git a/test-suite/generated-src/objc/DBVarnameInterface+Private.mm b/test-suite/generated-src/objc/DBVarnameInterface+Private.mm index fca3a07d1..ad0674e54 100644 --- a/test-suite/generated-src/objc/DBVarnameInterface+Private.mm +++ b/test-suite/generated-src/objc/DBVarnameInterface+Private.mm @@ -30,6 +30,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::VarnameInterface>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::VarnameInterface>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBVarnameInterface methods + - (nonnull DBVarnameRecord *)Rmethod:(nonnull DBVarnameRecord *)RArg { try { auto objcpp_result_ = _cppRefHandle.get()->_rmethod_(::djinni_generated::VarnameRecord::toCpp(RArg)); @@ -51,7 +58,7 @@ - (nullable DBVarnameInterface *)Imethod:(nullable DBVarnameInterface *)IArg { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto VarnameInterface::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/objc/DBWcharTestHelpers+Private.mm b/test-suite/generated-src/objc/DBWcharTestHelpers+Private.mm index 36936a5af..29243ef29 100644 --- a/test-suite/generated-src/objc/DBWcharTestHelpers+Private.mm +++ b/test-suite/generated-src/objc/DBWcharTestHelpers+Private.mm @@ -31,6 +31,13 @@ - (id)initWithCpp:(const std::shared_ptr<::testsuite::WcharTestHelpers>&)cppRef return self; } +- (const std::shared_ptr<::testsuite::WcharTestHelpers>&) cppRef +{ + return _cppRefHandle.get(); +} + +// DBWcharTestHelpers methods + + (nonnull DBWcharTestRec *)getRecord { try { auto objcpp_result_ = ::testsuite::WcharTestHelpers::get_record(); @@ -66,7 +73,7 @@ + (BOOL)checkRecord:(nonnull DBWcharTestRec *)rec { if (!objc) { return nullptr; } - return objc->_cppRefHandle.get(); + return [objc cppRef]; } auto WcharTestHelpers::fromCppOpt(const CppOptType& cpp) -> ObjcType diff --git a/test-suite/generated-src/outFileList.txt b/test-suite/generated-src/outFileList.txt index 3f28125dc..78791ccc8 100644 --- a/test-suite/generated-src/outFileList.txt +++ b/test-suite/generated-src/outFileList.txt @@ -4,6 +4,13 @@ djinni-output-temp/cpp/record_with_duration_and_derivings.cpp djinni-output-temp/cpp/date_record.hpp djinni-output-temp/cpp/date_record.cpp djinni-output-temp/cpp/map_date_record.hpp +djinni-output-temp/cpp/interface_inheritance_constant.hpp +djinni-output-temp/cpp/interface_inheritance_constant.cpp +djinni-output-temp/cpp/base_cpp_interface_inheritance.hpp +djinni-output-temp/cpp/sub_cpp_interface_inheritance.hpp +djinni-output-temp/cpp/base_objc_java_interface_inheritance.hpp +djinni-output-temp/cpp/sub_objc_java_interface_inheritance.hpp +djinni-output-temp/cpp/interface_encapsulator.hpp djinni-output-temp/cpp/_varname_record_.hpp djinni-output-temp/cpp/_varname_interface_.hpp djinni-output-temp/cpp/extended_record_base.hpp @@ -48,6 +55,12 @@ djinni-output-temp/java/TestDuration.java djinni-output-temp/java/RecordWithDurationAndDerivings.java djinni-output-temp/java/DateRecord.java djinni-output-temp/java/MapDateRecord.java +djinni-output-temp/java/InterfaceInheritanceConstant.java +djinni-output-temp/java/BaseCppInterfaceInheritance.java +djinni-output-temp/java/SubCppInterfaceInheritance.java +djinni-output-temp/java/BaseObjcJavaInterfaceInheritance.java +djinni-output-temp/java/SubObjcJavaInterfaceInheritance.java +djinni-output-temp/java/InterfaceEncapsulator.java djinni-output-temp/java/VarnameRecord.java djinni-output-temp/java/VarnameInterface.java djinni-output-temp/java/ExtendedRecord.java @@ -90,6 +103,18 @@ djinni-output-temp/jni/NativeDateRecord.hpp djinni-output-temp/jni/NativeDateRecord.cpp djinni-output-temp/jni/NativeMapDateRecord.hpp djinni-output-temp/jni/NativeMapDateRecord.cpp +djinni-output-temp/jni/NativeInterfaceInheritanceConstant.hpp +djinni-output-temp/jni/NativeInterfaceInheritanceConstant.cpp +djinni-output-temp/jni/NativeBaseCppInterfaceInheritance.hpp +djinni-output-temp/jni/NativeBaseCppInterfaceInheritance.cpp +djinni-output-temp/jni/NativeSubCppInterfaceInheritance.hpp +djinni-output-temp/jni/NativeSubCppInterfaceInheritance.cpp +djinni-output-temp/jni/NativeBaseObjcJavaInterfaceInheritance.hpp +djinni-output-temp/jni/NativeBaseObjcJavaInterfaceInheritance.cpp +djinni-output-temp/jni/NativeSubObjcJavaInterfaceInheritance.hpp +djinni-output-temp/jni/NativeSubObjcJavaInterfaceInheritance.cpp +djinni-output-temp/jni/NativeInterfaceEncapsulator.hpp +djinni-output-temp/jni/NativeInterfaceEncapsulator.cpp djinni-output-temp/jni/NativeVarnameRecord.hpp djinni-output-temp/jni/NativeVarnameRecord.cpp djinni-output-temp/jni/NativeVarnameInterface.hpp @@ -164,6 +189,13 @@ djinni-output-temp/objc/DBDateRecord.h djinni-output-temp/objc/DBDateRecord.mm djinni-output-temp/objc/DBMapDateRecord.h djinni-output-temp/objc/DBMapDateRecord.mm +djinni-output-temp/objc/DBInterfaceInheritanceConstant.h +djinni-output-temp/objc/DBInterfaceInheritanceConstant.mm +djinni-output-temp/objc/DBBaseCppInterfaceInheritance.h +djinni-output-temp/objc/DBSubCppInterfaceInheritance.h +djinni-output-temp/objc/DBBaseObjcJavaInterfaceInheritance.h +djinni-output-temp/objc/DBSubObjcJavaInterfaceInheritance.h +djinni-output-temp/objc/DBInterfaceEncapsulator.h djinni-output-temp/objc/DBVarnameRecord.h djinni-output-temp/objc/DBVarnameRecord.mm djinni-output-temp/objc/DBVarnameInterface.h @@ -222,6 +254,18 @@ djinni-output-temp/objc/DBDateRecord+Private.h djinni-output-temp/objc/DBDateRecord+Private.mm djinni-output-temp/objc/DBMapDateRecord+Private.h djinni-output-temp/objc/DBMapDateRecord+Private.mm +djinni-output-temp/objc/DBInterfaceInheritanceConstant+Private.h +djinni-output-temp/objc/DBInterfaceInheritanceConstant+Private.mm +djinni-output-temp/objc/DBBaseCppInterfaceInheritance+Private.h +djinni-output-temp/objc/DBBaseCppInterfaceInheritance+Private.mm +djinni-output-temp/objc/DBSubCppInterfaceInheritance+Private.h +djinni-output-temp/objc/DBSubCppInterfaceInheritance+Private.mm +djinni-output-temp/objc/DBBaseObjcJavaInterfaceInheritance+Private.h +djinni-output-temp/objc/DBBaseObjcJavaInterfaceInheritance+Private.mm +djinni-output-temp/objc/DBSubObjcJavaInterfaceInheritance+Private.h +djinni-output-temp/objc/DBSubObjcJavaInterfaceInheritance+Private.mm +djinni-output-temp/objc/DBInterfaceEncapsulator+Private.h +djinni-output-temp/objc/DBInterfaceEncapsulator+Private.mm djinni-output-temp/objc/DBVarnameRecord+Private.h djinni-output-temp/objc/DBVarnameRecord+Private.mm djinni-output-temp/objc/DBVarnameInterface+Private.h diff --git a/test-suite/handwritten-src/cpp/base_cpp_interface_inheritance_impl.cpp b/test-suite/handwritten-src/cpp/base_cpp_interface_inheritance_impl.cpp new file mode 100644 index 000000000..255ce13e2 --- /dev/null +++ b/test-suite/handwritten-src/cpp/base_cpp_interface_inheritance_impl.cpp @@ -0,0 +1,18 @@ +#include "base_cpp_interface_inheritance_impl.hpp" +#include "interface_inheritance_constant.hpp" + +namespace testsuite { + +std::string BaseCppInterfaceInheritanceImpl::base_method() { + return InterfaceInheritanceConstant::BASE_METHOD_RETURN_VALUE; +} + +std::string BaseCppInterfaceInheritanceImpl::override_method() { + return InterfaceInheritanceConstant::BASE_OVERRIDE_METHOD_RETURN_VALUE; +} + +std::shared_ptr BaseCppInterfaceInheritance::create() { + return std::make_shared(); +} + +} // namespace testsuite diff --git a/test-suite/handwritten-src/cpp/base_cpp_interface_inheritance_impl.hpp b/test-suite/handwritten-src/cpp/base_cpp_interface_inheritance_impl.hpp new file mode 100644 index 000000000..305d0ed4e --- /dev/null +++ b/test-suite/handwritten-src/cpp/base_cpp_interface_inheritance_impl.hpp @@ -0,0 +1,15 @@ +#include "base_cpp_interface_inheritance.hpp" + +namespace testsuite { + +class BaseCppInterfaceInheritanceImpl : public BaseCppInterfaceInheritance { +public: + BaseCppInterfaceInheritanceImpl() {} + virtual ~BaseCppInterfaceInheritanceImpl() {} + + virtual std::string base_method() override; + + virtual std::string override_method() override; +}; + +} // namespace testsuite diff --git a/test-suite/handwritten-src/cpp/interface_encapsulator_impl.cpp b/test-suite/handwritten-src/cpp/interface_encapsulator_impl.cpp new file mode 100644 index 000000000..659b9b230 --- /dev/null +++ b/test-suite/handwritten-src/cpp/interface_encapsulator_impl.cpp @@ -0,0 +1,45 @@ +#include "interface_encapsulator_impl.hpp" + +#include "base_cpp_interface_inheritance_impl.hpp" +#include "sub_cpp_interface_inheritance_impl.hpp" +#include "base_objc_java_interface_inheritance.hpp" +#include "sub_objc_java_interface_inheritance.hpp" + +namespace testsuite { + +void InterfaceEncapsulatorImpl::set_cpp_object(const std::shared_ptr & object) { + mCppObject = object; +} + +std::shared_ptr InterfaceEncapsulatorImpl::get_cpp_object() { + return mCppObject; +} + +std::shared_ptr InterfaceEncapsulatorImpl::sub_cpp_as_base_cpp() { + return std::make_shared(); +} + +void InterfaceEncapsulatorImpl::set_objc_java_object(const std::shared_ptr & object) { + mObjcJavaObject = object; +} + +std::shared_ptr InterfaceEncapsulatorImpl::get_objc_java_object() { + return mObjcJavaObject; +} + +std::shared_ptr InterfaceEncapsulator::create() { + return std::make_shared(); +} + +std::shared_ptr InterfaceEncapsulatorImpl::cast_base_arg_to_sub(const std::shared_ptr & subAsBase) { + auto subAsSub = std::dynamic_pointer_cast(subAsBase); + return subAsSub; +} + + +} // namespace testsuite + + + + + diff --git a/test-suite/handwritten-src/cpp/interface_encapsulator_impl.hpp b/test-suite/handwritten-src/cpp/interface_encapsulator_impl.hpp new file mode 100644 index 000000000..73296aec2 --- /dev/null +++ b/test-suite/handwritten-src/cpp/interface_encapsulator_impl.hpp @@ -0,0 +1,28 @@ +#include "interface_encapsulator.hpp" + +namespace testsuite { + +class InterfaceEncapsulatorImpl : public InterfaceEncapsulator { +public: + InterfaceEncapsulatorImpl() {} + virtual ~InterfaceEncapsulatorImpl() {} + + virtual void set_cpp_object(const std::shared_ptr & object) override; + + virtual std::shared_ptr get_cpp_object() override; + + virtual std::shared_ptr sub_cpp_as_base_cpp() override; + + virtual void set_objc_java_object(const std::shared_ptr & object) override; + + virtual std::shared_ptr get_objc_java_object() override; + + virtual std::shared_ptr cast_base_arg_to_sub(const std::shared_ptr & subAsBase) override; + +private: + + std::shared_ptr mCppObject; + std::shared_ptr mObjcJavaObject; +}; + +} // namespace testsuite diff --git a/test-suite/handwritten-src/cpp/sub_cpp_interface_inheritance_impl.cpp b/test-suite/handwritten-src/cpp/sub_cpp_interface_inheritance_impl.cpp new file mode 100644 index 000000000..cc47c1232 --- /dev/null +++ b/test-suite/handwritten-src/cpp/sub_cpp_interface_inheritance_impl.cpp @@ -0,0 +1,26 @@ +#include "sub_cpp_interface_inheritance_impl.hpp" +#include "base_cpp_interface_inheritance_impl.hpp" +#include "interface_inheritance_constant.hpp" + +namespace testsuite { + +SubCppInterfaceInheritanceImpl::SubCppInterfaceInheritanceImpl() + : mSuper{std::make_shared()} {}; + +std::string SubCppInterfaceInheritanceImpl::base_method() { + return mSuper->base_method(); +} + +std::string SubCppInterfaceInheritanceImpl::override_method() { + return InterfaceInheritanceConstant::SUB_OVERRIDE_METHOD_RETURN_VALUE; +} + +std::string SubCppInterfaceInheritanceImpl::sub_method() { + return InterfaceInheritanceConstant::SUB_METHOD_RETURN_VALUE; +} + +std::shared_ptr SubCppInterfaceInheritance::create() { + return std::make_shared(); +} + +} // namespace testsuite diff --git a/test-suite/handwritten-src/cpp/sub_cpp_interface_inheritance_impl.hpp b/test-suite/handwritten-src/cpp/sub_cpp_interface_inheritance_impl.hpp new file mode 100644 index 000000000..a454af86a --- /dev/null +++ b/test-suite/handwritten-src/cpp/sub_cpp_interface_inheritance_impl.hpp @@ -0,0 +1,20 @@ +#include "sub_cpp_interface_inheritance.hpp" + +namespace testsuite { + +class SubCppInterfaceInheritanceImpl : public SubCppInterfaceInheritance { +public: + SubCppInterfaceInheritanceImpl(); + virtual ~SubCppInterfaceInheritanceImpl() {} + + virtual std::string base_method() override; + + virtual std::string override_method() override; + + virtual std::string sub_method() override; + +private: + std::shared_ptr mSuper; +}; + +} // namespace testsuite diff --git a/test-suite/handwritten-src/java/com/dropbox/djinni/test/AllTests.java b/test-suite/handwritten-src/java/com/dropbox/djinni/test/AllTests.java index b9239f958..895026844 100644 --- a/test-suite/handwritten-src/java/com/dropbox/djinni/test/AllTests.java +++ b/test-suite/handwritten-src/java/com/dropbox/djinni/test/AllTests.java @@ -23,6 +23,7 @@ public static Test suite() { mySuite.addTestSuite(DurationTest.class); mySuite.addTestSuite(MockRecordTest.class); mySuite.addTestSuite(WcharTest.class); + mySuite.addTestSuite(InterfaceInheritanceTest.class); return mySuite; } diff --git a/test-suite/handwritten-src/java/com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritanceImpl.java b/test-suite/handwritten-src/java/com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritanceImpl.java new file mode 100644 index 000000000..a22b3aae3 --- /dev/null +++ b/test-suite/handwritten-src/java/com/dropbox/djinni/test/BaseObjcJavaInterfaceInheritanceImpl.java @@ -0,0 +1,17 @@ +package com.dropbox.djinni.test; + +import javax.annotation.Nonnull; + +public class BaseObjcJavaInterfaceInheritanceImpl extends BaseObjcJavaInterfaceInheritance { + @Nonnull + @Override + public String baseMethod() { + return InterfaceInheritanceConstant.BASE_METHOD_RETURN_VALUE; + } + + @Nonnull + @Override + public String overrideMethod() { + return InterfaceInheritanceConstant.BASE_OVERRIDE_METHOD_RETURN_VALUE; + } +} diff --git a/test-suite/handwritten-src/java/com/dropbox/djinni/test/InterfaceInheritanceTest.java b/test-suite/handwritten-src/java/com/dropbox/djinni/test/InterfaceInheritanceTest.java new file mode 100644 index 000000000..c79601a6e --- /dev/null +++ b/test-suite/handwritten-src/java/com/dropbox/djinni/test/InterfaceInheritanceTest.java @@ -0,0 +1,104 @@ +package com.dropbox.djinni.test; + +import junit.framework.TestCase; + +public class InterfaceInheritanceTest extends TestCase { + public void testCppBaseClass() { + BaseCppInterfaceInheritance base = BaseCppInterfaceInheritance.create(); + + assertNotNull(base); + assertTrue(base instanceof BaseCppInterfaceInheritance); + + assertTrue(base.baseMethod().equals(InterfaceInheritanceConstant.BASE_METHOD_RETURN_VALUE)); + assertTrue(base.overrideMethod().equals(InterfaceInheritanceConstant.BASE_OVERRIDE_METHOD_RETURN_VALUE)); + } + + public void testCppSubClassInheritance() { + SubCppInterfaceInheritance sub = SubCppInterfaceInheritance.create(); + + assertNotNull(sub); + assertTrue(sub instanceof SubCppInterfaceInheritance); + assertTrue(sub instanceof BaseCppInterfaceInheritance); + + assertTrue(sub.baseMethod().equals(InterfaceInheritanceConstant.BASE_METHOD_RETURN_VALUE)); + assertTrue(sub.overrideMethod().equals(InterfaceInheritanceConstant.SUB_OVERRIDE_METHOD_RETURN_VALUE)); + assertTrue(sub.subMethod().equals(InterfaceInheritanceConstant.SUB_METHOD_RETURN_VALUE)); + + BaseCppInterfaceInheritance subAsBase = (BaseCppInterfaceInheritance)sub; + assertTrue(subAsBase.baseMethod().equals(InterfaceInheritanceConstant.BASE_METHOD_RETURN_VALUE)); + assertTrue(subAsBase.overrideMethod().equals(InterfaceInheritanceConstant.SUB_OVERRIDE_METHOD_RETURN_VALUE)); + } + + public void testCppSubClassEncapsulation() { + InterfaceEncapsulator encapsulator = InterfaceEncapsulator.create(); + + BaseCppInterfaceInheritance base = BaseCppInterfaceInheritance.create(); + encapsulator.setCppObject(base); + assertTrue(encapsulator.getCppObject() instanceof BaseCppInterfaceInheritance); + + SubCppInterfaceInheritance sub = SubCppInterfaceInheritance.create(); + encapsulator.setCppObject(sub); + assertTrue(encapsulator.getCppObject() instanceof SubCppInterfaceInheritance); + assertTrue(encapsulator.subCppAsBaseCpp() instanceof SubCppInterfaceInheritance); + } + + public void testJavaBaseClass() { + BaseObjcJavaInterfaceInheritance base = new BaseObjcJavaInterfaceInheritanceImpl(); + + assertNotNull(base); + assertTrue(base instanceof BaseObjcJavaInterfaceInheritance); + + assertTrue(base.baseMethod().equals(InterfaceInheritanceConstant.BASE_METHOD_RETURN_VALUE)); + assertTrue(base.overrideMethod().equals(InterfaceInheritanceConstant.BASE_OVERRIDE_METHOD_RETURN_VALUE)); + } + + public void testJavaSubClassInheritance() { + SubObjcJavaInterfaceInheritance sub = new SubObjcJavaInterfaceInheritanceImpl(); + + assertNotNull(sub); + assertTrue(sub instanceof SubObjcJavaInterfaceInheritance); + assertTrue(sub instanceof BaseObjcJavaInterfaceInheritance); + + assertTrue(sub.baseMethod().equals(InterfaceInheritanceConstant.BASE_METHOD_RETURN_VALUE)); + assertTrue(sub.overrideMethod().equals(InterfaceInheritanceConstant.SUB_OVERRIDE_METHOD_RETURN_VALUE)); + assertTrue(sub.subMethod().equals(InterfaceInheritanceConstant.SUB_METHOD_RETURN_VALUE)); + } + + public void testJavaSubClassEncapsulation() { + InterfaceEncapsulator encapsulator = InterfaceEncapsulator.create(); + + BaseObjcJavaInterfaceInheritance base = new BaseObjcJavaInterfaceInheritanceImpl(); + encapsulator.setObjcJavaObject(base); + + BaseObjcJavaInterfaceInheritance encappedBase = encapsulator.getObjcJavaObject(); + assertTrue(encappedBase instanceof BaseObjcJavaInterfaceInheritance); + assertTrue(encappedBase instanceof BaseObjcJavaInterfaceInheritanceImpl); + + SubObjcJavaInterfaceInheritance sub = new SubObjcJavaInterfaceInheritanceImpl(); + encapsulator.setObjcJavaObject(sub); + + BaseObjcJavaInterfaceInheritance encappedSub = encapsulator.getObjcJavaObject(); + assertTrue(encappedSub instanceof BaseObjcJavaInterfaceInheritance); + assertTrue(encappedSub instanceof SubObjcJavaInterfaceInheritance); + assertTrue(encappedSub instanceof SubObjcJavaInterfaceInheritanceImpl); + assertFalse(encappedSub instanceof BaseObjcJavaInterfaceInheritanceImpl); + } + + public void testJavaSubClassCasting() { + InterfaceEncapsulator encapsulator = InterfaceEncapsulator.create(); + + BaseObjcJavaInterfaceInheritance base = new BaseObjcJavaInterfaceInheritanceImpl(); + Object castBase = encapsulator.castBaseArgToSub(base); + assertNull(castBase); + + // FIXME: This test will fail. When castBaseArgToSub is called, a C++ object will be created to + // represent the Java object. Since castBaseArgToSub takes a DBBaseObjJavaInterfaceInheritance + // argument, the C++ object that is created will be BaseObjcJavaInterfaceInheritance object, + // slicing off all the additional members of the subtype and making it impossible to cast + // back to the provided subtype. + // SubObjcJavaInterfaceInheritance sub = new SubObjcJavaInterfaceInheritanceImpl(); + // Object castSub = encapsulator.castBaseArgToSub(sub); + // assertNotNull(castSub); + // assertTrue(castSub instanceof SubObjcJavaInterfaceInheritance); + } +} \ No newline at end of file diff --git a/test-suite/handwritten-src/java/com/dropbox/djinni/test/SubObjcJavaInterfaceInheritanceImpl.java b/test-suite/handwritten-src/java/com/dropbox/djinni/test/SubObjcJavaInterfaceInheritanceImpl.java new file mode 100644 index 000000000..9d3ae3833 --- /dev/null +++ b/test-suite/handwritten-src/java/com/dropbox/djinni/test/SubObjcJavaInterfaceInheritanceImpl.java @@ -0,0 +1,25 @@ +package com.dropbox.djinni.test; + +import javax.annotation.Nonnull; + +public class SubObjcJavaInterfaceInheritanceImpl extends SubObjcJavaInterfaceInheritance { + private BaseObjcJavaInterfaceInheritance superImpl = new BaseObjcJavaInterfaceInheritanceImpl(); + + @Nonnull + @Override + public String baseMethod() { + return superImpl.baseMethod(); + } + + @Nonnull + @Override + public String subMethod() { + return InterfaceInheritanceConstant.SUB_METHOD_RETURN_VALUE; + } + + @Nonnull + @Override + public String overrideMethod() { + return InterfaceInheritanceConstant.SUB_OVERRIDE_METHOD_RETURN_VALUE; + } +} diff --git a/test-suite/handwritten-src/objc/impl/DBBaseObjcJavaInterfaceInheritanceImpl.h b/test-suite/handwritten-src/objc/impl/DBBaseObjcJavaInterfaceInheritanceImpl.h new file mode 100644 index 000000000..eb9827f34 --- /dev/null +++ b/test-suite/handwritten-src/objc/impl/DBBaseObjcJavaInterfaceInheritanceImpl.h @@ -0,0 +1,7 @@ +#import + +#import "DBBaseObjcJavaInterfaceInheritance.h" + +@interface DBBaseObjcJavaInterfaceInheritanceImpl : NSObject + +@end diff --git a/test-suite/handwritten-src/objc/impl/DBBaseObjcJavaInterfaceInheritanceImpl.m b/test-suite/handwritten-src/objc/impl/DBBaseObjcJavaInterfaceInheritanceImpl.m new file mode 100644 index 000000000..96cef87fe --- /dev/null +++ b/test-suite/handwritten-src/objc/impl/DBBaseObjcJavaInterfaceInheritanceImpl.m @@ -0,0 +1,17 @@ +#import "DBBaseObjcJavaInterfaceInheritanceImpl.h" + +#import "DBInterfaceInheritanceConstant.h" + +@implementation DBBaseObjcJavaInterfaceInheritanceImpl + +- (nonnull NSString *)baseMethod +{ + return DBInterfaceInheritanceConstantBaseMethodReturnValue; +} + +- (nonnull NSString *)overrideMethod +{ + return DBInterfaceInheritanceConstantBaseOverrideMethodReturnValue; +} + +@end diff --git a/test-suite/handwritten-src/objc/impl/DBSubObjcJavaInterfaceInheritanceImpl.h b/test-suite/handwritten-src/objc/impl/DBSubObjcJavaInterfaceInheritanceImpl.h new file mode 100644 index 000000000..283875308 --- /dev/null +++ b/test-suite/handwritten-src/objc/impl/DBSubObjcJavaInterfaceInheritanceImpl.h @@ -0,0 +1,7 @@ +#import + +#import "DBSubObjcJavaInterfaceInheritance.h" + +@interface DBSubObjcJavaInterfaceInheritanceImpl : NSObject + +@end diff --git a/test-suite/handwritten-src/objc/impl/DBSubObjcJavaInterfaceInheritanceImpl.m b/test-suite/handwritten-src/objc/impl/DBSubObjcJavaInterfaceInheritanceImpl.m new file mode 100644 index 000000000..76840cf59 --- /dev/null +++ b/test-suite/handwritten-src/objc/impl/DBSubObjcJavaInterfaceInheritanceImpl.m @@ -0,0 +1,38 @@ +#import "DBSubObjcJavaInterfaceInheritanceImpl.h" + +#import "DBInterfaceInheritanceConstant.h" +#import "DBBaseObjcJavaInterfaceInheritanceImpl.h" + +@interface DBSubObjcJavaInterfaceInheritanceImpl () + +@property (nonnull, readonly, strong) DBBaseObjcJavaInterfaceInheritanceImpl *superImpl; + +@end + +@implementation DBSubObjcJavaInterfaceInheritanceImpl + +@synthesize superImpl = _superImpl; +- (DBBaseObjcJavaInterfaceInheritanceImpl *)superImpl +{ + if (!_superImpl) { + _superImpl = [[DBBaseObjcJavaInterfaceInheritanceImpl alloc] init]; + } + return _superImpl; +} + +- (nonnull NSString *)baseMethod +{ + return [self.superImpl baseMethod]; +} + +- (nonnull NSString *)overrideMethod +{ + return DBInterfaceInheritanceConstantSubOverrideMethodReturnValue; +} + +- (nonnull NSString *)subMethod +{ + return DBInterfaceInheritanceConstantSubMethodReturnValue; +} + +@end diff --git a/test-suite/handwritten-src/objc/tests/DBInterfaceInheritanceTests.mm b/test-suite/handwritten-src/objc/tests/DBInterfaceInheritanceTests.mm new file mode 100644 index 000000000..61e148a44 --- /dev/null +++ b/test-suite/handwritten-src/objc/tests/DBInterfaceInheritanceTests.mm @@ -0,0 +1,139 @@ +#import + +#import "DBInterfaceInheritanceConstant.h" +#import "DBInterfaceEncapsulator.h" + +#import "DBBaseCppInterfaceInheritance.h" +#import "DBSubCppInterfaceInheritance.h" + +#import "DBBaseObjcJavaInterfaceInheritanceImpl.h" +#import "DBSubObjcJavaInterfaceInheritanceImpl.h" + +@interface DBInterfaceInheritanceTests : XCTestCase + +@end + +@implementation DBInterfaceInheritanceTests + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +#pragma mark - C++ Inheritance Test Cases + +- (void)testCppBaseClass +{ + DBBaseCppInterfaceInheritance *base = [DBBaseCppInterfaceInheritance create]; + + XCTAssertNotNil(base); + XCTAssertTrue([base isKindOfClass:[DBBaseCppInterfaceInheritance class]]); + + XCTAssertTrue([[base baseMethod] isEqualToString:DBInterfaceInheritanceConstantBaseMethodReturnValue]); + XCTAssertTrue([[base overrideMethod] isEqualToString:DBInterfaceInheritanceConstantBaseOverrideMethodReturnValue]); +} + +- (void)testCppSubClassInheritance +{ + DBSubCppInterfaceInheritance *sub = [DBSubCppInterfaceInheritance create]; + XCTAssertNotNil(sub); + XCTAssertTrue([sub isKindOfClass:[DBSubCppInterfaceInheritance class]]); + XCTAssertTrue([sub isKindOfClass:[DBBaseCppInterfaceInheritance class]]); + + XCTAssertTrue([[sub baseMethod] isEqualToString:DBInterfaceInheritanceConstantBaseMethodReturnValue]); + XCTAssertTrue([[sub overrideMethod] isEqualToString:DBInterfaceInheritanceConstantSubOverrideMethodReturnValue]); + XCTAssertTrue([[sub subMethod] isEqualToString:DBInterfaceInheritanceConstantSubMethodReturnValue]); + + DBBaseCppInterfaceInheritance *subAsBase = (DBBaseCppInterfaceInheritance *)sub; + XCTAssertTrue([[subAsBase baseMethod] isEqualToString:DBInterfaceInheritanceConstantBaseMethodReturnValue]); + XCTAssertTrue([[subAsBase overrideMethod] isEqualToString:DBInterfaceInheritanceConstantSubOverrideMethodReturnValue]); +} + +- (void)testCppSubClassEncapsulation +{ + DBInterfaceEncapsulator *encapsulator = [DBInterfaceEncapsulator create]; + + DBBaseCppInterfaceInheritance *base = [DBBaseCppInterfaceInheritance create]; + [encapsulator setCppObject:base]; + XCTAssertTrue([[encapsulator getCppObject] isKindOfClass:[DBBaseCppInterfaceInheritance class]]); + + DBSubCppInterfaceInheritance *sub = [DBSubCppInterfaceInheritance create]; + [encapsulator setCppObject:sub]; + XCTAssertTrue([[encapsulator getCppObject] isKindOfClass:[DBSubCppInterfaceInheritance class]]); + XCTAssertTrue([[encapsulator subCppAsBaseCpp] isKindOfClass:[DBSubCppInterfaceInheritance class]]); +} + +#pragma mark - Objective-C Inheritance Test Cases + +- (void)testObjcBaseClass +{ + id base = [[DBBaseObjcJavaInterfaceInheritanceImpl alloc] init]; + + XCTAssertNotNil(base); + XCTAssertTrue([base conformsToProtocol:@protocol(DBBaseObjcJavaInterfaceInheritance)]); + + XCTAssertTrue([[base baseMethod] isEqualToString:DBInterfaceInheritanceConstantBaseMethodReturnValue]); + XCTAssertTrue([[base overrideMethod] isEqualToString:DBInterfaceInheritanceConstantBaseOverrideMethodReturnValue]); +} + +- (void)testObjcSubClassInheritance +{ + id sub = [[DBSubObjcJavaInterfaceInheritanceImpl alloc] init]; + XCTAssertNotNil(sub); + XCTAssertTrue([sub conformsToProtocol:@protocol(DBSubObjcJavaInterfaceInheritance)]); + XCTAssertTrue([sub conformsToProtocol:@protocol(DBBaseObjcJavaInterfaceInheritance)]); + + XCTAssertTrue([[sub baseMethod] isEqualToString:DBInterfaceInheritanceConstantBaseMethodReturnValue]); + XCTAssertTrue([[sub overrideMethod] isEqualToString:DBInterfaceInheritanceConstantSubOverrideMethodReturnValue]); + XCTAssertTrue([[sub subMethod] isEqualToString:DBInterfaceInheritanceConstantSubMethodReturnValue]); + + id subAsBase = (id)sub; + XCTAssertTrue([[subAsBase baseMethod] isEqualToString:DBInterfaceInheritanceConstantBaseMethodReturnValue]); + XCTAssertTrue([[subAsBase overrideMethod] isEqualToString:DBInterfaceInheritanceConstantSubOverrideMethodReturnValue]); +} + +- (void)testObjcSubClassEncapsulation +{ + DBInterfaceEncapsulator *encapsulator = [DBInterfaceEncapsulator create]; + + id base = [[DBBaseObjcJavaInterfaceInheritanceImpl alloc] init]; + [encapsulator setObjcJavaObject:base]; + + id encappedBase = [encapsulator getObjcJavaObject]; + XCTAssertTrue([encappedBase conformsToProtocol:@protocol(DBBaseObjcJavaInterfaceInheritance)]); + XCTAssertTrue([encappedBase isKindOfClass:[DBBaseObjcJavaInterfaceInheritanceImpl class]]); + + id sub = [[DBSubObjcJavaInterfaceInheritanceImpl alloc] init]; + [encapsulator setObjcJavaObject:sub]; + + id encappedSub = [encapsulator getObjcJavaObject]; + XCTAssertTrue([encappedSub conformsToProtocol:@protocol(DBBaseObjcJavaInterfaceInheritance)]); + XCTAssertTrue([encappedSub conformsToProtocol:@protocol(DBSubObjcJavaInterfaceInheritance)]); + XCTAssertTrue([encappedSub isKindOfClass:[DBSubObjcJavaInterfaceInheritanceImpl class]]); + XCTAssertFalse([encappedSub isKindOfClass:[DBBaseObjcJavaInterfaceInheritanceImpl class]]); +} + +- (void) testObjcSubClassCasting +{ + DBInterfaceEncapsulator *encapsulator = [DBInterfaceEncapsulator create]; + + id base = [[DBBaseObjcJavaInterfaceInheritanceImpl alloc] init]; + id castBase = [encapsulator castBaseArgToSub:base]; + XCTAssertNil(castBase); + + // FIXME: This test will fail. When castBaseArgToSub is called, a C++ object will be created to + // represent the Objective-C object. Since castBaseArgToSub takes a DBBaseObjJavaInterfaceInheritance + // argument, the C++ object that is created will be BaseObjcJavaInterfaceInheritance object, + // slicing off all the additional members of the subtype and making it impossible to cast + // back to the provided subtype. + // id sub = [[DBSubObjcJavaInterfaceInheritanceImpl alloc] init]; + // id castSub = [encapsulator castBaseArgToSub:sub]; + // XCTAssertNotNil(castSub); +} + +@end diff --git a/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj b/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj index d4e54ea11..5a06556f8 100644 --- a/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj +++ b/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj @@ -128,6 +128,20 @@ CFFD58B41B041BD9001E10B6 /* DBConstantsInterface+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = CFFD58B01B041BD9001E10B6 /* DBConstantsInterface+Private.mm */; }; CFFD58B71B041BFD001E10B6 /* constants_interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CFFD58B51B041BFD001E10B6 /* constants_interface.cpp */; }; CFFD58B81B041BFD001E10B6 /* constants_interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CFFD58B51B041BFD001E10B6 /* constants_interface.cpp */; }; + E07CADE91D58D44200567C5B /* base_cpp_interface_inheritance_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E07CADE71D58D44200567C5B /* base_cpp_interface_inheritance_impl.cpp */; }; + E07CADEC1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E07CADEA1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.cpp */; }; + E0EFF6C51D58F68A003F6C91 /* DBInterfaceInheritanceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6C41D58F68A003F6C91 /* DBInterfaceInheritanceTests.mm */; }; + E0EFF6CE1D590681003F6C91 /* DBInterfaceInheritanceConstant.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6CB1D590681003F6C91 /* DBInterfaceInheritanceConstant.mm */; }; + E0EFF6CF1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6CD1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.mm */; }; + E0EFF6D21D5906A2003F6C91 /* interface_encapsulator_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6D01D5906A2003F6C91 /* interface_encapsulator_impl.cpp */; }; + E0EFF6D61D59070E003F6C91 /* interface_inheritance_constant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6D41D59070E003F6C91 /* interface_inheritance_constant.cpp */; }; + E0EFF6E01D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6D91D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.mm */; }; + E0EFF6E21D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6DF1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.mm */; }; + E0EFF6EF1D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6E81D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.mm */; }; + E0EFF6F01D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6EB1D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.mm */; }; + E0EFF6F11D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6EE1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.mm */; }; + E0EFF6F71D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6F61D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.m */; }; + E0EFF6FA1D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = E0EFF6F91D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -398,6 +412,43 @@ CFFD58B01B041BD9001E10B6 /* DBConstantsInterface+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBConstantsInterface+Private.mm"; sourceTree = ""; }; CFFD58B51B041BFD001E10B6 /* constants_interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = constants_interface.cpp; sourceTree = ""; }; CFFD58B61B041BFD001E10B6 /* constants_interface.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = constants_interface.hpp; sourceTree = ""; }; + E07CADE71D58D44200567C5B /* base_cpp_interface_inheritance_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_cpp_interface_inheritance_impl.cpp; sourceTree = ""; }; + E07CADE81D58D44200567C5B /* base_cpp_interface_inheritance_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = base_cpp_interface_inheritance_impl.hpp; sourceTree = ""; }; + E07CADEA1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sub_cpp_interface_inheritance_impl.cpp; sourceTree = ""; }; + E07CADEB1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = sub_cpp_interface_inheritance_impl.hpp; sourceTree = ""; }; + E0EFF6C41D58F68A003F6C91 /* DBInterfaceInheritanceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBInterfaceInheritanceTests.mm; sourceTree = ""; }; + E0EFF6CA1D590681003F6C91 /* DBInterfaceInheritanceConstant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBInterfaceInheritanceConstant.h; sourceTree = ""; }; + E0EFF6CB1D590681003F6C91 /* DBInterfaceInheritanceConstant.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DBInterfaceInheritanceConstant.mm; sourceTree = ""; }; + E0EFF6CC1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBInterfaceInheritanceConstant+Private.h"; sourceTree = ""; }; + E0EFF6CD1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBInterfaceInheritanceConstant+Private.mm"; sourceTree = ""; }; + E0EFF6D01D5906A2003F6C91 /* interface_encapsulator_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = interface_encapsulator_impl.cpp; sourceTree = ""; }; + E0EFF6D11D5906A2003F6C91 /* interface_encapsulator_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = interface_encapsulator_impl.hpp; sourceTree = ""; }; + E0EFF6D41D59070E003F6C91 /* interface_inheritance_constant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = interface_inheritance_constant.cpp; sourceTree = ""; }; + E0EFF6D51D59070E003F6C91 /* interface_inheritance_constant.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = interface_inheritance_constant.hpp; sourceTree = ""; }; + E0EFF6D71D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBBaseCppInterfaceInheritance.h; sourceTree = ""; }; + E0EFF6D81D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBBaseCppInterfaceInheritance+Private.h"; sourceTree = ""; }; + E0EFF6D91D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBBaseCppInterfaceInheritance+Private.mm"; sourceTree = ""; }; + E0EFF6DD1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBSubCppInterfaceInheritance.h; sourceTree = ""; }; + E0EFF6DE1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBSubCppInterfaceInheritance+Private.h"; sourceTree = ""; }; + E0EFF6DF1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBSubCppInterfaceInheritance+Private.mm"; sourceTree = ""; }; + E0EFF6E31D5A02D5003F6C91 /* base_cpp_interface_inheritance.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = base_cpp_interface_inheritance.hpp; sourceTree = ""; }; + E0EFF6E51D5A02D5003F6C91 /* sub_cpp_interface_inheritance.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = sub_cpp_interface_inheritance.hpp; sourceTree = ""; }; + E0EFF6E61D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBBaseObjcJavaInterfaceInheritance.h; sourceTree = ""; }; + E0EFF6E71D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBBaseObjcJavaInterfaceInheritance+Private.h"; sourceTree = ""; }; + E0EFF6E81D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBBaseObjcJavaInterfaceInheritance+Private.mm"; sourceTree = ""; }; + E0EFF6E91D5A07B7003F6C91 /* DBInterfaceEncapsulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBInterfaceEncapsulator.h; sourceTree = ""; }; + E0EFF6EA1D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBInterfaceEncapsulator+Private.h"; sourceTree = ""; }; + E0EFF6EB1D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBInterfaceEncapsulator+Private.mm"; sourceTree = ""; }; + E0EFF6EC1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBSubObjcJavaInterfaceInheritance.h; sourceTree = ""; }; + E0EFF6ED1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBSubObjcJavaInterfaceInheritance+Private.h"; sourceTree = ""; }; + E0EFF6EE1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBSubObjcJavaInterfaceInheritance+Private.mm"; sourceTree = ""; }; + E0EFF6F21D5A07CC003F6C91 /* base_objc_java_interface_inheritance.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = base_objc_java_interface_inheritance.hpp; sourceTree = ""; }; + E0EFF6F31D5A07CC003F6C91 /* interface_encapsulator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = interface_encapsulator.hpp; sourceTree = ""; }; + E0EFF6F41D5A07CC003F6C91 /* sub_objc_java_interface_inheritance.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = sub_objc_java_interface_inheritance.hpp; sourceTree = ""; }; + E0EFF6F51D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBBaseObjcJavaInterfaceInheritanceImpl.h; sourceTree = ""; }; + E0EFF6F61D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBBaseObjcJavaInterfaceInheritanceImpl.m; sourceTree = ""; }; + E0EFF6F81D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBSubObjcJavaInterfaceInheritanceImpl.h; sourceTree = ""; }; + E0EFF6F91D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBSubObjcJavaInterfaceInheritanceImpl.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -442,6 +493,10 @@ children = ( 6536CD7119A6C96C00DD7715 /* DBClientInterfaceImpl.h */, 6536CD7219A6C96C00DD7715 /* DBClientInterfaceImpl.mm */, + E0EFF6F51D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.h */, + E0EFF6F61D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.m */, + E0EFF6F81D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.h */, + E0EFF6F91D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.m */, ); name = "handwritten-objc"; path = "../handwritten-src/objc/impl"; @@ -464,6 +519,12 @@ A278D45219BA3601006FD937 /* test_helpers.cpp */, CFC5D9FB1B152E4300BF2DF8 /* TranslateDuration.cpp */, 6551684E1C40511C003682A4 /* return_one_two.cpp */, + E07CADE71D58D44200567C5B /* base_cpp_interface_inheritance_impl.cpp */, + E07CADE81D58D44200567C5B /* base_cpp_interface_inheritance_impl.hpp */, + E07CADEA1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.cpp */, + E07CADEB1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.hpp */, + E0EFF6D01D5906A2003F6C91 /* interface_encapsulator_impl.cpp */, + E0EFF6D11D5906A2003F6C91 /* interface_encapsulator_impl.hpp */, ); name = "handwritten-cpp"; path = "../handwritten-src/cpp"; @@ -489,6 +550,7 @@ A200940E1B0697D300EF8D9B /* DBTokenTests.mm */, 6536CD8419A6C99800DD7715 /* DjinniObjcTestTests-Info.plist */, 6536CD8219A6C99800DD7715 /* InfoPlist.strings */, + E0EFF6C41D58F68A003F6C91 /* DBInterfaceInheritanceTests.mm */, ); name = Tests; path = "../handwritten-src/objc/tests"; @@ -571,6 +633,25 @@ B5F06A7F1D4973BD005BE736 /* DBObjcOnlyListener.h */, B5F06A801D4973BD005BE736 /* DBObjcOnlyListener+Private.h */, B5F06A811D4973BD005BE736 /* DBObjcOnlyListener+Private.mm */, + E0EFF6E61D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance.h */, + E0EFF6E71D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.h */, + E0EFF6E81D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.mm */, + E0EFF6E91D5A07B7003F6C91 /* DBInterfaceEncapsulator.h */, + E0EFF6EA1D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.h */, + E0EFF6EB1D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.mm */, + E0EFF6EC1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance.h */, + E0EFF6ED1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.h */, + E0EFF6EE1D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.mm */, + E0EFF6D71D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance.h */, + E0EFF6D81D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.h */, + E0EFF6D91D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.mm */, + E0EFF6DD1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance.h */, + E0EFF6DE1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.h */, + E0EFF6DF1D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.mm */, + E0EFF6CA1D590681003F6C91 /* DBInterfaceInheritanceConstant.h */, + E0EFF6CB1D590681003F6C91 /* DBInterfaceInheritanceConstant.mm */, + E0EFF6CC1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.h */, + E0EFF6CD1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.mm */, B5D8FC321C23E2F40045ADCF /* DBConstantRecord.h */, B5D8FC331C23E2F40045ADCF /* DBConstantRecord.mm */, B5D8FC341C23E2F40045ADCF /* DBConstantRecord+Private.h */, @@ -700,6 +781,13 @@ B5F06A6A1D497396005BE736 /* java_only_listener.hpp */, B5F06A6B1D497396005BE736 /* objc_only_listener.hpp */, B5F06A6C1D497396005BE736 /* uses_single_language_listeners.hpp */, + E0EFF6F21D5A07CC003F6C91 /* base_objc_java_interface_inheritance.hpp */, + E0EFF6F31D5A07CC003F6C91 /* interface_encapsulator.hpp */, + E0EFF6F41D5A07CC003F6C91 /* sub_objc_java_interface_inheritance.hpp */, + E0EFF6E31D5A02D5003F6C91 /* base_cpp_interface_inheritance.hpp */, + E0EFF6E51D5A02D5003F6C91 /* sub_cpp_interface_inheritance.hpp */, + E0EFF6D41D59070E003F6C91 /* interface_inheritance_constant.cpp */, + E0EFF6D51D59070E003F6C91 /* interface_inheritance_constant.hpp */, B5D8FC381C23E30D0045ADCF /* constant_record.hpp */, B5E9C93C1C1F9DCA0073C123 /* reverse_client_interface.hpp */, B52DA56C1B103FBE005CE75F /* assorted_primitives.cpp */, @@ -833,9 +921,11 @@ CFAED8761B54291900E3B8A3 /* DBEmptyRecord+Private.mm in Sources */, 655168421C404B81003682A4 /* DBFirstListener+Private.mm in Sources */, A24850271AF96EBC00AFE907 /* DBClientReturnedRecord.mm in Sources */, + E0EFF6FA1D5A0ACF003F6C91 /* DBSubObjcJavaInterfaceInheritanceImpl.m in Sources */, CFC5D9D61B15106400BF2DF8 /* DBExternRecordWithDerivings.mm in Sources */, CFC5DA0E1B15330000BF2DF8 /* record_with_duration_and_derivings.cpp in Sources */, A238CA941AF84B7100CDDCE5 /* DBMapDateRecord+Private.mm in Sources */, + E0EFF6D21D5906A2003F6C91 /* interface_encapsulator_impl.cpp in Sources */, CFFD588F1B019E79001E10B6 /* DBTestHelpers+Private.mm in Sources */, A24850291AF96EBC00AFE907 /* DBDateRecord.mm in Sources */, A278D45319BA3601006FD937 /* test_helpers.cpp in Sources */, @@ -862,8 +952,11 @@ B52DA5691B103F72005CE75F /* DBAssortedPrimitives.mm in Sources */, A24850281AF96EBC00AFE907 /* DBConstants.mm in Sources */, 655168431C404B81003682A4 /* DBSecondListener+Private.mm in Sources */, + E0EFF6E01D5A02B5003F6C91 /* DBBaseCppInterfaceInheritance+Private.mm in Sources */, CFFD58B71B041BFD001E10B6 /* constants_interface.cpp in Sources */, CFAED8751B54291900E3B8A3 /* DBEmptyRecord.mm in Sources */, + E07CADEC1D58D55800567C5B /* sub_cpp_interface_inheritance_impl.cpp in Sources */, + E0EFF6EF1D5A07B7003F6C91 /* DBBaseObjcJavaInterfaceInheritance+Private.mm in Sources */, A238CA9A1AF84B7100CDDCE5 /* DBNestedCollection+Private.mm in Sources */, CFFD58911B019E79001E10B6 /* DBUserToken+Private.mm in Sources */, B5153F9A1D54284100012654 /* DBJavaOnlyListener+Private.mm in Sources */, @@ -880,6 +973,7 @@ B5F06A861D4973BD005BE736 /* DBConflictUser+Private.mm in Sources */, B5E9C93B1C1F9D9D0073C123 /* reverse_client_interface_impl.cpp in Sources */, CFC5D9D81B15106400BF2DF8 /* DBExternRecordWithDerivings+Private.mm in Sources */, + E0EFF6CF1D590681003F6C91 /* DBInterfaceInheritanceConstant+Private.mm in Sources */, A238CAA21AF84B7100CDDCE5 /* DBSetRecord+Private.mm in Sources */, A2AE38491BB3074800B7A0C9 /* DJIProxyCaches.mm in Sources */, A238CA9E1AF84B7100CDDCE5 /* DBRecordWithDerivings+Private.mm in Sources */, @@ -894,6 +988,7 @@ 650CA05E1C2AB5AB007ADDDB /* ListenerCaller.cpp in Sources */, A248502A1AF96EBC00AFE907 /* DBMapDateRecord.mm in Sources */, B5F06A6D1D497396005BE736 /* extended_record_base.cpp in Sources */, + E0EFF6F71D5A09D8003F6C91 /* DBBaseObjcJavaInterfaceInheritanceImpl.m in Sources */, A238CA8E1AF84B7100CDDCE5 /* DBClientReturnedRecord+Private.mm in Sources */, B5F06A8A1D4973BD005BE736 /* DBExtendedRecord+Private.mm in Sources */, 6551684D1C4050A4003682A4 /* DBReturnTwo+Private.mm in Sources */, @@ -904,9 +999,16 @@ A248502E1AF96EBC00AFE907 /* DBPrimitiveList.mm in Sources */, B5F06A8C1D4973BD005BE736 /* DBObjcOnlyListener+Private.mm in Sources */, B5153F961D54283700012654 /* DBUsesSingleLanguageListeners+Private.mm in Sources */, + E07CADE91D58D44200567C5B /* base_cpp_interface_inheritance_impl.cpp in Sources */, + A209B57A1BBA2A0A0070C310 /* DBOptColorRecord+Private.mm in Sources */, B5D8FC371C23E2F40045ADCF /* DBConstantRecord+Private.mm in Sources */, B519111B1D542B0700772DFE /* wchar_test_helpers.cpp in Sources */, + E0EFF6D61D59070E003F6C91 /* interface_inheritance_constant.cpp in Sources */, + E0EFF6E21D5A02B5003F6C91 /* DBSubCppInterfaceInheritance+Private.mm in Sources */, + E0EFF6F01D5A07B7003F6C91 /* DBInterfaceEncapsulator+Private.mm in Sources */, A238CAA01AF84B7100CDDCE5 /* DBRecordWithNestedDerivings+Private.mm in Sources */, + E0EFF6F11D5A07B7003F6C91 /* DBSubObjcJavaInterfaceInheritance+Private.mm in Sources */, + E0EFF6CE1D590681003F6C91 /* DBInterfaceInheritanceConstant.mm in Sources */, CFC5DA0A1B1532F600BF2DF8 /* DBRecordWithDurationAndDerivings+Private.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -945,6 +1047,7 @@ CFC5D9F31B15276900BF2DF8 /* DBDurationTests.m in Sources */, CFC5D9EB1B1513E800BF2DF8 /* DBExternInterface2+Private.mm in Sources */, CFC5DA0B1B1532F600BF2DF8 /* DBRecordWithDurationAndDerivings+Private.mm in Sources */, + E0EFF6C51D58F68A003F6C91 /* DBInterfaceInheritanceTests.mm in Sources */, CFC5D9E91B1513E800BF2DF8 /* DBExternInterface1+Private.mm in Sources */, 6536CD9419A6C9A800DD7715 /* DBSetRecordTests.mm in Sources */, CFC5D9D91B15106400BF2DF8 /* DBExternRecordWithDerivings+Private.mm in Sources */,