From 2add119d9f50b60f45c1ec5a34a80c9b6babc09a Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 14 Oct 2019 17:22:47 +0200 Subject: [PATCH] Make find implementation run on a separate thread for each file --- .../ImplementationProvider.scala | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/metals/src/main/scala/scala/meta/internal/implementation/ImplementationProvider.scala b/metals/src/main/scala/scala/meta/internal/implementation/ImplementationProvider.scala index 22b439b32b8..18b298cb25f 100644 --- a/metals/src/main/scala/scala/meta/internal/implementation/ImplementationProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/implementation/ImplementationProvider.scala @@ -27,6 +27,8 @@ import scala.collection.mutable import scala.meta.internal.symtab.GlobalSymbolTable import scala.util.control.NonFatal import scala.meta.internal.mtags.Mtags +import scala.concurrent.ExecutionContext +import java.util.concurrent.ConcurrentLinkedQueue final class ImplementationProvider( semanticdbs: Semanticdbs, @@ -35,7 +37,7 @@ final class ImplementationProvider( buildTargets: BuildTargets, buffer: Buffers, definitionProvider: DefinitionProvider -) { +)(implicit ec: ExecutionContext) { import ImplementationProvider._ private val globalTable = new GlobalClassTable(buildTargets) @@ -81,7 +83,9 @@ final class ImplementationProvider( } } - def implementations(params: TextDocumentPositionParams): List[Location] = { + def implementations( + params: TextDocumentPositionParams + ): List[Location] = { val source = params.getTextDocument.getUri.toAbsolutePath lazy val global = globalTable.globalSymbolTableFor(source) val locations = for { @@ -177,29 +181,37 @@ final class ImplementationProvider( } import TokenEditDistance.fromBuffer - + val allLocations = new ConcurrentLinkedQueue[Location] for { classContext <- inheritanceContext.toIterable plainParentSymbol <- classContext.findSymbol(symbol).toIterable parentSymbol = addParameterSignatures(plainParentSymbol, classContext) symbolClass <- classFromSymbol(parentSymbol, classContext.findSymbol) - (file, locations) <- findImplementation(symbolClass.symbol, classContext) - implPath = AbsolutePath(file) - implDocument <- findSemanticdb(implPath).toIterable - distance = fromBuffer(implPath, implDocument.text, buffer) - implLocation <- locations - implReal = implLocation.toRealNames(symbolClass, translateKey = true) - implSymbol <- findImplementationSymbol( - parentSymbol, - implDocument, - symbolClass, - classContext, - implReal - ) - implOccurrence <- findDefOccurrence(implDocument, implSymbol, source) - range <- implOccurrence.range - revised <- distance.toRevised(range.toLSP) - } yield new Location(file.toUri.toString, revised) + parallelMap = findImplementation( + symbolClass.symbol, + classContext + ).par + } parallelMap.foreach { + case (file, locations) => + val implPath = AbsolutePath(file) + for { + implDocument <- findSemanticdb(implPath).toIterable + distance = fromBuffer(implPath, implDocument.text, buffer) + implLocation <- locations + implReal = implLocation.toRealNames(symbolClass, translateKey = true) + implSymbol <- findImplementationSymbol( + parentSymbol, + implDocument, + symbolClass, + classContext, + implReal + ) + implOccurence <- findDefOccurrence(implDocument, implSymbol, source) + range <- implOccurence.range + revised <- distance.toRevised(range.toLSP) + } allLocations.add(new Location(file.toUri.toString, revised)) + } + allLocations.asScala } private def findSemanticdb(fileSource: AbsolutePath): Option[TextDocument] =