diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/AugmentScala2Traits.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExtensionMethods.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Memoize.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/MixinOps.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/SymUtils.scala | 9 | ||||
-rw-r--r-- | tests/pos/scala2traits/dotty-subclass.scala | 8 | ||||
-rw-r--r-- | tests/pos/scala2traits/scala-trait.scala | 6 |
9 files changed, 57 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index 1c4d5c282..fdeee82de 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -346,6 +346,9 @@ class Definitions { lazy val UncheckedStableAnnot = ctx.requiredClass("scala.annotation.unchecked.uncheckedStable") lazy val UncheckedVarianceAnnot = ctx.requiredClass("scala.annotation.unchecked.uncheckedVariance") lazy val VolatileAnnot = ctx.requiredClass("scala.volatile") + lazy val FieldMetaAnnot = ctx.requiredClass("scala.annotation.meta.field") + lazy val GetterMetaAnnot = ctx.requiredClass("scala.annotation.meta.getter") + lazy val SetterMetaAnnot = ctx.requiredClass("scala.annotation.meta.setter") // convenient one-parameter method types def methOfAny(tp: Type) = MethodType(List(AnyType), tp) diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index f24c41ee2..d2b0d5030 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -215,6 +215,10 @@ object SymDenotations { final def transformAnnotations(f: Annotation => Annotation)(implicit ctx: Context): Unit = annotations = annotations.mapConserve(f) + /** Keep only those annotations that satisfy `p` */ + final def filterAnnotations(p: Annotation => Boolean)(implicit ctx: Context): Unit = + annotations = annotations.filterConserve(p) + /** Optionally, the annotation matching the given class symbol */ final def getAnnotation(cls: Symbol)(implicit ctx: Context): Option[Annotation] = dropOtherAnnotations(annotations, cls) match { @@ -230,9 +234,9 @@ object SymDenotations { final def removeAnnotation(cls: Symbol)(implicit ctx: Context): Unit = annotations = myAnnotations.filterNot(_ matches cls) - /** Copy all annotations from given symbol by adding them to this symbol */ - final def addAnnotations(from: Symbol)(implicit ctx: Context): Unit = - from.annotations.foreach(addAnnotation) + /** Add all given annotations to this symbol */ + final def addAnnotations(annots: TraversableOnce[Annotation])(implicit ctx: Context): Unit = + annots.foreach(addAnnotation) @tailrec private def dropOtherAnnotations(anns: List[Annotation], cls: Symbol)(implicit ctx: Context): List[Annotation] = anns match { @@ -282,6 +286,13 @@ object SymDenotations { // ------ Names ---------------------------------------------- + /** The expanded name of this denotation. */ + final def expandedName(implicit ctx: Context) = + if (is(ExpandedName) || isConstructor) name + else name.expandedName(initial.asSymDenotation.owner) + // need to use initial owner to disambiguate, as multiple private symbols with the same name + // might have been moved from different origins into the same class + /** The name with which the denoting symbol was created */ final def originalName(implicit ctx: Context) = { val d = initial.asSymDenotation @@ -1077,11 +1088,7 @@ object SymDenotations { def ensureNotPrivate(implicit ctx: Context) = if (is(Private)) copySymDenotation( - name = - if (is(ExpandedName) || isConstructor) this.name - else this.name.expandedName(initial.asSymDenotation.owner), - // need to use initial owner to disambiguate, as multiple private symbols with the same name - // might have been moved from different origins into the same class + name = expandedName, initFlags = this.flags &~ Private | ExpandedName) else this } diff --git a/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala b/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala index c3e205f83..6c2d63d10 100644 --- a/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala +++ b/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala @@ -69,16 +69,13 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform info = fullyParameterizedType(mold.info, mixin)) } - def traitSetter(getter: TermSymbol) = { - val separator = if (getter.is(Private)) nme.EXPAND_SEPARATOR else nme.TRAIT_SETTER_SEPARATOR - val expandedGetterName = - if (getter.is(ExpandedName)) getter.name - else getter.name.expandedName(getter.owner, separator) + def traitSetter(getter: TermSymbol) = getter.copy( - name = expandedGetterName.setterName, + name = getter.ensureNotPrivate.name + .expandedName(getter.owner, nme.TRAIT_SETTER_SEPARATOR) + .asTermName.setterName, flags = Method | Accessor | ExpandedName, info = MethodType(getter.info.resultType :: Nil, defn.UnitType)) - } for (sym <- mixin.info.decls) { if (needsForwarder(sym) || sym.isConstructor || sym.isGetter && sym.is(Lazy)) diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index ef0faae80..36a1b9b30 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -117,7 +117,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful imeth.flags | Final &~ (Override | Protected | AbsOverride), fullyParameterizedType(imeth.info, imeth.owner.asClass), privateWithin = imeth.privateWithin, coord = imeth.coord) - extensionMeth.addAnnotations(from = imeth)(ctx.withPhase(thisTransformer)) + extensionMeth.addAnnotations(imeth.annotations)(ctx.withPhase(thisTransformer)) // need to change phase to add tailrec annotation which gets removed from original method in the same phase. extensionMeth } diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala index 6b19b6d13..cf3011bc8 100644 --- a/src/dotty/tools/dotc/transform/Memoize.scala +++ b/src/dotty/tools/dotc/transform/Memoize.scala @@ -50,7 +50,16 @@ import Decorators._ name = sym.name.asTermName.fieldName, flags = Private | (if (sym is Stable) EmptyFlags else Mutable), info = sym.info.resultType, - coord = tree.pos).enteredAfter(thisTransform) + coord = tree.pos) + .withAnnotationsCarrying(sym, defn.FieldMetaAnnot) + .enteredAfter(thisTransform) + + /** Can be used to filter annotations on getters and setters; not used yet */ + def keepAnnotations(denot: SymDenotation, meta: ClassSymbol) = { + val cpy = sym.copySymDenotation() + cpy.filterAnnotations(_.symbol.derivesFrom(meta)) + if (cpy.annotations ne denot.annotations) cpy.installAfter(thisTransform) + } lazy val field = sym.field.orElse(newField).asTerm if (sym.is(Accessor, butNot = NoFieldNeeded)) diff --git a/src/dotty/tools/dotc/transform/MixinOps.scala b/src/dotty/tools/dotc/transform/MixinOps.scala index 64f0edfb8..3685a00fc 100644 --- a/src/dotty/tools/dotc/transform/MixinOps.scala +++ b/src/dotty/tools/dotc/transform/MixinOps.scala @@ -13,12 +13,15 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx: val superCls: Symbol = cls.superClass val mixins: List[ClassSymbol] = cls.mixins - def implementation(member: TermSymbol): TermSymbol = - member.copy( + def implementation(member: TermSymbol): TermSymbol = { + val res = member.copy( owner = cls, name = member.name.stripScala2LocalSuffix, flags = member.flags &~ Deferred, info = cls.thisType.memberInfo(member)).enteredAfter(thisTransform).asTerm + res.addAnnotations(member.annotations) + res + } def superRef(target: Symbol, pos: Position = cls.pos): Tree = { val sup = if (target.isConstructor && !target.owner.is(Trait)) diff --git a/src/dotty/tools/dotc/transform/SymUtils.scala b/src/dotty/tools/dotc/transform/SymUtils.scala index d3e029a74..14f6a2e22 100644 --- a/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/src/dotty/tools/dotc/transform/SymUtils.scala @@ -11,6 +11,7 @@ import Names._ import StdNames._ import NameOps._ import Flags._ +import Annotations._ import language.implicitConversions object SymUtils { @@ -90,4 +91,12 @@ class SymUtils(val self: Symbol) extends AnyVal { def implClass(implicit ctx: Context): Symbol = self.owner.info.decl(self.name.implClassName).symbol + + def annotationsCarrying(meta: ClassSymbol)(implicit ctx: Context): List[Annotation] = + self.annotations.filter(_.symbol.hasAnnotation(meta)) + + def withAnnotationsCarrying(from: Symbol, meta: ClassSymbol)(implicit ctx: Context): self.type = { + self.addAnnotations(from.annotationsCarrying(meta)) + self + } } diff --git a/tests/pos/scala2traits/dotty-subclass.scala b/tests/pos/scala2traits/dotty-subclass.scala index 4e162dd14..62720b993 100644 --- a/tests/pos/scala2traits/dotty-subclass.scala +++ b/tests/pos/scala2traits/dotty-subclass.scala @@ -1,7 +1,13 @@ // This is supposed to be compiled by Dotty class Sub extends T -class A extends S2T with S2Tprivate { +trait DT { + + @volatile lazy val dx = 2 + +} + +class A extends S2T with S2Tprivate with DT { val a: Int = 3 var b = 2 } diff --git a/tests/pos/scala2traits/scala-trait.scala b/tests/pos/scala2traits/scala-trait.scala index db05bc941..4d91b12b2 100644 --- a/tests/pos/scala2traits/scala-trait.scala +++ b/tests/pos/scala2traits/scala-trait.scala @@ -9,7 +9,7 @@ trait T { trait S2T { var x: Int = 0 lazy val y: Int = 1 -// val z: Int = 2 + val z: Int = 2 val a: Int var b: Int @@ -19,13 +19,13 @@ trait S2T { trait S2Tprivate { private var x: Int = 0 private lazy val y: Int = 1 -// private val z: Int = 2 // @darkdimius uncomment once lazy vals can be inherited. + private val z: Int = 2 private def f(x: Int): Int = x + y def xx = x def xx_=(x: Int) = this.x = x def yy = y -// def zz = z + def zz = z def ff(x: Int) = f(x) } |