Scala宏找不到伴生对象中声明的类型

Scala宏找不到伴生对象中声明的类型,scala,scala-macros,Scala,Scala Macros,在Scala宏(2.11 | 2.12)中,我没有找到一种方法来支持在伴随对象中声明的类型(case类或case对象) 通过以下类型的示例 sealed trait Foo object Foo { case class Bar(lorem: String) extends Foo case object Ipsum extends Foo } 。。。使用声明为bellow的宏 import language.experimental.macros import scala.refl

在Scala宏(2.11 | 2.12)中,我没有找到一种方法来支持在伴随对象中声明的类型(case类或case对象)

通过以下类型的示例

sealed trait Foo

object Foo {
  case class Bar(lorem: String) extends Foo
  case object Ipsum extends Foo
}
。。。使用声明为bellow的宏

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

def testImpl[A: c.WeakTypeTag](c: Context): c.Expr[Unit] = {
  import c.universe._

  val tpe = c.weakTypeOf[A]

  c.typecheck(q"""$tpe.unapply(Foo.Bar("lorem"))""")

  reify({})
}

def test[A] = macro testImpl[A]
,当使用
test[Foo.Bar]
为类型
Foo.Bar
调用它时,会引发编译错误:

error: exception during macro expansion:
scala.reflect.macros.TypecheckException: value unapply is not a member of Foo.Bar
    at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$3(Typers.scala:32)
    at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$2(Typers.scala:26)
    at scala.reflect.macros.contexts.Typers.doTypecheck$1(Typers.scala:25)
    at scala.reflect.macros.contexts.Typers.$anonfun$typecheck$7(Typers.scala:38)
    at scala.reflect.macros.contexts.Typers$$Lambda$676/541572263.apply(Unknown Source)
    at scala.reflect.internal.Trees.wrappingIntoTerm(Trees.scala:1710)
    at scala.reflect.internal.Trees.wrappingIntoTerm$(Trees.scala:1707)
    at scala.reflect.internal.SymbolTable.wrappingIntoTerm(SymbolTable.scala:16)
    at scala.reflect.macros.contexts.Typers.typecheck(Typers.scala:38)
    at scala.reflect.macros.contexts.Typers.typecheck$(Typers.scala:20)
    at scala.reflect.macros.contexts.Context.typecheck(Context.scala:6)
    at scala.reflect.macros.contexts.Context.typecheck(Context.scala:6)
    at .testImpl(<pastie>:31)

       test[Foo.Bar]
           ^
错误:宏扩展期间出现异常:
scala.reflect.macros.TypecheckException:值unapply不是Foo.Bar的成员
在scala.reflect.macros.context.Typers.$anonfun$typecheck$3(Typers.scala:32)
在scala.reflect.macros.context.Typers.$anonfun$typecheck$2(Typers.scala:26)
在scala.reflect.macros.context.Typers.doTypecheck$1(Typers.scala:25)
在scala.reflect.macros.context.Typers.$anonfun$typecheck$7(Typers.scala:38)
位于scala.reflect.macros.contexts.Typers$$Lambda$676/541572263.apply(未知源)
在scala.reflect.internal.Trees.wrappingIntoTerm(Trees.scala:1710)
位于scala.reflect.internal.Trees.wrappingintotterm$(Trees.scala:1707)
在scala.reflect.internal.SymbolTable.wrappingIntoTerm(SymbolTable.scala:16)中
在scala.reflect.macros.context.Typers.typecheck(Typers.scala:38)中
位于scala.reflect.macros.contexts.Typers.typecheck$(Typers.scala:20)
在scala.reflect.macros.Context.Context.typecheck(Context.scala:6)中
在scala.reflect.macros.Context.Context.typecheck(Context.scala:6)中
at.testImpl(:31)
测试[Foo.Bar]
^

直接使用
c.typecheck(q““Foo.Bar.unapply(Foo.Bar(“lorem”))”)”)进行测试没有错误,因此我想在类型解析方面还有更多的工作要做。

当我编写
${tpe.companion}
而不仅仅是
$tpe
时,它不会抛出任何错误,但我不知道你的目标是什么,因此,它可能没有什么帮助。我已经尝试过了,在我的例子中,它是不够的,但是如果与
.decl(termNames.CONSTRUCTOR).asMethod.returnType
(使用return完全限定类型)一起使用,它似乎在某种程度上起到了作用。在需要一个术语的情况下,取消引用一个类型充其量只能是脆弱的。这个问题还不清楚什么是充分的答案。我写
${tpe.companion}
时,它不会抛出任何错误,而不仅仅是
$tpe
,但我不知道你的目标是什么,所以它很可能没有帮助。我已经尝试过了,在我的情况下,它是不够的,但如果与
一起使用,它似乎会以某种方式起作用(termNames.CONSTRUCTOR).asMethod.returnType
(使用return完全限定类型)似乎在需要术语的地方取消引用一个类型充其量是脆弱的。从这个问题上不清楚什么是充分的答案。