Skip to content

Commit

Permalink
improvement: Specifically choose which targets to compile
Browse files Browse the repository at this point in the history
Previously, we would wait for full compilation for debugger and scalafix, however that is not needed, we only need to compile the current target in that case.

Now, we specify it explicitely.
  • Loading branch information
tgodzik committed Aug 5, 2024
1 parent 66cfbde commit 27f8f0d
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,25 @@ final class Compilations(

def previouslyCompiled: Iterable[b.BuildTargetIdentifier] = lastCompile

def compilationFinished(targets: Seq[BuildTargetIdentifier]): Future[Unit] =
def compilationFinished(
targets: Seq[BuildTargetIdentifier],
compileInverseDependencies: Boolean,
): Future[Unit] =
if (currentlyCompiling.isEmpty) {
Future(())
} else {
} else if (compileInverseDependencies) {
cascadeCompile(targets)
} else {
compileTargets(targets)
}

def compilationFinished(
source: AbsolutePath
source: AbsolutePath,
compileInverseDependencies: Boolean,
): Future[Unit] =
expand(source).flatMap(targets => compilationFinished(targets.toSeq))
expand(source).flatMap(targets =>
compilationFinished(targets.toSeq, compileInverseDependencies)
)

def compileTarget(
target: b.BuildTargetIdentifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,69 +91,71 @@ case class ScalafixProvider(
val fromDisk = file.toInput
val inBuffers = file.toInputFromBuffers(buffers)

compilations.compilationFinished(file).flatMap { _ =>
val scalafixEvaluation =
scalafixEvaluate(
file,
scalaTarget,
inBuffers.value,
retried || isUnsaved(inBuffers.text, fromDisk.text),
rules,
)

scalafixEvaluation
.recover { case exception =>
reportScalafixError(
"Unable to run scalafix, please check logs for more info.",
exception,
compilations
.compilationFinished(file, compileInverseDependencies = false)
.flatMap { _ =>
val scalafixEvaluation =
scalafixEvaluate(
file,
scalaTarget,
inBuffers.value,
retried || isUnsaved(inBuffers.text, fromDisk.text),
rules,
)
throw exception
}
.flatMap {
case results
if !scalafixSucceded(results) && hasStaleOrMissingSemanticdb(
results
) && buildHasErrors(file) =>
val msg = "Attempt to organize your imports failed. " +
"It looks like you have compilation issues causing your semanticdb to be stale. " +
"Ensure everything is compiling and try again."
scribe.warn(
msg
)
languageClient.showMessage(
MessageType.Warning,
msg,
)
Future.successful(Nil)
case results if !scalafixSucceded(results) =>
val scalafixError = getMessageErrorFromScalafix(results)
val exception = ScalafixRunException(scalafixError)
if (
scalafixError.startsWith("Unknown rule") ||
scalafixError.startsWith("Class not found")
) {
languageClient
.showMessage(Messages.unknownScalafixRules(scalafixError))
}

scribe.error(scalafixError, exception)
if (!retried && hasStaleOrMissingSemanticdb(results)) {
// Retry, since the semanticdb might be stale
runScalafixRules(file, scalaTarget, rules, retried = true)
} else {
Future.failed(exception)
}
case results =>
Future.successful {
val edits = for {
fileEvaluation <- results.getFileEvaluations().headOption
patches <- fileEvaluation.previewPatches().asScala
} yield textEditsFrom(patches, inBuffers)
edits.getOrElse(Nil)
}
scalafixEvaluation
.recover { case exception =>
reportScalafixError(
"Unable to run scalafix, please check logs for more info.",
exception,
)
throw exception
}
.flatMap {
case results
if !scalafixSucceded(results) && hasStaleOrMissingSemanticdb(
results
) && buildHasErrors(file) =>
val msg = "Attempt to organize your imports failed. " +
"It looks like you have compilation issues causing your semanticdb to be stale. " +
"Ensure everything is compiling and try again."
scribe.warn(
msg
)
languageClient.showMessage(
MessageType.Warning,
msg,
)
Future.successful(Nil)
case results if !scalafixSucceded(results) =>
val scalafixError = getMessageErrorFromScalafix(results)
val exception = ScalafixRunException(scalafixError)
if (
scalafixError.startsWith("Unknown rule") ||
scalafixError.startsWith("Class not found")
) {
languageClient
.showMessage(Messages.unknownScalafixRules(scalafixError))
}

scribe.error(scalafixError, exception)
if (!retried && hasStaleOrMissingSemanticdb(results)) {
// Retry, since the semanticdb might be stale
runScalafixRules(file, scalaTarget, rules, retried = true)
} else {
Future.failed(exception)
}
case results =>
Future.successful {
val edits = for {
fileEvaluation <- results.getFileEvaluations().headOption
patches <- fileEvaluation.previewPatches().asScala
} yield textEditsFrom(patches, inBuffers)
edits.getOrElse(Nil)
}

}
}
}
}
}

private def createTemporarySemanticdb(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,25 +250,28 @@ class DebugProvider(
val connectToServer = () => {
val targets = parameters.getTargets().asScala.toSeq

compilations.compilationFinished(targets).flatMap { _ =>
val conn =
startDebugSession(buildServer, parameters, cancelPromise)
.map { uri =>
val socket = connect(uri)
connectedToServer.trySuccess(())
socket
compilations
.compilationFinished(targets, compileInverseDependencies = false)
.flatMap { _ =>
val conn =
startDebugSession(buildServer, parameters, cancelPromise)
.map { uri =>
val socket = connect(uri)
connectedToServer.trySuccess(())
socket
}

val startupTimeout =
clientConfig.initialConfig.debugServerStartTimeout

conn
.withTimeout(startupTimeout, TimeUnit.SECONDS)
.recover { case exception =>
connectedToServer.tryFailure(exception)
cancelPromise.trySuccess(())
throw exception
}

val startupTimeout = clientConfig.initialConfig.debugServerStartTimeout

conn
.withTimeout(startupTimeout, TimeUnit.SECONDS)
.recover { case exception =>
connectedToServer.tryFailure(exception)
cancelPromise.trySuccess(())
throw exception
}
}
}
}

val proxyFactory = { () =>
Expand Down
Loading

0 comments on commit 27f8f0d

Please sign in to comment.