Skip to content

Commit 5213d92

Browse files
author
Oron Port
committed
Workaround scala/scala3#23650 to handle annotation and named argument transformations to fix context generation
1 parent bf3d539 commit 5213d92

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

plugin/src/main/scala/plugin/MetaContextGenPhase.scala

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class MetaContextGenPhase(setting: Setting) extends CommonPhase:
4040
extension (tree: ValOrDefDef)(using Context)
4141
def needsNewContext: Boolean =
4242
tree match
43-
case _: ValDef => true // valdefs always generate new context
43+
case _: ValDef => true // valdefs always generate new context
4444
case dd: DefDef =>
4545
val sym = tree.symbol
4646
// defdefs generate new context if they are not inline
@@ -71,7 +71,9 @@ class MetaContextGenPhase(setting: Setting) extends CommonPhase:
7171
val nameOptTree = mkOptionString(nameOpt)
7272
val positionTree = srcPos.positionTree
7373
val docOptTree = mkOptionString(docOpt)
74-
val annotTree = mkList(annotations.map(_.tree))
74+
// the compiler does not transform the annotations, so we need to do it here.
75+
// See: https://github.com/scala/scala3/issues/23650
76+
val annotTree = mkList(annotations.map(a => transformAllDeep(a.tree)))
7577
tree
7678
.select(setMetaSym)
7779
.appliedToArgs(
@@ -112,7 +114,7 @@ class MetaContextGenPhase(setting: Setting) extends CommonPhase:
112114
t match
113115
case vd: ValDef if vd.isEmpty || ignoreValDef(vd) => (None, None, Nil)
114116
case dd: DefDef => (None, None, Nil)
115-
case _ =>
117+
case _ =>
116118
(
117119
Some(t.name.toString.nameCheck(t)),
118120
t.symbol.docString,
@@ -134,20 +136,32 @@ class MetaContextGenPhase(setting: Setting) extends CommonPhase:
134136
end match
135137
end getMetaInfo
136138

139+
// The tranformation skips over the named arguments, so we need to transform them here.
140+
// See: https://github.com/scala/scala3/issues/23650
141+
def fixApply(tree: Apply)(using Context): Apply =
142+
val updatedArgs = tree.args.map {
143+
case namedArg @ NamedArg(name, arg) =>
144+
cpy.NamedArg(namedArg)(name = name, arg = transformAllDeep(arg))
145+
case a => a
146+
}
147+
cpy.Apply(tree)(fun = tree.fun, args = updatedArgs)
148+
end fixApply
149+
137150
override def transformApply(tree: Apply)(using Context): Tree =
151+
val fixedApply = fixApply(tree)
138152
val origApply = applyStack.head
139153
applyStack = applyStack.drop(1)
140154
if (
141-
tree.tpe.isParameterless && !tree.fun.symbol.ignoreMetaContext && !tree.fun.symbol.forwardMetaContext
155+
fixedApply.tpe.isParameterless && !fixedApply.fun.symbol.ignoreMetaContext && !fixedApply.fun.symbol.forwardMetaContext
142156
)
143-
tree match
157+
fixedApply match
144158
// found a context argument
145159
case ContextArg(argTree) =>
146160
treeOwnerApplyMap.get(origApply) match
147161
case Some(ownerTree, srcPos) =>
148162
getMetaInfo(ownerTree, srcPos) match
149163
case Some(metaInfo) =>
150-
tree.replaceArg(argTree, argTree.setMeta(metaInfo))
164+
fixedApply.replaceArg(argTree, argTree.setMeta(metaInfo))
151165
case None =>
152166
val sym = argTree.symbol
153167
contextDefs.get(sym.fixedFullName) match
@@ -158,17 +172,18 @@ class MetaContextGenPhase(setting: Setting) extends CommonPhase:
158172
)
159173
case _ =>
160174
// do nothing
161-
tree
175+
fixedApply
162176
// No owner tree found, so it's anonymous. Yet we may want to apply no new context
163177
// at all and just keep the propagated context.
164178
case None =>
165179
// keeping the propagated context
166-
if (tree.fun.symbol.name.toString.contains("$")) tree
180+
if (fixedApply.fun.symbol.name.toString.contains("$")) fixedApply
167181
// generating a new anonymous context
168-
else tree.replaceArg(argTree, argTree.setMeta(None, origApply.srcPos, None, Nil))
182+
else
183+
fixedApply.replaceArg(argTree, argTree.setMeta(None, origApply.srcPos, None, Nil))
169184
end match
170-
case _ => tree
171-
else tree
185+
case _ => fixedApply
186+
else fixedApply
172187
end transformApply
173188

174189
override def prepareForBlock(tree: Block)(using Context): Context =

0 commit comments

Comments
 (0)