Commit 6e958ef2 authored by Miro Knejp's avatar Miro Knejp

Load YAML files into the AST

parent e181adc0
...@@ -2,7 +2,10 @@ import com.typesafe.sbt.SbtStartScript ...@@ -2,7 +2,10 @@ import com.typesafe.sbt.SbtStartScript
scalaVersion := "2.11.0" scalaVersion := "2.11.0"
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1" libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1",
"org.yaml" % "snakeyaml" % "1.15"
)
scalaSource in Compile := baseDirectory.value / "source" scalaSource in Compile := baseDirectory.value / "source"
......
...@@ -179,3 +179,46 @@ class YamlGenerator(spec: Spec) extends Generator(spec) { ...@@ -179,3 +179,46 @@ class YamlGenerator(spec: Spec) extends Generator(spec) {
// unused // unused
} }
} }
object YamlGenerator {
def metaFromYaml(td: ExternTypeDecl) = MExtern(
td.ident.name.stripPrefix(td.properties("prefix").toString), // Make sure the generator uses this type with its original name for all intents and purposes
td.params.size,
defType(td),
td.body,
MExtern.Cpp(
nested(td, "cpp")("typename").toString,
nested(td, "cpp")("header").toString,
nested(td, "cpp")("byValue").asInstanceOf[Boolean]),
MExtern.Objc(
nested(td, "objc")("typename").toString,
nested(td, "objc")("header").toString,
nested(td, "objc")("boxed").toString,
nested(td, "objc")("pointer").asInstanceOf[Boolean],
nested(td, "objc")("hash").toString),
MExtern.Objcpp(
nested(td, "objcpp")("translator").toString,
nested(td, "objcpp")("header").toString),
MExtern.Java(
nested(td, "java")("typename").toString,
nested(td, "java")("boxed").toString,
nested(td, "java")("reference").asInstanceOf[Boolean],
nested(td, "java")("generic").asInstanceOf[Boolean],
nested(td, "java")("hash").toString),
MExtern.Jni(
nested(td, "jni")("translator").toString,
nested(td, "jni")("header").toString,
nested(td, "jni")("typename").toString,
nested(td, "jni")("typeSignature").toString)
)
private def nested(td: ExternTypeDecl, key: String) = {
td.properties.get(key).collect { case m: JMap[_, _] => m.collect { case (k: String, v: Any) => (k, v) } } getOrElse(Map[String, Any]())
}
private def defType(td: ExternTypeDecl) = td.body match {
case i: Interface => DInterface
case r: Record => DRecord
case e: Enum => DEnum
}
}
...@@ -22,6 +22,9 @@ import djinni.ast.Interface.Method ...@@ -22,6 +22,9 @@ import djinni.ast.Interface.Method
import djinni.ast.Record.DerivingType.DerivingType import djinni.ast.Record.DerivingType.DerivingType
import djinni.syntax._ import djinni.syntax._
import djinni.ast._ import djinni.ast._
import java.util.{Map => JMap}
import org.yaml.snakeyaml.Yaml
import scala.collection.JavaConversions._
import scala.collection.mutable import scala.collection.mutable
import scala.util.parsing.combinator.RegexParsers import scala.util.parsing.combinator.RegexParsers
import scala.util.parsing.input.{Position, Positional} import scala.util.parsing.input.{Position, Positional}
...@@ -84,7 +87,8 @@ private object IdlParser extends RegexParsers { ...@@ -84,7 +87,8 @@ private object IdlParser extends RegexParsers {
def typeDef: Parser[TypeDef] = record | enum | interface def typeDef: Parser[TypeDef] = record | enum | interface
def record: Parser[Record] = "record" ~> extRecord ~ bracesList(field | const) ~ opt(deriving) ^^ { def recordHeader = "record" ~> extRecord
def record: Parser[Record] = recordHeader ~ bracesList(field | const) ~ opt(deriving) ^^ {
case ext~items~deriving => { case ext~items~deriving => {
val fields = items collect {case f: Field => f} val fields = items collect {case f: Field => f}
val consts = items collect {case c: Const => c} val consts = items collect {case c: Const => c}
...@@ -103,12 +107,14 @@ private object IdlParser extends RegexParsers { ...@@ -103,12 +107,14 @@ private object IdlParser extends RegexParsers {
}).toSet }).toSet
} }
def enum: Parser[Enum] = "enum" ~> bracesList(enumOption) ^^ Enum.apply def enumHeader = "enum".r
def enum: Parser[Enum] = enumHeader ~> bracesList(enumOption) ^^ Enum.apply
def enumOption: Parser[Enum.Option] = doc ~ ident ^^ { def enumOption: Parser[Enum.Option] = doc ~ ident ^^ {
case doc~ident => Enum.Option(ident, doc) case doc~ident => Enum.Option(ident, doc)
} }
def interface: Parser[Interface] = "interface" ~> extInterface ~ bracesList(method | const) ^^ { def interfaceHeader = "interface" ~> extInterface
def interface: Parser[Interface] = interfaceHeader ~ bracesList(method | const) ^^ {
case ext~items => { case ext~items => {
val methods = items collect {case m: Method => m} val methods = items collect {case m: Method => m}
val consts = items collect {case c: Const => c} val consts = items collect {case c: Const => c}
...@@ -116,6 +122,11 @@ private object IdlParser extends RegexParsers { ...@@ -116,6 +122,11 @@ private object IdlParser extends RegexParsers {
} }
} }
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 staticLabel: Parser[Boolean] = ("static ".r | "".r) ^^ { def staticLabel: Parser[Boolean] = ("static ".r | "".r) ^^ {
case "static " => true case "static " => true
case "" => false case "" => false
...@@ -212,6 +223,44 @@ def parse(origin: String, in: java.io.Reader): Either[Error,IdlFile] = { ...@@ -212,6 +223,44 @@ def parse(origin: String, in: java.io.Reader): Either[Error,IdlFile] = {
} }
} }
def parseExtern(origin: String, in: java.io.Reader): Either[Error, Seq[TypeDecl]] = {
val yaml = new Yaml();
val tds = mutable.MutableList[TypeDecl]()
for(properties <- yaml.loadAll(in).collect { case doc: JMap[_, _] => doc.collect { case (k: String, v: Any) => (k, v) } }) {
val name = properties("name").toString
val ident = Ident(name, fileStack.top, Loc(fileStack.top, 1, 1))
val params = properties.get("params").fold(Seq[TypeParam]())(_.asInstanceOf[java.util.ArrayList[String]].collect { case s: String => TypeParam(Ident(s.asInstanceOf[String], fileStack.top, Loc(fileStack.top, 1, 1))) })
IdlParser.parseAll(IdlParser.externTypeDecl, properties("typedef").toString) match {
case IdlParser.Success(ty: TypeDef, _) =>
tds += ExternTypeDecl(ident, params, ty, properties.toMap, origin)
case IdlParser.NoSuccess(msg, input) =>
return Left(Error(Loc(fileStack.top, 1, 1), "'typedef' has an unrecognized value"))
}
}
Right(tds)
}
def parseExternFile(externFile: File, inFileListWriter: Option[Writer]) : Seq[TypeDecl] = {
if (inFileListWriter.isDefined) {
inFileListWriter.get.write(externFile + "\n")
}
visitedFiles.add(externFile)
fileStack.push(externFile)
val fin = new FileInputStream(externFile)
try {
parseExtern(externFile.getName, new InputStreamReader(fin, "UTF-8")) match {
case Right(x) => x
case Left(err) => throw err.toException
}
}
finally {
fin.close()
fileStack.pop()
}
}
def parseFile(idlFile: File, inFileListWriter: Option[Writer]): Seq[TypeDecl] = { def parseFile(idlFile: File, inFileListWriter: Option[Writer]): Seq[TypeDecl] = {
if (inFileListWriter.isDefined) { if (inFileListWriter.isDefined) {
inFileListWriter.get.write(idlFile + "\n") inFileListWriter.get.write(idlFile + "\n")
...@@ -236,7 +285,7 @@ def parseFile(idlFile: File, inFileListWriter: Option[Writer]): Seq[TypeDecl] = ...@@ -236,7 +285,7 @@ def parseFile(idlFile: File, inFileListWriter: Option[Writer]): Seq[TypeDecl] =
case IdlFileRef(file) => case IdlFileRef(file) =>
types = parseFile(file, inFileListWriter) ++ types types = parseFile(file, inFileListWriter) ++ types
case ExternFileRef(file) => case ExternFileRef(file) =>
types types = parseExternFile(file, inFileListWriter) ++ types
} }
} }
}) })
......
...@@ -53,7 +53,7 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = { ...@@ -53,7 +53,7 @@ def resolve(metas: Scope, idl: Seq[TypeDecl]): Option[Error] = {
} }
topScope = topScope.updated(typeDecl.ident.name, typeDecl match { topScope = topScope.updated(typeDecl.ident.name, typeDecl match {
case td: InternTypeDecl => MDef(typeDecl.ident.name, typeDecl.params.length, defType, typeDecl.body) case td: InternTypeDecl => MDef(typeDecl.ident.name, typeDecl.params.length, defType, typeDecl.body)
case td: ExternTypeDecl => throw new AssertionError("not implemented") case td: ExternTypeDecl => YamlGenerator.metaFromYaml(td)
}) })
} }
......
@extern "yaml-test.yaml"
# This file tests YAML dumped by Djinni can be parsed back in
extern_record_with_derivings = record
{
member: test_record_with_derivings;
e: test_color;
} deriving(eq, ord)
extern_interface_1 = interface +c
{
foo(i: test_client_interface): test_client_returned_record;
}
extern_interface_2 = interface +j +o
{
foo(i: test_test_helpers): extern_record_with_derivings;
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#pragma once
#include "client_interface.hpp"
#include "client_returned_record.hpp"
#include <memory>
class ExternInterface1 {
public:
virtual ~ExternInterface1() {}
virtual ::ClientReturnedRecord foo(const std::shared_ptr<::ClientInterface> & i) = 0;
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#pragma once
#include "extern_record_with_derivings.hpp"
#include "test_helpers.hpp"
#include <memory>
class ExternInterface2 {
public:
virtual ~ExternInterface2() {}
virtual ExternRecordWithDerivings foo(const std::shared_ptr<::TestHelpers> & i) = 0;
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#include "extern_record_with_derivings.hpp" // my header
bool operator==(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs) {
return lhs.member == rhs.member &&
lhs.e == rhs.e;
}
bool operator!=(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs) {
return !(lhs == rhs);
}
bool operator<(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs) {
if (lhs.member < rhs.member) {
return true;
}
if (rhs.member < lhs.member) {
return false;
}
if (lhs.e < rhs.e) {
return true;
}
if (rhs.e < lhs.e) {
return false;
}
return false;
}
bool operator>(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs) {
return rhs < lhs;
}
bool operator<=(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs) {
return !(rhs < lhs);
}
bool operator>=(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs) {
return !(lhs < rhs);
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#pragma once
#include "color.hpp"
#include "record_with_derivings.hpp"
#include <utility>
/** This file tests YAML dumped by Djinni can be parsed back in */
struct ExternRecordWithDerivings final {
::RecordWithDerivings member;
::color e;
friend bool operator==(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs);
friend bool operator!=(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs);
friend bool operator<(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs);
friend bool operator>(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs);
friend bool operator<=(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs);
friend bool operator>=(const ExternRecordWithDerivings& lhs, const ExternRecordWithDerivings& rhs);
ExternRecordWithDerivings(::RecordWithDerivings member,
::color e)
: member(std::move(member))
, e(std::move(e))
{}
};
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
package com.dropbox.djinni.test;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class ExternInterface1 {
public abstract com.dropbox.djinni.test.ClientReturnedRecord foo(com.dropbox.djinni.test.ClientInterface i);
public static final class CppProxy extends ExternInterface1
{
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 com.dropbox.djinni.test.ClientReturnedRecord foo(com.dropbox.djinni.test.ClientInterface i)
{
assert !this.destroyed.get() : "trying to use a destroyed object";
return native_foo(this.nativeRef, i);
}
private native com.dropbox.djinni.test.ClientReturnedRecord native_foo(long _nativeRef, com.dropbox.djinni.test.ClientInterface i);
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
package com.dropbox.djinni.test;
public abstract class ExternInterface2 {
public abstract ExternRecordWithDerivings foo(com.dropbox.djinni.test.TestHelpers i);
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
package com.dropbox.djinni.test;
/** This file tests YAML dumped by Djinni can be parsed back in */
public final class ExternRecordWithDerivings implements Comparable<ExternRecordWithDerivings> {
/*package*/ final com.dropbox.djinni.test.RecordWithDerivings mMember;
/*package*/ final com.dropbox.djinni.test.Color mE;
public ExternRecordWithDerivings(
com.dropbox.djinni.test.RecordWithDerivings member,
com.dropbox.djinni.test.Color e) {
this.mMember = member;
this.mE = e;
}
public com.dropbox.djinni.test.RecordWithDerivings getMember() {
return mMember;
}
public com.dropbox.djinni.test.Color getE() {
return mE;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ExternRecordWithDerivings)) {
return false;
}
ExternRecordWithDerivings other = (ExternRecordWithDerivings) obj;
return this.mMember.equals(other.mMember) &&
this.mE == other.mE;
}
@Override
public int hashCode() {
// Pick an arbitrary non-zero starting value
int hashCode = 17;
hashCode = hashCode * 31 + (mMember.hashCode());
hashCode = hashCode * 31 + mE.hashCode();
return hashCode;
}
@Override
public int compareTo(ExternRecordWithDerivings other) {
int tempResult;
tempResult = this.mMember.compareTo(other.mMember);
if (tempResult != 0) {
return tempResult;
}
tempResult = this.mE.compareTo(other.mE);if (tempResult != 0) {
return tempResult;
}
return 0;
}
}
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#include "NativeExternInterface1.hpp" // my header
#include "NativeClientInterface.hpp"
#include "NativeClientReturnedRecord.hpp"
namespace djinni_generated {
NativeExternInterface1::NativeExternInterface1() : ::djinni::JniInterface<::ExternInterface1, NativeExternInterface1>("com/dropbox/djinni/test/ExternInterface1$CppProxy") {}
NativeExternInterface1::~NativeExternInterface1() = default;
CJNIEXPORT void JNICALL Java_com_dropbox_djinni_test_ExternInterface1_00024CppProxy_nativeDestroy(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef)
{
try {
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
delete reinterpret_cast<djinni::CppProxyHandle<::ExternInterface1>*>(nativeRef);
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, )
}
CJNIEXPORT ::djinni_generated::NativeClientReturnedRecord::JniType JNICALL Java_com_dropbox_djinni_test_ExternInterface1_00024CppProxy_native_1foo(JNIEnv* jniEnv, jobject /*this*/, jlong nativeRef, ::djinni_generated::NativeClientInterface::JniType j_i)
{
try {
DJINNI_FUNCTION_PROLOGUE1(jniEnv, nativeRef);
const auto& ref = ::djinni::CppProxyHandle<::ExternInterface1>::get(nativeRef);
auto r = ref->foo(::djinni_generated::NativeClientInterface::toCpp(jniEnv, j_i));
return ::djinni::release(::djinni_generated::NativeClientReturnedRecord::fromCpp(jniEnv, r));
} JNI_TRANSLATE_EXCEPTIONS_RETURN(jniEnv, 0 /* value doesn't matter */)
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#pragma once
#include "djinni_support.hpp"
#include "extern_interface_1.hpp"
namespace djinni_generated {
class NativeExternInterface1 final : ::djinni::JniInterface<::ExternInterface1, NativeExternInterface1> {
public:
using CppType = std::shared_ptr<::ExternInterface1>;
using JniType = jobject;
using Boxed = NativeExternInterface1;
~NativeExternInterface1();
static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass<NativeExternInterface1>::get()._fromJava(jniEnv, j); }
static ::djinni::LocalRef<JniType> fromCpp(JNIEnv* jniEnv, const CppType& c) { return {jniEnv, ::djinni::JniClass<NativeExternInterface1>::get()._toJava(jniEnv, c)}; }
private:
NativeExternInterface1();
friend ::djinni::JniClass<NativeExternInterface1>;
friend ::djinni::JniInterface<::ExternInterface1, NativeExternInterface1>;
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#include "NativeExternInterface2.hpp" // my header
#include "NativeExternRecordWithDerivings.hpp"
#include "NativeTestHelpers.hpp"
namespace djinni_generated {
NativeExternInterface2::NativeExternInterface2() : ::djinni::JniInterface<::ExternInterface2, NativeExternInterface2>() {}
NativeExternInterface2::~NativeExternInterface2() = default;
NativeExternInterface2::JavaProxy::JavaProxy(JniType j) : JavaProxyCacheEntry(j) { }
NativeExternInterface2::JavaProxy::~JavaProxy() = default;
::ExternRecordWithDerivings NativeExternInterface2::JavaProxy::foo(const std::shared_ptr<::TestHelpers> & c_i) {
auto jniEnv = ::djinni::jniGetThreadEnv();
::djinni::JniLocalScope jscope(jniEnv, 10);
const auto& data = ::djinni::JniClass<::djinni_generated::NativeExternInterface2>::get();
auto jret = jniEnv->CallObjectMethod(getGlobalRef(), data.method_foo,
::djinni::get(::djinni_generated::NativeTestHelpers::fromCpp(jniEnv, c_i)));
::djinni::jniExceptionCheck(jniEnv);
return ::djinni_generated::NativeExternRecordWithDerivings::toCpp(jniEnv, jret);
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#pragma once
#include "djinni_support.hpp"
#include "extern_interface_2.hpp"
namespace djinni_generated {
class NativeExternInterface2 final : ::djinni::JniInterface<::ExternInterface2, NativeExternInterface2> {
public:
using CppType = std::shared_ptr<::ExternInterface2>;
using JniType = jobject;
using Boxed = NativeExternInterface2;
~NativeExternInterface2();
static CppType toCpp(JNIEnv* jniEnv, JniType j) { return ::djinni::JniClass<NativeExternInterface2>::get()._fromJava(jniEnv, j); }
static ::djinni::LocalRef<JniType> fromCpp(JNIEnv* jniEnv, const CppType& c) { return {jniEnv, ::djinni::JniClass<NativeExternInterface2>::get()._toJava(jniEnv, c)}; }
private:
NativeExternInterface2();
friend ::djinni::JniClass<NativeExternInterface2>;
friend ::djinni::JniInterface<::ExternInterface2, NativeExternInterface2>;
class JavaProxy final : ::djinni::JavaProxyCacheEntry, public ::ExternInterface2
{
public:
JavaProxy(JniType j);
~JavaProxy();
::ExternRecordWithDerivings foo(const std::shared_ptr<::TestHelpers> & i) override;
private:
using ::djinni::JavaProxyCacheEntry::getGlobalRef;
friend ::djinni::JniInterface<::ExternInterface2, ::djinni_generated::NativeExternInterface2>;
friend ::djinni::JavaProxyCache<JavaProxy>;
};
const ::djinni::GlobalRef<jclass> clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/ExternInterface2") };
const jmethodID method_foo { ::djinni::jniGetMethodID(clazz.get(), "foo", "(Lcom/dropbox/djinni/test/TestHelpers;)Lcom/dropbox/djinni/test/ExternRecordWithDerivings;") };
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#include "NativeExternRecordWithDerivings.hpp" // my header
#include "NativeColor.hpp"
#include "NativeRecordWithDerivings.hpp"
namespace djinni_generated {
NativeExternRecordWithDerivings::NativeExternRecordWithDerivings() = default;
NativeExternRecordWithDerivings::~NativeExternRecordWithDerivings() = default;
auto NativeExternRecordWithDerivings::fromCpp(JNIEnv* jniEnv, const CppType& c) -> ::djinni::LocalRef<JniType> {
const auto& data = ::djinni::JniClass<NativeExternRecordWithDerivings>::get();
auto r = ::djinni::LocalRef<JniType>{jniEnv->NewObject(data.clazz.get(), data.jconstructor,
::djinni::get(::djinni_generated::NativeRecordWithDerivings::fromCpp(jniEnv, c.member)),
::djinni::get(::djinni_generated::NativeColor::fromCpp(jniEnv, c.e)))};
::djinni::jniExceptionCheck(jniEnv);
return r;
}
auto NativeExternRecordWithDerivings::toCpp(JNIEnv* jniEnv, JniType j) -> CppType {
::djinni::JniLocalScope jscope(jniEnv, 3);
assert(j != nullptr);
const auto& data = ::djinni::JniClass<NativeExternRecordWithDerivings>::get();
return {::djinni_generated::NativeRecordWithDerivings::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mMember)),
::djinni_generated::NativeColor::toCpp(jniEnv, jniEnv->GetObjectField(j, data.field_mE))};
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#pragma once
#include "djinni_support.hpp"
#include "extern_record_with_derivings.hpp"
namespace djinni_generated {
class NativeExternRecordWithDerivings final {
public:
using CppType = ::ExternRecordWithDerivings;
using JniType = jobject;
using Boxed = NativeExternRecordWithDerivings;
~NativeExternRecordWithDerivings();
static CppType toCpp(JNIEnv* jniEnv, JniType j);
static ::djinni::LocalRef<JniType> fromCpp(JNIEnv* jniEnv, const CppType& c);
private:
NativeExternRecordWithDerivings();
friend ::djinni::JniClass<NativeExternRecordWithDerivings>;
const ::djinni::GlobalRef<jclass> clazz { ::djinni::jniFindClass("com/dropbox/djinni/test/ExternRecordWithDerivings") };
const jmethodID jconstructor { ::djinni::jniGetMethodID(clazz.get(), "<init>", "(Lcom/dropbox/djinni/test/RecordWithDerivings;Lcom/dropbox/djinni/test/Color;)V") };
const jfieldID field_mMember { ::djinni::jniGetFieldID(clazz.get(), "mMember", "Lcom/dropbox/djinni/test/RecordWithDerivings;") };
const jfieldID field_mE { ::djinni::jniGetFieldID(clazz.get(), "mE", "Lcom/dropbox/djinni/test/Color;") };
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#include "extern_interface_1.hpp"
#include <memory>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@class DBExternInterface1;
namespace djinni_generated {
class ExternInterface1
{
public:
using CppType = std::shared_ptr<::ExternInterface1>;
using ObjcType = DBExternInterface1*;
using Boxed = ExternInterface1;
static CppType toCpp(ObjcType objc);
static ObjcType fromCpp(const CppType& cpp);
private:
class ObjcProxy;
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBExternInterface1+Private.h"
#import "DBExternInterface1.h"
#import "DBClientInterface+Private.h"
#import "DBClientReturnedRecord+Private.h"
#import "DJICppWrapperCache+Private.h"
#import "DJIError.h"
#include <exception>
#include <utility>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@interface DBExternInterface1 ()
@property (nonatomic, readonly) ::djinni::DbxCppWrapperCache<::ExternInterface1>::Handle cppRef;
- (id)initWithCpp:(const std::shared_ptr<::ExternInterface1>&)cppRef;
@end
@implementation DBExternInterface1
- (id)initWithCpp:(const std::shared_ptr<::ExternInterface1>&)cppRef
{
if (self = [super init]) {
_cppRef.assign(cppRef);
}
return self;
}
- (nonnull DBClientReturnedRecord *)foo:(nullable id<DBClientInterface>)i {
try {
auto r = _cppRef.get()->foo(::djinni_generated::ClientInterface::toCpp(i));
return ::djinni_generated::ClientReturnedRecord::fromCpp(r);
} DJINNI_TRANSLATE_EXCEPTIONS()
}
@end
namespace djinni_generated {
auto ExternInterface1::toCpp(ObjcType objc) -> CppType
{
if (!objc) {
return nullptr;
}
return objc.cppRef.get();
}
auto ExternInterface1::fromCpp(const CppType& cpp) -> ObjcType
{
if (!cpp) {
return nil;
}
return ::djinni::DbxCppWrapperCache<::ExternInterface1>::getInstance()->get(cpp, [] (const CppType& p) {
return [[DBExternInterface1 alloc] initWithCpp:p];
});
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBClientInterface.h"
#import "DBClientReturnedRecord.h"
#import <Foundation/Foundation.h>
@interface DBExternInterface1 : NSObject
- (nonnull DBClientReturnedRecord *)foo:(nullable id<DBClientInterface>)i;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#include "extern_interface_2.hpp"
#include <memory>
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@protocol DBExternInterface2;
namespace djinni_generated {
class ExternInterface2
{
public:
using CppType = std::shared_ptr<::ExternInterface2>;
using ObjcType = id<DBExternInterface2>;
using Boxed = ExternInterface2;
static CppType toCpp(ObjcType objc);
static ObjcType fromCpp(const CppType& cpp);
private:
class ObjcProxy;
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBExternInterface2+Private.h"
#import "DBExternInterface2.h"
#import "DBExternRecordWithDerivings+Private.h"
#import "DBTestHelpers+Private.h"
#import "DJIObjcWrapperCache+Private.h"
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
namespace djinni_generated {
class ExternInterface2::ObjcProxy final
: public ::ExternInterface2
, public ::djinni::DbxObjcWrapperCache<ObjcProxy>::Handle
{
public:
using Handle::Handle;
::ExternRecordWithDerivings foo(const std::shared_ptr<::TestHelpers> & c_i) override
{
@autoreleasepool {
auto r = [(ObjcType)Handle::get() foo:(::djinni_generated::TestHelpers::fromCpp(c_i))];
return ::djinni_generated::ExternRecordWithDerivings::toCpp(r);
}
}
};
} // namespace djinni_generated
namespace djinni_generated {
auto ExternInterface2::toCpp(ObjcType objc) -> CppType
{
if (!objc) {
return nullptr;
}
return ::djinni::DbxObjcWrapperCache<ObjcProxy>::getInstance()->get(objc);
}
auto ExternInterface2::fromCpp(const CppType& cpp) -> ObjcType
{
if (!cpp) {
return nil;
}
return dynamic_cast<ObjcProxy&>(*cpp).Handle::get();
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBExternRecordWithDerivings.h"
#import "DBTestHelpers.h"
#import <Foundation/Foundation.h>
@protocol DBExternInterface2
- (nonnull DBExternRecordWithDerivings *)foo:(nullable DBTestHelpers *)i;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBExternRecordWithDerivings.h"
#include "extern_record_with_derivings.hpp"
static_assert(__has_feature(objc_arc), "Djinni requires ARC to be enabled for this file");
@class DBExternRecordWithDerivings;
namespace djinni_generated {
struct ExternRecordWithDerivings
{
using CppType = ::ExternRecordWithDerivings;
using ObjcType = DBExternRecordWithDerivings*;
using Boxed = ExternRecordWithDerivings;
static CppType toCpp(ObjcType objc);
static ObjcType fromCpp(const CppType& cpp);
};
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBExternRecordWithDerivings+Private.h"
#import "DBRecordWithDerivings+Private.h"
#import "DJIMarshal+Private.h"
#include <cassert>
namespace djinni_generated {
auto ExternRecordWithDerivings::toCpp(ObjcType obj) -> CppType
{
assert(obj);
return {::djinni_generated::RecordWithDerivings::toCpp(obj.member),
::djinni::Enum<::color, DBColor>::toCpp(obj.e)};
}
auto ExternRecordWithDerivings::fromCpp(const CppType& cpp) -> ObjcType
{
return [[DBExternRecordWithDerivings alloc] initWithMember:(::djinni_generated::RecordWithDerivings::fromCpp(cpp.member))
e:(::djinni::Enum<::color, DBColor>::fromCpp(cpp.e))];
}
} // namespace djinni_generated
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBColor.h"
#import "DBRecordWithDerivings.h"
#import <Foundation/Foundation.h>
/** This file tests YAML dumped by Djinni can be parsed back in */
@interface DBExternRecordWithDerivings : NSObject
- (nonnull id)initWithMember:(nonnull DBRecordWithDerivings *)member
e:(DBColor)e;
@property (nonatomic, readonly, nonnull) DBRecordWithDerivings * member;
@property (nonatomic, readonly) DBColor e;
- (NSComparisonResult)compare:(nonnull DBExternRecordWithDerivings *)other;
@end
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from yaml-test.djinni
#import "DBExternRecordWithDerivings.h"
@implementation DBExternRecordWithDerivings
- (id)initWithMember:(nonnull DBRecordWithDerivings *)member
e:(DBColor)e
{
if (self = [super init]) {
_member = member;
_e = e;
}
return self;
}
- (BOOL)isEqual:(id)other
{
if (![other isKindOfClass:[DBExternRecordWithDerivings class]]) {
return NO;
}
DBExternRecordWithDerivings *typedOther = (DBExternRecordWithDerivings *)other;
return [self.member isEqual:typedOther.member] &&
self.e == typedOther.e;
}
- (NSUInteger)hash
{
return NSStringFromClass([self class]).hash ^
(self.member.hash) ^
(NSUInteger)self.e;
}
- (NSComparisonResult)compare:(DBExternRecordWithDerivings *)other
{
NSComparisonResult tempResult;
tempResult = [self.member compare:other.member];
if (tempResult != NSOrderedSame) {
return tempResult;
}
if (self.e < other.e) {
tempResult = NSOrderedAscending;
} else if (self.e > other.e) {
tempResult = NSOrderedDescending;
} else {
tempResult = NSOrderedSame;
}
if (tempResult != NSOrderedSame) {
return tempResult;
}
return NSOrderedSame;
}
@end
#import <XCTest/XCTest.h>
#import "DBDateRecord+Private.h" #import "DBDateRecord+Private.h"
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include "date_record.hpp" #include "date_record.hpp"
#import <XCTest/XCTest.h>
@interface DBDateRecordTests : XCTestCase @interface DBDateRecordTests : XCTestCase
...@@ -35,14 +35,14 @@ ...@@ -35,14 +35,14 @@
- (void)testObjcRoundTrip - (void)testObjcRoundTrip
{ {
NSDate *now = [NSDate date]; NSDate *now = [NSDate date];
DBDateRecord *date1 = [[DBDateRecord alloc] initWithCreatedAt:now]; DBDateRecord *date1 = [[DBDateRecord alloc] initWithCreatedAt:now];
const auto cpp_date1 = [date1 cppDateRecord]; const auto cpp_date1 = djinni_generated::DateRecord::toCpp(date1);
DBDateRecord *date2 = [[DBDateRecord alloc] initWithCppDateRecord:cpp_date1]; DBDateRecord *date2 = djinni_generated::DateRecord::fromCpp(cpp_date1);
const auto cpp_date2 = [date2 cppDateRecord]; const auto cpp_date2 = djinni_generated::DateRecord::toCpp(date2);
DBDateRecord *date3 = [[DBDateRecord alloc] initWithCppDateRecord:cpp_date2]; DBDateRecord *date3 = djinni_generated::DateRecord::fromCpp(cpp_date2);
const auto cpp_date3 = [date3 cppDateRecord]; const auto cpp_date3 = djinni_generated::DateRecord::toCpp(date3);
const bool cpp_is_equal = cpp_date1.created_at == cpp_date2.created_at && cpp_date2.created_at == cpp_date3.created_at; const bool cpp_is_equal = cpp_date1.created_at == cpp_date2.created_at && cpp_date2.created_at == cpp_date3.created_at;
// cpp is a integer representation (with less precision than NSDate), so direct comparison will work // cpp is a integer representation (with less precision than NSDate), so direct comparison will work
XCTAssertTrue(cpp_is_equal); XCTAssertTrue(cpp_is_equal);
...@@ -59,8 +59,8 @@ ...@@ -59,8 +59,8 @@
{ {
const auto now = std::chrono::system_clock::now(); const auto now = std::chrono::system_clock::now();
DateRecord cpp_date_now(now); DateRecord cpp_date_now(now);
DBDateRecord *objcDate = [[DBDateRecord alloc] initWithCppDateRecord:cpp_date_now]; DBDateRecord *objcDate = djinni_generated::DateRecord::fromCpp(cpp_date_now);
const auto boomerang_cpp_date = [objcDate cppDateRecord]; const auto boomerang_cpp_date = djinni_generated::DateRecord::toCpp(objcDate);
XCTAssertTrue(now == boomerang_cpp_date.created_at); XCTAssertTrue(now == boomerang_cpp_date.created_at);
} }
......
...@@ -89,6 +89,28 @@ fi ...@@ -89,6 +89,28 @@ fi
--idl "$in_relative" \ --idl "$in_relative" \
) )
# Make sure we can parse back our own generated YAML file
cp "$base_dir/djinni/yaml-test.djinni" "$temp_out/yaml"
"$base_dir/../src/run-assume-built" \
--java-out "$temp_out/java" \
--java-package $java_package \
--ident-java-field mFooBar \
\
--cpp-out "$temp_out/cpp" \
--ident-cpp-enum-type foo_bar \
--cpp-optional-template "std::experimental::optional" \
--cpp-optional-header "<experimental/optional>" \
\
--jni-out "$temp_out/jni" \
--ident-jni-class NativeFooBar \
--ident-jni-file NativeFooBar \
\
--objc-out "$temp_out/objc" \
--objcpp-out "$temp_out/objc" \
--objc-type-prefix DB \
\
--idl "$temp_out/yaml/yaml-test.djinni"
# Copy changes from "$temp_output" to final dir. # Copy changes from "$temp_output" to final dir.
mirror() { mirror() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment