Skip to content

Commit

Permalink
Emits SourceInfos when incremental compilation fails
Browse files Browse the repository at this point in the history
  • Loading branch information
Friendseeker committed Dec 9, 2023
1 parent be2bb54 commit 769e381
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 5 deletions.
23 changes: 21 additions & 2 deletions internal/compiler-bridge/src/main/scala/xsbt/CompilerBridge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import scala.collection.mutable
import scala.reflect.io.AbstractFile
import scala.tools.nsc.CompilerCommand
import Log.debug
import xsbti.compile.analysis.ReadSourceInfos

import java.io.File

/**
Expand Down Expand Up @@ -49,6 +51,16 @@ class InterfaceCompileFailed(
override val toString: String
) extends xsbti.CompileFailed

class InterfaceCompileFailed2(
val arguments: Array[String],
val sourceInfos: ReadSourceInfos,
override val toString: String
) extends xsbti.CompileFailed2 {
import scala.collection.JavaConverters._
val problems: Array[Problem] =
sourceInfos.getAllSourceInfos.values().asScala.flatMap(_.getReportedProblems).toArray
}

class InterfaceCompileCancelled(val arguments: Array[String], override val toString: String)
extends xsbti.CompileCancelled

Expand Down Expand Up @@ -180,8 +192,10 @@ private final class CachedCompiler0(
}

underlyingReporter.printSummary()
if (!noErrors(underlyingReporter))
handleErrors(underlyingReporter, log)
if (!noErrors(underlyingReporter)) {
val infos = callback.getSourceInfos
handleErrors(infos, log)
}

// the case where we cancelled compilation _after_ some compilation errors got reported
// will be handled by line above so errors still will be reported properly just potentially not
Expand All @@ -195,6 +209,11 @@ private final class CachedCompiler0(
throw new InterfaceCompileFailed(args, dreporter.problems, "Compilation failed")
}

def handleErrors(sourceInfos: ReadSourceInfos, log: Logger): Nothing = {
debug(log, "Compilation failed (CompilerInterface)")
throw new InterfaceCompileFailed2(args, sourceInfos, "Compilation failed")
}

def handleCompilationCancellation(dreporter: DelegatingReporter, log: Logger): Nothing = {
assert(dreporter.cancelled, "We should get here only if when compilation got cancelled")
debug(log, "Compilation cancelled (CompilerInterface)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
package xsbti;

import xsbti.api.DependencyContext;
import xsbti.compile.analysis.ReadSourceInfos;

import java.io.File;
import java.nio.file.Path;
Expand Down Expand Up @@ -260,4 +261,6 @@ void problem(String what,
boolean isPickleJava();

Optional<T2<Path, Path>> getPickleJarPair();

ReadSourceInfos getSourceInfos();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package xsbti;

import xsbti.compile.analysis.ReadSourceInfos;

public abstract class CompileFailed2 extends CompileFailed {
public abstract ReadSourceInfos sourceInfos();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,25 @@ private final class AnalysisCallback(
}
}

def getSourceInfos: SourceInfos = {
// Collect Source Info from current run
val sources = reporteds.keySet ++ unreporteds.keySet ++ mainClasses.keySet
val sourceToInfo = sources.map { source =>
val info = SourceInfos.makeInfo(
getOrNil(reporteds.iterator.map { case (k, v) => k -> v.asScala.toSeq }.toMap, source),
getOrNil(unreporteds.iterator.map { case (k, v) => k -> v.asScala.toSeq }.toMap, source),
getOrNil(mainClasses.iterator.map { case (k, v) => k -> v.asScala.toSeq }.toMap, source)
)
(source, info)
}.toMap
val sourceInfoFromCurrentRun = new MSourceInfos(sourceToInfo)
// Collect reported problems from previous run
incHandlerOpt.map(_.previousAnalysisPruned) match {
case Some(prevAnalysis) => prevAnalysis.infos ++ sourceInfoFromCurrentRun
case None => sourceInfoFromCurrentRun
}
}

override def apiPhaseCompleted(): Unit = {
// If we know we're done with cycles (presumably because all sources were invalidated) we can store early analysis
// and picke data now. Otherwise, we need to wait for dependency information to decide if there are more cycles.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ object SourceInfos {
}
}

private final class MSourceInfos(val allInfos: Map[VirtualFileRef, SourceInfo])
private[inc] final class MSourceInfos(val allInfos: Map[VirtualFileRef, SourceInfo])
extends SourceInfos {

def ++(o: SourceInfos) = {
Expand Down
6 changes: 4 additions & 2 deletions internal/zinc-testing/src/main/scala/xsbti/TestCallback.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import java.io.File
import java.nio.file.Path
import java.{ util => ju }
import ju.Optional

import xsbti.api.{ DependencyContext, ClassLike }
import xsbti.api.{ ClassLike, DependencyContext }
import xsbti.compile.analysis.ReadSourceInfos

import scala.collection.mutable.ArrayBuffer

Expand Down Expand Up @@ -153,6 +153,8 @@ class TestCallback extends AnalysisCallback2 {
override def isPickleJava: Boolean = false

override def getPickleJarPair = Optional.empty()

override def getSourceInfos: ReadSourceInfos = null
}

object TestCallback {
Expand Down

0 comments on commit 769e381

Please sign in to comment.