Skip to content

Commit 5a42cfa

Browse files
committed
Polishings
1 parent a9e9275 commit 5a42cfa

File tree

1 file changed

+24
-35
lines changed

1 file changed

+24
-35
lines changed

compiler/src/dotty/tools/dotc/transform/AccessProxies.scala

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -58,33 +58,38 @@ abstract class AccessProxies {
5858
def needsAccessor(sym: Symbol)(implicit ctx: Context): Boolean
5959

6060
/** A fresh accessor symbol */
61-
def newAccessorSymbol(owner: Symbol, name: TermName, info: Type, pos: Position)(implicit ctx: Context): TermSymbol = {
61+
private def newAccessorSymbol(owner: Symbol, name: TermName, info: Type, pos: Position)(implicit ctx: Context): TermSymbol = {
6262
val sym = ctx.newSymbol(owner, name, Synthetic | Method, info, coord = pos).entered
6363
if (sym.allOverriddenSymbols.exists(!_.is(Deferred))) sym.setFlag(Override)
6464
sym
6565
}
6666

67+
/** An accessor symbol, create a fresh one unless one exists already */
68+
private def accessorSymbol(owner: Symbol, accessorName: TermName, accessorInfo: Type, accessed: Symbol)(implicit ctx: Context) = {
69+
def refersToAccessed(sym: Symbol) = accessedBy.get(sym) == Some(accessed)
70+
owner.info.decl(accessorName).suchThat(refersToAccessed).symbol.orElse {
71+
val acc = newAccessorSymbol(owner, accessorName, accessorInfo, accessed.pos)
72+
accessedBy(acc) = accessed
73+
acc
74+
}
75+
}
76+
77+
/** Rewire reference to refer to `accessor` symbol */
6778
private def rewire(reference: RefTree, accessor: Symbol)(implicit ctx: Context): Tree = {
6879
reference match {
6980
case Select(qual, _) => qual.select(accessor)
7081
case Ident(name) => ref(accessor)
7182
}
7283
}.withPos(reference.pos)
7384

74-
private def isAccessor(sym: Symbol, accessed: Symbol) = accessedBy.get(sym) == Some(accessed)
75-
85+
/** Given a reference to a getter accessor, the corresponding setter reference */
7686
def useSetter(getterRef: RefTree)(implicit ctx: Context): Tree = {
7787
val getter = getterRef.symbol
7888
val accessed = accessedBy(getter)
7989
val accessedName = accessed.name.asTermName
8090
val setterName = accessorNameKind(accessedName.setterName)
81-
val setter =
82-
getter.owner.info.decl(setterName).suchThat(isAccessor(_, accessed)).symbol.orElse {
83-
val setterInfo = MethodType(getter.info.widenExpr :: Nil, defn.UnitType)
84-
val setter = newAccessorSymbol(getter.owner, setterName, setterInfo, getter.pos)
85-
accessedBy(setter) = accessed
86-
setter
87-
}
91+
val setterInfo = MethodType(getter.info.widenExpr :: Nil, defn.UnitType)
92+
val setter = accessorSymbol(getter.owner, setterName, setterInfo, accessed)
8893
rewire(getterRef, setter)
8994
}
9095

@@ -94,12 +99,8 @@ abstract class AccessProxies {
9499
* @param reference The original reference to the non-public symbol
95100
* @param onLHS The reference is on the left-hand side of an assignment
96101
*/
97-
def useAccessor(reference: RefTree, onLHS: Boolean)(implicit ctx: Context): Tree = {
98-
assert(!onLHS)
99-
102+
def useAccessor(reference: RefTree)(implicit ctx: Context): Tree = {
100103
val accessed = reference.symbol.asTerm
101-
102-
103104
var accessorClass = hostForAccessorOf(accessed: Symbol)
104105
if (!accessorClass.exists) {
105106
val curCls = ctx.owner.enclosingClass
@@ -108,23 +109,10 @@ abstract class AccessProxies {
108109
reference.pos)
109110
accessorClass = curCls
110111
}
111-
112-
val accessorName = accessorNameKind(
113-
if (onLHS) accessed.name.setterName else accessed.name)
114-
115-
116-
val accessor =
117-
accessorClass.info.decl(accessorName).suchThat(isAccessor(_, accessed)).symbol.orElse {
118-
val accessorRawInfo =
119-
if (onLHS) MethodType(accessed.info :: Nil, defn.UnitType)
120-
else accessed.info.ensureMethodic
121-
val accessorInfo =
122-
accessorRawInfo.asSeenFrom(accessorClass.thisType, accessed.owner)
123-
124-
val acc = newAccessorSymbol(accessorClass, accessorName, accessorInfo, accessed.pos)
125-
accessedBy(acc) = accessed
126-
acc
127-
}
112+
val accessorName = accessorNameKind(accessed.name)
113+
val accessorInfo =
114+
accessed.info.ensureMethodic.asSeenFrom(accessorClass.thisType, accessed.owner)
115+
val accessor = accessorSymbol(accessorClass, accessorName, accessorInfo, accessed)
128116
rewire(reference, accessor)
129117
}
130118

@@ -135,15 +123,16 @@ abstract class AccessProxies {
135123
ctx.error("Implementation restriction: cannot use private constructors in inline methods", tree.pos)
136124
tree // TODO: create a proper accessor for the private constructor
137125
}
138-
else useAccessor(tree, onLHS = false)
139-
case Assign(lhs: RefTree, rhs) if needsAccessor(lhs.symbol) =>
140-
cpy.Apply(tree)(useAccessor(lhs, onLHS = true), List(rhs))
126+
else useAccessor(tree)
141127
case _ =>
142128
tree
143129
}
144130
}
145131
}
146132
object AccessProxies {
133+
/** Where an accessor for the `accessed` symbol should be placed.
134+
* This is the closest enclosing class that has `accessed` as a member.
135+
*/
147136
def hostForAccessorOf(accessed: Symbol)(implicit ctx: Context): Symbol =
148137
ctx.owner.ownersIterator.findSymbol(_.derivesFrom(accessed.owner))
149138
}

0 commit comments

Comments
 (0)