FSC перекомпилируется каждый раз - PullRequest
3 голосов
/ 27 сентября 2010

FSC перекомпилирует мои файлы .scala каждый раз, даже когда в этом нет необходимости - я могу скомпилировать его дважды, не редактируя ничего между попытками, и он перекомпилирует их!Например, у меня есть 2 файла

Hello.scala

class Hello{
  print("hello")
}

и Tokens.scala:

abstract class Token(val str: String, val start: Int, val end: Int)
  {override def toString = getClass.getSimpleName + "(" + "[" + start + "-" + end + "]" + str + ")"}
class InputToken(str: String, start: Int, end: Int)
        extends Token(str, start, end)
 class ParsedToken(str: String, start: Int, end: Int, val invisible: Boolean)
        extends Token(str, start, end)

Когда я спрашиваю муравей скомпилировать проект с чистого листаследующий вывод:

ant compile
init:
    [mkdir] Created dir: D:\projects\Test\build\classes
    [mkdir] Created dir: D:\projects\Test\build\test\classes

compile:
      [fsc] Base directory is `D:\projects\Test`
      [fsc] Compiling source files: somepackage\Hello.scala, somepackage\Tokens.scala to D:\projects\Test\build\classes

BUILD SUCCESSFUL

Чем я ничего не редактирую и не спрашиваю муравьиную компиляцию снова:

ant compile
init:
    [mkdir] Created dir: D:\projects\Test\build\classes
    [mkdir] Created dir: D:\projects\Test\build\test\classes

compile:
      [fsc] Base directory is `D:\projects\Test`
      [fsc] Compiling source files: somepackage\Tokens.scala to D:\projects\Test\build\classes

BUILD SUCCESSFUL

Как видите, fsc работает умно в случае Hello.scala (нетперекомпиляция) и действует глупо в случае Tokens.scala.Я полагаю, что проблема как-то связана с наследованием, но это все.

Так что же не так?

Ответы [ 2 ]

5 голосов
/ 27 сентября 2010

Tokens.scala перекомпилируется, потому что нет файла класса, соответствующего его базовому имени.То есть он не создает файл Tokens.class.При принятии решения о том, должен ли исходный файл быть скомпилирован, fsc ищет файл класса с тем же базовым именем, и если файл класса не существует или время модификации исходного файла больше, чем у файла класса, исходный файл будет перестроен,Если вы можете, я предлагаю вам взглянуть на Simple Build Tool , его режим непрерывной компиляции точно отслеживает сопоставление исходного кода -> и не будет перекомпилировать Tokens.scala

Для дополнительного смеха подумайтео том, что может сделать компилятор, если у вас есть другой исходный файл с class Tokens.

Хотя scala допускает произвольные общедоступные классы / объекты в любом исходном файле, все еще есть довольно много инструментов, которые предполагают, что выбудет в некоторой степени соответствовать соглашению java и, по крайней мере, иметь один класс / объект в файле с тем же именем, что и базовое имя исходного файла.

4 голосов
/ 27 сентября 2010

Мне не нравится много публикаций, написанных другими, но я думаю, что этот вопрос заслуживает более полного ответа, чем то, что было строго задано.

Итак, во-первых, fsc перекомпилирует все по умолчанию, период.Это ant, а не fsc, что исключает Hello.scala, поскольку имя файла соответствует имени класса.Он не пропускает Tokens.scala, потому что не существует скомпилированного класса с именем Tokens, поэтому при отсутствии Tokens.class он перекомпилируется Tokens.scala.

Это неправильносо Скалой.Scala отличается в одном фундаментальном аспекте от Java тем, что из-за технических ограничений на JVM изменение в trait требует перекомпиляции каждого класса, объекта или экземпляра, в котором он используется.

Теперь можно исправитьant задача сделать что-то умнее, начиная с Scala 2.8.Я беру эту информацию из blogtrader.net от Caoyuan, плагина Scala для славы Netbeans.Вы определяете задачу Scala для цели сборки, как показано ниже:

<scalac srcdir="${src.dir}"
        destdir="${build.classes.dir}"
        classpathref="build.classpath"
        force="yes"
        addparams="-make:transitive -dependencyfile ${build.dir}/.scala_dependencies"
        >
    <src path="${basedir}/src1"/> 
    <!--include name="compile/**/*.scala"/-->
    <!--exclude name="forget/**/*.scala"/-->
</scalac>

Она говорит ant перекомпилировать все, так как ant просто недостаточно умен, чтобы выяснить, что нужно перекомпилировать или нет,Он также сообщает Scala , что нужно создать файл, содержащий зависимости компиляции, и использовать алгоритм транзитивной зависимости, чтобы выяснить, что нужно перекомпилировать или нет.

Вам также нужно изменить цель init навключите каталог сборки в путь к классу сборки, так как Scala потребуется для перекомпиляции других классов.Это должно выглядеть так:

<path id="build.classpath">
    <pathelement location="${scala-library.jar}"/>
    <pathelement location="${scala-compiler.jar}"/>
    <pathelement location="${build.classes.dir}"/>
</path>

Для получения более подробной информации, пожалуйста, обратитесь к блогу Цаоюаня.

...