From b4635494c6b880a8ef157eef4f7bf84392c8bf47 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 17 May 2021 18:39:07 +0200 Subject: [PATCH] Add support for Scala 2.13.6 Scala 2.13.6 also includes the support for using some of the Scala 3 syntax. When the proper options is detected "-Xsource:3", we now change the dialect to be able to parse the enriched syntax. Additionally, we also now make it the default in case we don't know anything about the scalac options. --- bin/test-release.sh | 1 + build.sbt | 17 +++++-- .../metals/MetalsLanguageServer.scala | 10 ++++- .../meta/internal/metals/ScalaTarget.scala | 12 ++++- .../metals/ScalaVersionSelector.scala | 5 ++- .../meta/internal/metals/ScalaVersions.scala | 20 ++++++++- .../scala/tests/pc/CompletionDocSuite.scala | 27 +++++++++++- .../test/scala/tests/pc/CompletionSuite.scala | 6 ++- .../tests/feature/FoldingCrossLspSuite.scala | 44 +++++++++++++++++++ 9 files changed, 128 insertions(+), 14 deletions(-) diff --git a/bin/test-release.sh b/bin/test-release.sh index dec16311734..5ddca552d1b 100755 --- a/bin/test-release.sh +++ b/bin/test-release.sh @@ -17,6 +17,7 @@ coursier fetch \ org.scalameta:mtags_2.13.3:$version \ org.scalameta:mtags_2.13.4:$version \ org.scalameta:mtags_2.13.5:$version \ + org.scalameta:mtags_2.13.6:$version \ org.scalameta:mtags_2.12.8:$version \ org.scalameta:mtags_2.12.9:$version \ org.scalameta:mtags_2.12.10:$version \ diff --git a/build.sbt b/build.sbt index 8ae5df21f9b..6603c7f59a1 100644 --- a/build.sbt +++ b/build.sbt @@ -189,10 +189,10 @@ lazy val V = new { val scala211 = "2.11.12" val sbtScala = "2.12.12" val scala212 = "2.12.13" - val scala213 = "2.13.5" + val scala213 = "2.13.6" val ammonite212Version = scala212 - val ammonite213Version = scala213 - val scalameta = "4.4.17" + val ammonite213Version = "2.13.5" + val scalameta = "4.4.18" val semanticdb = scalameta val bsp = "2.0.0-M13" val bloop = "1.4.8-19-4d9f966b" @@ -222,7 +222,16 @@ lazy val V = new { def deprecatedScala2Versions = Seq(scala211, "2.12.8", "2.12.9", "2.13.0", "2.13.1", "2.13.2") def nonDeprecatedScala2Versions = - Seq(scala213, scala212, "2.12.12", "2.12.11", "2.12.10", "2.13.3", "2.13.4") + Seq( + scala213, + scala212, + "2.12.12", + "2.12.11", + "2.12.10", + "2.13.3", + "2.13.4", + "2.13.5" + ) def scala2Versions = nonDeprecatedScala2Versions ++ deprecatedScala2Versions // Scala 3 diff --git a/metals/src/main/scala/scala/meta/internal/metals/MetalsLanguageServer.scala b/metals/src/main/scala/scala/meta/internal/metals/MetalsLanguageServer.scala index a0fb0a4ae8f..be4d77707c1 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/MetalsLanguageServer.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/MetalsLanguageServer.scala @@ -2178,7 +2178,10 @@ class MetalsLanguageServer( source.isAmmoniteScript ) ) - ScalaVersions.dialectForScalaVersion(scalaVersion) + ScalaVersions.dialectForScalaVersion( + scalaVersion, + includeSource3 = true + ) } val reluri = source.toIdeallyRelativeURI(sourceItem) val input = sourceToIndex0.toInput @@ -2402,7 +2405,10 @@ class MetalsLanguageServer( addSourceJarSymbols(path) } else if (path.isDirectory) { val dialect = - ScalaVersions.dialectForScalaVersion(scalaTarget.scalaVersion) + ScalaVersions.dialectForScalaVersion( + scalaTarget.scalaVersion, + includeSource3 = true + ) definitionIndex.addSourceDirectory(path, dialect) } else { scribe.warn(s"unexpected dependency: $path") diff --git a/metals/src/main/scala/scala/meta/internal/metals/ScalaTarget.scala b/metals/src/main/scala/scala/meta/internal/metals/ScalaTarget.scala index d34bf65246a..bace01918e7 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ScalaTarget.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ScalaTarget.scala @@ -24,7 +24,17 @@ case class ScalaTarget( def dialect: Dialect = { scalaVersion match { case _ if info.getDataKind() == "sbt" => Sbt - case other => ScalaVersions.dialectForScalaVersion(other) + case other => + val dialect = + ScalaVersions.dialectForScalaVersion(other, includeSource3 = false) + def containsSource3 = scalac.getOptions().contains("-Xsource:3") + dialect match { + case Scala213 if containsSource3 => + Scala213Source3 + case Scala212 if containsSource3 => + Scala212Source3 + case other => other + } } } diff --git a/metals/src/main/scala/scala/meta/internal/metals/ScalaVersionSelector.scala b/metals/src/main/scala/scala/meta/internal/metals/ScalaVersionSelector.scala index 4990d9c0eb6..af1d2ba7564 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ScalaVersionSelector.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ScalaVersionSelector.scala @@ -44,6 +44,9 @@ class ScalaVersionSelector( } def fallbackDialect(isAmmonite: Boolean): Dialect = { - ScalaVersions.dialectForScalaVersion(fallbackScalaVersion(isAmmonite)) + ScalaVersions.dialectForScalaVersion( + fallbackScalaVersion(isAmmonite), + includeSource3 = true + ) } } 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 3b0883950cc..ee355f28f9f 100644 --- a/metals/src/main/scala/scala/meta/internal/metals/ScalaVersions.scala +++ b/metals/src/main/scala/scala/meta/internal/metals/ScalaVersions.scala @@ -89,11 +89,24 @@ object ScalaVersions { scalaVersion.split('.').take(2).mkString(".") } - def dialectForScalaVersion(scalaVersion: String): Dialect = { + /** + * Select scalameta dialect for a Scala version + * + * @param scalaVersion + * @param includeSource3 if to use dialect with Source3, which will parse Scala 2 code + * that compiles with the -Xsource:3 flag. In some cases where we don't use diagnostics + * it makes sense to always use Source3 dialects. + */ + def dialectForScalaVersion( + scalaVersion: String, + includeSource3: Boolean + ): Dialect = { val scalaBinaryVersion = scalaBinaryVersionFromFullVersion(scalaVersion) scalaBinaryVersion match { case "2.11" => Scala211 + case "2.12" if includeSource3 => Scala212Source3 case "2.12" => Scala212 + case "2.13" if includeSource3 => Scala213Source3 case "2.13" => Scala213 case version if version.startsWith("3") => Scala3 case _ => Scala213 @@ -135,6 +148,9 @@ object ScalaVersions { } def dialectForDependencyJar(filename: String): Dialect = - dialectForScalaVersion(scalaBinaryVersionFromJarName(filename)) + dialectForScalaVersion( + scalaBinaryVersionFromJarName(filename), + includeSource3 = true + ) } diff --git a/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala b/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala index dbabfd9c013..af23ea3e588 100644 --- a/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala +++ b/tests/cross/src/test/scala/tests/pc/CompletionDocSuite.scala @@ -232,6 +232,11 @@ class CompletionDocSuite extends BaseCompletionSuite { |Predef scala |""".stripMargin, "2.13.5" -> + s""" + |${predefDocString(commonlyUsedTypesPost2134)} + |Predef scala + |""".stripMargin, + "2.13.6" -> s""" |${predefDocString(commonlyUsedTypesPost2134)} |Predef scala @@ -383,7 +388,8 @@ class CompletionDocSuite extends BaseCompletionSuite { "2.13.3" -> iteratorDocs213(), "2.13.4" -> iteratorDocs213(), // LinearSeqIterator should actually not be added since it's private and it's fixed in 2.13.5 - "2.13.5" -> iteratorDocs213(withLinearSeqIterator = false) + "2.13.5" -> iteratorDocs213(withLinearSeqIterator = false), + "2.13.6" -> iteratorDocs213(withLinearSeqIterator = false) ) ) @@ -420,6 +426,9 @@ class CompletionDocSuite extends BaseCompletionSuite { |global: ExecutionContext |""".stripMargin, "2.13.5" -> s"""|$executionDocstringPost2134 + |global: ExecutionContext + |""".stripMargin, + "2.13.6" -> s"""|$executionDocstringPost2134 |global: ExecutionContext |""".stripMargin ) @@ -509,6 +518,19 @@ class CompletionDocSuite extends BaseCompletionSuite { |section on `StringBuilders` for more information. |StringBuilder scala.collection.mutable |""".stripMargin, + "2.13.6" -> + """|> A builder for mutable sequence of characters. This class provides an API + |mostly compatible with `java.lang.StringBuilder`, except where there are + |conflicts with the Scala collections API (such as the `reverse` method.) + | + |$multipleResults + | + | + |**See** + |- ["Scala's Collection Library overview"](https://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html#stringbuilders) + |section on `StringBuilders` for more information. + |StringBuilder scala.collection.mutable + |""".stripMargin, "2.13" -> """|> A builder for mutable sequence of characters. This class provides an API |mostly compatible with `java.lang.StringBuilder`, except where there are @@ -587,7 +609,8 @@ class CompletionDocSuite extends BaseCompletionSuite { "2.13.2" -> vectorDocs213, "2.13.3" -> vectorDocs213, "2.13.4" -> vectorDocs213, - "2.13.5" -> vectorDocs213 + "2.13.5" -> vectorDocs213, + "2.13.6" -> vectorDocs213 ) ) check( diff --git a/tests/cross/src/test/scala/tests/pc/CompletionSuite.scala b/tests/cross/src/test/scala/tests/pc/CompletionSuite.scala index 48297c4ef71..e4d702f5f17 100644 --- a/tests/cross/src/test/scala/tests/pc/CompletionSuite.scala +++ b/tests/cross/src/test/scala/tests/pc/CompletionSuite.scala @@ -433,7 +433,8 @@ class CompletionSuite extends BaseCompletionSuite { * might have been a bug in presentation compiler that we were using * https://github.com/scalameta/metals/issues/2546 */ - "2.13.5" -> "Inner a.Outer" + "2.13.5" -> "Inner a.Outer", + "2.13.6" -> "Inner a.Outer" ) ) @@ -655,7 +656,8 @@ class CompletionSuite extends BaseCompletionSuite { |""".stripMargin, compat = Map( "3.0" -> "DelayedLazyVal scala.concurrent", - "2.13.5" -> "DelayedLazyVal - scala.concurrent" + "2.13.5" -> "DelayedLazyVal - scala.concurrent", + "2.13.6" -> "DelayedLazyVal - scala.concurrent" ) ) diff --git a/tests/slow/src/test/scala/tests/feature/FoldingCrossLspSuite.scala b/tests/slow/src/test/scala/tests/feature/FoldingCrossLspSuite.scala index d89a24d877b..8031413aa55 100644 --- a/tests/slow/src/test/scala/tests/feature/FoldingCrossLspSuite.scala +++ b/tests/slow/src/test/scala/tests/feature/FoldingCrossLspSuite.scala @@ -41,4 +41,48 @@ class FoldingCrossLspSuite extends BaseLspSuite("foldingRange-cross") { ) } yield () } + + test("source-3") { + for { + _ <- server.initialize( + s"""| + |/metals.json + |{ + | "a": { "scalaVersion" : "${V.scala213}", "scalacOptions" : ["-Xsource:3"] } + |} + |/a/src/main/scala/a/Main.scala + |package b + |import scala.concurrent.Future as F + |object a { + | def func(args: String*) = { + | println("") + | println("") + | println("") + | println("") + | } + | val args = List.empty[String] + | func(args*) + |} + |""".stripMargin + ) + _ <- server.didOpen("a/src/main/scala/a/Main.scala") + _ = assertNoDiagnostics() + _ <- server.assertFolded( + "a/src/main/scala/a/Main.scala", + """|package b + |import scala.concurrent.Future as F + |object a >>region>>{ + | def func(args: String*) = >>region>>{ + | println("") + | println("") + | println("") + | println("") + | }<