aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-10-10 16:25:26 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-11-22 20:10:18 +0100
commit1e1f260577d8522a5c99052cea5b3ebe64a12830 (patch)
tree790d8735bf20fcb38088408227e1af7651464be7 /src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
parent33feb9dea9db0695f510654348455133707e0740 (diff)
downloaddotty-1e1f260577d8522a5c99052cea5b3ebe64a12830.tar.gz
dotty-1e1f260577d8522a5c99052cea5b3ebe64a12830.tar.bz2
dotty-1e1f260577d8522a5c99052cea5b3ebe64a12830.zip
Add the right constructor to Java annotations
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/ClassfileParser.scala')
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 8dd9314ee..fb5a6309b 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -128,6 +128,7 @@ class ClassfileParser(
for (i <- 0 until in.nextChar) parseMember(method = false)
for (i <- 0 until in.nextChar) parseMember(method = true)
classInfo = parseAttributes(classRoot.symbol, classInfo)
+ if (isAnnotation) addAnnotationConstructor(classInfo)
setClassInfo(classRoot, classInfo)
setClassInfo(moduleRoot, staticInfo)
}
@@ -551,6 +552,45 @@ class ClassfileParser(
newType
}
+ /** Add a synthetic constructor and potentially also default getters which
+ * reflects the fields of the annotation with given `classInfo`.
+ * Annotations in Scala are assumed to get all their arguments as constructor
+ * parameters. For Java annotations we need to fake it by making up the constructor.
+ * Note that default getters have type Nothing. That's OK because we need
+ * them only to signal that the corresponding parameter is optional.
+ */
+ def addAnnotationConstructor(classInfo: Type, tparams: List[Symbol] = Nil)(implicit ctx: Context): Unit = {
+ def addDefaultGetter(attr: Symbol, n: Int) =
+ ctx.newSymbol(
+ owner = moduleRoot.symbol,
+ name = nme.CONSTRUCTOR.defaultGetterName(n),
+ flags = attr.flags & Flags.AccessFlags,
+ info = defn.NothingType).entered
+
+ classInfo match {
+ case classInfo @ TempPolyType(tparams, restpe) if tparams.isEmpty =>
+ addAnnotationConstructor(restpe, tparams)
+ case classInfo: TempClassInfoType =>
+ val attrs = classInfo.decls.toList.filter(_.isTerm)
+ val targs = tparams.map(_.typeRef)
+ val methType = MethodType(
+ attrs.map(_.name.asTermName),
+ attrs.map(_.info.resultType),
+ classRoot.typeRef.appliedTo(targs))
+ val constr = ctx.newSymbol(
+ owner = classRoot.symbol,
+ name = nme.CONSTRUCTOR,
+ flags = Flags.Synthetic,
+ info = if (tparams.isEmpty) methType else TempPolyType(tparams, methType)
+ ).entered
+ for ((attr, i) <- attrs.zipWithIndex)
+ if (attr.hasAnnotation(defn.AnnotationDefaultAnnot)) {
+ constr.setFlag(Flags.HasDefaultParams)
+ addDefaultGetter(attr, i)
+ }
+ }
+ }
+
/** Enter own inner classes in the right scope. It needs the scopes to be set up,
* and implicitly current class' superclasses.
*/