Skip to content

Commit

Permalink
Fix macros (#14)
Browse files Browse the repository at this point in the history
* Fix macros on Scala 3

* Add extra test

* Fix

* Revert .gitignore changes

* clean-up

Co-authored-by: Krzysztof Romanowski <[email protected]>
  • Loading branch information
alexarchambault and romanowski authored Mar 23, 2022
1 parent 2fe5e2b commit 264fad7
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 27 deletions.
28 changes: 12 additions & 16 deletions dependency/src/main/scala-2/dependency/literal/LiteralMacros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,38 +39,34 @@ abstract class LiteralMacros(val c: whitebox.Context) {
helper(0)
}

private def insertExpr(str: String, idLen: Int, insert: c.Tree, indices: List[Int]): c.Tree =
private def insertExpr(str: String, indices: List[(Int, Int, c.Expr[Any])]): c.Tree =
indices match {
case Nil => q"$str"
case idx :: tail =>
case (idx, idLen, insert) :: tail =>
val (prefix, suffix) = str.splitAt(idx)
val prefixExpr = insertExpr(prefix, idLen, insert, tail)
val prefixExpr = insertExpr(prefix, tail)
q"$prefixExpr + $insert + ${suffix.substring(idLen)}"
}

protected final type Mappings = Seq[(String, c.Tree)]

protected def applyMappings(str: String, mappings: Mappings): c.Expr[String] = {
val matchOpt = mappings
val substitutions = mappings
.iterator
.zipWithIndex
.map {
.flatMap {
case ((id, expr), i) =>
val idx = str.indexOf(id)
(id, expr, i, idx)
val indices0 = indices(str, id)
indices0.map(idx => (idx, id.length, c.Expr(expr)))
}
.find(_._4 >= 0)
matchOpt match {
case None => c.Expr(q"$str")
case Some((id, expr, i, idx)) =>
val indices0 = indices(str, id)
val tree = insertExpr(str, id.length, expr, indices0.reverse)
c.Expr(tree)
}
.toList
.sortBy(-_._1)
val tree = insertExpr(str, substitutions)
c.Expr(tree)
}

def mappings(args: Seq[c.Tree]): Mappings =
args.map(arg => (UUID.randomUUID().toString.filter(_ != '-'), arg))
def input(inputs: Seq[String], mappings: Mappings): String =
(inputs.zip(mappings).flatMap { case (s, (id, _)) => Seq(s, id) } ++ inputs.drop(mappings.length)).mkString
}
}
27 changes: 16 additions & 11 deletions dependency/src/main/scala-3/dependency/literal/Mappings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,27 @@ private[literal] final case class Mappings(mappings: List[(String, QExpr[String]
helper(0)
}

private def insertExpr(str: String, idLen: Int, insert: QExpr[String], indices: List[Int])(using Quotes): QExpr[String] =
indices match {
private def insertExpr(str: String, substitutions: List[(Int, Int, QExpr[String])])(using Quotes): QExpr[String] =
substitutions match {
case Nil => QExpr(str)
case idx :: tail =>
case (idx, idLen, insert) :: tail =>
val (prefix, suffix) = str.splitAt(idx)
val prefixExpr = insertExpr(prefix, idLen, insert, tail)
val prefixExpr = insertExpr(prefix, tail)
'{$prefixExpr + $insert + ${QExpr(suffix.substring(idLen))}}
}

def Expr(str: String)(using Quotes): QExpr[String] =
mappings match {
case Nil => QExpr(str)
case (id, expr) :: tail =>
val indices0 = indices(str, id)
insertExpr(str, id.length, expr, indices0)
}
def Expr(str: String)(using Quotes): QExpr[String] = {

val substitutions = mappings
.flatMap {
case (id, expr) =>
val indices0 = indices(str, id)
indices0.map(idx => (idx, id.length, expr))
}
.sortBy(-_._1)

insertExpr(str, substitutions)
}

def stringOption(opt: Option[String])(using Quotes): QExpr[Option[String]] =
opt match {
Expand Down
23 changes: 23 additions & 0 deletions dependency/src/test/scala/dependency/LiteralTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@ class LiteralTests extends munit.FunSuite {
val expected = Dependency("org", "name", "1.2").copy(
exclude = CovariantSet(Module("fu", "ba"))
)
expect(dep == expected)
}

test("dependency interpolation") {
val org = "org.org"
val name = "name-name"
val version = "123-version"
val dep = dep"$org::$name:$version"
val expected = Dependency(org, name, version)
expect(dep.name == expected.name)
expect(dep.organization == expected.organization)
expect(dep.version == expected.version)
}

test("other dependency interpolation") {
val org = "org.org"
val name = "name"
val version = "123-version"
val dep = dep"$org::$name-$name:$version"
val expected = Dependency(org, s"$name-$name", version)
expect(dep.name == expected.name)
expect(dep.organization == expected.organization)
expect(dep.version == expected.version)
}

}

0 comments on commit 264fad7

Please sign in to comment.