Skip to content

Commit 9bd5ed2

Browse files
authored
Merge pull request #181 from softwaremill/fix-i159
Extract focuses from nested `Inlined` trees when determining modification path in Scala 3 macro
2 parents fcf1f7c + 9169d90 commit 9bd5ed2

File tree

2 files changed

+38
-11
lines changed

2 files changed

+38
-11
lines changed

quicklens/src/main/scala-3/com/softwaremill/quicklens/QuicklensMacros.scala

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -326,19 +326,24 @@ object QuicklensMacros {
326326
accumulateToCopy(owner, mod, objTerm, children)
327327
}
328328

329-
val focusesTrees: Seq[Tree] = focuses.map(_.asTerm)
330-
val paths: Seq[Seq[PathSymbol]] = focusesTrees.zip(focuses).map { (tree, focus) =>
331-
tree match
332-
/** Single inlined path */
333-
case Inlined(_, _, Block(List(DefDef(_, _, _, Some(p))), _)) =>
334-
toPath(p, focus)
335-
/** One of paths from modifyAll */
336-
case Block(List(DefDef(_, _, _, Some(p))), _) =>
337-
toPath(p, focus)
338-
case _ =>
339-
report.errorAndAbort(unsupportedShapeInfo(tree))
329+
def extractFocus(tree: Tree): Tree = tree match {
330+
/** Single inlined path */
331+
case Inlined(_, _, p) =>
332+
extractFocus(p)
333+
/** One of paths from modifyAll */
334+
case Block(List(DefDef(_, _, _, Some(p))), _) =>
335+
p
336+
case _ =>
337+
println(tree)
338+
report.errorAndAbort(unsupportedShapeInfo(tree))
340339
}
341340

341+
val focusesTrees: Seq[Tree] = focuses.map(_.asTerm)
342+
val paths: Seq[Seq[PathSymbol]] =
343+
focusesTrees.zip(focuses).map { (tree, focus) =>
344+
toPath(extractFocus(tree), focus)
345+
}
346+
342347
val pathTree: PathTree =
343348
paths.foldLeft(PathTree.empty) { (tree, path) => tree <> path }
344349

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.softwaremill.quicklens.test
2+
3+
import org.scalatest.flatspec.AnyFlatSpec
4+
import org.scalatest.matchers.should.Matchers
5+
import com.softwaremill.quicklens.*
6+
7+
class CustomModifyProxyTest extends AnyFlatSpec with Matchers {
8+
9+
it should "correctly modify a class using a custom modify proxy method" in {
10+
case class State(foo: Int)
11+
12+
inline def set[A](state: State, inline path: State => A, value: A): State = {
13+
modify(state)(path).setTo(value)
14+
}
15+
16+
val state = State(100)
17+
val res = set(state, _.foo, 200)
18+
val expected = State(200)
19+
res.shouldBe(expected)
20+
}
21+
22+
}

0 commit comments

Comments
 (0)