如何在运行时定义一个包含对对象方法的调用而没有伴随类的类?

问题描述

以下 Scala (2.12.12) 代码以预期的行为运行。 ClassDef 树是使用工具箱定义的,并返回一个 ClassSymbol

class MyObj

object MyObj {
  def foo(x: Int): Int = x
}

object Test {

  import ru._

  def main(args: Array[String]): Unit = {

    val objSymbol = ru.typeOf[MyObj].typeSymbol.companion  // This is the most important line!

    val tree = ClassDef(
      Modifiers(),TypeName("Program"),List(),Template(
        List(Ident(TypeName("AnyRef"))),noSelfType,List(
          DefDef(
            Modifiers(),termNames.CONSTRUCTOR,List(List()),TypeTree(),Block(
              List(
                Apply(Select(Super(This(typeNames.EMPTY),typeNames.EMPTY),termNames.CONSTRUCTOR),List())
              ),Literal(Constant(()))
            )
          ),DefDef(
            Modifiers(),TermName("fn"),Apply(Select(Ident(objSymbol),TermName("foo")),List(Literal(Constant(10))))
          )
        )
      )
    )

    val clsSymbol = Reflection.toolBox.define(tree).asInstanceOf[ClassSymbol]
  }

}

然而,class MyObj 仅用于允许我们通过 ru.typeOf[MyObj].typeSymbol.companion 获取对象的符号。在某些情况下,object 没有伴随类,我想修改代码,使其无需 class MyObj 即可工作。

这是我迄今为止尝试过的:


尝试 1。

val objSymbol = ru.typeOf[MyObj.type].typeSymbol

在编译器中产生以下错误。我不知道如何理解,并且在 Scala 语言开发人员讨论之外找不到很多提到这种错误的地方。

Exception in thread "main" scala.tools.reflect.ToolBoxError: reflective compilation has Failed:


  Unexpected tree in genLoad: erp12.scala_cbgp.lang.MyObj.type/class scala.reflect.internal.Trees$TypeTree at: noposition
     while compiling: <no file>
        during phase: jvm
     library version: version 2.12.12
    compiler version: version 2.12.12
  reconstructed args: 

  last tree to typer: TypeTree(class Int)
       tree position: <unkNown>
            tree tpe: Int
              symbol: (final abstract) class Int in package scala
   symbol deFinition: final abstract class Int extends  (a ClassSymbol with SynchronizedClassSymbol)
      symbol package: scala
       symbol owners: class Int
           call site: constructor Program in class Program in package __wrapper$1$78b0f9d262f74777a2e9b5209fcd5413

尝试 2。

currentMirror.staticModule(MyObj.getClass.getCanonicalName)

还尝试了变体:

  • runtimeMirror(getClass.getClassLoader) vs currentMirror
  • MyObj.getClass.getTypeNameMyObj.getClass.getCanonicalName(在本例中相同)

这会抛出一个带有 ToolBoxErrorvalue foo is not a member of object erp12.scala_cbgp.lang.MyObj$,这让我相信它返回的符号与我需要的符号不同。


尝试 3。

currentMirror.staticclass(MyObj.getClass.getCanonicalName)

产生与尝试 1 相同的结果。


对我做错了什么的任何指导将不胜感激。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)