aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2015-06-12 13:25:38 +0200
committerDmitry Petrashko <dark@d-d.me>2015-06-12 13:25:38 +0200
commitae8a24638551913a60097a5a07c74f5e98e43af0 (patch)
treeb0dbbd4da34eb1e8488b22e494ffee7e00b314fd
parent1962ada58fcd2333a2e40179ab0ac6efb6167ed2 (diff)
parent0584e0ff783419b927145509f8c1dfea5e0510f4 (diff)
downloaddotty-ae8a24638551913a60097a5a07c74f5e98e43af0.tar.gz
dotty-ae8a24638551913a60097a5a07c74f5e98e43af0.tar.bz2
dotty-ae8a24638551913a60097a5a07c74f5e98e43af0.zip
Merge pull request #635 from dotty-staging/fix/private-scala2-trait-setters
Some fixes around mixin and memoization
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala3
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala23
-rw-r--r--src/dotty/tools/dotc/transform/AugmentScala2Traits.scala11
-rw-r--r--src/dotty/tools/dotc/transform/ExtensionMethods.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Memoize.scala11
-rw-r--r--src/dotty/tools/dotc/transform/MixinOps.scala7
-rw-r--r--src/dotty/tools/dotc/transform/SymUtils.scala9
-rw-r--r--tests/pos/scala2traits/dotty-subclass.scala8
-rw-r--r--tests/pos/scala2traits/scala-trait.scala6
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)
}