@@ -93,6 +93,24 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
93
93
}
94
94
}
95
95
96
+ private var dynamicImportEnclosingClasses : Set [Symbol ] = Set .empty
97
+
98
+ private def enterDynamicImportEnclosingClass [A ](cls : Symbol )(body : => A ): A = {
99
+ val saved = dynamicImportEnclosingClasses
100
+ dynamicImportEnclosingClasses = saved + cls
101
+ try
102
+ body
103
+ finally
104
+ dynamicImportEnclosingClasses = saved
105
+ }
106
+
107
+ private def hasImplicitThisPrefixToDynamicImportEnclosingClass (tpe : Type )(using Context ): Boolean =
108
+ tpe match
109
+ case tpe : ThisType => dynamicImportEnclosingClasses.contains(tpe.cls)
110
+ case TermRef (prefix, _) => hasImplicitThisPrefixToDynamicImportEnclosingClass(prefix)
111
+ case _ => false
112
+ end hasImplicitThisPrefixToDynamicImportEnclosingClass
113
+
96
114
/** DefDefs in class templates that export methods to JavaScript */
97
115
private val exporters = mutable.Map .empty[Symbol , mutable.ListBuffer [Tree ]]
98
116
@@ -297,10 +315,15 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
297
315
298
316
assert(currentOwner.isTerm, s " unexpected owner: $currentOwner at ${tree.sourcePos}" )
299
317
318
+ val enclosingClass = currentOwner.enclosingClass
319
+
300
320
// new DynamicImportThunk { def apply(): Any = body }
301
321
val dynamicImportThunkAnonClass = AnonClass (currentOwner, List (jsdefn.DynamicImportThunkType ), span) { cls =>
302
322
val applySym = newSymbol(cls, nme.apply, Method , MethodType (Nil , Nil , defn.AnyType ), coord = span).entered
303
- val newBody = transform(body).changeOwnerAfter(currentOwner, applySym, thisPhase)
323
+ val transformedBody = enterDynamicImportEnclosingClass(enclosingClass) {
324
+ transform(body)
325
+ }
326
+ val newBody = transformedBody.changeOwnerAfter(currentOwner, applySym, thisPhase)
304
327
val applyDefDef = DefDef (applySym, newBody)
305
328
List (applyDefDef)
306
329
}
@@ -310,6 +333,14 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
310
333
.appliedToTypeTree(tpeArg)
311
334
.appliedTo(dynamicImportThunkAnonClass)
312
335
336
+ // #17344 Make `ThisType`-based references to enclosing classes of `js.dynamicImport` explicit
337
+ case tree : Ident if hasImplicitThisPrefixToDynamicImportEnclosingClass(tree.tpe) =>
338
+ def rec (tpe : Type ): Tree = (tpe : @ unchecked) match // exhaustive because of the `if ... =>`
339
+ case tpe : ThisType => This (tpe.cls)
340
+ case tpe @ TermRef (prefix, _) => rec(prefix).select(tpe.symbol)
341
+
342
+ rec(tree.tpe).withSpan(tree.span)
343
+
313
344
// Compile-time errors and warnings for js.Dynamic.literal
314
345
case Apply (Apply (fun, nameArgs), args)
315
346
if fun.symbol == jsdefn.JSDynamicLiteral_applyDynamic ||
0 commit comments