diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index b4bcea828..3642c3775 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -293,9 +293,20 @@ 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)) + var localMethods = i.methods + for (p <- i.properties) { + var argSeq = Option(p.ty) + localMethods = localMethods :+ Interface.Method(Ident(s"get_${p.ident.name}", ident.file, ident.loc), Seq.empty, argSeq, Doc(Seq(s"getter for ${p.ident.name}")), false, true) + if (!p.readOnly) { + localMethods = localMethods :+ Interface.Method(Ident(s"set_${p.ident.name}", ident.file, ident.loc), Seq(Field(Ident(s"new_${p.ident.name}", p.ident.file, p.ident.loc), p.ty, Doc(Seq(p.ident)))), None, Doc(Seq(s"setter for ${p.ident.name}")), false, false) + } + } + val methodNamesInScope = localMethods.map(m => idCpp.method(m.ident)) writeHppFile(ident, origin, refs.hpp, refs.hppFwds, w => { writeDoc(w, doc) @@ -307,7 +318,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { // Constants generateHppConstants(w, i.consts) // Methods - for (m <- i.methods) { + for (m <- localMethods) { w.wl writeMethodDoc(w, m, idCpp.local) val ret = marshal.returnType(m.ret, methodNamesInScope) diff --git a/src/source/JNIGenerator.scala b/src/source/JNIGenerator.scala index 0720a151b..5a98ce56a 100644 --- a/src/source/JNIGenerator.scala +++ b/src/source/JNIGenerator.scala @@ -191,6 +191,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) @@ -373,6 +376,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 51ab88c90..79c3dfba1 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") } @@ -145,7 +149,16 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { generateJavaConstants(w, i.consts) val throwException = spec.javaCppException.fold("")(" throws " + _) - for (m <- i.methods if !m.static) { + var localMethods = i.methods + for (p <- i.properties) { + var argSeq = Option(p.ty) + localMethods = localMethods :+ Interface.Method(Ident(s"get_${p.ident.name}", ident.file, ident.loc), Seq.empty, argSeq, Doc(Seq(s"getter for ${p.ident.name}")), false, false) + if (!p.readOnly) { + localMethods = localMethods :+ Interface.Method(Ident(s"set_${p.ident.name}", ident.file, ident.loc), Seq(Field(Ident(s"new_${p.ident.name}", p.ident.file, p.ident.loc), p.ty, Doc(Seq(p.ident)))), None, Doc(Seq(s"setter for ${p.ident.name}")), false, false) + } + } + + for (m <- localMethods if !m.static) { skipFirst { w.wl } writeMethodDoc(w, m, idJava.local) val ret = marshal.returnType(m.ret) @@ -156,7 +169,7 @@ class JavaGenerator(spec: Spec) extends Generator(spec) { marshal.nullityAnnotation(m.ret).foreach(w.wl) w.wl("public abstract " + ret + " " + idJava.method(m.ident) + params.mkString("(", ", ", ")") + throwException + ";") } - for (m <- i.methods if m.static) { + for (m <- localMethods if m.static) { skipFirst { w.wl } writeMethodDoc(w, m, idJava.local) val ret = marshal.returnType(m.ret) @@ -167,6 +180,7 @@ 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("(", ", ", ")") + ";") } + if (i.ext.cpp) { w.wl javaAnnotationHeader.foreach(w.wl) @@ -188,7 +202,8 @@ 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 + + for (m <- localMethods 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(", ") diff --git a/src/source/ObjcGenerator.scala b/src/source/ObjcGenerator.scala index 420c6cd1d..0a91a10e6 100644 --- a/src/source/ObjcGenerator.scala +++ b/src/source/ObjcGenerator.scala @@ -111,6 +111,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 6b6d67c3a..2292c2060 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 fb171240b..6d6f50c8a 100644 --- a/src/source/ast.scala +++ b/src/source/ast.scala @@ -79,9 +79,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 9e79e9960..2522338c5 100644 --- a/src/source/parser.scala +++ b/src/source/parser.scala @@ -18,12 +18,14 @@ package djinni import java.io.{File, FileNotFoundException, InputStreamReader, FileInputStream, 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.control.Breaks._ @@ -150,11 +152,12 @@ 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) } } @@ -162,7 +165,7 @@ private object IdlParser extends RegexParsers { def externEnum: Parser[Enum] = enumHeader ^^ { case _ => Enum(List(), false) } def externFlags: Parser[Enum] = flagsHeader ^^ { case _ => Enum(List(), true) } 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 @@ -172,6 +175,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) } @@ -196,6 +203,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..5b5d71095 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" @@ -15,3 +16,4 @@ @import "extended_record.djinni" @import "varnames.djinni" @import "relative_paths.djinni" + diff --git a/test-suite/djinni/properties.djinni b/test-suite/djinni/properties.djinni new file mode 100644 index 000000000..98f634979 --- /dev/null +++ b/test-suite/djinni/properties.djinni @@ -0,0 +1,11 @@ +properties_test_helper = interface +c { + + item: i32; + test_string: string; + other_method(argument: string) : string; + test_list: list; + readonly read_only_bool: bool; + + static create_new(): properties_test_helper; +} + 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..9172e8b80 --- /dev/null +++ b/test-suite/generated-src/cpp/properties_test_helper.hpp @@ -0,0 +1,43 @@ +// 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() {} + + virtual std::string other_method(const std::string & argument) = 0; + + static std::shared_ptr create_new(); + + /**getter for item */ + virtual int32_t get_item() const = 0; + + /**setter for item */ + virtual void set_item(int32_t new_item) = 0; + + /**getter for test_string */ + virtual std::string get_test_string() const = 0; + + /**setter for test_string */ + virtual void set_test_string(const std::string & new_test_string) = 0; + + /**getter for test_list */ + virtual std::vector get_test_list() const = 0; + + /**setter for test_list */ + virtual void set_test_list(const std::vector & new_test_list) = 0; + + /**getter for read_only_bool */ + virtual bool get_read_only_bool() const = 0; +}; + +} // namespace testsuite diff --git a/test-suite/generated-src/inFileList.txt b/test-suite/generated-src/inFileList.txt index 3b2f259db..4e42b951c 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..def5a57b9 --- /dev/null +++ b/test-suite/generated-src/java/com/dropbox/djinni/test/PropertiesTestHelper.java @@ -0,0 +1,128 @@ +// 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 { + @Nonnull + public abstract String otherMethod(@Nonnull String argument); + + /**getter for item */ + public abstract int getItem(); + + /**setter for item */ + public abstract void setItem(int newItem); + + /**getter for test_string */ + @Nonnull + public abstract String getTestString(); + + /**setter for test_string */ + public abstract void setTestString(@Nonnull String newTestString); + + /**getter for test_list */ + @Nonnull + public abstract ArrayList getTestList(); + + /**setter for test_list */ + public abstract void setTestList(@Nonnull ArrayList newTestList); + + /**getter for read_only_bool */ + public abstract boolean getReadOnlyBool(); + + @CheckForNull + public static native PropertiesTestHelper createNew(); + + 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 String otherMethod(String argument) + { + assert !this.destroyed.get() : "trying to use a destroyed object"; + return native_otherMethod(this.nativeRef, argument); + } + private native String native_otherMethod(long _nativeRef, String argument); + + @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..bb29f381e --- /dev/null +++ b/test-suite/generated-src/jni/NativePropertiesTestHelper.cpp @@ -0,0 +1,111 @@ +// 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 jstring JNICALL Java_com_dropbox_djinni_test_PropertiesTestHelper_00024CppProxy_native_1otherMethod(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, jstring j_argument) +{ + try { + DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef); + const auto& ref = ::djinni::objectFromHandleAddress<::testsuite::PropertiesTestHelper>(nativeRef); + auto r = ref->other_method(::djinni::String::toCpp(jniEnv, j_argument)); + 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_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..7c78003f2 --- /dev/null +++ b/test-suite/generated-src/objc/DBPropertiesTestHelper+Private.mm @@ -0,0 +1,103 @@ +// 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; +} + +- (nonnull NSString *)otherMethod:(nonnull NSString *)argument { + try { + auto objcpp_result_ = _cppRefHandle.get()->other_method(::djinni::String::toCpp(argument)); + return ::djinni::String::fromCpp(objcpp_result_); + } DJINNI_TRANSLATE_EXCEPTIONS() +} + ++ (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..4dd93bc42 --- /dev/null +++ b/test-suite/generated-src/objc/DBPropertiesTestHelper.h @@ -0,0 +1,22 @@ +// AUTOGENERATED FILE - DO NOT MODIFY! +// This file generated by Djinni from properties.djinni + +#import +@class DBPropertiesTestHelper; + + +@interface DBPropertiesTestHelper : NSObject + +- (nonnull NSString *)otherMethod:(nonnull NSString *)argument; + ++ (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 a99741bc7..4849648fc 100644 --- a/test-suite/generated-src/outFileList.txt +++ b/test-suite/generated-src/outFileList.txt @@ -52,6 +52,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 @@ -96,6 +97,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 @@ -181,6 +183,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 @@ -247,6 +251,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 @@ -332,4 +337,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..1332b196a --- /dev/null +++ b/test-suite/handwritten-src/cpp/properties_test_helper_impl.cpp @@ -0,0 +1,48 @@ +// +// 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(); + } + + std::string PropertiesTestHelperImpl::other_method(const std::string & argument) { + return argument; + } + + int32_t PropertiesTestHelperImpl::get_item() const { + return m_item; + } + + void PropertiesTestHelperImpl::set_item(int32_t new_item) { + m_item = new_item; + } + + std::string PropertiesTestHelperImpl::get_test_string() const { + return m_test_string; + } + + void PropertiesTestHelperImpl::set_test_string(const std::string & new_test_string) { + m_test_string = new_test_string; + } + + std::vector PropertiesTestHelperImpl::get_test_list() const { + return m_test_list; + } + + void PropertiesTestHelperImpl::set_test_list(const std::vector & new_test_list) { + m_test_list = new_test_list; + } + + bool PropertiesTestHelperImpl::get_read_only_bool() const { + 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..2f96a23e3 --- /dev/null +++ b/test-suite/handwritten-src/cpp/properties_test_helper_impl.hpp @@ -0,0 +1,44 @@ +// +// 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: + std::string other_method(const std::string & argument) override; + + int32_t get_item() const override; + void set_item(int32_t new_item) override; + + std::string get_test_string() const override; + void set_test_string(const std::string & new_test_string) override; + + std::vector get_test_list() const override; + void set_test_list(const std::vector & new_test_list) override; + + bool get_read_only_bool() const override; +}; + +} + +#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 1c8210679..97ef06b31 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 36b34b027..dc54bbd1b 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 */; }; @@ -164,6 +167,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 = ""; }; 176915461F7B837D00967E9D /* DBAccessFlags+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBAccessFlags+Private.h"; sourceTree = ""; }; 176915471F7B837D00967E9D /* DBEmptyFlags+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "DBEmptyFlags+Private.h"; sourceTree = ""; }; 650CA04E1C2AB460007ADDDB /* listener_caller.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = listener_caller.hpp; sourceTree = ""; }; @@ -505,6 +515,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"; @@ -525,6 +537,7 @@ 6536CD7D19A6C99800DD7715 /* DBNestedCollectionTests.mm */, 6536CD7E19A6C99800DD7715 /* DBPrimitiveListTests.mm */, B52DA56F1B104025005CE75F /* DBPrimitivesTests.m */, + 22A756781DCB6FF200671B6D /* DPPropertyTests.m */, 6536CD7F19A6C99800DD7715 /* DBRecordWithDerivingsCppTests.mm */, 6536CD8019A6C99800DD7715 /* DBRecordWithDerivingsObjcTests.mm */, 6536CD8119A6C99800DD7715 /* DBSetRecordTests.mm */, @@ -678,6 +691,9 @@ A24850221AF96EBC00AFE907 /* DBPrimitiveList.mm */, A242493A1AF192E0003BF8F0 /* DBPrimitiveList+Private.h */, A238CA841AF84B7100CDDCE5 /* DBPrimitiveList+Private.mm */, + 22A756741DCB6C2D00671B6D /* DBPropertiesTestHelper.h */, + 22A756751DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.h */, + 22A756761DCB6C2D00671B6D /* DBPropertiesTestHelper+Private.mm */, B58B16AB1D5AC9BC00EF92B5 /* DBRecordUsingExtendedRecord.h */, B58B16AA1D5AC9BC00EF92B5 /* DBRecordUsingExtendedRecord.mm */, B58B16A91D5AC9BC00EF92B5 /* DBRecordUsingExtendedRecord+Private.h */, @@ -794,6 +810,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 */, @@ -906,6 +923,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 */, @@ -965,6 +983,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 */, @@ -1026,6 +1045,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 */,