From ab355b8bb80bf506ab509e18ca3fbfd5be61e775 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Sat, 5 Jun 2021 12:48:28 +0200 Subject: [PATCH] Enable organize imports for Scala 3 Since 0.9.29 it's possible to use most of the existing rules on Scala 3 including organize-imports. This still have 2 caveats: - unused imports will not be removed since we don't get that information from the compiler - we will need to run 2.13 scalafix for Scala 3 sources until Scalafix is released for Scala 3. This is only a problem for ExplicitResultTypes, which anyway wouldn't work in Metals. --- .../internal/metals/ScalafixProvider.scala | 4 ++- .../metals/codeactions/OrganizeImports.scala | 10 +------ .../feature/CrossCodeActionLspSuite.scala | 29 +++++++++++++++++++ .../codeactions/BaseCodeActionLspSuite.scala | 6 ++-- 4 files changed, 37 insertions(+), 12 deletions(-) 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 57dd9e25b8f..277b3b8d498 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ScalafixProvider.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ScalafixProvider.scala @@ -147,7 +147,9 @@ case class ScalafixProvider( file: AbsolutePath, scalaTarget: ScalaTarget ): Try[ScalafixEvaluation] = { - val scalaBinaryVersion = scalaTarget.scalaBinaryVersion + val defaultScalaVersion = scalaTarget.scalaBinaryVersion + val scalaBinaryVersion = + if (defaultScalaVersion.startsWith("3")) "2.13" else defaultScalaVersion val targetRoot = buildTargets.scalacOptions(scalaTarget.info.getId()).map { diff --git a/metals/src/main/scala/scala/meta/internal/metals/codeactions/OrganizeImports.scala b/metals/src/main/scala/scala/meta/internal/metals/codeactions/OrganizeImports.scala index 60273e7be67..8d1f9ae03ef 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/codeactions/OrganizeImports.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/codeactions/OrganizeImports.scala @@ -8,7 +8,6 @@ import scala.meta.internal.metals.CodeAction import scala.meta.internal.metals.MetalsEnrichments.XtensionString import scala.meta.internal.metals.MetalsEnrichments._ import scala.meta.internal.metals.ScalaTarget -import scala.meta.internal.metals.ScalaVersions import scala.meta.internal.metals.ScalacDiagnostic import scala.meta.internal.metals.ScalafixProvider import scala.meta.io.AbsolutePath @@ -42,15 +41,8 @@ final class OrganizeImports( target <- buildTargets.scalaTarget(buildId) } yield target scalaTarget match { - case Some(target) - if !ScalaVersions.isScala3Version(target.scalaVersion) => + case Some(target) => organizeImportsEdits(file, target) - case Some(target) - if ScalaVersions.isScala3Version(target.scalaVersion) => - scribe.info( - s"Organize import doesn't work on ${target.scalaVersion} files" - ) - Future.successful(Seq()) case _ => Future.successful(Seq()) } } else Future.successful(Seq()) diff --git a/tests/slow/src/test/scala/tests/feature/CrossCodeActionLspSuite.scala b/tests/slow/src/test/scala/tests/feature/CrossCodeActionLspSuite.scala index 8e65fa34ec4..7ced7973aaa 100644 --- a/tests/slow/src/test/scala/tests/feature/CrossCodeActionLspSuite.scala +++ b/tests/slow/src/test/scala/tests/feature/CrossCodeActionLspSuite.scala @@ -2,6 +2,7 @@ package tests.feature import scala.meta.internal.metals.BuildInfo import scala.meta.internal.metals.codeactions.ExtractRenameMember +import scala.meta.internal.metals.codeactions.OrganizeImports import scala.meta.internal.mtags.MtagsEnrichments.XtensionAbsolutePath import munit.Location @@ -23,6 +24,34 @@ class CrossCodeActionLspSuite |""".stripMargin ) + check( + "organize-imports", + """ + |package a + |import scala.concurrent.{ExecutionContext, Future} + |import scala.util.Try<<>> + | + |object A { + | val executionContext: ExecutionContext = ??? + | val k = Future.successful(1) + | val tr = Try{ new Exception("name") } + |} + |""".stripMargin, + s"${OrganizeImports.title}", + """|package a + |import scala.concurrent.ExecutionContext + |import scala.concurrent.Future + |import scala.util.Try + | + |object A { + | val executionContext: ExecutionContext = ??? + | val k = Future.successful(1) + | val tr = Try{ new Exception("name") } + |} + |""".stripMargin, + kind = List(OrganizeImports.kind) + ) + checkExtractedMember( "extract-enum", """|package a diff --git a/tests/unit/src/main/scala/tests/codeactions/BaseCodeActionLspSuite.scala b/tests/unit/src/main/scala/tests/codeactions/BaseCodeActionLspSuite.scala index d8cabb58225..49525d9d58d 100644 --- a/tests/unit/src/main/scala/tests/codeactions/BaseCodeActionLspSuite.scala +++ b/tests/unit/src/main/scala/tests/codeactions/BaseCodeActionLspSuite.scala @@ -39,7 +39,9 @@ abstract class BaseCodeActionLspSuite(suiteName: String) fileName: String = "A.scala" )(implicit loc: Location): Unit = { val scalacOptionsJson = - s""""scalacOptions": ["${scalacOptions.mkString("\",\"")}"]""" + if (scalacOptions.nonEmpty) + s""""scalacOptions": ["${scalacOptions.mkString("\",\"")}"],""" + else "" val path = s"a/src/main/scala/a/$fileName" val newPath = renamePath.getOrElse(path) val fileContent = input.replace("<<", "").replace(">>", "") @@ -50,7 +52,7 @@ abstract class BaseCodeActionLspSuite(suiteName: String) cleanWorkspace() for { _ <- server.initialize(s"""/metals.json - |{"a":{$scalacOptionsJson, "scalaVersion" : "$scalaVersion"}} + |{"a":{$scalacOptionsJson "scalaVersion" : "$scalaVersion"}} |$scalafixConf |/$path |$fileContent""".stripMargin)