Commit 051a36f8 authored by Miro Knejp's avatar Miro Knejp Committed by Jacob Potter

Use marshalling objects to generate code for member and constant types

parent bf108787
......@@ -123,7 +123,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
for (c <- consts) {
w.wl
writeDoc(w, c.doc)
w.wl(s"static const ${marshal.typename(c.ty)} ${idCpp.const(c.ident)};")
w.wl(s"static const ${marshal.fieldType(c.ty)} ${idCpp.const(c.ident)};")
}
}
......@@ -156,7 +156,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
val skipFirst = SkipFirst()
for (c <- consts) {
skipFirst{ w.wl }
w.w(s"const ${marshal.typename(c.ty)} $selfName::${idCpp.const(c.ident)} = ")
w.w(s"const ${marshal.fieldType(c.ty)} $selfName::${idCpp.const(c.ident)} = ")
writeCppConst(w, c.ty, c.value)
w.wl(";")
}
......@@ -188,7 +188,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
for (f <- r.fields) {
w.wl
writeDoc(w, f.doc)
w.wl(marshal.typename(f.ty) + " " + idCpp.field(f.ident) + ";")
w.wl(marshal.fieldType(f.ty) + " " + idCpp.field(f.ident) + ";")
}
w.wl
......@@ -212,7 +212,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
val skipFirst = SkipFirst()
for (f <- r.fields) {
skipFirst { w.wl(",") }
w.w(marshal.typename(f.ty) + " " + idCpp.local(f.ident))
w.w(marshal.fieldType(f.ty) + " " + idCpp.local(f.ident))
}
w.wl(") :")
w.nested {
......
......@@ -26,6 +26,9 @@ class CppMarshal(spec: Spec) extends Marshal(spec) {
override def returnType(ret: Option[TypeRef]): String = ret.fold("void")(toCppType(_, None))
override def fqReturnType(ret: Option[TypeRef]): String = ret.fold("void")(toCppType(_, spec.cppNamespace))
override def fieldType(tm: MExpr): String = typename(tm)
override def fqFieldType(tm: MExpr): String = fqTypename(tm)
private def toCppType(ty: TypeRef, namespace: Option[String] = None): String = toCppType(ty.resolved, namespace)
private def toCppType(tm: MExpr, namespace: Option[String]): String = {
def base(m: Meta): String = m match {
......
......@@ -102,7 +102,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w.wl(s"const jmethodID jconstructor { djinni::jniGetMethodID(clazz.get(), ${q("<init>")}, $constructorSig) };")
for (f <- r.fields) {
val javaFieldName = idJava.field(f.ident)
val javaSig = q(jniMarshal.typename(f.ty))
val javaSig = q(jniMarshal.fqTypename(f.ty))
w.wl(s"const jfieldID field_$javaFieldName { djinni::jniGetFieldID(clazz.get(), ${q(javaFieldName)}, $javaSig) };")
}
w.wl
......@@ -309,7 +309,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
if (!m.static) w.wl(s"const std::shared_ptr<$cppSelf> & ref = djinni::CppProxyHandle<$cppSelf>::get(nativeRef);")
for (p <- m.params) {
val jniHelperClass = toJniHelperClass(p.ty)
val cppType = cppMarshal.fqTypename(p.ty)
val cppType = cppMarshal.fqFieldType(p.ty)
val localVar = "c_" + idCpp.local(p.ident)
val paramName = "j_" + idJava.local(p.ident)
w.wl(s"$cppType $localVar = $jniHelperClass::fromJava(jniEnv, $paramName);")
......@@ -320,7 +320,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
w.wl
m.ret match {
case Some(r) =>
val cppRetType = cppMarshal.fqTypename(r)
val cppRetType = cppMarshal.fqFieldType(r)
val jniHelperClass = toJniHelperClass(r)
w.wl(s"$cppRetType cr = $callExpr;")
w.wl
......@@ -410,7 +410,7 @@ class JNIGenerator(spec: Spec) extends Generator(spec) {
}
def storeLocal(w: IndentWriter, name: String, ty: TypeRef, expr: String) = {
val jniTy = toJniType(ty)
val jniTy = jniMarshal.fqFieldType(ty)
if (isJavaHeapObject(ty)) {
w.wl(s"djinni::LocalRef<$jniTy> $name(jniEnv, $expr);")
s"$name.get()"
......
......@@ -8,7 +8,7 @@ class JNIMarshal(spec: Spec) extends Marshal(spec) {
// For JNI typename() is always fully qualified and describes the mangled Java type to be used in field/method signatures
override def typename(tm: MExpr): String = javaTypeSignature(tm)
def typename(name: String, ty: TypeDef): String = throw new AssertionError("not supported")
def typename(name: String, ty: TypeDef): String = throw new AssertionError("not applicable")
override def fqTypename(tm: MExpr): String = typename(tm)
def fqTypename(name: String, ty: TypeDef): String = typename(name, ty)
......@@ -19,6 +19,9 @@ class JNIMarshal(spec: Spec) extends Marshal(spec) {
override def returnType(ret: Option[TypeRef]): String = ret.fold("void")(toJniType)
override def fqReturnType(ret: Option[TypeRef]): String = returnType(ret)
override def fieldType(tm: MExpr): String = paramType(tm)
override def fqFieldType(tm: MExpr): String = fqParamType(tm)
// Name for the autogenerated class containing field/method IDs and toJava()/fromJava() methods
def helperClass(name: String) = spec.jniClassIdentStyle(name)
def fqHelperClass(name: String) = withNs(Some(spec.jniNamespace), helperClass(name))
......
......@@ -100,7 +100,7 @@ class JavaGenerator(spec: Spec) extends Generator(spec) {
for (c <- consts) {
writeDoc(w, c.doc)
javaAnnotationHeader.foreach(w.wl)
w.w(s"public static final ${marshal.typename(c.ty)} ${idJava.const(c.ident)} = ")
w.w(s"public static final ${marshal.fieldType(c.ty)} ${idJava.const(c.ident)} = ")
writeJavaConst(w, c.ty, c.value)
w.wl(";")
w.wl
......@@ -230,7 +230,7 @@ class JavaGenerator(spec: Spec) extends Generator(spec) {
// Field definitions.
for (f <- r.fields) {
w.wl
w.wl(s"/*package*/ final ${marshal.typename(f.ty)} ${idJava.field(f.ident)};")
w.wl(s"/*package*/ final ${marshal.fieldType(f.ty)} ${idJava.field(f.ident)};")
}
// Constructor.
......
......@@ -18,6 +18,9 @@ class JavaMarshal(spec: Spec) extends Marshal(spec) {
override def returnType(ret: Option[TypeRef]): String = ret.fold("void")(ty => toJavaType(ty.resolved, None))
override def fqReturnType(ret: Option[TypeRef]): String = ret.fold("void")(ty => toJavaType(ty.resolved, spec.javaPackage))
override def fieldType(tm: MExpr): String = typename(tm)
override def fqFieldType(tm: MExpr): String = fqTypename(tm)
private def toJavaType(tm: MExpr, packageName: Option[String]): String = {
def f(tm: MExpr, needRef: Boolean): String = {
tm.base match {
......
......@@ -25,6 +25,11 @@ abstract class Marshal(spec: Spec) {
def returnType(ret: Option[TypeRef]): String
def fqReturnType(ret: Option[TypeRef]): String
def fieldType(tm: MExpr): String
def fieldType(ty: TypeRef): String = fieldType(ty.resolved)
def fqFieldType(tm: MExpr): String
def fqFieldType(ty: TypeRef): String = fqFieldType(ty.resolved)
implicit def identToString(ident: Ident): String = ident.name
protected val idCpp = spec.cppIdentStyle
protected val idJava = spec.javaIdentStyle
......
......@@ -90,8 +90,8 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
def writeObjcConstVariable(w: IndentWriter, c: Const, s: String): Unit = c.ty.resolved.base match {
// MBinary | MList | MSet | MMap are not allowed for constants.
// Primitives should be `const type`. All others are pointers and should be `type * const`
case t: MPrimitive => w.w(s"const ${toObjcTypeDef(c.ty)}$s${idObjc.const(c.ident)}")
case _ => w.w(s"${toObjcTypeDef(c.ty)} const $s${idObjc.const(c.ident)}")
case t: MPrimitive => w.w(s"const ${marshal.fqFieldType(c.ty)} $s${idObjc.const(c.ident)}")
case _ => w.w(s"${marshal.fqFieldType(c.ty)} const $s${idObjc.const(c.ident)}")
}
def generateObjcConstants(w: IndentWriter, consts: Seq[Const], selfName: String) = {
......@@ -244,7 +244,7 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
for (f <- r.fields) {
w.wl
writeDoc(w, f.doc)
w.wl(s"@property (nonatomic, readonly) ${toObjcTypeDef(f.ty)}${idObjc.field(f.ident)};")
w.wl(s"@property (nonatomic, readonly) ${marshal.fqFieldType(f.ty)} ${idObjc.field(f.ident)};")
}
if (r.derivingTypes.contains(DerivingType.Ord)) {
w.wl
......@@ -310,12 +310,4 @@ class ObjcGenerator(spec: Spec) extends Generator(spec) {
f(tm, needRef)
}
def toObjcTypeDef(ty: TypeRef): String = toObjcTypeDef(ty.resolved, false)
def toObjcTypeDef(ty: TypeRef, needRef: Boolean): String = toObjcTypeDef(ty.resolved, needRef)
def toObjcTypeDef(tm: MExpr): String = toObjcTypeDef(tm, false)
def toObjcTypeDef(tm: MExpr, needRef: Boolean): String = {
val (name, asterisk) = toObjcType(tm, needRef)
name + (if (asterisk) " *" else " ")
}
}
......@@ -22,6 +22,9 @@ class ObjcMarshal(spec: Spec) extends Marshal(spec) {
override def returnType(ret: Option[TypeRef]): String = ret.fold("void")(paramType)
override def fqReturnType(ret: Option[TypeRef]): String = returnType(ret)
override def fieldType(tm: MExpr): String = paramType(tm)
override def fqFieldType(tm: MExpr): String = fqParamType(tm)
// Return value: (Type_Name, Is_Class_Or_Not)
def toObjcType(ty: TypeRef): (String, Boolean) = toObjcType(ty.resolved, false)
def toObjcType(ty: TypeRef, needRef: Boolean): (String, Boolean) = toObjcType(ty.resolved, needRef)
......
......@@ -124,8 +124,8 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
def writeObjcConstVariable(w: IndentWriter, c: Const, s: String): Unit = c.ty.resolved.base match {
// MBinary | MList | MSet | MMap are not allowed for constants.
// Primitives should be `const type`. All others are pointers and should be `type * const`
case t: MPrimitive => w.w(s"const ${toObjcTypeDef(c.ty)}$s${idObjc.const(c.ident)}")
case _ => w.w(s"${toObjcTypeDef(c.ty)} const $s${idObjc.const(c.ident)}")
case t: MPrimitive => w.w(s"const ${objcMarshal.fqFieldType(c.ty)} $s${idObjc.const(c.ident)}")
case _ => w.w(s"${objcMarshal.fqFieldType(c.ty)} const $s${idObjc.const(c.ident)}")
}
def generateObjcConstants(w: IndentWriter, consts: Seq[Const], selfName: String) = {
......@@ -323,7 +323,7 @@ class ObjcppGenerator(spec: Spec) extends Generator(spec) {
w.w("@autoreleasepool").braced {
m.params.foreach(p =>
translateCppTypeToObjc(idCpp.local("cpp_" + p.ident.name), idCpp.local(p.ident), p.ty, true, w))
m.ret.fold()(r => w.w(toObjcTypeDef(r) + "objcRet = "))
m.ret.fold()(r => w.w(objcMarshal.fqFieldType(r) + " objcRet = "))
w.w("[_objcRef " + idObjc.method(m.ident))
val skipFirst = SkipFirst()
for (p <- m.params) {
......
......@@ -12,11 +12,14 @@ class ObjcppMarshal(spec: Spec) extends Marshal(spec) {
override def fqTypename(tm: MExpr): String = throw new AssertionError("not applicable")
def fqTypename(name: String, ty: TypeDef): String = throw new AssertionError("not applicable")
def paramType(tm: MExpr): String = throw new AssertionError("not applicable")
def fqParamType(tm: MExpr): String = throw new AssertionError("not applicable")
override def paramType(tm: MExpr): String = throw new AssertionError("not applicable")
override def fqParamType(tm: MExpr): String = throw new AssertionError("not applicable")
def returnType(ret: Option[TypeRef]): String = throw new AssertionError("not applicable")
def fqReturnType(ret: Option[TypeRef]): String = throw new AssertionError("not applicable")
override def returnType(ret: Option[TypeRef]): String = throw new AssertionError("not applicable")
override def fqReturnType(ret: Option[TypeRef]): String = throw new AssertionError("not applicable")
override def fieldType(tm: MExpr): String = throw new AssertionError("not applicable")
override def fqFieldType(tm: MExpr): String = throw new AssertionError("not applicable")
// Name for the autogenerated proxy class wrapping +o interfaces
def helperClass(name: String) = idCpp.ty(name)
......
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