Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jvican committed Nov 13, 2018
1 parent dd70e81 commit 634e450
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
25 changes: 24 additions & 1 deletion backend/src/main/scala/bloop/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ object Compiler {
}
}

def warningsFromPreviousRuns(
previous: CompileAnalysis,
current: CompileAnalysis
): List[xsbti.Problem] = {
import scala.collection.JavaConverters._
val previousSourceInfos = previous.readSourceInfos().getAllSourceInfos.asScala.toMap
val currentSourceInfos = current.readSourceInfos().getAllSourceInfos.asScala.toMap
val eligibleSourceInfos =
previousSourceInfos.filterKeys(f => !currentSourceInfos.contains(f)).values
eligibleSourceInfos.flatMap { i =>
i.getReportedProblems.filter(_.severity() == xsbti.Severity.Warn)
}.toList
}

def compile(compileInputs: CompileInputs): Task[Result] = {
val classesDir = compileInputs.classesDir.toFile
def getInputs(compilers: Compilers): Inputs = {
Expand Down Expand Up @@ -137,13 +151,22 @@ object Compiler {
val compilers = compileInputs.compilerCache.get(scalaInstance)
val inputs = getInputs(compilers)

// We don't want nanosecond granularity, we're happy with milliseconds
// We don't need nanosecond granularity, we're happy with milliseconds
def elapsed: Long = ((System.nanoTime() - start).toDouble / 1e6).toLong

import scala.util.{Success, Failure}
val logger = compileInputs.reporter.logger
val previousAnalysis = InterfaceUtil.toOption(compileInputs.previousResult.analysis())
BloopZincCompiler.compile(inputs, compileInputs.mode, logger).materialize.map {
case Success(result) =>
// Report warnings that occurred in previous compilation cycles
previousAnalysis.foreach { previous =>
warningsFromPreviousRuns(previous, result.analysis()).foreach { p =>
// Note that buffered warnings are not added back to the current analysis on purpose
compileInputs.reporter.log(p)
}
}

val res = PreviousResult.of(Optional.of(result.analysis()), Optional.of(result.setup()))
Result.Success(compileInputs.reporter, res, elapsed)
case Failure(f: StopPipelining) => Result.Blocked(f.failedProjectNames)
Expand Down
7 changes: 7 additions & 0 deletions backend/src/main/scala/bloop/reporter/Reporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,11 @@ object Reporter {
val ps = sourceInfos.flatMap(_._2.getReportedProblems).map(Problem.fromZincProblem(_))
new LogReporter(logger, cwd, identity, ReporterConfig.defaultFormat, ps)
}
/*
def getWarningsFromAnalysis(analysis: CompileAnalysis): List[xsbti.Problem] = {
import scala.collection.JavaConverters._
val sourceInfos = analysis.readSourceInfos.getAllSourceInfos.asScala.toBuffer
val ps = sourceInfos.flatMap(_._2.getReportedProblems).map(Problem.fromZincProblem(_))
ps.filter(_.)
}*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,16 @@ object BloopIncremental {
} yield callback.get
}

try incremental.entrypoint(initialInvClasses, initialInvSources, setOfSources, binaryChanges, lookup, previous, doCompile, classfileManager, 1)
/* Normal Zinc happens to add the source infos of the previous result to the infos
* of the new previous result. In constrast, we desire to only have the source infos
* of those files that we have indeed compiled so that we can know from the outside
* to which extent a new compilation overlaps with a previous compilation. This is
* important whenever we want to know which warnings were not reported in the new
* compilation but should be reported given that they are still present in the codebase.
*/
val previousWithNoSourceInfos =
previous.copy(infos = previous.infos -- previous.infos.allInfos.keys)
try incremental.entrypoint(initialInvClasses, initialInvSources, setOfSources, binaryChanges, lookup, previousWithNoSourceInfos, doCompile, classfileManager, 1)
catch { case e: Throwable => classfileManager.complete(false); throw e }
}

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/main/scala/bloop/bsp/BloopBspServices.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,9 @@ final class BloopBspServices(
}

def reportError(p: Project, problems: List[Problem], elapsedMs: Long): String = {
// Don't show warnings in this "final report", we're handling them in the reporter
val count = bloop.reporter.Problem.count(problems)
s"${p.name} [${elapsedMs}ms] (errors ${count.errors}, warnings ${count.warnings})"
s"${p.name} [${elapsedMs}ms] (errors ${count.errors})"
}

Interpreter.execute(action, Task.now(state)).map { newState =>
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/test/scala/bloop/bsp/BspProtocolSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -307,16 +307,14 @@ class BspProtocolSpec {
deleteNewFile()
compileMainProject.map {
case Left(e) => Left(e)
case Right(result) => Right(result)
/*
case Right(result) =>
// Uncomment whenever we receive a report on the third no-op
if (receivedReports == 3) Right(result)
else {
Left(
Response.internalError(s"Expected 3, got ${receivedReports} reports")
)
}
*/
}
}
}
Expand Down Expand Up @@ -354,7 +352,9 @@ class BspProtocolSpec {
)
} else if (isMainProject(report.target) && receivedReports == 2) {
// This is the last compilation which should be successful
// TODO(jvican): Test the initial warning is buffered and shown to the client
receivedReports += 1
Assert.assertEquals(s"Warnings in $MainProject != 1", 1, report.warnings)
Assert.assertEquals(s"Errors in $MainProject != 0", 0, report.errors)
()
} else {
Assert.fail(s"Unexpected compilation report: $report")
Expand All @@ -376,8 +376,8 @@ class BspProtocolSpec {
"[diagnostic] local val in method main is never used Range(Position(5,8),Position(5,8))"
val warnings = logger.underlying.getMessagesAt(Some("warn"))
Assert.assertTrue(
s"Expected $expectedWarning, obtained $warnings.",
warnings == List(expectedWarning)
s"Expected two times $expectedWarning, obtained $warnings.",
warnings == List(expectedWarning, expectedWarning)
)

// The syntax error has to be present as a diagnostic, not a normal log error
Expand Down

0 comments on commit 634e450

Please sign in to comment.