diff --git a/metals-bench/src/main/scala/bench/ClasspathFuzzBench.scala b/metals-bench/src/main/scala/bench/ClasspathFuzzBench.scala index d60bea30ca9..8239900417a 100644 --- a/metals-bench/src/main/scala/bench/ClasspathFuzzBench.scala +++ b/metals-bench/src/main/scala/bench/ClasspathFuzzBench.scala @@ -46,7 +46,7 @@ class ClasspathFuzzBench { @BenchmarkMode(Array(Mode.SingleShotTime)) @OutputTimeUnit(TimeUnit.MILLISECONDS) def run(): Seq[SymbolInformation] = { - symbols.search(query) + symbols.search(query, None) } } diff --git a/metals-bench/src/main/scala/bench/WorkspaceFuzzBench.scala b/metals-bench/src/main/scala/bench/WorkspaceFuzzBench.scala index df8a0f7e38f..c1328e1d62a 100644 --- a/metals-bench/src/main/scala/bench/WorkspaceFuzzBench.scala +++ b/metals-bench/src/main/scala/bench/WorkspaceFuzzBench.scala @@ -37,7 +37,7 @@ class WorkspaceFuzzBench { @BenchmarkMode(Array(Mode.SingleShotTime)) @OutputTimeUnit(TimeUnit.MILLISECONDS) def upper(): Seq[SymbolInformation] = { - symbols.search(query) + symbols.search(query, None) } } diff --git a/metals/src/main/scala/scala/meta/internal/metals/DefinitionProvider.scala b/metals/src/main/scala/scala/meta/internal/metals/DefinitionProvider.scala index 249a1b53847..cd76c4ce507 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/DefinitionProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/DefinitionProvider.scala @@ -175,8 +175,9 @@ final class DefinitionProvider( else true } + val dialect = scalaVersionSelector.dialectFromBuildTarget(path) val locs = workspaceSearch - .searchExactFrom(ident.value, path, token) + .searchExactFrom(ident.value, path, token, dialect) val reducedGuesses = if (locs.size > 1) diff --git a/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala b/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala index 22e08c5ab8e..65b050432b4 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/MetalsLspService.scala @@ -1677,7 +1677,8 @@ class MetalsLspService( ): Future[List[SymbolInformation]] = indexingPromise.future.map { _ => val timer = new Timer(time) - val result = workspaceSymbols.search(params.getQuery, token).toList + val result = + workspaceSymbols.search(params.getQuery, token, currentDialect).toList if (clientConfig.initialConfig.statistics.isWorkspaceSymbol) { scribe.info( s"time: found ${result.length} results for query '${params.getQuery}' in $timer" @@ -1687,9 +1688,12 @@ class MetalsLspService( } def workspaceSymbol(query: String): Seq[SymbolInformation] = { - workspaceSymbols.search(query) + workspaceSymbols.search(query, currentDialect) } + private def currentDialect = + focusedDocument().flatMap(scalaVersionSelector.dialectFromBuildTarget) + def indexSources(): Future[Unit] = Future { indexer.indexWorkspaceSources(buildTargets.allWritableData) } diff --git a/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSearchVisitor.scala b/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSearchVisitor.scala index 796b86ed4cb..3a40891b1a3 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSearchVisitor.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSearchVisitor.scala @@ -5,6 +5,7 @@ import java.{util => ju} import scala.collection.mutable +import scala.meta.Dialect import scala.meta.internal.metals.MetalsEnrichments._ import scala.meta.internal.mtags.GlobalSymbolIndex import scala.meta.internal.mtags.Symbol @@ -32,6 +33,7 @@ class WorkspaceSearchVisitor( token: CancelChecker, index: GlobalSymbolIndex, saveClassFileToDisk: Boolean, + preferredDialect: Option[Dialect], )(implicit rc: ReportContext) extends SymbolSearchVisitor { private val fromWorkspace = new ju.ArrayList[l.SymbolInformation]() @@ -94,8 +96,20 @@ class WorkspaceSearchVisitor( val term = Symbol(Symbols.Global(pkg, Descriptor.Term(nme))) index.definitions(term) } else forTpe - - defs.sortBy(_.path.toURI.toString).headOption + val chosenDefs = + preferredDialect match { + case None => defs + case Some(preferredDialect) => + val dialects = Set( + preferredDialect.toString(), + preferredDialect.toString() ++ "Source3", + ) + val withPreferredDialect = + defs.filter(defn => dialects.contains(defn.dialect.toString)) + if (withPreferredDialect.nonEmpty) withPreferredDialect + else defs + } + chosenDefs.sortBy(_.path.toURI.toString).headOption } override def shouldVisitPackage(pkg: String): Boolean = true override def visitWorkspaceSymbol( diff --git a/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSymbolProvider.scala b/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSymbolProvider.scala index ee90b0900da..c9cde2b03f6 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSymbolProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/WorkspaceSymbolProvider.scala @@ -6,6 +6,7 @@ import java.nio.file.Path import scala.collection.concurrent.TrieMap import scala.util.control.NonFatal +import scala.meta.Dialect import scala.meta.internal.mtags.GlobalSymbolIndex import scala.meta.internal.pc.InterruptException import scala.meta.io.AbsolutePath @@ -39,14 +40,21 @@ final class WorkspaceSymbolProvider( var inDependencies: ClasspathSearch = ClasspathSearch.empty - def search(query: String): Seq[l.SymbolInformation] = { - search(query, () => ()) + def search( + query: String, + preferredDialect: Option[Dialect], + ): Seq[l.SymbolInformation] = { + search(query, () => (), preferredDialect) } - def search(query: String, token: CancelChecker): Seq[l.SymbolInformation] = { + def search( + query: String, + token: CancelChecker, + preferredDialect: Option[Dialect], + ): Seq[l.SymbolInformation] = { if (query.isEmpty) return Nil try { - searchUnsafe(query, token) + searchUnsafe(query, token, preferredDialect) } catch { case InterruptException() => Nil @@ -57,6 +65,7 @@ final class WorkspaceSymbolProvider( queryString: String, path: AbsolutePath, token: CancelToken, + preferredDialect: Option[Dialect], ): Seq[l.SymbolInformation] = { val query = WorkspaceSymbolQuery.exact(queryString) val visistor = @@ -66,6 +75,7 @@ final class WorkspaceSymbolProvider( token, index, saveClassFileToDisk, + preferredDialect, ) val targetId = buildTargets.inverseSources(path) search(query, visistor, targetId) @@ -205,6 +215,7 @@ final class WorkspaceSymbolProvider( private def searchUnsafe( textQuery: String, token: CancelChecker, + preferredDialect: Option[Dialect], ): Seq[l.SymbolInformation] = { val query = WorkspaceSymbolQuery.fromTextQuery(textQuery) val visitor = @@ -214,6 +225,7 @@ final class WorkspaceSymbolProvider( token, index, saveClassFileToDisk, + preferredDialect, ) search(query, visitor, None) visitor.allResults() diff --git a/tests/unit/src/main/scala/tests/BaseWorkspaceSymbolSuite.scala b/tests/unit/src/main/scala/tests/BaseWorkspaceSymbolSuite.scala index c58bc898a33..d09f8e5e7c0 100644 --- a/tests/unit/src/main/scala/tests/BaseWorkspaceSymbolSuite.scala +++ b/tests/unit/src/main/scala/tests/BaseWorkspaceSymbolSuite.scala @@ -25,7 +25,7 @@ abstract class BaseWorkspaceSymbolSuite extends BaseSuite { expected: String, )(implicit loc: Location): Unit = { test(query) { - val result = symbols.search(query) + val result = symbols.search(query, None) val obtained = if (result.length > 100) s"${result.length} results" else { diff --git a/tests/unit/src/main/scala/tests/debug/BaseStepDapSuite.scala b/tests/unit/src/main/scala/tests/debug/BaseStepDapSuite.scala index ac56b5dd688..a598c8ae062 100644 --- a/tests/unit/src/main/scala/tests/debug/BaseStepDapSuite.scala +++ b/tests/unit/src/main/scala/tests/debug/BaseStepDapSuite.scala @@ -89,6 +89,7 @@ abstract class BaseStepDapSuite( .at("a/src/main/scala/a/ScalaMain.scala", line = 5)(StepIn) .at("a/src/main/java/a/JavaClass.java", line = 5)(StepOut) .at("a/src/main/scala/a/ScalaMain.scala", line = 6)(Continue), + focusFile = "a/src/main/scala/a/ScalaMain.scala", ) assertSteps("step-into-scala-lib", withoutVirtualDocs = true)( @@ -162,12 +163,14 @@ abstract class BaseStepDapSuite( steps .at("a/src/main/scala/a/Main.scala", line = 6)(Continue) .at("a/src/main/scala/a/Main.scala", line = 13)(Continue), + focusFile = "a/src/main/scala/a/Main.scala", ) def assertSteps(name: TestOptions, withoutVirtualDocs: Boolean = false)( sources: String, main: String, instrument: StepNavigator => StepNavigator, + focusFile: String = "a/src/main/scala/Main.scala", )(implicit loc: Location): Unit = { test(name, withoutVirtualDocs) { cleanWorkspace() @@ -176,6 +179,7 @@ abstract class BaseStepDapSuite( for { _ <- initialize(workspaceLayout) + _ <- server.didFocus(focusFile) navigator = instrument(StepNavigator(workspace)) debugger <- debugMain("a", main, navigator) _ <- debugger.initialize