Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move logic outline files logic out of pc
- Loading branch information
1 parent
f31b404
commit d1060a8
Showing
25 changed files
with
704 additions
and
319 deletions.
There are no files selected for viewing
303 changes: 204 additions & 99 deletions
303
metals/src/main/scala/scala/meta/internal/metals/Compilers.scala
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
191 changes: 191 additions & 0 deletions
191
metals/src/main/scala/scala/meta/internal/metals/OutlineFilesProvider.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
package scala.meta.internal.metals | ||
|
||
import java.util.Optional | ||
import java.util.concurrent.atomic.AtomicBoolean | ||
import java.{util => ju} | ||
|
||
import scala.collection.concurrent.TrieMap | ||
|
||
import scala.meta.internal.metals.MetalsEnrichments._ | ||
import scala.meta.io.AbsolutePath | ||
import scala.meta.pc.VirtualFileParams | ||
import scala.meta.pc.{OutlineFiles => JOutlineFiles} | ||
|
||
import ch.epfl.scala.bsp4j.BuildTargetIdentifier | ||
|
||
class OutlineFilesProvider( | ||
buildTargets: BuildTargets, | ||
buffers: Buffers, | ||
) { | ||
private val outlineFiles = | ||
new TrieMap[BuildTargetIdentifier, BuildTargetOutlineFilesProvider]() | ||
|
||
def shouldRestartPc( | ||
id: BuildTargetIdentifier, | ||
reason: PcRestartReason, | ||
): Boolean = { | ||
reason match { | ||
case DidCompile(true) => true | ||
case _ => | ||
outlineFiles.get(id) match { | ||
case Some(provider) => | ||
// if it was never compiled successfully by the build server | ||
// we don't restart pc not to lose information from outline compile | ||
provider.wasSuccessfullyCompiledByBuildServer | ||
case None => true | ||
} | ||
} | ||
} | ||
|
||
def onDidCompile(id: BuildTargetIdentifier, wasSuccessful: Boolean): Unit = { | ||
outlineFiles.get(id) match { | ||
case Some(provider) => | ||
if (wasSuccessful) provider.successfulCompilation() | ||
case None => | ||
for { | ||
scalaTarget <- buildTargets.scalaTarget(id) | ||
// we don't perform outline compilation for Scala 3 | ||
if (!ScalaVersions.isScala3Version(scalaTarget.scalaVersion)) | ||
} outlineFiles.putIfAbsent( | ||
id, | ||
new BuildTargetOutlineFilesProvider( | ||
buildTargets, | ||
buffers, | ||
id, | ||
wasSuccessful, | ||
), | ||
) | ||
} | ||
} | ||
|
||
def didChange(id: BuildTargetIdentifier, path: AbsolutePath): Unit = { | ||
for { | ||
provider <- outlineFiles.get(id) | ||
} provider.didChange(path) | ||
} | ||
|
||
def getOutlineFiles( | ||
buildTargetId: Option[BuildTargetIdentifier] | ||
): Optional[JOutlineFiles] = { | ||
val res: Option[JOutlineFiles] = | ||
for { | ||
id <- buildTargetId | ||
provider <- outlineFiles.get(id) | ||
outlineFiles <- provider.outlineFiles() | ||
} yield outlineFiles | ||
res.asJava | ||
} | ||
|
||
def enrichWithOutlineFiles( | ||
buildTargetId: Option[BuildTargetIdentifier] | ||
)(vFile: CompilerVirtualFileParams): CompilerVirtualFileParams = { | ||
val optOutlineFiles = | ||
for { | ||
id <- buildTargetId | ||
provider <- outlineFiles.get(id) | ||
outlineFiles <- provider.outlineFiles() | ||
} yield outlineFiles | ||
|
||
optOutlineFiles | ||
.map(outlineFiles => vFile.copy(outlineFiles = Optional.of(outlineFiles))) | ||
.getOrElse(vFile) | ||
} | ||
|
||
def enrichWithOutlineFiles( | ||
path: AbsolutePath | ||
)(vFile: CompilerVirtualFileParams): CompilerVirtualFileParams = { | ||
val optOutlineFiles = | ||
for { | ||
bt <- buildTargets.inferBuildTarget(path) | ||
provider <- outlineFiles.get(bt) | ||
outlineFiles <- provider.outlineFiles() | ||
} yield outlineFiles | ||
|
||
optOutlineFiles | ||
.map(outlineFiles => vFile.copy(outlineFiles = Optional.of(outlineFiles))) | ||
.getOrElse(vFile) | ||
} | ||
|
||
def clear(): Unit = { | ||
outlineFiles.clear() | ||
} | ||
} | ||
|
||
class BuildTargetOutlineFilesProvider( | ||
buildTargets: BuildTargets, | ||
buffers: Buffers, | ||
id: BuildTargetIdentifier, | ||
wasCompilationSuccessful: Boolean, | ||
) { | ||
private val changedDocuments = | ||
ConcurrentHashSet.empty[AbsolutePath] | ||
|
||
private val wasAllOutlined: AtomicBoolean = | ||
new AtomicBoolean(false) | ||
|
||
private val wasSuccessfullyCompiled: AtomicBoolean = | ||
new AtomicBoolean(wasCompilationSuccessful) | ||
|
||
def wasSuccessfullyCompiledByBuildServer: Boolean = | ||
wasSuccessfullyCompiled.get() | ||
|
||
def successfulCompilation(): Unit = { | ||
wasSuccessfullyCompiled.set(true) | ||
changedDocuments.clear() | ||
} | ||
|
||
def didChange(path: AbsolutePath): Boolean = | ||
changedDocuments.add(path) | ||
|
||
def outlineFiles(): Option[OutlineFiles] = { | ||
if (!wasSuccessfullyCompiled.get() && !wasAllOutlined.getAndSet(true)) { | ||
// initial outline compilation that is a substitute for build server compilation | ||
val allFiles = | ||
buildTargets | ||
.buildTargetSources(id) | ||
.flatMap(_.listRecursive.toList) | ||
.flatMap(toVirtualFileParams(_)) | ||
.toList | ||
.asJava | ||
Some( | ||
OutlineFiles( | ||
allFiles, | ||
isFirstCompileSubstitute = true, | ||
) | ||
) | ||
} else { | ||
changedDocuments.asScala.toList.flatMap( | ||
toVirtualFileParams | ||
) match { | ||
case Nil => None | ||
case files => | ||
Some( | ||
OutlineFiles( | ||
files.asJava, | ||
isFirstCompileSubstitute = false, | ||
) | ||
) | ||
} | ||
} | ||
} | ||
|
||
private def toVirtualFileParams( | ||
path: AbsolutePath | ||
): Option[VirtualFileParams] = | ||
buffers.get(path).orElse(path.readTextOpt).map { text => | ||
CompilerVirtualFileParams( | ||
path.toURI, | ||
text, | ||
) | ||
} | ||
|
||
} | ||
|
||
sealed trait PcRestartReason | ||
case object InverseDependency extends PcRestartReason | ||
case class DidCompile(wasSuccess: Boolean) extends PcRestartReason | ||
|
||
case class OutlineFiles( | ||
files: ju.List[VirtualFileParams], | ||
isFirstCompileSubstitute: Boolean = false, | ||
) extends JOutlineFiles |
6 changes: 0 additions & 6 deletions
6
mtags-interfaces/src/main/java/scala/meta/pc/CompilerFiles.java
This file was deleted.
Oops, something went wrong.
16 changes: 16 additions & 0 deletions
16
mtags-interfaces/src/main/java/scala/meta/pc/OutlineFiles.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package scala.meta.pc; | ||
import java.util.List; | ||
|
||
public interface OutlineFiles { | ||
|
||
/** | ||
* Will this outline compilation be substitute for build server's compilation. | ||
* Used if the first compilation using build server is unsuccessful. | ||
*/ | ||
boolean isFirstCompileSubstitute(); | ||
|
||
/** | ||
* Files that should be outline compiled before calculating result. | ||
*/ | ||
List<VirtualFileParams> files(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 30 additions & 3 deletions
33
mtags-shared/src/main/scala/scala/meta/internal/metals/CompilerOffsetParams.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,57 @@ | ||
package scala.meta.internal.metals | ||
|
||
import java.net.URI | ||
import java.util.Optional | ||
|
||
import scala.meta.pc.CancelToken | ||
import scala.meta.pc.OffsetParams | ||
import scala.meta.pc.OutlineFiles | ||
import scala.meta.pc.RangeParams | ||
|
||
case class CompilerOffsetParams( | ||
uri: URI, | ||
text: String, | ||
offset: Int, | ||
token: CancelToken = EmptyCancelToken | ||
token: CancelToken, | ||
override val outlineFiles: Optional[OutlineFiles] | ||
) extends OffsetParams | ||
|
||
object CompilerOffsetParams { | ||
def apply( | ||
uri: URI, | ||
text: String, | ||
offset: Int, | ||
token: CancelToken = EmptyCancelToken | ||
): CompilerOffsetParams = | ||
CompilerOffsetParams(uri, text, offset, token, Optional.empty()) | ||
} | ||
|
||
case class CompilerRangeParams( | ||
uri: URI, | ||
text: String, | ||
offset: Int, | ||
endOffset: Int, | ||
token: CancelToken = EmptyCancelToken | ||
token: CancelToken, | ||
override val outlineFiles: Optional[OutlineFiles] | ||
) extends RangeParams { | ||
|
||
def toCompilerOffsetParams: CompilerOffsetParams = | ||
CompilerOffsetParams( | ||
uri, | ||
text, | ||
offset, | ||
token | ||
token, | ||
outlineFiles | ||
) | ||
} | ||
|
||
object CompilerRangeParams { | ||
def apply( | ||
uri: URI, | ||
text: String, | ||
offset: Int, | ||
endOffset: Int, | ||
token: CancelToken = EmptyCancelToken | ||
): CompilerRangeParams = | ||
CompilerRangeParams(uri, text, offset, endOffset, token, Optional.empty()) | ||
} |
Oops, something went wrong.