aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2014-12-21 22:38:21 +0200
committerDmitry Petrashko <dark@d-d.me>2014-12-21 22:38:21 +0200
commit2833b0107cdd95bdceb4d8aa968e0f66a6eb24e3 (patch)
tree9c2cb6eae1e2f7df4a49c58b342c8ac708afe478
parent13ec91b955b5c10da750b26e10f793ea44a72945 (diff)
parent823930308048a26c07bb54ac77923ba8e24e68a4 (diff)
downloaddotty-2833b0107cdd95bdceb4d8aa968e0f66a6eb24e3.tar.gz
dotty-2833b0107cdd95bdceb4d8aa968e0f66a6eb24e3.tar.bz2
dotty-2833b0107cdd95bdceb4d8aa968e0f66a6eb24e3.zip
Merge pull request #315 from dotty-staging/fix/annot-vararg-constr
Allow for varargs passed to Java annotation constructors.
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala39
-rw-r--r--tests/pending/pos/annot.scala5
-rw-r--r--tests/pos/annot.scala6
3 files changed, 30 insertions, 20 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index cc3d3eb7f..24b2f4257 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -553,12 +553,15 @@ class ClassfileParser(
newType
}
- /** Add a synthetic constructor and potentially also default getters which
+ /** Add synthetic constructor(s) 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.
+ * If the constructor takes as last parameter an array, it can also accept
+ * a vararg argument. We solve this by creating two constructors, one with
+ * an array, the other with a repeated parameter.
*/
def addAnnotationConstructor(classInfo: Type, tparams: List[Symbol] = Nil)(implicit ctx: Context): Unit = {
def addDefaultGetter(attr: Symbol, n: Int) =
@@ -574,21 +577,33 @@ class ClassfileParser(
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(
+ val paramNames = attrs.map(_.name.asTermName)
+ val paramTypes = attrs.map(_.info.resultType)
+
+ def addConstr(ptypes: List[Type]) = {
+ val mtype = MethodType(paramNames, ptypes, classRoot.typeRef.appliedTo(targs))
+ val constrType = if (tparams.isEmpty) mtype else TempPolyType(tparams, mtype)
+ val constr = ctx.newSymbol(
owner = classRoot.symbol,
name = nme.CONSTRUCTOR,
flags = Flags.Synthetic,
- info = if (tparams.isEmpty) methType else TempPolyType(tparams, methType)
+ info = constrType
).entered
- for ((attr, i) <- attrs.zipWithIndex)
- if (attr.hasAnnotation(defn.AnnotationDefaultAnnot)) {
- constr.setFlag(Flags.HasDefaultParams)
- addDefaultGetter(attr, i)
- }
+ for ((attr, i) <- attrs.zipWithIndex)
+ if (attr.hasAnnotation(defn.AnnotationDefaultAnnot)) {
+ constr.setFlag(Flags.HasDefaultParams)
+ addDefaultGetter(attr, i)
+ }
+ }
+
+ addConstr(paramTypes)
+ if (paramTypes.nonEmpty)
+ paramTypes.last match {
+ case defn.ArrayType(elemtp) =>
+ addConstr(paramTypes.init :+ defn.RepeatedParamType.appliedTo(elemtp))
+ case _ =>
+ }
+
}
}
diff --git a/tests/pending/pos/annot.scala b/tests/pending/pos/annot.scala
deleted file mode 100644
index 8e21803b4..000000000
--- a/tests/pending/pos/annot.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-class Test {
-
- @SuppressWarnings("hi") def foo() = ???
-
-}
diff --git a/tests/pos/annot.scala b/tests/pos/annot.scala
index ab80aba27..c3a17ff1d 100644
--- a/tests/pos/annot.scala
+++ b/tests/pos/annot.scala
@@ -2,11 +2,11 @@ import java.beans.Transient
class Test {
- @SuppressWarnings(Array("hi")) def foo() = ??? // evalutation of annotation on type cannot be deffered as requires implicit resolution(only generic Array$.apply applies here)
+ @SuppressWarnings(Array("hi")) def foo() = ??? // evalutation of annotation on type cannot be deferred as requires implicit resolution(only generic Array$.apply applies here)
- @SuppressWarnings(Array("hi", "foo")) def foo2() = ??? //can be deffered as there is a non-generic method
+ @SuppressWarnings(Array("hi", "foo")) def foo2() = ??? //can be deferred as there is a non-generic method
-// @SuppressWarnings("hi") def foo3() = ??? // can be written in java and is serialized this way in bytecode. doesn't typecheck
+ @SuppressWarnings("hi") def foo3() = ??? // can be written in java and is serialized this way in bytecode. doesn't typecheck
@Transient(false) def bar = ???