Skip to content

Commit 94ce66f

Browse files
committed
Backend: emit all annotations.
1 parent b830a08 commit 94ce66f

File tree

1 file changed

+43
-18
lines changed

1 file changed

+43
-18
lines changed

src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import dotty.tools.dotc.util.{Positions, DotClass}
2828
import Decorators._
2929
import tpd._
3030
import scala.tools.asm
31+
import NameOps._
3132
import StdNames.nme
3233

3334
class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
@@ -138,12 +139,13 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
138139
val PartialFunctionClass: Symbol = defn.PartialFunctionClass
139140
val AbstractPartialFunctionClass: Symbol = defn.AbstractPartialFunctionClass
140141
val String_valueOf: Symbol = defn.String_valueOf_Object
142+
lazy val Predef_classOf: Symbol = ctx.requiredMethod(toDenot(defn.ScalaPredefModule).moduleClass.asClass, nme.classOf)
141143

142144
lazy val AnnotationRetentionAttr = ctx.requiredClass("java.lang.annotation.Retention")
143145
lazy val AnnotationRetentionSourceAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE")
144146
lazy val AnnotationRetentionClassAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS")
145147
lazy val AnnotationRetentionRuntimeAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME")
146-
148+
lazy val JavaAnnotationClass = ctx.requiredClass("java.lang.annotation.Annotation")
147149

148150

149151
def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses.map{x =>
@@ -235,13 +237,34 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
235237
case ClazzTag => av.visit(name, const.typeValue.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
236238
case EnumTag =>
237239
val edesc = innerClasesStore.typeDescriptor(const.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class.
238-
val evalue = const.symbolValue.name.toString // value the actual enumeration value.
240+
val evalue = const.symbolValue.name.toString // value the actual enumeration value.
239241
av.visitEnum(name, edesc, evalue)
240242
}
243+
case t: TypeApply if (t.fun.symbol == Predef_classOf) =>
244+
av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType)
245+
case t: Select =>
246+
if (t.symbol.denot.is(Flags.Enum)) {
247+
val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class.
248+
val evalue = t.symbol.name.toString // value the actual enumeration value.
249+
av.visitEnum(name, edesc, evalue)
250+
} else {
251+
assert(toDenot(t.symbol).name.toTermName.defaultGetterIndex >= 0) // this should be default getter. do not emmit.
252+
}
253+
case t: SeqLiteral =>
254+
val arrAnnotV: AnnotationVisitor = av.visitArray(name)
255+
for(arg <- t.elems) { emitArgument(arrAnnotV, null, arg, bcodeStore)(innerClasesStore) }
256+
arrAnnotV.visitEnd()
257+
241258
case Apply(fun, args) if (fun.symbol == defn.ArrayClass.primaryConstructor ||
242259
(toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply)) =>
243260
val arrAnnotV: AnnotationVisitor = av.visitArray(name)
244-
val flatArgs = args.flatMap {
261+
262+
var actualArgs = if (fun.tpe.isInstanceOf[ImplicitMethodType]) {
263+
// generic array method, need to get implicit argument out of the way
264+
fun.asInstanceOf[Apply].args
265+
} else args
266+
267+
val flatArgs = actualArgs.flatMap {
245268
case t: tpd.SeqLiteral => t.elems
246269
case e => List(e)
247270
}
@@ -258,14 +281,14 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
258281
for(arg <- BCodeAsmCommon.arrEncode(sb)) { arrAnnotV.visit(name, arg) }
259282
arrAnnotV.visitEnd()
260283
} // for the lazy val in ScalaSigBytes to be GC'ed, the invoker of emitAnnotations() should hold the ScalaSigBytes in a method-local var that doesn't escape.
261-
262-
case NestedAnnotArg(annInfo) =>
263-
val AnnotationInfo(typ, args, assocs) = annInfo
264-
assert(args.isEmpty, args)
284+
*/
285+
case t @ Apply(constr, args) if t.tpe.derivesFrom(JavaAnnotationClass) =>
286+
val typ = t.tpe.classSymbol.denot.info
287+
val assocs = assocsFromApply(t)
265288
val desc = innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the nested annotation class
266-
val nestedVisitor = av.visitAnnotation(name, desc)
289+
val nestedVisitor = av.visitAnnotation(name, desc)
267290
emitAssocs(nestedVisitor, assocs, bcodeStore)(innerClasesStore)
268-
*/}
291+
}
269292
}
270293

271294
override def emitAnnotations(cw: asm.ClassVisitor, annotations: List[Annotation], bcodeStore: BCodeHelpers)(innerClasesStore: bcodeStore.BCInnerClassGen) {
@@ -486,21 +509,23 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
486509
implicit def annotHelper(a: Annotation): AnnotationHelper = new AnnotationHelper {
487510
def atp: Type = a.tree.tpe
488511

489-
def assocs: List[(Name, Tree)] = {
490-
a.tree match {
491-
case Apply(fun, args) =>
492-
fun.tpe.widen match {
493-
case MethodType(names, _) =>
494-
names zip args
495-
}
496-
}
497-
}
512+
def assocs: List[(Name, Tree)] = assocsFromApply(a.tree)
498513

499514
def symbol: Symbol = a.tree.symbol
500515

501516
def args: List[Tree] = List.empty // those arguments to scala-defined annotations. they are never emmited
502517
}
503518

519+
def assocsFromApply(tree: Tree) = {
520+
tree match {
521+
case Apply(fun, args) =>
522+
fun.tpe.widen match {
523+
case MethodType(names, _) =>
524+
names zip args
525+
}
526+
}
527+
}
528+
504529

505530
implicit def nameHelper(n: Name): NameHelper = new NameHelper {
506531
def toTypeName: Name = n.toTypeName

0 commit comments

Comments
 (0)