-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent overcompilation in mixed projects without pipelining #868
Conversation
It is possible to invoke the java compiiler in astate where the output directory doens't exist. When this happens, the compiler throws an IllegalStateException: [error] sbt.internal.inc.BatchScriptRunner$PreciseScriptedError: {line 8} Command failed: 'run' [error] Caused by: java.lang.IllegalStateException: directory not found: /var/folders/zv/2wskcxc14cn6kyj4yb53whc40000gn/T/sbt_4bd7559c/target/classes [error] at com.sun.tools.javac.main.Main.error(Main.java:186) [error] at com.sun.tools.javac.main.Main.checkDirectory(Main.java:345) [error] at com.sun.tools.javac.main.Main.processArgs(Main.java:274) [error] at com.sun.tools.javac.main.Main.compile(Main.java:414) [error] at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129) [error] at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138) [error] at sbt.internal.inc.javac.LocalJavaCompiler.run(LocalJava.scala:327) [error] at sbt.internal.inc.javac.AnalyzingJavaCompiler.$anonfun$compile$12(AnalyzingJavaCompiler.scala:167) ...
@@ -340,18 +340,21 @@ object Incremental { | |||
incremental.invalidateInitial(previous.relations, initialChanges) | |||
|
|||
// If there's any compilation at all, invalidate all java sources too, so we have access to their type information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about this part? Does this change lead to a loss of type information?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That comment was added in 0504f70 (port of https://github.com/mspnf/zinc/blob/9ef2eba6f829c2afa783987f64ea4e785b678265/internal/zinc-core/src/main/scala/sbt/internal/inc/Incremental.scala). The type information that this makes it available is to the downstream subproject compilation, which is only relevant in pipelining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, cool, thanks.
We should always call Files.createDirectories to ensure the output directory exists. If the directory already exists and is a directory, Files.createDirectories is a no-op and is the same amount of io as the Files.exists check. If the directory exists but is actually a file, then that is a bug and compilcation is likely to fail so we should throw an exception.
When any java source is invalidated, we want to recompile the entire subproject to generate the java class signatures. For this reason, it is necessary to invalidate _all_ of the java sources when any change is detected. We don't however want to recompile all of the java sources if _none_ of them have changed. Prior to this change, in the sbt build with pipelining off, changing any scala source in a mixed project would rebuild all of the java sources which could trigger a cascade of invalidations that could potentially invalidate the entire project even when none of the java sources had actually changed. Due to this behavioral change, in 0504f70 it was necessary to change the iteration count in less-inter-inv-java test from 3 to 2 because the overcompiling behavior made it only do one cycle when a single source file was changed because all of the sources were automatically invalidated. This commit restores the old behavior so the test can be restored as well. It also adds a test for mixed projects to ensure that changing a scala file does not automatically trigger recompilation of java files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
if (initialInvSources0.nonEmpty) initialInvSources0 ++ javaSources | ||
else Set.empty[VirtualFileRef] | ||
if (isPickleJava && initialInvSources0.nonEmpty) initialInvSources0 ++ javaSources | ||
else initialInvSources0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 There's no point in invalidating Java sources unless isPickleJava
is on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. I was about to submit a comment justifying this choice but I don't need to since you've confirmed my intuition.
internal/zinc-core/src/main/scala/sbt/internal/inc/Incremental.scala
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
The latest zinc will overcompile mixed projects when scala sources have changed but no java sources have. Fixes #867.