diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index 119636fd7..323087aac 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -271,6 +271,9 @@ class CppGenerator(spec: Spec) extends Generator(spec) { i.consts.map(c => { refs.find(c.ty, true) }) + i.properties.map(p => { + refs.find(p.ty, true) + }) val self = marshal.typename(ident, i) val methodNamesInScope = i.methods.map(m => idCpp.method(m.ident)) @@ -297,6 +300,16 @@ class CppGenerator(spec: Spec) extends Generator(spec) { w.wl(s"virtual $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}$constFlag = 0;") } } + // Properties + for (p <- i.properties) { + w.wl + writeDoc(w, p.doc) + val ret = marshal.fieldType(p.ty) + w.wl(s"virtual $ret get_${idCpp.method(p.ident)}() = 0;") + if(!p.readOnly) { + w.wl(s"virtual void set_${idCpp.method(p.ident)}($ret new_${idCpp.method(p.ident)}) = 0;") + } + } } }) diff --git a/src/source/JNIGenerator.scala b/src/source/JNIGenerator.scala index c36234ec0..fae0378d5 100644 --- a/src/source/JNIGenerator.scala +++ b/src/source/JNIGenerator.scala @@ -184,6 +184,9 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { i.consts.foreach(c => { refs.find(c.ty) }) + i.properties.foreach(p => { + refs.find(p.ty) + }) val jniSelf = jniMarshal.helperClass(ident) val cppSelf = cppMarshal.fqTypename(ident, i) + cppTypeArgs(typeParams) @@ -366,6 +369,27 @@ class JNIGenerator(spec: Spec) extends Generator(spec) { m.ret.fold()(r => w.wl(s"return ::djinni::release(${jniMarshal.fromCpp(r, "r")});")) }) } + for(p <- i.properties) { + nativeHook(s"native_get${idJava.method(p.ident).capitalize}", false, Nil, Option(p.ty), { + w.wl(s"const auto& ref = ::djinni::objectFromHandleAddress<$cppSelf>(nativeRef);") + val methodName = "get_" + idCpp.method(p.ident) + val ret = "auto r = " + val call = s"ref->$methodName" + w.wl(s"${ret}${call}();") + w.wl(s"return ::djinni::release(${jniMarshal.fromCpp(p.ty, "r")});") + }) + if(!p.readOnly) { + val setterParam = Iterable(Field(p.ident, p.ty, Doc(Nil))); + nativeHook(s"native_set${idJava.method(p.ident).capitalize}", false, setterParam, Option(null), { + w.wl(s"const auto& ref = ::djinni::objectFromHandleAddress<$cppSelf>(nativeRef);") + val methodName = "set_" + idCpp.method(p.ident) + val call = s"ref->$methodName" + val params = jniMarshal.toCpp(p.ty, "j_" + idJava.local(p.ident)) + w.wl(s"${call}(${params});") + w.wl(";") + }) + } + } } } diff --git a/src/source/JavaGenerator.scala b/src/source/JavaGenerator.scala index d97299a63..8eb3e22f6 100644 --- a/src/source/JavaGenerator.scala +++ b/src/source/JavaGenerator.scala @@ -130,6 +130,10 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { i.consts.map(c => { refs.find(c.ty) }) + i.properties.map(p => { + refs.find(p.ty) + }) + if (i.ext.cpp) { refs.java.add("java.util.concurrent.atomic.AtomicBoolean") } @@ -167,6 +171,17 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { marshal.nullityAnnotation(m.ret).foreach(w.wl) w.wl("public static native "+ ret + " " + idJava.method(m.ident) + params.mkString("(", ", ", ")") + ";") } + for (p <- i.properties) { + skipFirst { w.wl } + writeDoc(w, p.doc) + val ret = marshal.fqTypename(p.ty) + val meth = idJava.method(p.ident).capitalize; + w.wl("public abstract " + ret + " get" + meth + "();") + if(!p.readOnly) { + w.wl("public abstract void set" + meth + "(" + ret + " new" + meth + ");") + } + } + if (i.ext.cpp) { w.wl javaAnnotationHeader.foreach(w.wl) @@ -202,6 +217,28 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { } w.wl(s"private native $ret native_$meth(long _nativeRef${preComma(params)});") } + + for (p <- i.properties) { + val ret = marshal.fieldType(p.ty) + var meth = idJava.method(p.ident).capitalize + w.wl + w.wl(s"@Override") + w.wl(s"public $ret get$meth()$throwException").braced { + w.wl("assert !this.destroyed.get() : \"trying to use a destroyed object\";") + w.wl(s"return native_get$meth(this.nativeRef);") + } + w.wl(s"private native ${ret} native_get${meth}(long _nativeRef);") + + if(!p.readOnly) { + w.wl + w.wl(s"@Override") + w.wl(s"public void set$meth(${ret} new${meth})$throwException").braced { + w.wl("assert !this.destroyed.get() : \"trying to use a destroyed object\";") + w.wl(s"native_set$meth(this.nativeRef, new${meth});") + } + w.wl(s"private native void native_set${meth}(long _nativeRef, ${ret} new${meth});") + } + } } } } diff --git a/src/source/ObjcGenerator.scala b/src/source/ObjcGenerator.scala index 3d573aad5..91a8599f1 100644 --- a/src/source/ObjcGenerator.scala +++ b/src/source/ObjcGenerator.scala @@ -112,6 +112,13 @@ class ObjcGenerator(spec: Spec) extends BaseObjcGenerator(spec) { writeObjcFuncDecl(m, w) w.wl(";") } + for(p <- i.properties) { + w.wl + writeDoc(w, p.doc) + val nullability = marshal.nullability(p.ty.resolved).fold("")(", " + _) + val readonly = if(p.readOnly) ", readonly" else "" + w.wl(s"@property (nonatomic${nullability}${readonly}) ${marshal.fqFieldType(p.ty)} ${idObjc.field(p.ident)};") + } for (c <- i.consts if !marshal.canBeConstVariable(c)) { w.wl writeDoc(w, c.doc) diff --git a/src/source/ObjcppGenerator.scala b/src/source/ObjcppGenerator.scala index ab0263f5d..5ad741f8b 100644 --- a/src/source/ObjcppGenerator.scala +++ b/src/source/ObjcppGenerator.scala @@ -70,6 +70,9 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { i.consts.map(c => { refs.find(c.ty) }) + i.properties.map(p => { + refs.find(p.ty) + }) val self = objcMarshal.typename(ident, i) val cppSelf = cppMarshal.fqTypename(ident, i) @@ -197,6 +200,23 @@ class ObjcppGenerator(spec: Spec) extends BaseObjcGenerator(spec) { } } + for (p <- i.properties) { + w.wl + w.wl(s"- (${marshal.fqFieldType(p.ty)})${idObjc.method(p.ident)}") + w.braced { + val call = "_cppRefHandle.get()->get_" + idCpp.method(p.ident) + "();" + w.wl(s"auto objcpp_result_ = ${call}") + w.wl(s"return ${objcppMarshal.fromCpp(p.ty, "objcpp_result_")};") + } + if(!p.readOnly) { + w.wl(s"- (void)set${idObjc.method(p.ident).capitalize}:(${marshal.fqFieldType(p.ty)})${idCpp.method(p.ident)}") + w.braced { + val call = s"_cppRefHandle.get()->set_${idCpp.method(p.ident)}(${objcppMarshal.toCpp(p.ty, idCpp.method(p.ident))})"; + w.wl(s"${call};") + } + } + } + if (i.consts.nonEmpty) { w.wl generateObjcConstants(w, i.consts, self, ObjcConstantType.ConstMethod) diff --git a/src/source/ast.scala b/src/source/ast.scala index 6d2ca62c8..5c02d28e5 100644 --- a/src/source/ast.scala +++ b/src/source/ast.scala @@ -74,9 +74,10 @@ object Record { } } -case class Interface(ext: Ext, methods: Seq[Interface.Method], consts: Seq[Const]) extends TypeDef +case class Interface(ext: Ext, methods: Seq[Interface.Method], consts: Seq[Const], properties: Seq[Interface.Property]) extends TypeDef object Interface { case class Method(ident: Ident, params: Seq[Field], ret: Option[TypeRef], doc: Doc, static: Boolean, const: Boolean) + case class Property(ident: Ident, ty: TypeRef, doc: Doc, readOnly: Boolean) } case class Field(ident: Ident, ty: TypeRef, doc: Doc) diff --git a/src/source/parser.scala b/src/source/parser.scala index a7f06841f..7fde3d029 100644 --- a/src/source/parser.scala +++ b/src/source/parser.scala @@ -16,14 +16,16 @@ package djinni -import java.io.{File, InputStreamReader, FileInputStream, Writer} +import java.io.{File, FileInputStream, InputStreamReader, Writer} -import djinni.ast.Interface.Method +import djinni.ast.Interface.{Method, Property} import djinni.ast.Record.DerivingType.DerivingType import djinni.syntax._ import djinni.ast._ import java.util.{Map => JMap} + import org.yaml.snakeyaml.Yaml + import scala.collection.JavaConversions._ import scala.collection.mutable import scala.util.parsing.combinator.RegexParsers @@ -119,18 +121,19 @@ private object IdlParser extends RegexParsers { } def interfaceHeader = "interface" ~> extInterface - def interface: Parser[Interface] = interfaceHeader ~ bracesList(method | const) ^^ { + def interface: Parser[Interface] = interfaceHeader ~ bracesList(method | const | property) ^^ { case ext~items => { val methods = items collect {case m: Method => m} val consts = items collect {case c: Const => c} - Interface(ext, methods, consts) + val properties = items collect {case p: Property => p} + Interface(ext, methods, consts, properties) } } 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(ext, List(), List(), List()) } def staticLabel: Parser[Boolean] = ("static ".r | "".r) ^^ { case "static " => true @@ -140,6 +143,10 @@ private object IdlParser extends RegexParsers { case "const " => true case "" => false } + def readOnlyLabel: Parser[Boolean] = ("readonly ".r | "".r) ^^ { + case "readonly " => true + case "" => false + } def method: Parser[Interface.Method] = doc ~ staticLabel ~ constLabel ~ ident ~ parens(repsepend(field, ",")) ~ opt(ret) ^^ { case doc~staticLabel~constLabel~ ident~params~ret => Interface.Method(ident, params, ret, doc, staticLabel, constLabel) } @@ -164,6 +171,10 @@ private object IdlParser extends RegexParsers { case doc~_~ident~_~typeRef~_~value => Const(ident, typeRef, value, doc) } + def property: Parser[Interface.Property] = doc ~ readOnlyLabel ~ ident ~ ret ^^ { + case doc~readOnlyLabel~ident~ret => Interface.Property(ident, ret, doc, readOnlyLabel) + } + def typeRef: Parser[TypeRef] = typeExpr ^^ TypeRef def typeExpr: Parser[TypeExpr] = ident ~ typeList(typeExpr) ^^ { case ident~typeArgs => TypeExpr(ident, typeArgs) diff --git a/src/source/resolver.scala b/src/source/resolver.scala index aac986b1e..b605bdf16 100644 --- a/src/source/resolver.scala +++ b/src/source/resolver.scala @@ -292,6 +292,11 @@ private def resolveInterface(scope: Scope, i: Interface) { case _ => } } + + for (p <- i.properties) { + dupeChecker.check(p.ident) + resolveRef(scope, p.ty) + } // Name checking for constants. Type check only possible after resolving record field types. for (c <- i.consts) { dupeChecker.check(c.ident) diff --git a/test-suite/djinni/common.djinni b/test-suite/djinni/common.djinni index dc2e71bf3..601c653fd 100644 --- a/test-suite/djinni/common.djinni +++ b/test-suite/djinni/common.djinni @@ -1,3 +1,4 @@ +@import "properties.djinni" @import "set.djinni" @import "derivings.djinni" @import "nested_collection.djinni" @@ -14,4 +15,4 @@ @import "single_language_interfaces.djinni" @import "extended_record.djinni" @import "varnames.djinni" -@import "relative_paths.djinni" +@import "relative_paths.djinni" \ No newline at end of file diff --git a/test-suite/djinni/properties.djinni b/test-suite/djinni/properties.djinni new file mode 100644 index 000000000..ca32285b3 --- /dev/null +++ b/test-suite/djinni/properties.djinni @@ -0,0 +1,9 @@ +properties_test_helper = interface +c { + + item: i32; + test_string: string; + test_list: list; + readonly read_only_bool: bool; + + static create_new(): properties_test_helper; +} \ No newline at end of file diff --git a/test-suite/generated-src/cpp/properties_test_helper.hpp b/test-suite/generated-src/cpp/properties_test_helper.hpp new file mode 100644 index 000000000..61fca88a8 --- /dev/null +++ b/test-suite/generated-src/cpp/properties_test_helper.hpp @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#pragma once + +#include +#include +#include +#include + +namespace testsuite { + +class PropertiesTestHelper { +public: + virtual ~PropertiesTestHelper() {} + + static std::shared_ptr create_new(); + + virtual int32_t get_item() = 0; + virtual void set_item(int32_t new_item) = 0; + + virtual std::string get_test_string() = 0; + virtual void set_test_string(std::string new_test_string) = 0; + + virtual std::vector get_test_list() = 0; + virtual void set_test_list(std::vector new_test_list) = 0; + + virtual bool get_read_only_bool() = 0; +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/inFileList.txt b/test-suite/generated-src/inFileList.txt index c2f69d2c8..27702d17f 100644 --- a/test-suite/generated-src/inFileList.txt +++ b/test-suite/generated-src/inFileList.txt @@ -1,5 +1,6 @@ djinni/all.djinni djinni/common.djinni +djinni/properties.djinni djinni/set.djinni djinni/derivings.djinni djinni/nested_collection.djinni diff --git a/test-suite/generated-src/java/com/dropbox/djinni/test/PropertiesTestHelper.java b/test-suite/generated-src/java/com/dropbox/djinni/test/PropertiesTestHelper.java new file mode 100644 index 000000000..fa41d0547 --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/PropertiesTestHelper.java @@ -0,0 +1,105 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +package com.dropbox.djinni.test; + +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public abstract class PropertiesTestHelper { + @CheckForNull + public static native PropertiesTestHelper createNew(); + + public abstract int getItem(); + public abstract void setItem(int newItem); + + public abstract String getTestString(); + public abstract void setTestString(String newTestString); + + public abstract ArrayList getTestList(); + public abstract void setTestList(ArrayList newTestList); + + public abstract boolean getReadOnlyBool(); + + private static final class CppProxy extends PropertiesTestHelper + { + 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(); + } + + @Override + public int getItem() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_getItem(this.nativeRef); + } + private native int native_getItem(long _nativeRef); + + @Override + public void setItem(int newItem) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + native_setItem(this.nativeRef, newItem); + } + private native void native_setItem(long _nativeRef, int newItem); + + @Override + public String getTestString() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_getTestString(this.nativeRef); + } + private native String native_getTestString(long _nativeRef); + + @Override + public void setTestString(String newTestString) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + native_setTestString(this.nativeRef, newTestString); + } + private native void native_setTestString(long _nativeRef, String newTestString); + + @Override + public ArrayList getTestList() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_getTestList(this.nativeRef); + } + private native ArrayList native_getTestList(long _nativeRef); + + @Override + public void setTestList(ArrayList newTestList) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + native_setTestList(this.nativeRef, newTestList); + } + private native void native_setTestList(long _nativeRef, ArrayList newTestList); + + @Override + public boolean getReadOnlyBool() + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_getReadOnlyBool(this.nativeRef); + } + private native boolean native_getReadOnlyBool(long _nativeRef); + } +} diff --git a/test-suite/generated-src/jni/NativePropertiesTestHelper.cpp b/test-suite/generated-src/jni/NativePropertiesTestHelper.cpp new file mode 100644 index 000000000..2671b35f3 --- /dev/null +++ b/test-suite/generated-src/jni/NativePropertiesTestHelper.cpp @@ -0,0 +1,101 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#include "NativePropertiesTestHelper.hpp" // my header +#include "Marshal.hpp" + +namespace djinni_generated { + +NativePropertiesTestHelper::NativePropertiesTestHelper() : ::djinni::JniInterface<::testsuite::PropertiesTestHelper, NativePropertiesTestHelper>("com/dropbox/djinni/test/PropertiesTestHelper$CppProxy") {} + +NativePropertiesTestHelper::~NativePropertiesTestHelper() = default; + + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + delete reinterpret_cast<::djinni::CppProxyHandle<::testsuite::PropertiesTestHelper>*>(nativeRef); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_createNew(JNIEnv* jniEnv, jobject /*this*/) +{ + try { + DJINNI_FUNCTION_PROLOGUE0(jniEnv); + auto r = ::testsuite::PropertiesTestHelper::create_new(); + return ::djinni::release(::djinni_generated::NativePropertiesTestHelper::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT jint JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1getItem(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + auto r = ref->get_item(); + return ::djinni::release(::djinni::I32::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1setItem(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jint j_item) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + ref->set_item(::djinni::I32::toCpp(jniEnv, j_item)); + ; + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jstring JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1getTestString(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + auto r = ref->get_test_string(); + return ::djinni::release(::djinni::String::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1setTestString(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jstring j_testString) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + ref->set_test_string(::djinni::String::toCpp(jniEnv, j_testString)); + ; + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jobject JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1getTestList(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + auto r = ref->get_test_list(); + return ::djinni::release(::djinni::List<::djinni::I32>::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1setTestList(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jobject j_testList) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + ref->set_test_list(::djinni::List<::djinni::I32>::toCpp(jniEnv, j_testList)); + ; + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, ) +} + +CJNIEXPORT jboolean JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1getReadOnlyBool(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + auto r = ref->get_read_only_bool(); + return ::djinni::release(::djinni::Bool::fromCpp(jniEnv, r)); + } JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */) +} + +} // namespace djinni_generated diff --git a/test-suite/generated-src/jni/NativePropertiesTestHelper.hpp b/test-suite/generated-src/jni/NativePropertiesTestHelper.hpp new file mode 100644 index 000000000..60f40499b --- /dev/null +++ b/test-suite/generated-src/jni/NativePropertiesTestHelper.hpp @@ -0,0 +1,32 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#pragma once + +#include "djinni_support.hpp" +#include "properties_test_helper.hpp" + +namespace djinni_generated { + +class NativePropertiesTestHelper final : ::djinni::JniInterface<::testsuite::PropertiesTestHelper, NativePropertiesTestHelper> { +public: + using CppType = std::shared_ptr<::testsuite::PropertiesTestHelper>; + using CppOptType = std::shared_ptr<::testsuite::PropertiesTestHelper>; + using JniType = jobject; + + using Boxed = NativePropertiesTestHelper; + + ~NativePropertiesTestHelper(); + + 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: + NativePropertiesTestHelper(); + friend ::djinni::JniClass; + friend ::djinni::JniInterface<::testsuite::PropertiesTestHelper, NativePropertiesTestHelper>; + +}; + +} // namespace djinni_generated diff --git a/test-suite/generated-src/objc/DBPropertiesTestHelper+Private.h b/test-suite/generated-src/objc/DBPropertiesTestHelper+Private.h new file mode 100644 index 000000000..a8ac9920a --- /dev/null +++ b/test-suite/generated-src/objc/DBPropertiesTestHelper+Private.h @@ -0,0 +1,31 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#include "properties_test_helper.hpp" +#include + +static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file"); + +@class DBPropertiesTestHelper; + +namespace djinni_generated { + +class PropertiesTestHelper +{ +public: + using CppType = std::shared_ptr<::testsuite::PropertiesTestHelper>; + using CppOptType = std::shared_ptr<::testsuite::PropertiesTestHelper>; + using ObjcType = DBPropertiesTestHelper*; + + using Boxed = PropertiesTestHelper; + + 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/DBPropertiesTestHelper+Private.mm b/test-suite/generated-src/objc/DBPropertiesTestHelper+Private.mm new file mode 100644 index 000000000..d4cac6d71 --- /dev/null +++ b/test-suite/generated-src/objc/DBPropertiesTestHelper+Private.mm @@ -0,0 +1,96 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#import "DBPropertiesTestHelper+Private.h" +#import "DBPropertiesTestHelper.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 DBPropertiesTestHelper () + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::PropertiesTestHelper>&)cppRef; + +@end + +@implementation DBPropertiesTestHelper { + ::djinni::CppProxyCache::Handle> _cppRefHandle; +} + +- (id)initWithCpp:(const std::shared_ptr<::testsuite::PropertiesTestHelper>&)cppRef +{ + if (self = [super init]) { + _cppRefHandle.assign(cppRef); + } + return self; +} + ++ (nullable DBPropertiesTestHelper *)createNew { + try { + auto objcpp_result_ = ::testsuite::PropertiesTestHelper::create_new(); + return ::djinni_generated::PropertiesTestHelper::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + +- (int32_t)item +{ + auto objcpp_result_ = _cppRefHandle.get()->get_item(); + return ::djinni::I32::fromCpp(objcpp_result_); +} +- (void)setItem:(int32_t)item +{ + _cppRefHandle.get()->set_item(::djinni::I32::toCpp(item)); +} + +- (NSString *)testString +{ + auto objcpp_result_ = _cppRefHandle.get()->get_test_string(); + return ::djinni::String::fromCpp(objcpp_result_); +} +- (void)setTestString:(NSString *)test_string +{ + _cppRefHandle.get()->set_test_string(::djinni::String::toCpp(test_string)); +} + +- (NSArray *)testList +{ + auto objcpp_result_ = _cppRefHandle.get()->get_test_list(); + return ::djinni::List<::djinni::I32>::fromCpp(objcpp_result_); +} +- (void)setTestList:(NSArray *)test_list +{ + _cppRefHandle.get()->set_test_list(::djinni::List<::djinni::I32>::toCpp(test_list)); +} + +- (BOOL)readOnlyBool +{ + auto objcpp_result_ = _cppRefHandle.get()->get_read_only_bool(); + return ::djinni::Bool::fromCpp(objcpp_result_); +} + +namespace djinni_generated { + +auto PropertiesTestHelper::toCpp(ObjcType objc) -> CppType +{ + if (!objc) { + return nullptr; + } + return objc->_cppRefHandle.get(); +} + +auto PropertiesTestHelper::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/DBPropertiesTestHelper.h b/test-suite/generated-src/objc/DBPropertiesTestHelper.h new file mode 100644 index 000000000..1a4bd5487 --- /dev/null +++ b/test-suite/generated-src/objc/DBPropertiesTestHelper.h @@ -0,0 +1,20 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#import +@class DBPropertiesTestHelper; + + +@interface DBPropertiesTestHelper : NSObject + ++ (nullable DBPropertiesTestHelper *)createNew; + +@property (nonatomic) int32_t item; + +@property (nonatomic, nonnull) NSString * testString; + +@property (nonatomic, nonnull) NSArray * testList; + +@property (nonatomic, readonly) BOOL readOnlyBool; + +@end diff --git a/test-suite/generated-src/outFileList.txt b/test-suite/generated-src/outFileList.txt index 0229246a0..a6d7eac9d 100644 --- a/test-suite/generated-src/outFileList.txt +++ b/test-suite/generated-src/outFileList.txt @@ -48,6 +48,7 @@ djinni-output-temp/cpp/record_with_derivings.cpp djinni-output-temp/cpp/record_with_nested_derivings.hpp djinni-output-temp/cpp/record_with_nested_derivings.cpp djinni-output-temp/cpp/set_record.hpp +djinni-output-temp/cpp/properties_test_helper.hpp djinni-output-temp/java/TestDuration.java djinni-output-temp/java/RecordWithDurationAndDerivings.java djinni-output-temp/java/DateRecord.java @@ -88,6 +89,7 @@ djinni-output-temp/java/NestedCollection.java djinni-output-temp/java/RecordWithDerivings.java djinni-output-temp/java/RecordWithNestedDerivings.java djinni-output-temp/java/SetRecord.java +djinni-output-temp/java/PropertiesTestHelper.java djinni-output-temp/jni/NativeTestDuration.hpp djinni-output-temp/jni/NativeTestDuration.cpp djinni-output-temp/jni/NativeRecordWithDurationAndDerivings.hpp @@ -167,6 +169,8 @@ djinni-output-temp/jni/NativeRecordWithNestedDerivings.hpp djinni-output-temp/jni/NativeRecordWithNestedDerivings.cpp djinni-output-temp/jni/NativeSetRecord.hpp djinni-output-temp/jni/NativeSetRecord.cpp +djinni-output-temp/jni/NativePropertiesTestHelper.hpp +djinni-output-temp/jni/NativePropertiesTestHelper.cpp djinni-output-temp/objc/DBTestDuration.h djinni-output-temp/objc/DBRecordWithDurationAndDerivings.h djinni-output-temp/objc/DBRecordWithDurationAndDerivings.mm @@ -228,6 +232,7 @@ djinni-output-temp/objc/DBRecordWithNestedDerivings.h djinni-output-temp/objc/DBRecordWithNestedDerivings.mm djinni-output-temp/objc/DBSetRecord.h djinni-output-temp/objc/DBSetRecord.mm +djinni-output-temp/objc/DBPropertiesTestHelper.h djinni-output-temp/objc/DBTestDuration+Private.h djinni-output-temp/objc/DBTestDuration+Private.mm djinni-output-temp/objc/DBRecordWithDurationAndDerivings+Private.h @@ -307,4 +312,6 @@ djinni-output-temp/objc/DBRecordWithNestedDerivings+Private.h djinni-output-temp/objc/DBRecordWithNestedDerivings+Private.mm djinni-output-temp/objc/DBSetRecord+Private.h djinni-output-temp/objc/DBSetRecord+Private.mm +djinni-output-temp/objc/DBPropertiesTestHelper+Private.h +djinni-output-temp/objc/DBPropertiesTestHelper+Private.mm djinni-output-temp/yaml/yaml-test.yaml diff --git a/test-suite/handwritten-src/cpp/properties_test_helper_impl.cpp b/test-suite/handwritten-src/cpp/properties_test_helper_impl.cpp new file mode 100644 index 000000000..4ebc27deb --- /dev/null +++ b/test-suite/handwritten-src/cpp/properties_test_helper_impl.cpp @@ -0,0 +1,44 @@ +// +// properties_test_helper_impl.cpp +// DjinniObjcTest +// +// Created by Samuel Hall on 03/11/2016. +// Copyright © 2016 Dropbox, Inc. All rights reserved. +// + +#include "properties_test_helper_impl.hpp" + +namespace testsuite { + + std::shared_ptr PropertiesTestHelper::create_new() { + return std::make_shared(); + } + + int32_t PropertiesTestHelperImpl::get_item() { + return m_item; + } + + void PropertiesTestHelperImpl::set_item(int32_t new_item) { + m_item = new_item; + } + + std::string PropertiesTestHelperImpl::get_test_string() { + return m_test_string; + } + + void PropertiesTestHelperImpl::set_test_string(std::string new_test_string) { + m_test_string = new_test_string; + } + + std::vector PropertiesTestHelperImpl::get_test_list() { + return m_test_list; + } + + void PropertiesTestHelperImpl::set_test_list(std::vector new_test_list) { + m_test_list = new_test_list; + } + + bool PropertiesTestHelperImpl::get_read_only_bool() { + return m_read_only_bool; + } +} diff --git a/test-suite/handwritten-src/cpp/properties_test_helper_impl.hpp b/test-suite/handwritten-src/cpp/properties_test_helper_impl.hpp new file mode 100644 index 000000000..1159115f4 --- /dev/null +++ b/test-suite/handwritten-src/cpp/properties_test_helper_impl.hpp @@ -0,0 +1,43 @@ +// +// properties_test_helper_impl.hpp +// DjinniObjcTest +// +// Created by Samuel Hall on 03/11/2016. +// Copyright © 2016 Dropbox, Inc. All rights reserved. +// + +#ifndef properties_test_helper_impl_hpp +#define properties_test_helper_impl_hpp + +#include + +#include "properties_test_helper.hpp" + +namespace testsuite { + +class PropertiesTestHelperImpl : public PropertiesTestHelper { + +private: + + int32_t m_item; + std::string m_test_string; + std::vector m_test_list; + bool m_read_only_bool = true; + +public: + + int32_t get_item(); + void set_item(int32_t new_item); + + std::string get_test_string(); + void set_test_string(std::string new_test_string); + + std::vector get_test_list(); + void set_test_list(std::vector new_test_list); + + bool get_read_only_bool(); +}; + +} + +#endif /* properties_test_helper_impl_hpp */ 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..40995c1a8 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 @@ -14,6 +14,7 @@ public static Test suite() { mySuite.addTestSuite(NestedCollectionTest.class); mySuite.addTestSuite(MapRecordTest.class); mySuite.addTestSuite(PrimitiveListTest.class); + mySuite.addTestSuite(PropertyTest.class); mySuite.addTestSuite(RecordWithDerivingsTest.class); mySuite.addTestSuite(CppExceptionTest.class); mySuite.addTestSuite(ClientInterfaceTest.class); diff --git a/test-suite/handwritten-src/java/com/dropbox/djinni/test/PropertyTest.java b/test-suite/handwritten-src/java/com/dropbox/djinni/test/PropertyTest.java new file mode 100644 index 000000000..600e57842 --- /dev/null +++ b/test-suite/handwritten-src/java/com/dropbox/djinni/test/PropertyTest.java @@ -0,0 +1,50 @@ +package com.dropbox.djinni.test; + +import junit.framework.TestCase; +import java.util.ArrayList; + +/** + * Created by Sam on 04/11/2016. + */ +public class PropertyTest extends TestCase { + + public void testProperties() { + + PropertiesTestHelper testHelper = PropertiesTestHelper.createNew(); + + // Test integer property. + testHelper.setItem(1); + + assertEquals(1, testHelper.getItem()); + + // Test string property. + testHelper.setTestString("fooBar"); + + assertEquals("fooBar", testHelper.getTestString()); + + // Test list property. + ArrayList list = new ArrayList(); + list.add(1); + list.add(2); + list.add(3); + + testHelper.setTestList(list); + + for (int i = 0; i < list.size();i++) { + assertEquals(list.get(i), testHelper.getTestList().get(i)); + } + } + + public void testReadOnlyProperty() { + + PropertiesTestHelper testHelper = PropertiesTestHelper.createNew(); + + // Test readonly property. + assertEquals(true, testHelper.getReadOnlyBool()); + + try { + assertNull(PropertiesTestHelper.class.getDeclaredMethod("setReadOnlyBool", void.class)); + } catch (NoSuchMethodException e) { + } + } +} diff --git a/test-suite/handwritten-src/objc/tests/DPPropertyTests.m b/test-suite/handwritten-src/objc/tests/DPPropertyTests.m new file mode 100644 index 000000000..2031cb260 --- /dev/null +++ b/test-suite/handwritten-src/objc/tests/DPPropertyTests.m @@ -0,0 +1,56 @@ +// +// DPPropertyTests.m +// DjinniObjcTest +// +// Created by Samuel Hall on 03/11/2016. +// Copyright © 2016 Dropbox, Inc. All rights reserved. +// + +#import + +#include "DBPropertiesTestHelper.h" + +@interface DPPropertyTests : XCTestCase + +@end + +@implementation DPPropertyTests + +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testProperties { + + DBPropertiesTestHelper *testHelper = [DBPropertiesTestHelper createNew]; + + // Test integer property + testHelper.item = 1; + + XCTAssert(testHelper.item == 1); + + // Test string property + testHelper.testString = @"fooBar"; + + XCTAssert([testHelper.testString isEqualToString:@"fooBar"]); + + // Test list property + NSArray *list = [NSArray arrayWithObjects:@1, @2, @3, nil]; + + testHelper.testList = list; + + for (unsigned int i = 0; i < list.count;i++) { + XCTAssert([list objectAtIndex:i] == [testHelper.testList objectAtIndex:i]); + } + + // Test read only property + XCTAssert(testHelper.readOnlyBool == true); + + XCTAssert([testHelper respondsToSelector:NSSelectorFromString(@"setReadOnlyBool:")] == false); +} + +@end diff --git a/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj b/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj index 498d67c09..0510aa0b7 100644 --- a/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj +++ b/test-suite/objc/DjinniObjcTest.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 22A756721DCB66AE00671B6D /* properties_test_helper_impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22A756701DCB66AE00671B6D /* properties_test_helper_impl.cpp */; }; + 22A756771DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = 22A756761DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.mm */; }; + 22A756791DCB6FF200671B6D /* DPPropertyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 22A756781DCB6FF200671B6D /* DPPropertyTests.m */; }; 5AEA68151D38F4A40083D770 /* DBWcharTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 728E11201D37DE27005A554D /* DBWcharTests.m */; }; 650CA05A1C2AB48E007ADDDB /* DBListenerCaller+Private.mm in Sources */ = {isa = PBXBuildFile; fileRef = 650CA0571C2AB48E007ADDDB /* DBListenerCaller+Private.mm */; }; 650CA05E1C2AB5AB007ADDDB /* ListenerCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 650CA05D1C2AB5AB007ADDDB /* ListenerCaller.cpp */; }; @@ -159,6 +162,13 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 22A756701DCB66AE00671B6D /* properties_test_helper_impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = properties_test_helper_impl.cpp; sourceTree = ""; }; + 22A756711DCB66AE00671B6D /* properties_test_helper_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = properties_test_helper_impl.hpp; sourceTree = ""; }; + 22A756731DCB685F00671B6D /* properties_test_helper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = properties_test_helper.hpp; sourceTree = ""; }; + 22A756741DCB6C2D00671B6D /* DBPropertiesTestHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBPropertiesTestHelper.h; sourceTree = ""; }; + 22A756751DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBPropertiesTestHelper+Private.h"; sourceTree = ""; }; + 22A756761DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "DBPropertiesTestHelper+Private.mm"; sourceTree = ""; }; + 22A756781DCB6FF200671B6D /* DPPropertyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DPPropertyTests.m; sourceTree = ""; }; 650CA04E1C2AB460007ADDDB /* listener_caller.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = listener_caller.hpp; sourceTree = ""; }; 650CA0551C2AB48E007ADDDB /* DBListenerCaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBListenerCaller.h; sourceTree = ""; }; 650CA0561C2AB48E007ADDDB /* DBListenerCaller+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBListenerCaller+Private.h"; sourceTree = ""; }; @@ -482,6 +492,8 @@ A278D45219BA3601006FD937 /* test_helpers.cpp */, CFC5D9FB1B152E4300BF2DF8 /* TranslateDuration.cpp */, 6551684E1C40511C003682A4 /* return_one_two.cpp */, + 22A756701DCB66AE00671B6D /* properties_test_helper_impl.cpp */, + 22A756711DCB66AE00671B6D /* properties_test_helper_impl.hpp */, ); name = "handwritten-cpp"; path = "../handwritten-src/cpp"; @@ -501,6 +513,7 @@ 6536CD7D19A6C99800DD7715 /* DBNestedCollectionTests.mm */, 6536CD7E19A6C99800DD7715 /* DBPrimitiveListTests.mm */, B52DA56F1B104025005CE75F /* DBPrimitivesTests.m */, + 22A756781DCB6FF200671B6D /* DPPropertyTests.m */, 6536CD7F19A6C99800DD7715 /* DBRecordWithDerivingsCppTests.mm */, 6536CD8019A6C99800DD7715 /* DBRecordWithDerivingsObjcTests.mm */, 6536CD8119A6C99800DD7715 /* DBSetRecordTests.mm */, @@ -671,6 +684,9 @@ A24850221AF96EBC00AFE907 /* DBPrimitiveList.mm */, A242493A1AF192E0003BF8F0 /* DBPrimitiveList+Private.h */, A238CA841AF84B7100CDDCE5 /* DBPrimitiveList+Private.mm */, + 22A756741DCB6C2D00671B6D /* DBPropertiesTestHelper.h */, + 22A756751DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.h */, + 22A756761DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.mm */, A242493E1AF192E0003BF8F0 /* DBRecordWithDerivings.h */, A24850231AF96EBC00AFE907 /* DBRecordWithDerivings.mm */, A242493D1AF192E0003BF8F0 /* DBRecordWithDerivings+Private.h */, @@ -756,6 +772,7 @@ A24249691AF192FC003BF8F0 /* map_record.hpp */, A242496A1AF192FC003BF8F0 /* nested_collection.hpp */, A242496B1AF192FC003BF8F0 /* primitive_list.hpp */, + 22A756731DCB685F00671B6D /* properties_test_helper.hpp */, A242496C1AF192FC003BF8F0 /* record_with_derivings.cpp */, A242496D1AF192FC003BF8F0 /* record_with_derivings.hpp */, CFC5DA0C1B15330000BF2DF8 /* record_with_duration_and_derivings.cpp */, @@ -867,6 +884,7 @@ CFC5DA0E1B15330000BF2DF8 /* record_with_duration_and_derivings.cpp in Sources */, A238CA941AF84B7100CDDCE5 /* DBMapDateRecord+Private.mm in Sources */, CFFD588F1B019E79001E10B6 /* DBTestHelpers+Private.mm in Sources */, + 22A756771DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.mm in Sources */, A24850291AF96EBC00AFE907 /* DBDateRecord.mm in Sources */, A278D45319BA3601006FD937 /* test_helpers.cpp in Sources */, 6551684C1C4050A4003682A4 /* DBReturnOne+Private.mm in Sources */, @@ -921,6 +939,7 @@ A24249751AF192FC003BF8F0 /* record_with_derivings.cpp in Sources */, CFC5D9D01B15105100BF2DF8 /* extern_record_with_derivings.cpp in Sources */, B58B16B71D5AD56600EF92B5 /* DBInterfaceUsingExtendedRecord.mm in Sources */, + 22A756721DCB66AE00671B6D /* properties_test_helper_impl.cpp in Sources */, B51911181D542A7000772DFE /* DBWcharTestHelpers+Private.mm in Sources */, A238CA901AF84B7100CDDCE5 /* DBConstants+Private.mm in Sources */, B51911521D555EE900772DFE /* DBVarnameInterface+Private.mm in Sources */, @@ -981,6 +1000,7 @@ CFC5D9F31B15276900BF2DF8 /* DBDurationTests.m in Sources */, CFC5D9EB1B1513E800BF2DF8 /* DBExternInterface2+Private.mm in Sources */, CFC5DA0B1B1532F600BF2DF8 /* DBRecordWithDurationAndDerivings+Private.mm in Sources */, + 22A756791DCB6FF200671B6D /* DPPropertyTests.m in Sources */, CFC5D9E91B1513E800BF2DF8 /* DBExternInterface1+Private.mm in Sources */, 6536CD9419A6C9A800DD7715 /* DBSetRecordTests.mm in Sources */, CFC5D9D91B15106400BF2DF8 /* DBExternRecordWithDerivings+Private.mm in Sources */,