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 5e0a84afec6..57a30646891 100644
--- a/metals/src/main/scala/scala/meta/internal/implementation/ImplementationProvider.scala
+++ b/metals/src/main/scala/scala/meta/internal/implementation/ImplementationProvider.scala
@@ -396,7 +396,8 @@ final class ImplementationProvider(
   }
 
   private def semanticdbForJarFile(fileSource: AbsolutePath) = {
-    val dialect = ScalaVersions.dialectForDependencyJar(fileSource.filename)
+    val dialect =
+      ScalaVersions.dialectForDependencyJar(fileSource, buildTargets)
     FileIO.slurp(fileSource, StandardCharsets.UTF_8)
     val textDocument = Mtags.index(fileSource, dialect)
     textDocument
diff --git a/metals/src/main/scala/scala/meta/internal/metals/BuildTargets.scala b/metals/src/main/scala/scala/meta/internal/metals/BuildTargets.scala
index 9226f663cff..476c37a6ba6 100644
--- a/metals/src/main/scala/scala/meta/internal/metals/BuildTargets.scala
+++ b/metals/src/main/scala/scala/meta/internal/metals/BuildTargets.scala
@@ -430,14 +430,31 @@ final class BuildTargets private (
    * in other capacity than as a fallback, since both source jar
    * and normal jar might not be in the same directory.
    *
-   * @param sourceJarPath path to the nromaljar
+   * @param sourceJarPath path to the normal jar
    * @return path to the source jar for that jar
    */
   private def sourceJarPathFallback(
       sourceJarPath: AbsolutePath
-  ): Option[AbsolutePath] = {
-    val fallback = sourceJarPath.parent.resolve(
-      sourceJarPath.filename.replace(".jar", "-sources.jar")
+  ): Option[AbsolutePath] =
+    findInTheSameDirectoryWithReplace(sourceJarPath, ".jar", "-sources.jar")
+
+  /**
+   * Try to resolve path to normal jar from source jar,
+   * should only be used as fallback, since jar and source jar
+   * do not have to be in the same directory.
+   */
+  private def jarFromSourceJarFallback(
+      jarPath: AbsolutePath
+  ): Option[AbsolutePath] =
+    findInTheSameDirectoryWithReplace(jarPath, "-sources.jar", ".jar")
+
+  private def findInTheSameDirectoryWithReplace(
+      path: AbsolutePath,
+      fromPattern: String,
+      toPattern: String,
+  ) = {
+    val fallback = path.parent.resolve(
+      path.filename.replace(fromPattern, toPattern)
     )
     if (fallback.exists) Some(fallback)
     else None
@@ -578,7 +595,7 @@ final class BuildTargets private (
       jar: AbsolutePath,
   ): Option[AbsolutePath] = {
     data
-      .fromOptions(_.findSourceJarOf(jar, Some(id)))
+      .fromOptions(_.findConnectedArtifact(jar, Some(id)))
       .orElse(sourceJarPathFallback(jar))
   }
 
@@ -586,10 +603,21 @@ final class BuildTargets private (
       jar: AbsolutePath
   ): Option[AbsolutePath] = {
     data
-      .fromOptions(_.findSourceJarOf(jar, targetId = None))
+      .fromOptions(_.findConnectedArtifact(jar, targetId = None))
       .orElse(sourceJarPathFallback(jar))
   }
 
+  def findJarFor(
+      id: BuildTargetIdentifier,
+      sourceJar: AbsolutePath,
+  ): Option[AbsolutePath] = {
+    data
+      .fromOptions(
+        _.findConnectedArtifact(sourceJar, Some(id), classifier = null)
+      )
+      .orElse(jarFromSourceJarFallback(sourceJar))
+  }
+
   def inverseDependencySource(
       sourceJar: AbsolutePath
   ): collection.Set[BuildTargetIdentifier] = {
diff --git a/metals/src/main/scala/scala/meta/internal/metals/Indexer.scala b/metals/src/main/scala/scala/meta/internal/metals/Indexer.scala
index d9d8dcfa93b..90922ae0f92 100644
--- a/metals/src/main/scala/scala/meta/internal/metals/Indexer.scala
+++ b/metals/src/main/scala/scala/meta/internal/metals/Indexer.scala
@@ -415,7 +415,7 @@ case class Indexer(indexProviders: IndexProviders)(implicit rc: ReportContext) {
       case Right(zip) =>
         scribe.debug(s"Indexing JDK sources from $zip")
         usedJars += zip
-        val dialect = ScalaVersions.dialectForDependencyJar(zip.filename)
+        val dialect = ScalaVersions.dialectForDependencyJar(zip, buildTargets)
         sharedIndices.jvmTypeHierarchy.getTypeHierarchy(zip) match {
           case Some(overrides) =>
             definitionIndex.addIndexedSourceJar(zip, Nil, dialect)
@@ -540,7 +540,7 @@ case class Indexer(indexProviders: IndexProviders)(implicit rc: ReportContext) {
    * @param path JAR path
    */
   private def addSourceJarSymbols(path: AbsolutePath): Unit = {
-    val dialect = ScalaVersions.dialectForDependencyJar(path.filename)
+    val dialect = ScalaVersions.dialectForDependencyJar(path, buildTargets)
     tables.jarSymbols.getTopLevels(path) match {
       case Some(toplevels) =>
         tables.jarSymbols.getTypeHierarchy(path) match {
diff --git a/metals/src/main/scala/scala/meta/internal/metals/ScalaVersions.scala b/metals/src/main/scala/scala/meta/internal/metals/ScalaVersions.scala
index 4fac1a21a94..bcae4c1e9c0 100644
--- a/metals/src/main/scala/scala/meta/internal/metals/ScalaVersions.scala
+++ b/metals/src/main/scala/scala/meta/internal/metals/ScalaVersions.scala
@@ -1,8 +1,15 @@
 package scala.meta.internal.metals
 
+import java.io.UncheckedIOException
+
+import scala.collection.concurrent.TrieMap
+
 import scala.meta.Dialect
 import scala.meta.dialects._
+import scala.meta.internal.io.FileIO
+import scala.meta.internal.metals.MetalsEnrichments._
 import scala.meta.internal.semver.SemVer
+import scala.meta.io.AbsolutePath
 
 class ScalaVersions(
     deprecatedScalaVersions: Seq[String],
@@ -13,6 +20,8 @@ class ScalaVersions(
     scala3: String,
 ) {
 
+  private val jarScalaVersionIndex = TrieMap[String, String]()
+
   def isScala3Milestone(version: String): Boolean =
     version.startsWith("3.0.0-M") || version.startsWith("3.0.0-RC")
 
@@ -150,7 +159,9 @@ class ScalaVersions(
   }
 
   private val scalaVersionRegex =
-    raw"(_)(\d)(\.\d{1,2})?(\.\d(-(RC|M)\d)?)?".r
+    raw"_(\d)(\.\d{1,2})?(\.\d(-(RC|M)\d)?)?".r
+  private val scalaLibraryRegex =
+    raw"scala-library-(\d)(\.\d{1,2})(\.\d(-(RC|M)\d)?)".r
 
   /**
    * Extract scala binary version from dependency jar name.
@@ -160,35 +171,66 @@ class ScalaVersions(
    *   `some-library_2.13-4.5.0` -> 2.13
    *   `some-library_2.13-2.11` -> 2.13
    */
-  def scalaBinaryVersionFromJarName(filename: String): String = {
+  def scalaBinaryVersionFromJarName(filename: String): Option[String] = {
     val dropEnding = filename
       .stripSuffix(".jar")
 
-    scalaVersionRegex
-      .findAllMatchIn(dropEnding)
-      .toList
+    List(scalaLibraryRegex, scalaVersionRegex)
+      .flatMap(_.findAllMatchIn(dropEnding).toList)
       .flatMap { m =>
-        val hasUnderscorePrefix = Option(m.group(1)).isDefined
-        val major = m.group(2)
-        val minor = Option(m.group(3)).getOrElse("")
-        val ending = Option(m.group(4)).getOrElse("")
+        val major = m.group(1)
+        val minor = Option(m.group(2)).getOrElse("")
+        val ending = Option(m.group(3)).getOrElse("")
         val version = s"$major$minor$ending"
 
         if (isSupportedScalaBinaryVersion(version))
-          Some(version -> hasUnderscorePrefix)
+          Some(version)
         else None
       }
-      .sortBy(_._2)(Ordering.Boolean.reverse)
       .headOption
-      .map { case (version, _) => scalaBinaryVersionFromFullVersion(version) }
-      .getOrElse("2.13")
+      .map(scalaBinaryVersionFromFullVersion)
   }
 
-  def dialectForDependencyJar(filename: String): Dialect =
-    dialectForScalaVersion(
-      scalaBinaryVersionFromJarName(filename),
-      includeSource3 = true,
-    )
+  def dialectForDependencyJar(
+      jar: AbsolutePath,
+      buildTargets: BuildTargets,
+  ): Dialect = {
+    lazy val buildTargetAndScalaVersion =
+      buildTargets
+        .inverseDependencySource(jar)
+        .flatMap(id => buildTargets.scalaTarget(id))
+        .map(target => (target.scalaBinaryVersion, target.id))
+        .toList
+        .sortBy(_._1)
+        .headOption
+
+    def fromTastyExistance = {
+      val fromTasty = buildTargetAndScalaVersion
+        .flatMap { case (_, id) => buildTargets.findJarFor(id, jar) }
+        .flatMap(
+          FileIO.withJarFileSystem(_, create = false) { root =>
+            try {
+              root.listRecursive
+                .find(f => f.isFile && f.filename.endsWith(".tasty"))
+                .map(_ => "3")
+                .orElse(Some("2.13"))
+            } catch {
+              case _: UncheckedIOException => None
+            }
+          }
+        )
+      fromTasty.foreach(jarScalaVersionIndex.put(jar.toURI.toString(), _))
+      fromTasty
+    }
+
+    val scalaVersion =
+      scalaBinaryVersionFromJarName(jar.toNIO.getFileName().toString())
+        .orElse(jarScalaVersionIndex.get(jar.toURI.toString()))
+        .orElse(fromTastyExistance)
+        .orElse(buildTargetAndScalaVersion.map(_._1))
+        .getOrElse("2.13")
+    dialectForScalaVersion(scalaVersion, includeSource3 = true)
+  }
 
 }
 
diff --git a/metals/src/main/scala/scala/meta/internal/metals/StandaloneSymbolSearch.scala b/metals/src/main/scala/scala/meta/internal/metals/StandaloneSymbolSearch.scala
index c9f257dabe1..77834b033cf 100644
--- a/metals/src/main/scala/scala/meta/internal/metals/StandaloneSymbolSearch.scala
+++ b/metals/src/main/scala/scala/meta/internal/metals/StandaloneSymbolSearch.scala
@@ -44,7 +44,10 @@ class StandaloneSymbolSearch(
 
   private val index = OnDemandSymbolIndex.empty()
   sources.foreach(s =>
-    index.addSourceJar(s, ScalaVersions.dialectForDependencyJar(s.filename))
+    index.addSourceJar(
+      s,
+      ScalaVersions.dialectForDependencyJar(s, buildTargets),
+    )
   )
 
   private val docs = new Docstrings(index)
diff --git a/metals/src/main/scala/scala/meta/internal/metals/TargetData.scala b/metals/src/main/scala/scala/meta/internal/metals/TargetData.scala
index b3ee4f757f5..bb868f60409 100644
--- a/metals/src/main/scala/scala/meta/internal/metals/TargetData.scala
+++ b/metals/src/main/scala/scala/meta/internal/metals/TargetData.scala
@@ -206,9 +206,10 @@ final class TargetData {
     }
   }
 
-  def findSourceJarOf(
+  def findConnectedArtifact(
       jar: AbsolutePath,
       targetId: Option[BuildTargetIdentifier],
+      classifier: String = "sources",
   ): Option[AbsolutePath] = {
     val jarUri = jar.toURI.toString()
     def depModules: Iterator[MavenDependencyModule] = targetId match {
@@ -228,10 +229,10 @@ final class TargetData {
       module <- depModules
       artifacts = module.getArtifacts().asScala
       if artifacts.exists(artifact => isUriEqual(artifact.getUri(), jarUri))
-      sourceJar <- artifacts.find(_.getClassifier() == "sources")
-      sourceJarPath = sourceJar.getUri().toAbsolutePath
-      if sourceJarPath.exists
-    } yield sourceJarPath
+      foundJar <- artifacts.find(_.getClassifier() == classifier)
+      foundJarPath = foundJar.getUri().toAbsolutePath
+      if foundJarPath.exists
+    } yield foundJarPath
     allFound.headOption
   }
 
diff --git a/metals/src/main/scala/scala/meta/internal/tvp/MetalsTreeViewProvider.scala b/metals/src/main/scala/scala/meta/internal/tvp/MetalsTreeViewProvider.scala
index 7ffb0429971..dc53d989fed 100644
--- a/metals/src/main/scala/scala/meta/internal/tvp/MetalsTreeViewProvider.scala
+++ b/metals/src/main/scala/scala/meta/internal/tvp/MetalsTreeViewProvider.scala
@@ -132,9 +132,8 @@ class MetalsTreeViewProvider(
     val dialect =
       if (path.isJarFileSystem) {
         path.jarPath
-          .map { p =>
-            ScalaVersions.dialectForDependencyJar(p.filename)
-          }
+          .flatMap(p => ScalaVersions.scalaBinaryVersionFromJarName(p.filename))
+          .map(ScalaVersions.dialectForScalaVersion(_, includeSource3 = true))
           .getOrElse(dialects.Scala3)
       } else dialectFromWorkspace
     val input = path.toInput
@@ -264,7 +263,7 @@ class FolderTreeViewProvider(
     valueTooltip = _.toString,
     toplevels = () => buildTargets.allSourceJars.filter(_.exists),
     loadSymbols = (path, symbol) => {
-      val dialect = ScalaVersions.dialectForDependencyJar(path.filename)
+      val dialect = ScalaVersions.dialectForDependencyJar(path, buildTargets)
       classpath.jarSymbols(path, symbol, dialect)
     },
     toplevelIcon = "package",
diff --git a/tests/unit/src/main/scala/tests/MetalsTestEnrichments.scala b/tests/unit/src/main/scala/tests/MetalsTestEnrichments.scala
index e66107e6e66..cb0835fbd04 100644
--- a/tests/unit/src/main/scala/tests/MetalsTestEnrichments.scala
+++ b/tests/unit/src/main/scala/tests/MetalsTestEnrichments.scala
@@ -106,7 +106,11 @@ object MetalsTestEnrichments {
       }
       libraries.foreach(
         _.sources.entries.foreach { s =>
-          val dialect = ScalaVersions.dialectForDependencyJar(s.filename)
+          val version = ScalaVersions
+            .scalaBinaryVersionFromJarName(s.filename)
+            .getOrElse("2.13")
+          val dialect =
+            ScalaVersions.dialectForScalaVersion(version, includeSource3 = true)
           wsp.index.addSourceJar(s, dialect)
         }
       )
diff --git a/tests/unit/src/test/scala/tests/DefinitionSuite.scala b/tests/unit/src/test/scala/tests/DefinitionSuite.scala
index a9f838bd8de..3a2b2f98d59 100644
--- a/tests/unit/src/test/scala/tests/DefinitionSuite.scala
+++ b/tests/unit/src/test/scala/tests/DefinitionSuite.scala
@@ -45,9 +45,15 @@ abstract class DefinitionSuiteBase(
     // Step 2. Index dependency sources
     index.addSourceJar(JdkSources().right.get, dialect)
     input.dependencySources.entries.foreach { jar =>
+      val scalaVersion = ScalaVersions
+        .scalaBinaryVersionFromJarName(jar.filename)
+        .getOrElse("2.13")
       index.addSourceJar(
         jar,
-        ScalaVersions.dialectForDependencyJar(jar.filename),
+        ScalaVersions.dialectForScalaVersion(
+          scalaVersion,
+          includeSource3 = true,
+        ),
       )
     }
 
diff --git a/tests/unit/src/test/scala/tests/ScalaVersionsSuite.scala b/tests/unit/src/test/scala/tests/ScalaVersionsSuite.scala
index 86777b76a1f..57c0740793c 100644
--- a/tests/unit/src/test/scala/tests/ScalaVersionsSuite.scala
+++ b/tests/unit/src/test/scala/tests/ScalaVersionsSuite.scala
@@ -316,7 +316,7 @@ class ScalaVersionsSuite extends BaseSuite {
   checkJar("tested-3.0-sources.jar", "2.13")
 
   def checkJar(jar: String, expected: String): Unit = test(jar) {
-    val out = ScalaVersions.scalaBinaryVersionFromJarName(jar)
+    val out = ScalaVersions.scalaBinaryVersionFromJarName(jar).getOrElse("2.13")
     assertEquals(out, expected, jar)
   }