使用 Scala3 宏构建动态表达式
Building Dynamic Expressions with Scala3 macro
在Scala2的宏中,可以使用Context.parse等动态构造表达式。
def generateExpr[T: c.WeakTypeTag](target: C#Symbol): C#Expr[T] = {
if (target.isModule) {
c.Expr[T](c.parse(target.fullName))
} else {
c.Expr[T] {
c.parse(
s"""new ${target.fullName}(${
val a = target.asClass.primaryConstructor.asMethod
val b = a.paramLists
target.asClass.primaryConstructor.asMethod.paramLists
.collect {
case curry if !curry.exists(_.isImplicit) =>
curry.map { param => s"inject[${param.typeSignature.toString}]" }.mkString(",")
}
.mkString(")(")
}) with MixIn"""
)
}
}
}
即使预组合语法字面值引用了一个不在当前类路径中的符号,如果能在调用宏的模块中解析,编译也会成功。
然而,在发布的Scala3中没有这个功能。
我的目标是使用
- 使用宏引用不在模块类路径中的符号。
- 我想使用
new $T(???) with Trait
从类型信息。
这些不再可行了吗?
=====
https://github.com/lampepfl/dotty/discussions/12590
本期提到,对Trees部署变长参数也是未知数。这些将与动态 AST 构造相关。
Those are use cases that we explicitly did not want to support since they cause language fragmentation, with many possible dialects supported by macros. I am sure there are good use cases
for this, but overall I believe allowing this would be detrimental to the language ecosystem as a whole.
在Scala2的宏中,可以使用Context.parse等动态构造表达式。
def generateExpr[T: c.WeakTypeTag](target: C#Symbol): C#Expr[T] = {
if (target.isModule) {
c.Expr[T](c.parse(target.fullName))
} else {
c.Expr[T] {
c.parse(
s"""new ${target.fullName}(${
val a = target.asClass.primaryConstructor.asMethod
val b = a.paramLists
target.asClass.primaryConstructor.asMethod.paramLists
.collect {
case curry if !curry.exists(_.isImplicit) =>
curry.map { param => s"inject[${param.typeSignature.toString}]" }.mkString(",")
}
.mkString(")(")
}) with MixIn"""
)
}
}
}
即使预组合语法字面值引用了一个不在当前类路径中的符号,如果能在调用宏的模块中解析,编译也会成功。
然而,在发布的Scala3中没有这个功能。
我的目标是使用
- 使用宏引用不在模块类路径中的符号。
- 我想使用
new $T(???) with Trait
从类型信息。
这些不再可行了吗?
=====
https://github.com/lampepfl/dotty/discussions/12590
本期提到,对Trees部署变长参数也是未知数。这些将与动态 AST 构造相关。
Those are use cases that we explicitly did not want to support since they cause language fragmentation, with many possible dialects supported by macros. I am sure there are good use cases for this, but overall I believe allowing this would be detrimental to the language ecosystem as a whole.