2012-01-04 26 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类的依赖。

它也具有传递依赖性。