Как обнаружить зависимости от классов Java в источниках Scala? - PullRequest
1 голос
/ 04 января 2012

Я хочу построить некоторые статистические данные о том, какие классы стандартной библиотеки Java (классы java.* / javax.*) и методы используются в некотором исходном коде Scala (и как часто).

Что будетсамый простой способ сделать это?Есть ли возможность также охватить транзитивные зависимости, например, когда некоторый класс Lift зависит от метода стандартной библиотеки Scala, который, в свою очередь, зависит от метода стандартных библиотек Java?

Ответы [ 5 ]

2 голосов
/ 04 января 2012

JDepend выглядит так, как будто это может сделать: http://clarkware.com/software/JDepend.html

1 голос
/ 05 января 2012

Вы можете сделать это с помощью Structure101 . Загрузите проект S101 из байт-кода Scala / Java, перейдите в перспективу Collaboration (вкладка «Структура») и выберите корневые пакеты кода Scala в левой части дерева, а пакеты Java в правой части. Это покажет вам, какие элементы Java (до уровней package.class.method / field) используются вашим проектом Scala, а какие элементы Scala используют что-либо в библиотеках Java, и вы можете просмотреть детали, чтобы увидеть конкретные зависимости.

Вы также можете получить переходные зависимости с помощью тегов. Выберите элемент, щелкните правой кнопкой мыши, отметьте / использует / косвенно. Это пометит элементы с синей точкой, которая сворачивается через каждую перспективу. Вы можете скрыть все, кроме транзитивного замыкания (инвертировать теги, а затем скрыть теги). Полезное представление, вероятно, можно получить, перейдя в перспективу Slice, выбрав срез «внешний класс», основной кластер и воспользовавшись опцией group by parent. Это покажет все классы на одной диаграмме, сгруппированные по их родительским пакетам. Если у вас очень большой проект, вы можете переключиться на представление DSM, которое является более масштабируемым, чем ориентированный граф.

1 голос
/ 04 января 2012

Возможно, вы захотите взглянуть на ответ на этот вопрос , который, вероятно, можно адаптировать для решения вашей проблемы?

0 голосов
/ 15 июня 2012

Я написал плагин компилятора Scala, который решил эту проблему для меня. Это не красиво, но делает свою работу.

Основная часть, выполняющая работу, выглядит так:

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

    case tree@ValDef(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 tree@Template(parents, self, body) =>
      parents.foreach(p => findAllJavaTypes(p.tpe.baseTypeSeq.toList).foreach(sym => printJavaCustom(sym, posWithFallback(p.pos, tree.pos), "TpeDef")))

    case tree@Select(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

0 голосов
/ 25 января 2012

IntelliJ IDEA имеет функцию под названием Анализ зависимостей, которая будет делать то, что вы хотите.

Вы можете экспортировать анализ зависимостей в текстовый файл, и он будет содержать записи, такие как:

<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.

Она также выполняет транзитивные зависимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...