@@ -2,6 +2,8 @@ package dotty.tools
2
2
package dotc
3
3
package inlines
4
4
5
+ import scala .collection .mutable
6
+
5
7
import dotty .tools .dotc .ast .{Trees , tpd , untpd }
6
8
import Trees ._
7
9
import core ._
@@ -22,14 +24,21 @@ import transform.SymUtils.*
22
24
import config .Printers .inlining
23
25
import util .Property
24
26
import dotty .tools .dotc .transform .TreeMapWithStages ._
27
+ import dotty .tools .dotc .ast .desugar .packageObjectName
28
+ import dotty .tools .dotc .core .StdNames .str
29
+ import dotty .tools .dotc .util .{Spans , SrcPos }
30
+ import dotty .tools .dotc .typer .TopLevelExtensionModules .newAccessorModule
25
31
26
32
object PrepareInlineable {
27
33
import tpd ._
28
34
29
35
private val InlineAccessorsKey = new Property .Key [InlineAccessors ]
36
+ private val InlineAccessorsModuleKey = new Property .Key [mutable.Map [Symbol , Symbol ]]
30
37
31
38
def initContext (ctx : Context ): Context =
32
- ctx.fresh.setProperty(InlineAccessorsKey , new InlineAccessors )
39
+ ctx.fresh
40
+ .setProperty(InlineAccessorsKey , new InlineAccessors )
41
+ .setProperty(InlineAccessorsModuleKey , mutable.Map .empty)
33
42
34
43
def makeInlineable (tree : Tree )(using Context ): Tree =
35
44
ctx.property(InlineAccessorsKey ).get.makeInlineable(tree)
@@ -39,6 +48,19 @@ object PrepareInlineable {
39
48
case Some (inlineAccessors) => inlineAccessors.addAccessorDefs(cls, body)
40
49
case _ => body
41
50
51
+ def inlineAccessorsModule (topLevelClass : Symbol )(using Context ): Symbol =
52
+ assert(topLevelClass.asClass.owner.is(Package ), topLevelClass)
53
+ ctx.property(InlineAccessorsModuleKey ).get.getOrElse(topLevelClass, NoSymbol )
54
+
55
+ def requiredInlineAccessorsModule (topLevelClass : Symbol )(using Context ): Symbol =
56
+ assert(topLevelClass.asClass.owner.is(Package ), topLevelClass)
57
+ ctx.property(InlineAccessorsModuleKey ) match
58
+ case Some (inlineAccessorsModule) =>
59
+ inlineAccessorsModule.getOrElseUpdate(
60
+ topLevelClass,
61
+ newAccessorModule(str.TOPLEVEL_INLINE_SUFFIX ))
62
+ case None => NoSymbol
63
+
42
64
class InlineAccessors extends AccessProxies {
43
65
44
66
/** If an inline accessor name wraps a unique inline name, this is taken as indication
@@ -99,20 +121,32 @@ object PrepareInlineable {
99
121
* advantage that we can re-use the receiver as is. But it is only
100
122
* possible if the receiver is essentially this or an outer this, which is indicated
101
123
* by the test that we can find a host for the accessor.
124
+ *
125
+ * @param inlineSym symbol of the inline method
126
+ * @param compat use inline accessor format of 3.0-3.2
102
127
*/
103
- class MakeInlineableDirect (inlineSym : Symbol ) extends MakeInlineableMap (inlineSym) {
128
+ class MakeInlineableDirect (inlineSym : Symbol , compat : Boolean ) extends MakeInlineableMap (inlineSym) {
104
129
def preTransform (tree : Tree )(using Context ): Tree = tree match {
105
130
case tree : RefTree if needsAccessor(tree.symbol) =>
106
131
if tree.symbol.isConstructor then
107
132
report.error(" Implementation restriction: cannot use private constructors in inline methods" , tree.srcPos)
108
133
tree // TODO: create a proper accessor for the private constructor
109
- else
134
+ else if compat then
135
+ // Generate the accessor for backwards compatibility with 3.0-3.3
110
136
val nearestHost = AccessProxies .hostForAccessorOf(tree.symbol)
111
137
val host = if nearestHost.is(Package ) then ctx.owner.topLevelClass else nearestHost
112
138
useAccessor(tree, host)
139
+ else
140
+ // Generate the accessor for 3.4+
141
+ val nearestHost = AccessProxies .hostForAccessorOf(tree.symbol)
142
+ if nearestHost.is(Package ) || (tree.symbol.owner.isStaticOwner && ! nearestHost.isStaticOwner) then
143
+ useAccessor(tree, requiredInlineAccessorsModule(ctx.owner.topLevelClass))
144
+ else
145
+ useAccessor(tree, nearestHost)
113
146
case _ =>
114
147
tree
115
148
}
149
+
116
150
override def ifNoHost (reference : RefTree )(using Context ): Tree = reference
117
151
}
118
152
@@ -228,8 +262,12 @@ object PrepareInlineable {
228
262
// so no accessors are needed for them.
229
263
tree
230
264
else
265
+ // Generate inline accessors for 3.0-3.3
266
+ new MakeInlineablePassing (inlineSym).transform(
267
+ new MakeInlineableDirect (inlineSym, compat = true ).transform(tree))
268
+ // Generate and use inline accessors for 3.4+
231
269
new MakeInlineablePassing (inlineSym).transform(
232
- new MakeInlineableDirect (inlineSym).transform(tree))
270
+ new MakeInlineableDirect (inlineSym, compat = false ).transform(tree))
233
271
}
234
272
}
235
273
0 commit comments