Scala如何提取函数调用

时间:2017-04-13 14:23:02

标签: scala function abstract-syntax-tree

给定一串Scala代码,我需要提取任何函数调用的类和名称,例如,我想输出如下内容:

com.a.b.c.SomeClassA.someFunctionA
com.a.b.c.SomeClassA.someFunctionB
com.a.b.c.SomeClassB.anotherFunctionA

为此,我为提供的代码字符串生成一个AST并检查。我已经成功处理了应用节点,但是,我没有看到一个适用于所有情况的简单规则来获取我需要的信息,例如:

val val2 = val1.someFunctionA
val2.someFunctionB

确定AST中val2的类型似乎并不简单,因为生成该类型的子树可能是任意复杂的。

是否有一种简单的机制可以检查AST以提取函数名称和每个函数的类?

我注意到,在我的调试器中,在一个Select节点下,限定符有一个包含底层缓存的rawtpe,这个底层缓存似乎具有我需要的类型信息,但我还没有能够可靠地提取这些数据(也许是因为我正在深入研究AST的实现细节?)。

我应该采取完全不同的方法吗?任何想法都会受到欢迎。

1 个答案:

答案 0 :(得分:1)

符号将为您提供有关类和方法的信息。

非常强力的解决方案,其中tree是代表Tree的类型val val1 = new A(); val val2 = val1.foo; val2.bar

scala> val set = tree.collect { case method if method.symbol != null && method.symbol.isMethod => method.symbol }.toSet
set: scala.collection.immutable.Set[tb.u.Symbol] = Set(constructor A, method foo, method bar)

scala> set.map(sym => s"${sym.owner.name}.${sym.name}")
res25: scala.collection.immutable.Set[String] = Set(A.<init>, A.foo, B.bar)