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

dependency.literal.ModuleLiteralMacros.scala Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
package dependency
package literal

import dependency.parser.ModuleParser

import scala.reflect.macros.whitebox

// inspired from https://github.com/coursier/interface/blob/0bac6a4c93dfafeb79bd924a2f4bcb690ba4510a/interpolators/src/main/scala/coursierapi/Interpolators.scala

class ModuleLiteralMacros(override val c: whitebox.Context) extends LiteralMacros(c) {

  import c.universe._

  private def booleanOptExpr(value: Option[Boolean]): c.Tree =
    value match {
      case None        => q"_root_.scala.None"
      case Some(false) => q"_root_.scala.Some(false)"
      case Some(true)  => q"_root_.scala.Some(true)"
    }

  protected def nameAttributesExpr(nameAttributes: NameAttributes): (Tree, Tree) = {
    val (tpe, expr) = nameAttributes match {
      case NoAttributes =>
        (tq"_root_.dependency.NoAttributes.type", q"_root_.dependency.NoAttributes")
      case ScalaNameAttributes(fullCrossVersion, platform) =>
        val tpe0 = tq"_root_.dependency.ScalaNameAttributes"
        val expr0 = q"_root_.dependency.ScalaNameAttributes(${booleanOptExpr(fullCrossVersion)}, ${booleanOptExpr(platform)})"
        (tpe0, expr0)
    }
    (tpe, expr)
  }

  private def stringStringMap(map: Map[String, String], mappings: Mappings): c.Tree = {
    val entries = map.toVector.sorted.map { case (k, v) => q"_root_.scala.Tuple2(${applyMappings(k, mappings)}, ${applyMappings(v, mappings)})" }
    q"_root_.scala.collection.immutable.Map[_root_.java.lang.String, _root_.java.lang.String](..$entries)"
  }

  protected def moduleExpr(mod: AnyModule, mappings: Mappings): (Tree, c.Tree) = {
    val (nameAttrTpe, nameAttr) = nameAttributesExpr(mod.nameAttributes)
    val attr = stringStringMap(mod.attributes, mappings)
    val expr = q"""
      _root_.dependency.ModuleLike[$nameAttrTpe](
        ${applyMappings(mod.organization, mappings)},
        ${applyMappings(mod.name, mappings)},
        $nameAttr,
        $attr
      )
    """
    (nameAttrTpe, expr)
  }

  def module(args: c.Tree*): c.Tree = {
    val inputs = unsafeGetPrefixStrings()
    val mappings0 = mappings(args)
    val input0 = input(inputs, mappings0)
    ModuleParser.parse(input0) match {
      case Left(msg) => c.abort(c.enclosingPosition, msg)
      case Right(mod) =>
        val (_, expr) = moduleExpr(mod, mappings0)
        expr
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy