2017-04-13 24 views
1

鑑於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爲每個函數提取函數名稱和類?

我在我的調試器中發現,在選擇節點下,限定符有一個rawtpe來存放一個underlyingCache,這個underlyingCache似乎有我需要的類型信息,但是我一直無法可靠地提取這個數據(也許是因爲我正在研究AST的實現細節?)。

我應該採取一種完全不同的方法嗎?任何想法都會受到歡迎。

+0

我認爲你可以在類型確定階段之後發現的推斷類型,你這個階段之後視察了AST? – pedrofurla

+0

順便說一句,你是如何在編譯器插件或宏中提取AST的? – pedrofurla

+0

@pedrofurla使用scala.tools.reflect.ToolBox.parse然後typecheck產生一個AST – Mark

回答

1

這些符號會給你關於類和方法的信息。

一個非常強力的解決方案,其中tree是typechecked 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) 
+0

謝謝,符號有我需要的。 – Mark

+0

在'isMethod'檢查之後,我使用了'node.symbol.asMethod.fullName'來提取我們需要的東西。 – Mark