标签: scala-macros

如何获取传递给 Scala 宏的参数的运行时值?

我有一个表面上很简单的宏观问题,我已经用头撞了几个小时,但没有运气。也许有更多经验的人可以提供帮助。

我有以下宏:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object MacroObject {
  def run(s: String): Unit =
    macro runImpl

  def runImpl(c: Context)(s: c.Tree): c.Tree = {
    import c.universe._
    println(s)    // <-- I need the macro to know the value of s at compile time
    q"()"
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是:我希望宏知道s传递给它的值——不是 AST s,而是s它本身的值。具体来说,我希望它具有这种行为:

def runTheMacro(str: String): Unit = MacroObject.run(str)

final val HardCodedString1 = "Hello, world!"
runTheMacro(HardCodedString1)    // the macro should print "Hello, world!"
                                 // to the console during macro expansion …
Run Code Online (Sandbox Code Playgroud)

macros scala scala-macros scala-quasiquotes scala-reflect

6
推荐指数
1
解决办法
528
查看次数

如何使用宏在 Dotty 中生成一个类?

是否可以在 Dotty, Scala 3 中生成一个带有宏的新类?

兹拉亚

annotations scala metaprogramming dotty scala-macros

6
推荐指数
2
解决办法
729
查看次数

如何在 Scala 3 宏中创建泛型类型的实例?

我正在将宏从 Scala 2 移植到 Scala 3。作为其工作的一部分,Scala 2 宏使用默认构造函数创建泛型类型的实例。在 Scala 2 中使用准引用很容易做到这一点,但我在 Scala 3 宏上遇到了困难。这是迄今为止我最好的方法:

import scala.quoted.*

inline def make[A <: AnyRef]: A = ${ makeThat[A] }

private def makeThat[A <: AnyRef : Type](using Quotes): Expr[A] =
  import quotes.reflect.*

  '{ new A().asInstanceOf[A] }
Run Code Online (Sandbox Code Playgroud)

如果没有.asInstanceOf[A],编译器会发出错误消息:

[error] -- [E007] Type Mismatch Error: ...
[error] 17 |  '{ new A() }
[error]    |     ^^^^^^^
[error]    |Found:    Object
[error]    |Required: A
[error]    |
[error]    |where:    A is a type in method makeThat with …
Run Code Online (Sandbox Code Playgroud)

scala metaprogramming scala-macros scala-3

6
推荐指数
1
解决办法
501
查看次数

Scala 3 宏中的显式类型转换

我在 Scala 3 中定义了以下特征:

\n
trait A[T <: Tuple]\n
Run Code Online (Sandbox Code Playgroud)\n

然后,我使用 Scala 3 宏创建具有此特征的对象,对元组的实际类型执行进一步检查T;特别是,我想检查元组的所有类型(T_1,\xe2\x80\xa6,T_nT是否是另一个给定类型的子类型B

\n
trait B\nprivate def allSubtypesOfB[T <: Tuple: Type](using quotes: Quotes): Boolean = {\n    import quotes.reflect.*\n    case '[Nothing] => false // I don't want nothing to be in T\n    case '[head *: tail] if TypeRepr.of[head] <:< TypeRepr.of[B] => allSubtypesOfB[tail]\n    case '[EmptyTuple] => true\n    case _ => false\n}\n\ninline def createA[T <: Tuple] = ${ createAImpl[T] }\nprivate def createAImpl[T …
Run Code Online (Sandbox Code Playgroud)

generics scala tuples scala-macros scala-3

6
推荐指数
1
解决办法
338
查看次数

如何使用Scala-Macros获取构造函数参数名称

有没有办法使用scala-macros获取给定构造函数的参数名称?

谢谢

reflection macros constructor scala scala-macros

5
推荐指数
1
解决办法
2496
查看次数

在中缀位置的Scala无类型宏

在回答这个问题时,我一直在使用宏天堂分支在Scala中实现Haskell风格的"where"表达式.代码可在scala-where处获得.我现在可以写下面的内容:

val result = where ( f1(1) * f2(2), {
  def f1(x : Int) = x + 1
  def f2(x : Int) = x + 2
})
Run Code Online (Sandbox Code Playgroud)

但是,我真正想做的是能够在中缀位置调用它:

val result = ( f1(1) * f2(2)) where {
  def f1(x : Int) = x + 1
  def f2(x : Int) = x + 2
}
Run Code Online (Sandbox Code Playgroud)

通常情况下,这种事情很容易,但我看不到如何使用宏调用.表达式(f1(1)*f2(2))将不会在宏应用程序之前键入,因此构建隐式值类的操作不起作用.有没有办法获得这种语法呢?

如果做不到这一点,只需要两个参数列表即可:

val result = where (f1(1) * f2(2)) {
  def f1(x : Int) = x + 1
  def f2(x : Int) …
Run Code Online (Sandbox Code Playgroud)

macros scala scala-macros

5
推荐指数
1
解决办法
224
查看次数

是否可以访问宏中的符号表?

例如,要获取宏的呼叫站点上的所有值及其类型?或者至少只是当前班级的价值?例如:

class A {
  val v1 = 10
  var v2 = "2"

  def m {
    val m3 = true

    // Here I would like to get information that v1: Int, v2: String and
    // v3: Boolean are available
    macroInvocation() 
  }
}
Run Code Online (Sandbox Code Playgroud)

我查看了Context和Universe,但找不到好的方法.

到目前为止我找到的唯一解决方案是获取宏的封闭类/方法(通过Context),并搜索树.

macros scala scala-2.10 scala-macros

5
推荐指数
1
解决办法
787
查看次数

是否可以在scala宏中生成WeakTypeTag中的Apply?

我的WeakTypeTag宏中有一些类型,我想生成如下代码:

macroCreate[SomeObject] // => SomeObject(1)
Run Code Online (Sandbox Code Playgroud)

宏的定义将是这样的:

def macroCreate[A] = macro _macroCreate[A]
def _macroCreate[A](c: Context)(implicit wtt: c.WeakTypeTag[A]) = {
  c.Expr(Apply(Select(???, newTermName("apply")), List(c.literal(1).tree)))
}
Run Code Online (Sandbox Code Playgroud)

问题是,我如何得到Select给定的类型?

我可以使用一种解决方法,将类型转换为字符串,拆分"."然后创建一个Select字符串列表,但这看起来很糟糕.

是否可以Select直接从类型标签创建?

macros scala scala-2.10 scala-macros

5
推荐指数
1
解决办法
686
查看次数

列出所有可见的含义

如果可能的话,如何使用反射和宏列出所有可见的含义?我需要这个能够分析可用的类型类实例.

用例

case class Artist (name: String, genres: Set[Genre])
case class Genre (name: String)

object CatalogueDB extends MySQL {
  implicit val artistEntity = new Entity[Artist] {...}
  implicit val genreEntity = new Entity[Genre] {...}
}

trait MySQL {
  // Typeclasses let me restrict methods on `MySQL` to work only for types, 
  // which are associated with its instance.
  // E.g., the following method will only compile when either an `Artist` or
  // a `Genre` is passed to it when called on …
Run Code Online (Sandbox Code Playgroud)

reflection scala scala-macros

5
推荐指数
1
解决办法
118
查看次数

SBT插件:如何添加编译器插件作为未传播到下游的依赖项?

我正在写一个SBT插件.我想使用Circe JSON库,但它需要Scala 2.10上的Macro Paradise编译器插件.

通常,您将编译器插件添加到build.sbtSBT插件project/plugins.sbt.

现在,当您构建SBT插件时,其他插件将成为依赖项,因此您将它们放入并将build.sbt它们传播到您使用SBT插件的项目.

当我将以下片段放入build.sbt我的SBT插件时:

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
Run Code Online (Sandbox Code Playgroud)

Paradise编译器插件是否会传播到下游项目?

scala sbt scala-macros scala-macro-paradise sbt-plugin

5
推荐指数
1
解决办法
1130
查看次数