Skip to content

Commit

Permalink
fix tuple type in scala3 client macro (#214)
Browse files Browse the repository at this point in the history
  • Loading branch information
cornerman authored Aug 9, 2023
1 parent 98d3782 commit 6642199
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 10 deletions.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ lazy val sloth = crossProject(JSPlatform, JVMPlatform)
Deps.cats.value ::
Deps.chameleon.value ::

Deps.zioJson.value % Test ::
Deps.circe.core.value % Test ::
Deps.circe.generic.value % Test ::
Deps.circe.parser.value % Test ::
Expand Down
2 changes: 2 additions & 0 deletions project/Deps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ object Deps {
val cats = dep("org.typelevel" %%% "cats-core" % "2.9.0")
val chameleon = dep("com.github.cornerman" %%% "chameleon" % "0.3.7")

val zioJson = dep("dev.zio" %%% "zio-json" % "0.6.0")

val circe = new {
private val version = "0.14.1"
val core = dep("io.circe" %%% "circe-core" % version)
Expand Down
32 changes: 22 additions & 10 deletions sloth/src/main/scala-3/internal/Macros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,23 @@ private def getInnerTypeOutOfReturnType[Trait: Type, Result[_]: Type](using Quot
tpe.typeArgs.indexWhere(_ =:= firstParamType)
case _ => -1
}

val methodReturnType = getMethodType[Trait](method)
parameterTypeIndex match {
case -1 => methodReturnType.typeArgs.last
case index => methodReturnType.typeArgs(index)
}
}

def createTypeTreeTuple(using Quotes)(tupleTypesList: List[quotes.reflect.TypeRepr]): quotes.reflect.TypeRepr = {
import quotes.reflect.*

tupleTypesList match {
case Nil => TypeRepr.of[EmptyTuple]
case head :: tail => TypeRepr.of[*:].appliedTo(List(head, createTypeTreeTuple(tail)))
}
}

private def checkMethodErrors[Trait: Type, Result[_]: Type](using q: Quotes)(methods: Seq[quotes.reflect.Symbol]): Unit = {
import quotes.reflect.*

Expand Down Expand Up @@ -167,11 +176,18 @@ object TraitMacro {
case arg :: Nil => arg.asExpr
case allArgs => Expr.ofTupleFromSeq(allArgs.map(_.asExpr))
}


val tupleTypesList = origMethod.paramSymss.flatten.map(_.tree.asInstanceOf[ValDef].tpt.tpe)
val tupleType = tupleTypesList match {
case Nil => TypeRepr.of[Unit]
case head :: Nil => head
case tupleTypesList => createTypeTreeTuple(tupleTypesList)
}

val returnType = getInnerTypeOutOfReturnType[Trait, Result](method)

val clientImplType = TypeRepr.of[ClientImpl[PickleType, Result]].typeSymbol
val tupleTypeTree = TypeTree.of(using tupleExpr.asTerm.tpe.asType)
val tupleTypeTree = TypeTree.of(using tupleType.asType)
val returnTypeTree = TypeTree.of(using returnType.asType)

Apply(
Expand Down Expand Up @@ -232,14 +248,10 @@ object RouterMacro {
val path = traitPathPart :: methodPathPart :: Nil

val pathExpr = Expr(path)
val tupleTypesList = method.paramSymss.flatten.map(_.tree.asInstanceOf[ValDef].tpt.tpe)

def createTypeTreeTuple(tupleTypesList: List[TypeRepr]): TypeRepr = tupleTypesList match {
case Nil => TypeRepr.of[EmptyTuple]
case head :: tail => TypeRepr.of[*:].appliedTo(List(head, createTypeTreeTuple(tail)))
}


val returnType = getInnerTypeOutOfReturnType[Trait, Result](method)

val tupleTypesList = method.paramSymss.flatten.map(_.tree.asInstanceOf[ValDef].tpt.tpe)
val tupleType = tupleTypesList match {
case Nil => TypeRepr.of[Unit]
case head :: Nil => head
Expand Down
32 changes: 32 additions & 0 deletions sloth/src/test/scala-3/Sloth3Spec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package test3

import chameleon.*
import chameleon.ext.zioJson.given
import sloth.*
import zio.json.*

import org.scalatest.freespec.AsyncFreeSpec
import org.scalatest.matchers.must.Matchers

import scala.concurrent.Future

trait Api {
def single(page: Int): Future[String]
def list(page: Int, limit: Int): Future[String]
}

class Sloth3Spec extends AsyncFreeSpec with Matchers {

"compile client" in {
val client = Client[String, Future](null)
client.wire[Api]

succeed
}

"compile router" in {
val router = Router[String, Future].route[Api](null)

succeed
}
}

0 comments on commit 6642199

Please sign in to comment.