2012-01-04 66 views
1

我想建立一些統計數據,用於某些Scala源代碼(以及頻率)中的哪些Java標準庫類(在java.*/javax.*中)和方法。如何檢測Scala源中Java類的依賴性?

什麼是最直接的方法來做到這一點?是否有機會覆蓋傳遞性依賴關係, G。當某些Lift類依賴於Scala標準庫方法,而該方法又取決於Java標準庫方法?

回答

0

我寫了一個Scala編譯器插件,它爲我解決了這個問題。它不漂亮,但它的工作。

主要部分做的工作是這樣的:

for (tree <- unit.body) { 
    tree match { 
    case [email protected](mods, name, tparams, vparamss, tpt, rhs) 
     if isJavaAndNotAccessor(mods, rhs.symbol) => 
     printJava(rhs, "DefDef") 

    case [email protected]lDef(mods, name, tpt, rhs) => 
     if (isJavaAndNotAccessor(mods, tpt.symbol)) 
     printJava(tpt, "ValDef") 
     tpt.tpe.typeArgs.foreach(t => findAllJavaTypes(t.baseTypeSeq.toList).foreach(sym => printJavaCustom(sym, posWithFallback(sym.pos, tree.pos), "TpeArg"))) 

    case [email protected](parents, self, body) => 
     parents.foreach(p => findAllJavaTypes(p.tpe.baseTypeSeq.toList).foreach(sym => printJavaCustom(sym, posWithFallback(p.pos, tree.pos), "TpeDef"))) 

    case [email protected](qual, name) => 
     if (isJavaAndNotJLObjectInit(tree.symbol) && (tree.symbol.isMethod || tree.symbol.isValue || tree.symbol.isStaticMember)) 
     printJava(tree, "Select") 

    case _ => 
    } 
} 

private def findAllJavaTypes(types: List[Type]): List[Symbol] = { 
    def find0(types: List[Type], result: List[Type]): List[Type] = 
    if (types == List()) 
     result 
    else 
     find0(types.flatMap(_.typeArgs), types.filter(tpe => isJavaAndNotJLObject(tpe.typeSymbol)) ::: result) 

    find0(types, List()).distinct.map(_.typeSymbol) 
} 

代碼是在這裏舉行:https://github.com/soc/scala-compilerplugin-javausagecounter

1

你可能想看看答案this question這也許可以適應於解決問題了嗎?

1

你可以用Structure101來做到這一點。從Scala/Java字節碼中加載一個S101項目,進入Collaboration透視圖(Structure選項卡),然後在左側樹視圖中選擇Scala代碼的根包,並在rhs上選擇Java包。這將向您顯示Scala項目使用哪些Java項目(對於package.class.method/field級別的詳細信息),以及哪些Scala項目使用Java庫中的任何項目,並且可以深入查看特定的依賴關係。

您還可以使用標記獲取傳遞依賴關係。選擇該項目,右鍵單擊,標記/使用/間接。這將在每個透視圖中用藍點標出項目。您可以隱藏除傳遞閉包之外的所有內容(反轉標籤,然後隱藏標籤)。轉到「切片」透視圖,選擇「外部類」切片,主集羣,並使用父組選項,可能會獲得有用的視圖。這將顯示單個圖上的所有類,並按其父包進行分組。如果您有一個非常大的項目,則可以切換到DSM視圖,該視圖比有向圖更具可擴展性。

0

IntelliJ IDEA有一個名爲Analyze Dependencies的功能,它可以做你想做的事。

您可以依賴的分析導出到一個文本文件,它將包含類似條目:

<file path="$PROJECT_DIR$/src/main/scala/com/foo/config/Bootstrap.scala"> 
    <dependency path="$PROJECT_DIR$/src/main/scala/com/foo/ws/auth/Auth.scala" /> 
    <dependency path="$PROJECT_DIR$/src/main/scala/com/foo/domain/auth/User.scala" /> 
    <dependency path="$MAVEN_REPOSITORY$/org/scala-lang/scala-library/2.9.1/scala-library-2.9.1.jar!/scala/package.class" /> 
    <dependency path="/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/../Classes/classes.jar!/java/io/InputStream.class" /> 
    .... 

注意列出的最後一行是如何在Java的InputStream類的依賴。

它也具有傳遞依賴性。