All Downloads are FREE. Search and download functionalities are using the official Maven repository.

coursierapi.Interpolators.scala Maven / Gradle / Ivy

package coursierapi

import scala.collection.JavaConverters._
import scala.language.experimental.macros
import scala.reflect.macros.blackbox

object Interpolators {

  final class Macros(val c: blackbox.Context) {
    import c.universe._

    private def unsafeGetPrefixString: String = {
      c.prefix.tree match {
        case Apply(_, List(Apply(_, Literal(Constant(string: String)) :: Nil))) => string
        case _  => c.abort(c.enclosingPosition, "Only a single String literal is allowed here")
      }
    }

    private def scalaVersion = ScalaVersion.of(scala.util.Properties.versionNumberString)

    private def toModuleExpr(mod: Module): Expr[Module] = {
      val attrs = mod.getAttributes.asScala.toSeq.map { case (k, v) => q"_root_.scala.Tuple2($k, $v)" }
      c.Expr(q"""
        _root_.coursierapi.Module.of(
          ${mod.getOrganization},
          ${mod.getName},
          _root_.scala.collection.JavaConverters.mapAsJavaMapConverter(_root_.scala.collection.immutable.Map(..$attrs)).asJava
        )
      """)
    }

    def safeModule(args: Expr[Any]*): Expr[Module] = {
      val modString = unsafeGetPrefixString
      val mod = Module.parse(modString, scalaVersion)
      toModuleExpr(mod)
    }

    def safeDependency(args: Expr[Any]*): Expr[Dependency] = {
      val depString = unsafeGetPrefixString
      val dep = Dependency.parse(depString, scalaVersion)
      c.Expr(q"_root_.coursierapi.Dependency.of(${toModuleExpr(dep.getModule)}, ${dep.getVersion})")
    }

    def safeMavenRepository(args: Expr[Any]*): Expr[MavenRepository] = {
      val root = unsafeGetPrefixString
      // FIXME Check that there's no query string, fragment, … in uri?
      val uri = new java.net.URI(root)
      c.Expr(q"""_root_.coursierapi.MavenRepository.of($root)""")
    }

    def safeIvyRepository(args: Expr[Any]*): Expr[IvyRepository] = {
      val str = unsafeGetPrefixString
      // FIXME Check that there's no query string, fragment, … in uri?
      val r = IvyRepository.of(str)
      // Here, ideally, we should lift r as an Expr, but this is quite cumbersome to do (it involves lifting
      // Seq[coursier.ivy.Pattern.Chunk], where coursier.ivy.Pattern.Chunk is an ADT, …
      c.Expr(q"""_root_.coursierapi.IvyRepository.of($str)""")
    }
  }

  implicit class moduleString(val sc: StringContext) extends AnyVal {
    def mod(args: Any*): Module = macro Macros.safeModule
  }

  implicit class dependencyString(val sc: StringContext) extends AnyVal {
    def dep(args: Any*): Dependency = macro Macros.safeDependency
  }

  implicit class mavenRepositoryString(val sc: StringContext) extends AnyVal {
    def mvn(args: Any*): MavenRepository = macro Macros.safeMavenRepository
  }

  implicit class ivyRepositoryString(val sc: StringContext) extends AnyVal {
    def ivy(args: Any*): IvyRepository = macro Macros.safeIvyRepository
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy