@@ -13,6 +13,7 @@ import TypeUtils._
13
13
import Types ._
14
14
import util .Spans .Span
15
15
import config .Printers .transforms
16
+ import dotty .tools .dotc .util .SrcPos
16
17
17
18
/** A utility class for generating access proxies. Currently used for
18
19
* inline accessors and protected accessors.
@@ -66,8 +67,8 @@ abstract class AccessProxies {
66
67
trait Insert {
67
68
import ast .tpd ._
68
69
69
- /** The name of the accessor for definition with given `name ` in given `site` */
70
- def accessorNameOf (name : TermName , site : Symbol )(using Context ): TermName
70
+ /** The name of the accessor for definition with given accessed `sym ` in given `site` */
71
+ def accessorNameOf (sym : Symbol , site : Symbol )(using Context ): TermName
71
72
def needsAccessor (sym : Symbol )(using Context ): Boolean
72
73
73
74
def ifNoHost (reference : RefTree )(using Context ): Tree = {
@@ -130,13 +131,10 @@ abstract class AccessProxies {
130
131
* @param reference The original reference to the non-public symbol
131
132
* @param onLHS The reference is on the left-hand side of an assignment
132
133
*/
133
- def useAccessor (reference : RefTree )(using Context ): Tree = {
134
+ def useAccessor (reference : RefTree , accessorClass : Symbol )(using Context ): Tree = {
134
135
val accessed = reference.symbol.asTerm
135
- var accessorClass = hostForAccessorOf(accessed : Symbol )
136
136
if (accessorClass.exists) {
137
- if accessorClass.is(Package ) then
138
- accessorClass = ctx.owner.topLevelClass
139
- val accessorName = accessorNameOf(accessed.name, accessorClass)
137
+ val accessorName = accessorNameOf(accessed, accessorClass)
140
138
val accessorInfo =
141
139
accessed.info.ensureMethodic.asSeenFrom(accessorClass.thisType, accessed.owner)
142
140
val accessor = accessorSymbol(accessorClass, accessorName, accessorInfo, accessed)
@@ -152,7 +150,7 @@ abstract class AccessProxies {
152
150
report.error(" Implementation restriction: cannot use private constructors in inlineable methods" , tree.srcPos)
153
151
tree // TODO: create a proper accessor for the private constructor
154
152
}
155
- else useAccessor(tree)
153
+ else useAccessor(tree, hostForAccessorOf(tree.symbol) )
156
154
case _ =>
157
155
tree
158
156
}
@@ -171,4 +169,22 @@ object AccessProxies {
171
169
else recur(cls.owner)
172
170
recur(ctx.owner)
173
171
}
172
+
173
+ /** Where an accessor for the `accessed` symbol should be placed.
174
+ * This is the furthest static enclosing class that has `accessed` as a member.
175
+ */
176
+ def staticHostForAccessorOf (accessed : Symbol , srcPos : SrcPos )(using Context ): Symbol = {
177
+ val outerAccessibleClass =
178
+ if accessed.privateWithin.maybeOwner.exists && ! accessed.privateWithin.maybeOwner.isTopLevelClass then
179
+ accessed.privateWithin
180
+ else ctx.owner.topLevelClass
181
+ if outerAccessibleClass.is(Module ) then
182
+ outerAccessibleClass
183
+ else if outerAccessibleClass.companionClass.exists then
184
+ outerAccessibleClass.companionClass
185
+ else
186
+ // Should we generate a static owner? Generate companion class of the current top level class.
187
+ report.error(em " Cannot create inline accessor for $accessed. \n\n This can be fixed by creating a companion object for ${outerAccessibleClass}" , srcPos)
188
+ NoSymbol
189
+ }
174
190
}
0 commit comments