Skip to content

Commit

Permalink
Add support for binding methods with an implicit parameter list.
Browse files Browse the repository at this point in the history
  • Loading branch information
christian-schlichtherle committed Aug 11, 2021
1 parent 581cc1f commit b72830c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 13 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ lazy val scala: Project = project
.settings(
libraryDependencies ++= Seq(
Dependency.ScalaTest % Test,
"global.namespace.bali" % "bali-annotation" % "0.11.2",
"global.namespace.bali" % "bali-annotation" % "0.11.3",
) ++ {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, _)) => Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,24 @@ package bali.scala.sample.param

import bali.{Lookup, Module}

final case class Extension(name: String)

trait Param {

@Lookup("concat")
def appendZero(s: String): String

/*
@Lookup("concat")
def prependQuestionMark(n: Int): Int
*/
def pathName(dirName: String)(baseName: String)(implicit extension: Extension): String
}

@Module
trait ParamModule {

def concat(s: String = "?", n: Int = 0): String = s + n

def pathName(dirName: String)(baseName: String)(implicit extension: Extension): String = {
dirName + '/' + baseName + '.' + extension.name
}

val param: Param
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ class ParamModuleSpec extends AnyWordSpec {
val param = make[ParamModule].param
import param._

"work" in {
"support binding methods with parameters" in {
appendZero("A") shouldBe "A0"
// prependQuestionMark(1) shouldBe "?1"
}

"support binding methods with multiple parameter lists, including an implicit parameter list" in {
implicit val txt: Extension = Extension("TXT")
pathName(".")("README") shouldBe "./README.TXT"
}
}
}
17 changes: 11 additions & 6 deletions scala/src/main/scala-2/bali/scala/Make.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,21 @@ private final class Make(val c: blackbox.Context) extends MakeCompat {
abort(s"${ref.symbol}$withType${ref.tpe} in ${ref.symbol.owner} is not applicable to bind $memberSignature.")
}

def bindAs(rightHandSide: Tree) = {
def bindAs(rhs: Tree) = {
if (member.isStable) {
q"final override lazy val $memberName: $returnType = $rightHandSide"
q"final override lazy val $memberName: $returnType = $rhs"
} else {
q"final override def $memberName[..$typeParams4Lhs](...$paramLists4Lhs): $returnType = $rightHandSide"
q"final override def $memberName[..$typeParams4Lhs](...$explParamLists4Lhs)(implicit ..$implParams4Lhs): $returnType = $rhs"
}
}

def bindDependency(ref: Tree) = bindAs(rightHandSide(ref))

lazy val (explParamLists4Lhs, implParams4Lhs) = {
val (i, e) = paramLists.partition(_.exists(_.isImplicit))
paramLists4Lhs(e) -> paramLists4Lhs(i).flatten
}

lazy val fieldAlias = lookupAnnotationMap.get("field")

lazy val fieldAliasAndConstraint = fieldAlias.map(_ -> fieldConstraint)
Expand All @@ -65,7 +70,7 @@ private final class Make(val c: blackbox.Context) extends MakeCompat {

lazy val makeDependency = bindAs(q"_root_.bali.scala.make[$returnType]")

// If omitted, member annotations may get skipped, e.g. @Lookup, resulting in code generation errors:
// If skipped, member annotations may be missing, e.g. @Lookup, resulting in code generation errors:
lazy val member = internal.initialize(m)

lazy val memberName: TermName = member.name
Expand Down Expand Up @@ -94,7 +99,7 @@ private final class Make(val c: blackbox.Context) extends MakeCompat {

lazy val paramLists = memberType.paramLists

lazy val paramLists4Lhs = paramLists.map(_.map(s => q"${s.name.toTermName}: ${s.info}"))
def paramLists4Lhs(l: List[List[Symbol]]) = l.map(_.map(s => q"${s.name.toTermName}: ${s.info}"))

lazy val paramLists4Rhs = paramLists.map(_.map(_.name.toTermName))

Expand All @@ -110,7 +115,7 @@ private final class Make(val c: blackbox.Context) extends MakeCompat {
def typecheckAndExtract(ref: TermName) = {
val freshName = c.freshName(memberName)
val rhs = rightHandSide(q"$ref")
typecheck(q"def $freshName[..$typeParams4Lhs](...$paramLists4Lhs): $returnType = $rhs")
typecheck(q"def $freshName[..$typeParams4Lhs](...$explParamLists4Lhs)(implicit ..$implParams4Lhs): $returnType = $rhs")
.flatMap {
case q"def $_[..$_](...$_): $_ = ${ref: Tree}[..$_](...$_)" => Some(ref)
case _ => None
Expand Down

0 comments on commit b72830c

Please sign in to comment.