我想建立一些统计数据,用于某些Scala源代码(以及频率)中的哪些Java标准库类(在java.*
/javax.*
中)和方法。如何检测Scala源中Java类的依赖性?
什么是最直接的方法来做到这一点?是否有机会覆盖传递性依赖关系, G。当某些Lift类依赖于Scala标准库方法,而该方法又取决于Java标准库方法?
我想建立一些统计数据,用于某些Scala源代码(以及频率)中的哪些Java标准库类(在java.*
/javax.*
中)和方法。如何检测Scala源中Java类的依赖性?
什么是最直接的方法来做到这一点?是否有机会覆盖传递性依赖关系, G。当某些Lift类依赖于Scala标准库方法,而该方法又取决于Java标准库方法?
我写了一个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
JDepend看起来像它可以这样做:http://clarkware.com/software/JDepend.html
你可能想看看答案this question这也许可以适应于解决问题了吗?
你可以用Structure101来做到这一点。从Scala/Java字节码中加载一个S101项目,进入Collaboration透视图(Structure选项卡),然后在左侧树视图中选择Scala代码的根包,并在rhs上选择Java包。这将向您显示Scala项目使用哪些Java项目(对于package.class.method/field级别的详细信息),以及哪些Scala项目使用Java库中的任何项目,并且可以深入查看特定的依赖关系。
您还可以使用标记获取传递依赖关系。选择该项目,右键单击,标记/使用/间接。这将在每个透视图中用蓝点标出项目。您可以隐藏除传递闭包之外的所有内容(反转标签,然后隐藏标签)。转到“切片”透视图,选择“外部类”切片,主集群,并使用父组选项,可能会获得有用的视图。这将显示单个图上的所有类,并按其父包进行分组。如果您有一个非常大的项目,则可以切换到DSM视图,该视图比有向图更具可扩展性。
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类的依赖。
它也具有传递依赖性。