从方法符号和主体创建方法定义树

2024-07-04

有没有方便的方法来转MethodSymbol http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.reflect.api.Symbols%24MethodSymbolApi进入方法定义树的左侧(即DefDef http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/index.html#scala.reflect.api.Trees%24DefDefApi)在 Scala 2.10 中?

例如,假设我想创建一个宏,它将采用一个特征的实例,并使用一些调试功能包装该特征的所有方法。我可以写以下内容:

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

object WrapperExample {
  def wrap[A](a: A): A = macro wrap_impl[A]

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

    val wrapped = weakTypeOf[A]
    val f = Select(reify(Predef).tree, "println")

    val methods = wrapped.declarations.collect {
      case m: MethodSymbol if !m.isConstructor => DefDef(
        Modifiers(Flag.OVERRIDE),
        m.name,
        Nil, Nil,
        TypeTree(),
        Block(
          Apply(f, c.literal("Calling: " + m.name.decoded).tree :: Nil),
          Select(a.tree, m.name)
        )
      )
    }.toList

  //...
}

我已经省略了将这些方法粘贴到一个实现该特征的新匿名类中,然后实例化该类的无聊业务 - 您可以找到一个完整的工作示例here https://gist.github.com/4234441如果你有兴趣的话。

现在我可以这样写,例如:

scala> trait X { def foo = 1; def bar = 'a }
defined trait X

scala> val x = new X {}
x: X = $anon$1@15dd533

scala> val w: X = WrapperExample.wrap[X](x)
w: X = $1$$1@27c3a4a3

scala> w.foo
Calling: foo
res0: Int = 1

scala> w.bar
Calling: bar
res1: Symbol = 'a

所以它可以工作,但仅在非常简单的情况下 - 如果特征具有带有参数列表、访问修饰符、注释等的方法,则它不会工作。

我真正想要的是一个函数,它将采用方法符号和新主体的树并返回DefDef。我已经开始手写一个,但它涉及很多繁琐的事情,比如:

List(if (method.isImplicit) Some(Flag.IMPLICIT) else None, ...)

这很烦人、冗长且容易出错。我是否缺少一些更好的方法来在新的 Reflection API 中执行此操作?


据我所知,从符号到定义树没有标准的方法。

你最好的选择可能是迭代c.enclosingRun.units,递归到每个unit.body树木随行。如果您看到DefDef,其中有一个symbol等于你的符号,那么你就到达了目的地。更新。别忘了duplicate重用之前定义树!

这项技术远不是世界上最方便的事情,但它应该有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从方法符号和主体创建方法定义树 的相关文章

随机推荐

  • 为什么向 App.config 添加 **appSettings** 部分会导致 WPF 应用程序出现错误?

    在我的 WPF 应用程序 复合应用程序 中 我想将变量存储在应用程序配置文件 但一旦我添加应用程序设置App config 中的部分 它给了我这个错误 类型初始值设定项 System Windows Application 抛出了一个 例外
  • 如何知道 Bigquery 查询使用的槽数?

    我试图计算出每个大查询所使用的槽数 有办法查出来吗 根据谷歌文档 这样我们就可以计算使用的槽数 平均 时隙数 total slot ms TIMESTAMP DIFF end time start time MILLISECOND sele
  • 捕获信号并向用户报告问题的便携式方式

    如果由于某种奇迹 我们的程序中发生了段错误 我想捕获 SIGSEGV 并让用户 可能是 GUI 客户端 通过单个返回代码知道发生了严重问题 同时我想在命令行上显示信息以显示捕获了哪个信号 今天我们的信号处理程序如下所示 void catch
  • 以限制公共访问同时仍允许父类访问的方式覆盖子类中的公共方法?

    我有一个通用的 Collection 类 具有各种公共 getter 方法 要从 Collection 中获取一项 请调用 get 还有几种返回多个项目的方法 getMany getRange getAll find findAll que
  • 如何让 FetchContent 下载到特定位置?

    继获取内容 https cmake org cmake help latest module FetchContent html文档 例如使用类似的东西 FetchContent Declare gitache package libcwd
  • NServiceBus 错误是否意味着消息未按正确的顺序处理?

    假设我有一个银行应用程序 我不是在开发银行应用程序 但我相信它能表达我的观点 因为它在许多事件溯源示例中使用 它会生成以下消息 1 Apply 110 withdrawal to account A 2 Apply 70 credit to
  • 更改 Django 中的表名称

    我读过 Django 中的表名可以使用自定义元选项 https docs djangoproject com en dev ref models options 我想知道如何使用 db table 选项来继续使用应用程序名称 但稍微修改模型
  • 我应该如何在 Spring Integration 中构建消息?

    我编写了一个应用程序 正在对其进行重构以更好地利用 Spring Integration 应用程序处理文件的内容 问题 据我所知 是我当前的实现通过了Files代替Messages 即 Spring 集成Messages http docs
  • 计算随机生成的六边形的6个顶点

    我需要一些帮助来写方程式 我想生成仍然 完美 成比例 的随机大小的六边形 最左边的顶点将位于 0 0 我想考虑与最左边的顶点相关的其他顶点 从左顶点向上这么多 从它右边这么多 从它向下这么多 这不是那么简单的原因是因为我需要它成比例 目前
  • 如何在列表列表中找到元素和最大的列表?

    我有一个列表列表 x 1 2 3 4 5 6 7 8 9 2 2 0 我想得到列表中元素之和最大的列表 在这种情况下 7 8 9 我宁愿有一个幻想map or lambda或列表理解方法比for while if loop 此致 max提出
  • 如何在 SASS 中定义动态 mixin 或函数名称?

    我想在 SASS 中动态创建 mixin 以列表中的每个项目命名 但它似乎不起作用 我尝试了这个 但出现错误 event icons fair concert art show conference dance show film part
  • 无法使用 SHGetFileInfo 获取“我的电脑”特殊文件夹的图标

    我在用着SHGetFileInfo获取文件夹图标 除了调用时之外 一切正常SHGetFileInfo在 我的电脑 特殊文件夹 CLSID 20D04FE0 3AEA 1069 A2D8 08002B30309D 对于致电后的特殊情况SHGe
  • 是否允许 C 编译器用一种算法替换另一种算法?

    例如你有一个函数sort int numbers size t count 使用冒泡排序实现并且 C 编译器可以识别这种模式 是否允许编译器将其更改为另一个示例 就像快速排序一样 另一个例子是将所有从 0 到的数字相加n 编译器可以将 fo
  • 停止 lapply 从打印到控制台

    当我使用lapply并打印到控制台 它打印出不需要的内容 i NULL虽然我希望将预期的消息打印到控制台 我试过了suppressWarnings and suppressMessages但这些并不能消除不受欢迎的罪犯 我搜索了lapply
  • 有没有办法让每个人都可以访问 firestore 数据库,但只能通过应用程序?

    我正在使用 Firestore 创建 Android 应用程序 我的应用程序不需要身份验证 是否有任何安全规则允许每个人读取和写入 firestore 但只能通过我的应用程序 我试图找到一些规则 但每个规则都基于身份验证 感谢您的帮助 最接
  • Cocoa:在 CGEvent 中模拟 Command+Tab

    我想模拟Application Switcher在我的应用程序中 我认为 CGEvent 也许可以做到这一点 好了 了解了CGEvent的一些基本信息后 我就可以模拟按键了Command Tab 但应用程序切换器窗口只是一闪而过 并立即切换
  • Lua Base64 编码

    我不使用 lua 我尝试在互联网上搜索 这是做什么的 assert load Base64Decode BASE64 Script but is not Encoded like usualy nil bt ENV 每条编码消息都以G0x
  • Android Studio 设计预览是像素化的

    我的 android studio 设计预览很模糊 文本以及小部件 我尝试通过执行以下操作来修复它 Android Studio 属性 gt 兼容性 gt 更改高 DPI 设置 gt 覆盖高 DPI 我关闭了 android studio
  • Visual Studio 2005 内存使用情况

    我发现 Visual Studio 内存使用量通常约为 150 300 MB RAM 作为经常需要在打开多个 Visual Studio 实例的情况下运行的开发人员 是否有任何性能技巧可以优化 VS 使用的内存量 我正在运行带有一个加载项
  • 从方法符号和主体创建方法定义树

    有没有方便的方法来转MethodSymbol http www scala lang org archives downloads distrib files nightly docs library index html scala re