Skip to content

Commit

Permalink
outline twice for first compile
Browse files Browse the repository at this point in the history
  • Loading branch information
kasiaMarek committed Feb 13, 2024
1 parent 5bb0ae1 commit 376823c
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 26 deletions.
Expand Up @@ -14,10 +14,19 @@ trait CompilerWrapper[Reporter, Compiler] {

def stop(): Unit

def compiler(changeFiles: List[VirtualFileParams]): Compiler
def compiler(changeFiles: OutlineFiles): Compiler

def compiler(): Compiler = compiler(Nil)
def compiler(): Compiler = compiler(OutlineFiles.empty)

def presentationCompilerThread: Option[Thread]

}

case class OutlineFiles(
files: List[VirtualFileParams],
firstCompileSubstitute: Boolean = false
)

object OutlineFiles {
def empty = OutlineFiles(Nil)
}
12 changes: 11 additions & 1 deletion mtags/src/main/scala-2.13/scala/meta/internal/pc/Compat.scala
Expand Up @@ -26,7 +26,17 @@ trait Compat { this: MetalsGlobal =>
def constantType(c: ConstantType): ConstantType =
if (c.value.isSuitableLiteralType) LiteralType(c.value) else c

def runOutline(files: List[VirtualFileParams]): Unit = {
def runOutline(files: OutlineFiles): Unit = {
runOutline(files.files)
if(files.firstCompileSubstitute) {
// if first compilation substitute we compile all files twice
// first to emit symbols, second so signatures have information about those symbols
// this isn't a perfect strategy but much better than single compile
runOutline(files.files, forceNewUnit = true)
}
}

private def runOutline(files: List[VirtualFileParams], forceNewUnit: Boolean = false): Unit = {
this.settings.Youtline.value = true
files.foreach { params =>
val unit = this.addCompilationUnit(
Expand Down
Expand Up @@ -14,8 +14,8 @@ import scala.meta.pc.VirtualFileParams
class ScalaCompilerWrapper(global: MetalsGlobal)
extends CompilerWrapper[StoreReporter, MetalsGlobal] {

override def compiler(paths: List[VirtualFileParams]): MetalsGlobal = {
global.runOutline(paths)
override def compiler(files: OutlineFiles): MetalsGlobal = {
global.runOutline(files)
global
}

Expand Down
Expand Up @@ -168,7 +168,7 @@ case class ScalaPresentationCompiler(
EmptyCancelToken
) { pc =>
/* we will still want outline recompiled if the compilation was not succesful */
pc.compiler(Nil).richCompilationCache.foreach {
pc.compiler().richCompilationCache.foreach {
case (uriString, unit) =>
try {
val text = unit.source.content.mkString
Expand Down Expand Up @@ -211,23 +211,26 @@ case class ScalaPresentationCompiler(

private def outlineFiles(
current: VirtualFileParams
): List[VirtualFileParams] = {
if (wasFirstCompilationSuccessful.getAndSet(Some(true)).exists(!_)) {
// if first compilation was unsuccessful we want to outline all files
compilerFiles.iterator.flatMap(_.allPaths().asScala).foreach { path =>
val uri = path.toUri()
if (!changedDocuments.contains(uri)) {
val text = Files.readString(path)
changedDocuments += uri -> CompilerOffsetParams(uri, text, 0)
): OutlineFiles = {
val result =
if (wasFirstCompilationSuccessful.getAndSet(Some(true)).exists(!_)) {
// if first compilation was unsuccessful we want to outline all files
compilerFiles.iterator.flatMap(_.allPaths().asScala).foreach { path =>
val uri = path.toUri()
if (!changedDocuments.contains(uri)) {
val text = Files.readString(path)
changedDocuments += uri -> CompilerOffsetParams(uri, text, 0)
}
}
OutlineFiles(changedDocuments.values.toList, firstCompileSubstitute = true)
} else {
val files = changedDocuments.values.filterNot(_.uri() == current.uri()).toList
OutlineFiles(files)
}
}

val results =
changedDocuments.values.filterNot(_.uri() == current.uri()).toList
changedDocuments.clear()
changedDocuments += current.uri() -> current
results
result
}

override def didChange(
Expand All @@ -242,7 +245,7 @@ case class ScalaPresentationCompiler(
(),
EmptyCancelToken
) { pc =>
pc.compiler(Nil).richCompilationCache.remove(uri.toString())
pc.compiler().richCompilationCache.remove(uri.toString())
}
}

Expand Down Expand Up @@ -271,7 +274,7 @@ case class ScalaPresentationCompiler(
params.token
) { pc =>
new PcSyntheticDecorationsProvider(
pc.compiler(Nil),
pc.compiler(),
params
).provide().asJava
}
Expand Down Expand Up @@ -396,7 +399,7 @@ case class ScalaPresentationCompiler(
): CompletableFuture[CompletionItem] =
CompletableFuture.completedFuture {
compilerAccess.withSharedCompiler(None)(item) { pc =>
new CompletionItemResolver(pc.compiler(Nil)).resolve(item, symbol)
new CompletionItemResolver(pc.compiler()).resolve(item, symbol)
}
}

Expand Down Expand Up @@ -511,7 +514,7 @@ case class ScalaPresentationCompiler(
compilerAccess.withSharedCompiler(params.asScala.headOption)(
List.empty[SelectionRange].asJava
) { pc =>
new SelectionRangeProvider(pc.compiler(Nil), params)
new SelectionRangeProvider(pc.compiler(), params)
.selectionRange()
.asJava
}
Expand Down
@@ -1,13 +1,11 @@
package scala.meta.internal.pc

import scala.meta.pc.VirtualFileParams

import dotty.tools.dotc.reporting.StoreReporter

class Scala3CompilerWrapper(driver: MetalsDriver)
extends CompilerWrapper[StoreReporter, MetalsDriver]:

override def compiler(paths: List[VirtualFileParams]): MetalsDriver = driver
override def compiler(paths: OutlineFiles): MetalsDriver = driver

override def resetReporter(): Unit =
val ctx = driver.currentCtx
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/src/test/scala/tests/CompilersLspSuite.scala
Expand Up @@ -228,7 +228,7 @@ class CompilersLspSuite extends BaseCompletionLspSuite("compilers") {
} yield ()
}

test("never-compiling-reverse-order".ignore) {
test("never-compiling-reverse-order") {
cleanWorkspace()
for {
_ <- initialize(
Expand Down

0 comments on commit 376823c

Please sign in to comment.