@@ -15,32 +15,36 @@ import ast.Trees._
1515import util .Property
1616import util .Positions .Position
1717
18+ /** A utility class for generating access proxies. Currently used for
19+ * inline accessors and protected accessors.
20+ */
1821abstract class AccessProxies {
1922 import ast .tpd ._
2023
2124 def getterName : ClassifiedNameKind
2225 def setterName : ClassifiedNameKind
2326
27+ /** accessor -> accessed */
28+ private val accessedBy = newMutableSymbolMap[Symbol ]
29+
2430 /** The accessor definitions that need to be added to class `cls`
25- * As a side-effect, this method removes the `Accessed` annotations from
26- * the accessor symbols. So a second call of the same method will yield the empty list.
31+ * As a side-effect, this method removes entries from the `accessedBy` map.
32+ * So a second call of the same method will yield the empty list.
2733 */
28- private def accessorDefs (cls : Symbol )(implicit ctx : Context ): List [DefDef ] =
29- for {
30- accessor <- cls.info.decls.filter(sym => sym.name.is(getterName) || sym.name.is(setterName))
31- Annotation .Accessed (accessed) <- accessor.getAnnotation(defn.AccessedAnnot )
32- }
33- yield polyDefDef(accessor.asTerm, tps => argss => {
34- accessor.removeAnnotation(defn.AccessedAnnot )
35- val rhs =
36- if (accessor.name.is(setterName) &&
37- argss.nonEmpty && argss.head.nonEmpty) // defensive conditions
38- ref(accessed).becomes(argss.head.head)
39- else
40- ref(accessed).appliedToTypes(tps).appliedToArgss(argss)
41- rhs.withPos(accessed.pos)
42- })
34+ private def accessorDefs (cls : Symbol )(implicit ctx : Context ): Iterator [DefDef ] =
35+ for (accessor <- cls.info.decls.iterator; accessed <- accessedBy.remove(accessor)) yield
36+ polyDefDef(accessor.asTerm, tps => argss => {
37+ val accessRef = ref(TermRef (cls.thisType, accessed))
38+ val rhs =
39+ if (accessor.name.is(setterName) &&
40+ argss.nonEmpty && argss.head.nonEmpty) // defensive conditions
41+ accessRef.becomes(argss.head.head)
42+ else
43+ accessRef.appliedToTypes(tps).appliedToArgss(argss)
44+ rhs.withPos(accessed.pos)
45+ })
4346
47+ /** Add all needed accessors to the `body` of class `cls` */
4448 def addAccessorDefs (cls : Symbol , body : List [Tree ])(implicit ctx : Context ): List [Tree ] = {
4549 val accDefs = accessorDefs(cls)
4650 if (accDefs.isEmpty) body else body ++ accDefs
@@ -67,10 +71,7 @@ abstract class AccessProxies {
6771 def nameKind = if (onLHS) setterName else getterName
6872 val accessed = reference.symbol.asTerm
6973
70- def refersToAccessed (sym : Symbol ) = sym.getAnnotation(defn.AccessedAnnot ) match {
71- case Some (Annotation .Accessed (sym)) => sym `eq` accessed
72- case _ => false
73- }
74+ def refersToAccessed (sym : Symbol ) = accessedBy.get(sym) == Some (accessed)
7475
7576 val accessorInfo =
7677 if (onLHS) MethodType (accessed.info :: Nil , defn.UnitType )
@@ -80,7 +81,7 @@ abstract class AccessProxies {
8081 accessed.owner.info.decl(accessorName).suchThat(refersToAccessed).symbol
8182 .orElse {
8283 val acc = newAccessorSymbol(accessed, accessorName, accessorInfo)
83- acc.addAnnotation( Annotation . Accessed (accessed))
84+ accessedBy(acc) = accessed
8485 acc
8586 }
8687
0 commit comments