Scala 宏:生成的 class 无法使用未实现的成员进行编译
Scala Macros: Generated class fails to compile with unimplemented members
我的问题是我生成的 class' 成员没有被识别为已实现。这是为 Scala 2.10/2.11/2.12 构建的,默认为 2.11。使用 macroparadise 2.10.
这样做的目的是将某些特性标记为 可冻结 并为每个可冻结的方法生成一个实现 class scala.util.Try
它将在访问数据时调用其 get
方法。所有不可冻结的方法都填写throw new IllegalStateException
。并创建了一个自定义 freeze
方法,它创建了一个 Frozen
class 的实例,并使用特征定义的方法填充了所需的数据。
我已经设置了一个注释宏放置在 traits 上并生成一个 伴随对象 与一个内部 class Frozen
如下所示:
{
abstract trait JavaInfo extends scala.AnyRef {
@new CanFreeze() def isJavaInfo: Boolean;
@new CannotFreeze() def toJavaInfo: AnyRef
};
object JavaInfo extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
class Frozen extends JavaInfo with java.io.Serializable {
<paramaccessor> private val $isJavaInfo: scala.util.Try[Boolean] = _;
def <init>($isJavaInfo: scala.util.Try[Boolean]) = {
super.<init>();
()
};
override def isJavaInfo: Boolean = this.$isJavaInfo.get;
override def toJavaInfo: AnyRef = throw new IllegalStateException("Method not frozen!")
};
def freeze(valueToFreeze: JavaInfo): Frozen = new Frozen(scala.util.Try.apply(valueToFreeze.isJavaInfo))
};
()
}
当我尝试 运行 我的宏在特征 JavaInfo
上时发生以下错误:
[error] /Users/senk/projects/scala-debugger/scala-debugger-api/src/main/scala/org/scaladebugger/api/profiles/traits/info/JavaInfo.scala:9: class Frozen needs to be abstract, since:
[error] it has 2 unimplemented members.
[error] /** As seen from class Frozen, the missing signatures are as follows.
[error] * For convenience, these are usable as stub implementations.
[error] */
[error] override def isJavaInfo: Boolean = ???
[error] override def toJavaInfo: AnyRef = ???
[error] @Freezable trait JavaInfo {
[error] ^
[error] one error found
trait本身如下:
import org.scaladebugger.macros.freeze.{CanFreeze, CannotFreeze, Freezable}
@Freezable trait JavaInfo {
@CanFreeze def isJavaInfo: Boolean
@CannotFreeze def toJavaInfo: AnyRef
}
收到错误提示 Frozen
class 没有实现任何内容,即使我在正在构建的树中看到了实现。
您可以通过检查该分支和 运行ning sbt scalaDebuggerApi/compile
来测试失败,这将为 Scala 2.11 编译宏项目,然后是 API 本身。
想通了。我正在创建方法并实现它们的主体,但重复使用每个方法的旧修饰符并只是添加 Flag.OVERRIDE: FlagSet
。原来未实现的方法有一个 Flag.DEFERRED
,所以我生成了一个 Modifiers(OVERRIDE | DEFERRED)
,考虑到它有一个主体,这没有意义。似乎具有修饰符 DEFERRED
会导致编译器在检查方法时忽略主体,即使主体会显示在字节代码本身中。
我的问题是我生成的 class' 成员没有被识别为已实现。这是为 Scala 2.10/2.11/2.12 构建的,默认为 2.11。使用 macroparadise 2.10.
这样做的目的是将某些特性标记为 可冻结 并为每个可冻结的方法生成一个实现 class scala.util.Try
它将在访问数据时调用其 get
方法。所有不可冻结的方法都填写throw new IllegalStateException
。并创建了一个自定义 freeze
方法,它创建了一个 Frozen
class 的实例,并使用特征定义的方法填充了所需的数据。
我已经设置了一个注释宏放置在 traits 上并生成一个 伴随对象 与一个内部 class Frozen
如下所示:
{
abstract trait JavaInfo extends scala.AnyRef {
@new CanFreeze() def isJavaInfo: Boolean;
@new CannotFreeze() def toJavaInfo: AnyRef
};
object JavaInfo extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
class Frozen extends JavaInfo with java.io.Serializable {
<paramaccessor> private val $isJavaInfo: scala.util.Try[Boolean] = _;
def <init>($isJavaInfo: scala.util.Try[Boolean]) = {
super.<init>();
()
};
override def isJavaInfo: Boolean = this.$isJavaInfo.get;
override def toJavaInfo: AnyRef = throw new IllegalStateException("Method not frozen!")
};
def freeze(valueToFreeze: JavaInfo): Frozen = new Frozen(scala.util.Try.apply(valueToFreeze.isJavaInfo))
};
()
}
当我尝试 运行 我的宏在特征 JavaInfo
上时发生以下错误:
[error] /Users/senk/projects/scala-debugger/scala-debugger-api/src/main/scala/org/scaladebugger/api/profiles/traits/info/JavaInfo.scala:9: class Frozen needs to be abstract, since:
[error] it has 2 unimplemented members.
[error] /** As seen from class Frozen, the missing signatures are as follows.
[error] * For convenience, these are usable as stub implementations.
[error] */
[error] override def isJavaInfo: Boolean = ???
[error] override def toJavaInfo: AnyRef = ???
[error] @Freezable trait JavaInfo {
[error] ^
[error] one error found
trait本身如下:
import org.scaladebugger.macros.freeze.{CanFreeze, CannotFreeze, Freezable}
@Freezable trait JavaInfo {
@CanFreeze def isJavaInfo: Boolean
@CannotFreeze def toJavaInfo: AnyRef
}
收到错误提示 Frozen
class 没有实现任何内容,即使我在正在构建的树中看到了实现。
您可以通过检查该分支和 运行ning sbt scalaDebuggerApi/compile
来测试失败,这将为 Scala 2.11 编译宏项目,然后是 API 本身。
想通了。我正在创建方法并实现它们的主体,但重复使用每个方法的旧修饰符并只是添加 Flag.OVERRIDE: FlagSet
。原来未实现的方法有一个 Flag.DEFERRED
,所以我生成了一个 Modifiers(OVERRIDE | DEFERRED)
,考虑到它有一个主体,这没有意义。似乎具有修饰符 DEFERRED
会导致编译器在检查方法时忽略主体,即使主体会显示在字节代码本身中。