From 72bd65cb5a88f57015fc9acbeae07c423b820f96 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Thu, 19 Oct 2023 18:46:42 +0200 Subject: [PATCH] bugfix: Add back unintentionlly removed support for 2.11.x Previously, we would use the lates scalfix version by default, which doesn't support Scala 2.11 by default. Now, we fall back to the latest version that supported it. --- .../internal/metals/ScalafixProvider.scala | 42 +++++++++++++++++-- .../feature/Scala211ActionsLspSuite.scala | 40 ++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 tests/slow/src/test/scala/tests/feature/Scala211ActionsLspSuite.scala diff --git a/metals/src/main/scala/scala/meta/internal/metals/ScalafixProvider.scala b/metals/src/main/scala/scala/meta/internal/metals/ScalafixProvider.scala index 45e43513293..00143378c95 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ScalafixProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ScalafixProvider.scala @@ -18,18 +18,22 @@ import scala.meta.internal.metals.MetalsEnrichments._ import scala.meta.internal.metals.clients.language.MetalsLanguageClient import scala.meta.internal.metals.clients.language.MetalsQuickPickItem import scala.meta.internal.metals.clients.language.MetalsQuickPickParams +import scala.meta.internal.metals.{BuildInfo => V} import scala.meta.internal.mtags.SemanticdbClasspath import scala.meta.internal.semanticdb.TextDocuments import scala.meta.io.AbsolutePath import com.typesafe.config.ConfigFactory import coursierapi.Dependency +import coursierapi.Repository import org.eclipse.lsp4j.MessageParams import org.eclipse.lsp4j.MessageType import org.eclipse.{lsp4j => l} import scalafix.interfaces.Scalafix import scalafix.interfaces.ScalafixEvaluation import scalafix.interfaces.ScalafixFileEvaluationError +import scalafix.internal.interfaces.ScalafixCoursier +import scalafix.internal.interfaces.ScalafixInterfacesClassloader case class ScalafixProvider( buffers: Buffers, @@ -437,7 +441,9 @@ case class ScalafixProvider( case None => statusBar.trackBlockingTask("Downloading scalafix") { val scalafix = - Try(Scalafix.fetchAndClassloadInstance(scalaBinaryVersion)) + if (scalaBinaryVersion == "2.11") Try(scala211Fallback) + else + Try(Scalafix.fetchAndClassloadInstance(scalaBinaryVersion)) scalafix.foreach(api => scalafixCache.update(scalaBinaryVersion, api)) scalafix } @@ -445,6 +451,22 @@ case class ScalafixProvider( } + private def scala211Fallback: Scalafix = { + // last version that supports Scala 2.11.12 + val latestSupporting = "0.10.4" + val jars = ScalafixCoursier.scalafixCliJars( + Repository.defaults(), + latestSupporting, + V.scala211, + ) + val parent = new ScalafixInterfacesClassloader( + classOf[Scalafix].getClassLoader() + ); + Scalafix.classloadInstance( + new URLClassLoader(jars.asScala.toArray, parent) + ); + } + private def getRuleClassLoader( scalfixRulesKey: ScalafixRulesClasspathKey, scalafixClassLoader: ClassLoader, @@ -457,8 +479,22 @@ case class ScalafixProvider( ) { val rulesDependencies = scalfixRulesKey.usedRulesWithClasspath val organizeImportRule = + // Scalafix version that supports Scala 2.11 doesn't have the rule built in + if (scalfixRulesKey.scalaBinaryVersion == "2.11") + Some( + Dependency.of( + "com.github.liancheng", + "organize-imports_" + scalfixRulesKey.scalaBinaryVersion, + "0.6.0", + ) + ) + else None + + val allRules = Try( - Embedded.rulesClasspath(rulesDependencies.toList) + Embedded.rulesClasspath( + rulesDependencies.toList ++ organizeImportRule + ) ).map { paths => val classloader = Embedded.toClassLoader( Classpath(paths.map(AbsolutePath(_))), @@ -467,7 +503,7 @@ case class ScalafixProvider( rulesClassloaderCache.update(scalfixRulesKey, classloader) classloader } - organizeImportRule + allRules } } } diff --git a/tests/slow/src/test/scala/tests/feature/Scala211ActionsLspSuite.scala b/tests/slow/src/test/scala/tests/feature/Scala211ActionsLspSuite.scala new file mode 100644 index 00000000000..eebecc7741b --- /dev/null +++ b/tests/slow/src/test/scala/tests/feature/Scala211ActionsLspSuite.scala @@ -0,0 +1,40 @@ +package tests.feature + +import scala.meta.internal.metals.BuildInfo +import scala.meta.internal.metals.codeactions.SourceOrganizeImports + +import tests.codeactions.BaseCodeActionLspSuite + +class Scala211ActionsLspSuite + extends BaseCodeActionLspSuite("cross-code-actions") { + + override protected val scalaVersion: String = BuildInfo.scala211 + + check( + "basic", + """ + |package a + |import scala.concurrent.duration._ + |import scala.concurrent.Future<<>> + |import scala.concurrent.ExecutionContext.global + | + |object A { + | val d = Duration(10, MICROSECONDS) + | val k = Future.successful(1) + |} + |""".stripMargin, + s"${SourceOrganizeImports.title}", + """ + |package a + |import scala.concurrent.Future + |import scala.concurrent.duration._ + | + |object A { + | val d = Duration(10, MICROSECONDS) + | val k = Future.successful(1) + |} + |""".stripMargin, + kind = List(SourceOrganizeImports.kind), + scalacOptions = List("-Ywarn-unused-import"), + ) +}