[英]Scala macro annotation typecheck for implicit class fails
宏示例代码:
package macros
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
import scala.annotation.StaticAnnotation
class Ant extends StaticAnnotation {
def macroTransform(annottees: Any*): Unit = macro Ant.impl
}
object Ant {
def impl(c: Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
c.internal.enclosingOwner.asType.toType // this line is Ok
// ! Any commented line below causes the same compilation error
// c.internal.enclosingOwner.asType.toType.decls
// c.mirror.staticClass(c.internal.enclosingOwner.fullName + ".A".toString)
// c.typecheck(annottees.head)
q"""implicit class A(val v: Int) extends AnyVal { def ask() = println("ok") }"""
}
}
将whitebox.Context更改为macros.Context或blackbox.Context无济于事。 使用ImplicitViewsDisabled = true或使用MacrosDisabled = true更改参数无效。
执行样例代码:
package test
import macros.Ant
object Test extends App {
val a = new A(42)
a.ask() // Output should be "ok" (not 42)
// ! removing [implicit] lets code be compiled
@Ant implicit class A(v: Int) { def ask() = println(v)}
}
所以,除去线c.typecheck(annottees.head)和/或字线中的隐式@Ant A类 隐式 (V:智力)让代码编译。 否则编译会因错误而崩溃:
Error:scalac:
no progress in completing object Test: <?>
while compiling: D:\Projects\_Schemee\TestMacro1\src\test\Test.scala
during phase: globalPhase=typer, enteringPhase=namer
library version: version 2.11.6
compiler version: version 2.11.6
reconstructed args: -nobootcp -classpath ...
last tree to typer: Ident(v)
tree position: <unknown>
tree tpe: Int
symbol: value v
symbol definition: v: Int (a TermSymbol)
symbol package: test
symbol owners: value v -> method A -> object Test
call site: method A in object Test in package test
<Cannot read source file>
根据最新的IntelliJ编译。 有和没有Sbt。
问题是:如何在隐式类的宏注释中使用typecheck? (或者我错过了什么?)
编辑:
除此之外,尝试“手动”访问enclosingOwner声明或镜像类A时,会导致该错误。
它看起来像是sbt错误或与编译器行为的交互。
原始的例外:
java.lang.NullPointerException
at xsbt.Dependency$ExtractDependenciesByMemberRefTraverser$$anonfun$1.isDefinedAt(Dependency.scala:142)
该位置:
val typeSymbolCollector = new CollectTypeTraverser({
case tpe if !tpe.typeSymbol.isPackage => tpe.typeSymbol
})
遍历者有一条评论建议类似的问题:
/*
* Some macros appear to contain themselves as original tree.
* We must check that we don't inspect the same tree over and over.
* See https://issues.scala-lang.org/browse/SI-8486
* https://github.com/sbt/sbt/issues/1237
* https://github.com/sbt/sbt/issues/1544
*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.