aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
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
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')
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala40
3 files changed, 42 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index db969767b..c966f0d61 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -318,7 +318,7 @@ object Flags {
/** An unpickled Scala 2.x class */
final val Scala2x = typeFlag(26, "<scala-2.x>")
- /** A method that has default params */ // TODO: drop
+ /** A method that has default params */
final val DefaultParameterized = termFlag(27, "<defaultparam>")
/** Symbol is initialized to the default value, e.g. var x: T = _ */
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index aa8036fc5..7dba8c026 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2026,7 +2026,7 @@ object Types {
if ((paramNames eq this.paramNames) && (paramBounds eq this.paramBounds) && (restpe eq this.resultType)) this
else copy(paramNames, paramBounds, restpe)
- def copy(paramNames: List[TypeName], paramBounds: List[TypeBounds], restpe: Type)(implicit ctx: Context) =
+ def copy(paramNames: List[TypeName] = this.paramNames, paramBounds: List[TypeBounds] = this.paramBounds, restpe: Type)(implicit ctx: Context) =
PolyType(paramNames)(
x => paramBounds mapConserve (_.subst(this, x).bounds),
x => restpe.subst(this, x))
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.
*/