Skip to content

Commit dbc3c77

Browse files
committed
refactor: Migrate Metals server to Scala 3
This mostly involved: - changing imports - moving things between MtagsEnrichements variants - adding () - fixing bugs reported now as warning or errors (things previously not reported at all)
1 parent ccd5153 commit dbc3c77

File tree

216 files changed

+1071
-1082
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

216 files changed

+1071
-1082
lines changed

.scalafix.conf

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
rules = [
2-
OrganizeImports,
3-
ExplicitResultTypes,
4-
RemoveUnused
2+
OrganizeImports
53
]
64

7-
ExplicitResultTypes.rewriteStructuralTypesToNamedSubclass = false
8-
9-
RemoveUnused.imports = false
10-
115
OrganizeImports.groupedImports = Explode
126
OrganizeImports.expandRelative = true
13-
OrganizeImports.removeUnused = true
7+
OrganizeImports.removeUnused = false
148
OrganizeImports.groups = [
159
"re:javax?\\."
1610
"scala."

.scalafix2.conf

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
rules = [
2+
OrganizeImports,
3+
ExplicitResultTypes,
4+
RemoveUnused
5+
]
6+
7+
ExplicitResultTypes.rewriteStructuralTypesToNamedSubclass = false
8+
9+
RemoveUnused.imports = false
10+
11+
OrganizeImports.groupedImports = Explode
12+
OrganizeImports.expandRelative = true
13+
OrganizeImports.removeUnused = true
14+
OrganizeImports.groups = [
15+
"re:javax?\\."
16+
"scala."
17+
"scala.meta."
18+
"*"
19+
]

.scalafix3.conf

-13
This file was deleted.

.scalafmt.conf

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
version = "3.7.12"
2-
runner.dialect = scala213
2+
runner.dialect = scala3
33
project.git = true
44
align.preset = none
55
align.stripMargin = true
@@ -34,5 +34,6 @@ fileOverride {
3434
},
3535
"glob:**/mtags*/**" {
3636
trailingCommas = never
37+
runner.dialect = scala213
3738
}
3839
}

build.sbt

+70-40
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@ def crossSetting[A](
4444
logo := Welcome.logo
4545
usefulTasks := Welcome.tasks
4646

47-
ThisBuild / scalafixScalaBinaryVersion := scalaBinaryVersion.value
47+
ThisBuild / scalafixScalaBinaryVersion := "2.13"
4848

4949
inThisBuild(
5050
List(
5151
version ~= { dynVer =>
5252
if (isCI) dynVer
5353
else localSnapshotVersion // only for local publishing
5454
},
55-
scalaVersion := V.scala213,
56-
crossScalaVersions := List(V.scala213),
55+
scalaVersion := V.scala3,
56+
crossScalaVersions := List(V.scala3),
5757
organization := "org.scalameta",
5858
licenses := Seq(
5959
"Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")
@@ -137,7 +137,7 @@ commands ++= Seq(
137137
runMtagsPublishLocal(st, v, localSnapshotVersion)
138138
}
139139
"interfaces/publishLocal" ::
140-
s"++${V.scala213} metals/publishLocal" ::
140+
s"++${V.scala3} metals/publishLocal" ::
141141
"mtags-java/publishLocal" ::
142142
publishMtags
143143
},
@@ -220,6 +220,27 @@ val sharedSettings = sharedJavacOptions ++ sharedScalacOptions ++ List(
220220
)
221221
),
222222
),
223+
excludeDependencies ++= crossSetting(
224+
scalaVersion.value,
225+
if3 = {
226+
// Exclude cross published version dependencies leading to conflicts in Scala 3 vs 2.13
227+
// When using Scala 3 exclude Scala 2.13 standard native libraries,
228+
// when using Scala 2.13 exclude Scala 3 standard native libraries
229+
// Use full name, Maven style published artifacts cannot use artifact/cross version for exclusion rules
230+
List(
231+
ExclusionRule()
232+
.withOrganization("org.scala-lang.modules")
233+
.withName(
234+
"scala-collection-compat_2.13"
235+
),
236+
ExclusionRule()
237+
.withOrganization("org.scala-lang.modules")
238+
.withName(
239+
"scala-xml_2.13"
240+
),
241+
)
242+
},
243+
),
223244
scalacOptions ++= lintingOptions(scalaVersion.value),
224245
)
225246

@@ -282,21 +303,19 @@ def multiScalaDirectories(root: File, scalaVersion: String) = {
282303
result.toList
283304
}
284305

285-
def scala3ScalametaDependency =
286-
("org.scalameta" %% "scalameta" % V.scalameta)
287-
.cross(CrossVersion.for3Use2_13)
288-
.exclude("org.scala-lang", "scala-reflect")
289-
.exclude("org.scala-lang", "scala-compiler")
290-
// the correct one should be brought in by the scala 3 compiler
291-
.exclude("org.scala-lang", "scala-library")
292-
.exclude(
293-
"com.lihaoyi",
294-
"geny_2.13",
295-
) // avoid 2.13 and 3 on the classpath since we rely on it directly
296-
.exclude(
297-
"com.lihaoyi",
298-
"sourcecode_2.13",
299-
) // avoid 2.13 and 3 on the classpath since it comes in via pprint
306+
def scalametaDependency = ("org.scalameta" %% "scalameta" % V.scalameta)
307+
.cross(CrossVersion.for3Use2_13)
308+
.exclude("org.scala-lang", "scala-reflect")
309+
.exclude("org.scala-lang", "scala-compiler")
310+
.exclude("org.scala-lang.modules", "scala-collection-compat")
311+
.exclude(
312+
"com.lihaoyi",
313+
"geny_2.13",
314+
) // avoid 2.13 and 3 on the classpath since we rely on it directly
315+
.exclude(
316+
"com.lihaoyi",
317+
"sourcecode_2.13",
318+
)
300319

301320
val mtagsSettings = List(
302321
crossScalaVersions := V.supportedScalaVersions ++ V.nightlyScala3Versions,
@@ -327,7 +346,7 @@ val mtagsSettings = List(
327346
),
328347
if3 = List(
329348
"org.scala-lang" %% "scala3-compiler" % scalaVersion.value,
330-
scala3ScalametaDependency,
349+
scalametaDependency,
331350
),
332351
if3WithPresentationCompiler = List(
333352
"org.scala-lang" %% "scala3-presentation-compiler" % scalaVersion.value
@@ -360,21 +379,21 @@ val mtagsSettings = List(
360379
},
361380
)
362381

363-
lazy val mtags3 = project
382+
lazy val mtags2 = project
364383
.in(file(".mtags"))
365384
.settings(
366385
Compile / unmanagedSourceDirectories := Seq(),
367386
sharedSettings,
368387
mtagsSettings,
369388
Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "mtags" / "src" / "main" / "scala",
370389
Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "mtags-shared" / "src" / "main" / "scala",
371-
Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "mtags-shared" / "src" / "main" / "scala-3",
372-
moduleName := "mtags3",
373-
scalaVersion := V.scala3,
374-
target := (ThisBuild / baseDirectory).value / "mtags" / "target" / "target3",
390+
Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "mtags-shared" / "src" / "main" / "scala-2.13",
391+
moduleName := "mtags2",
392+
scalaVersion := V.scala213,
393+
target := (ThisBuild / baseDirectory).value / "mtags" / "target" / "target2",
375394
publish / skip := true,
376395
scalafixConfig := Some(
377-
(ThisBuild / baseDirectory).value / ".scalafix3.conf"
396+
(ThisBuild / baseDirectory).value / ".scalafix2.conf"
378397
),
379398
)
380399
.dependsOn(interfaces)
@@ -391,9 +410,6 @@ lazy val mtags3WithPresentationCompiler = project
391410
scalaVersion := V.firstScala3PCVersion,
392411
target := (ThisBuild / baseDirectory).value / "mtags" / "target" / "target3-wrapper",
393412
publish / skip := true,
394-
scalafixConfig := Some(
395-
(ThisBuild / baseDirectory).value / ".scalafix3.conf"
396-
),
397413
)
398414
.dependsOn(interfaces)
399415
.enablePlugins(BuildInfoPlugin)
@@ -443,7 +459,8 @@ lazy val metals = project
443459
// for BSP
444460
"org.scala-sbt.ipcsocket" % "ipcsocket" % "1.6.2",
445461
"ch.epfl.scala" % "bsp4j" % V.bsp,
446-
"ch.epfl.scala" %% "bloop-launcher-core" % V.bloop,
462+
("ch.epfl.scala" %% "bloop-launcher-core" % V.bloop)
463+
.cross(CrossVersion.for3Use2_13),
447464
// for LSP
448465
V.lsp4j,
449466
// for DAP
@@ -473,13 +490,16 @@ lazy val metals = project
473490
// Scala dependencies
474491
// ==================
475492
"org.scalameta" % "mdoc-interfaces" % V.mdoc,
476-
"org.scalameta" %% "scalafmt-dynamic" % V.scalafmt,
493+
("org.scalameta" %% "scalafmt-dynamic" % V.scalafmt)
494+
.cross(CrossVersion.for3Use2_13),
495+
"com.googlecode.java-diff-utils" % "diffutils" % "1.3.0",
477496
"ch.epfl.scala" % "scalafix-interfaces" % V.scalafix,
478497
// For reading classpaths.
479498
// for fetching ch.epfl.scala:bloop-frontend and other library dependencies
480499
"io.get-coursier" % "interface" % V.coursierInterfaces,
481500
// for comparing versions
482-
"io.get-coursier" %% "versions" % "0.3.2",
501+
("io.get-coursier" %% "versions" % "0.3.2")
502+
.cross(CrossVersion.for3Use2_13),
483503
// for logging
484504
"com.outr" %% "scribe" % V.scribe,
485505
"com.outr" %% "scribe-file" % V.scribe,
@@ -489,10 +509,11 @@ lazy val metals = project
489509
// For remote language server
490510
"com.lihaoyi" %% "requests" % "0.8.0",
491511
// for producing SemanticDB from Scala source files
492-
"org.scalameta" %% "scalameta" % V.scalameta,
493-
"org.scalameta" % "semanticdb-scalac-core" % V.scalameta cross CrossVersion.full,
512+
scalametaDependency,
513+
// "org.scalameta" % "semanticdb-scalac-core" % V.scalameta cross CrossVersion.full,
494514
// For starting Ammonite
495-
"io.github.alexarchambault.ammonite" %% "ammonite-runner" % "0.4.0",
515+
("io.github.alexarchambault.ammonite" %% "ammonite-runner" % "0.4.0")
516+
.cross(CrossVersion.for3Use2_13),
496517
"org.scala-lang.modules" %% "scala-xml" % "2.2.0",
497518
"org.scala-lang.modules" %% "scala-parallel-collections" % "1.0.4",
498519
("org.virtuslab.scala-cli" % "scala-cli-bsp" % V.scalaCli)
@@ -558,6 +579,7 @@ lazy val `sbt-metals` = project
558579
lazy val input = project
559580
.in(file("tests/input"))
560581
.settings(
582+
scalaVersion := V.scala213,
561583
sharedSettings,
562584
publish / skip := true,
563585
libraryDependencies ++= List(
@@ -690,7 +712,7 @@ lazy val mtest = project
690712
),
691713
libraryDependencies ++= {
692714
if (isScala3WithPresentationCompiler(scalaVersion.value))
693-
List(scala3ScalametaDependency)
715+
List(scalametaDependency)
694716
else Nil
695717
},
696718
Compile / unmanagedSourceDirectories ++= {
@@ -742,6 +764,7 @@ def isInTestShard(name: String, logger: Logger): Boolean = {
742764
lazy val metalsDependencies = project
743765
.in(file("target/.dependencies"))
744766
.settings(
767+
scalaVersion := V.scala213,
745768
publish / skip := true,
746769
// silent the intransitive dependency warning
747770
publishMavenStyle := false,
@@ -750,13 +773,13 @@ lazy val metalsDependencies = project
750773
// will pick them up and update them. They aren't actually used.
751774
"com.lihaoyi" %% "ammonite-util" % V.ammonite,
752775
"org.typelevel" % "kind-projector" % V.kindProjector cross CrossVersion.full,
753-
"com.olegpy" %% "better-monadic-for" % V.betterMonadicFor,
776+
("com.olegpy" %% "better-monadic-for" % V.betterMonadicFor),
754777
"com.lihaoyi" % "mill-contrib-testng" % V.mill,
755778
"org.virtuslab.scala-cli" % "cli_3" % V.scalaCli intransitive (),
756779
"ch.epfl.scala" % "bloop-maven-plugin" % V.mavenBloop,
757780
"ch.epfl.scala" %% "gradle-bloop" % V.gradleBloop,
758781
"com.sourcegraph" % "semanticdb-java" % V.javaSemanticdb,
759-
"ch.epfl.scala" %% "scala-debug-adapter" % V.debugAdapter intransitive (),
782+
("ch.epfl.scala" %% "scala-debug-adapter" % V.debugAdapter) intransitive (),
760783
),
761784
)
762785
.disablePlugins(ScalafixPlugin)
@@ -771,9 +794,16 @@ lazy val unit = project
771794
sharedSettings,
772795
Test / javaOptions += "-Xmx2G",
773796
libraryDependencies ++= List(
774-
"io.get-coursier" %% "coursier" % V.coursier, // for jars
775-
"ch.epfl.scala" %% "bloop-config" % V.bloopConfig,
797+
("io.get-coursier" %% "coursier" % V.coursier)
798+
.cross(CrossVersion.for3Use2_13), // for jars
799+
("ch.epfl.scala" %% "bloop-config" % V.bloopConfig)
800+
.cross(CrossVersion.for3Use2_13),
776801
"org.scalameta" %% "munit" % V.munit,
802+
// The dependencies listed below are only listed so Scala Steward
803+
// will pick them up and update them. They aren't actually used.
804+
("com.lihaoyi" %% "ammonite-util" % V.ammonite intransitive ())
805+
.cross(CrossVersion.for3Use2_13),
806+
"com.lihaoyi" % "mill-contrib-testng" % V.mill intransitive (),
777807
),
778808
buildInfoPackage := "tests",
779809
Compile / resourceGenerators += InputProperties

metals-bench/src/main/scala/bench/MetalsBench.scala

-43
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
package bench
22

3-
import scala.reflect.internal.util.BatchSourceFile
4-
import scala.reflect.io.VirtualFile
5-
import scala.tools.nsc.interactive.Global
6-
73
import scala.meta.dialects
8-
import scala.meta.interactive.InteractiveSemanticdb
94
import scala.meta.internal.metals.EmptyReportContext
105
import scala.meta.internal.metals.JdkSources
116
import scala.meta.internal.metals.logging.MetalsLogger
@@ -15,7 +10,6 @@ import scala.meta.internal.mtags.SemanticdbClasspath
1510
import scala.meta.internal.parsing.Trees
1611
import scala.meta.internal.semanticdb.TextDocument
1712
import scala.meta.internal.tokenizers.LegacyScanner
18-
import scala.meta.internal.tokenizers.LegacyToken
1913
import scala.meta.io.AbsolutePath
2014
import scala.meta.io.Classpath
2115

@@ -97,22 +91,6 @@ class MetalsBench {
9791
}
9892
}
9993

100-
@Benchmark
101-
@BenchmarkMode(Array(Mode.SingleShotTime))
102-
def scalacTokenize(): Unit = {
103-
val g = global
104-
scalaDependencySources.inputs.foreach { input =>
105-
val unit = new g.CompilationUnit(
106-
new BatchSourceFile(new VirtualFile(input.path), input.chars)
107-
)
108-
val scanner = g.newUnitScanner(unit)
109-
scanner.init()
110-
while (scanner.token != LegacyToken.EOF) {
111-
scanner.nextToken()
112-
}
113-
}
114-
}
115-
11694
@Benchmark
11795
@BenchmarkMode(Array(Mode.SingleShotTime))
11896
def scalametaParse(): Unit = {
@@ -122,27 +100,6 @@ class MetalsBench {
122100
}
123101
}
124102

125-
lazy val global: Global = InteractiveSemanticdb.newCompiler()
126-
127-
@Benchmark
128-
@BenchmarkMode(Array(Mode.SingleShotTime))
129-
def scalacParse(): Unit = {
130-
val g = global
131-
scalaDependencySources.inputs.foreach { input =>
132-
val unit = new g.CompilationUnit(
133-
new BatchSourceFile(new VirtualFile(input.path), input.chars)
134-
)
135-
val tree = g.newUnitParser(unit).parse()
136-
var i = 0
137-
new g.Traverser {
138-
override def apply[T <: g.Tree](tree: T): T = {
139-
i += 1
140-
super.apply(tree)
141-
}
142-
}.traverse(tree)
143-
}
144-
}
145-
146103
@Benchmark
147104
@BenchmarkMode(Array(Mode.SingleShotTime))
148105
def mtagsJavaParse(): Unit = {

metals/src/main/scala/scala/meta/internal/bsp/BspConfigGenerator.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import scala.meta.internal.bsp.BspConfigGenerationStatus._
77
import scala.meta.internal.builds.BuildServerProvider
88
import scala.meta.internal.builds.ShellRunner
99
import scala.meta.internal.metals.Messages.BspProvider
10-
import scala.meta.internal.metals.MetalsEnrichments._
10+
import scala.meta.internal.metals.MetalsEnrichments.given
1111
import scala.meta.internal.metals.clients.language.MetalsLanguageClient
1212
import scala.meta.io.AbsolutePath
1313

@@ -42,7 +42,7 @@ final class BspConfigGenerator(
4242
buildTools: List[BuildServerProvider]
4343
): Future[(BuildServerProvider, BspConfigGenerationStatus)] = {
4444
for {
45-
Some(buildTool) <- chooseBuildServerProvider(buildTools)
45+
case Some(buildTool) <- chooseBuildServerProvider(buildTools)
4646
status <- buildTool.generateBspConfig(
4747
workspace,
4848
args => runUnconditionally(buildTool, args),

0 commit comments

Comments
 (0)