Skip to content

Commit

Permalink
Add support for Scala 3 (#968)
Browse files Browse the repository at this point in the history
* Add Scala 3 support

* Rename dotty-related version checking methods

Pull request: #968
  • Loading branch information
anatoliykmetyuk authored Oct 8, 2020
1 parent 375f4e8 commit 105f53b
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 24 deletions.
15 changes: 9 additions & 6 deletions scalalib/api/src/ZincWorkerApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ object CompilationResult {
case class CompilationResult(analysisFile: os.Path, classes: PathRef)

object Util {
def isDotty(scalaVersion: String) =
scalaVersion.startsWith("0.") ||
scalaVersion.startsWith("3.")
def isDotty(scalaVersion: String) = scalaVersion.startsWith("0.")
def isScala3(scalaVersion: String) = scalaVersion.startsWith("3.")
def isDottyOrScala3(scalaVersion: String) = isDotty(scalaVersion) || isScala3(scalaVersion)

// eg, grepJar(classPath, name = "scala-library", versionPrefix = "2.13.")
// return first path in `classPath` that match:
Expand Down Expand Up @@ -82,15 +82,17 @@ object Util {
val PartialVersion = raw"""(\d+)\.(\d+)\.*""".r
val ReleaseVersion = raw"""(\d+)\.(\d+)\.(\d+)""".r
val MinorSnapshotVersion = raw"""(\d+)\.(\d+)\.([1-9]\d*)-SNAPSHOT""".r
val DottyVersion = raw"""(0|3)\.(\d+)\.(\d+).*""".r
val DottyVersion = raw"""0\.(\d+)\.(\d+).*""".r
val Scala3Version = raw"""3\.(\d+)\.(\d+)-(\w+).*""".r
val DottyNightlyVersion = raw"""(0|3)\.(\d+)\.(\d+)-bin-(.*)-NIGHTLY""".r
val TypelevelVersion = raw"""(\d+)\.(\d+)\.(\d+)-bin-typelevel.*""".r


def scalaBinaryVersion(scalaVersion: String) = scalaVersion match {
case ReleaseVersion(major, minor, _) => s"$major.$minor"
case MinorSnapshotVersion(major, minor, _) => s"$major.$minor"
case DottyVersion("0", minor, _) => s"0.$minor"
case DottyVersion(minor, _) => s"0.$minor"
case Scala3Version(minor, patch, milestone) => s"3.$minor.$patch-$milestone"
case TypelevelVersion(major, minor, _) => s"$major.$minor"
case _ => scalaVersion
}
Expand Down Expand Up @@ -140,7 +142,8 @@ object Util {
/** @return true if the compiler bridge can be downloaded as an already compiled jar */
def isBinaryBridgeAvailable(scalaVersion: String) = scalaVersion match {
case DottyNightlyVersion(major, minor, _, _) => major.toInt > 0 || minor.toInt >= 14 // 0.14.0-bin or more (not 0.13.0-bin)
case DottyVersion(major, minor, _) => major.toInt > 0 || minor.toInt >= 13 // 0.13.0-RC1 or more
case DottyVersion(minor, _) => minor.toInt >= 13 // 0.13.0-RC1 or more
case Scala3Version(_, _, _) => true
case _ => false
}
}
8 changes: 4 additions & 4 deletions scalalib/src/Dep.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import upickle.default.{macroRW, ReadWriter => RW}
import CrossVersion._

case class Dep(dep: coursier.Dependency, cross: CrossVersion, force: Boolean) {
import mill.scalalib.api.Util.{isDotty, DottyVersion}
import mill.scalalib.api.Util.{isDottyOrScala3, DottyVersion, Scala3Version}

def artifactName(binaryVersion: String, fullVersion: String, platformSuffix: String) = {
val suffix = cross.suffixString(binaryVersion, fullVersion, platformSuffix)
Expand Down Expand Up @@ -54,12 +54,12 @@ case class Dep(dep: coursier.Dependency, cross: CrossVersion, force: Boolean) {
*/
def withDottyCompat(scalaVersion: String): Dep =
cross match {
case cross: Binary if isDotty(scalaVersion) =>
case cross: Binary if isDottyOrScala3(scalaVersion) =>
val compatSuffix =
scalaVersion match {
case DottyVersion("3", _) =>
case Scala3Version(_, _, _) =>
"_2.13"
case DottyVersion("0", minor, patch) =>
case DottyVersion(minor, patch) =>
if (minor.toInt > 18 || minor.toInt == 18 && patch.toInt >= 1)
"_2.13"
else
Expand Down
16 changes: 15 additions & 1 deletion scalalib/src/Lib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ object Lib{
Agg(
ivy"$scalaOrganization::dotty-compiler:$scalaVersion".forceVersion()
)
else if (mill.scalalib.api.Util.isScala3(scalaVersion))
Agg(
ivy"$scalaOrganization::scala3-compiler:$scalaVersion".forceVersion()
)
else
Agg(
ivy"$scalaOrganization:scala-compiler:$scalaVersion".forceVersion(),
Expand All @@ -85,16 +89,26 @@ object Lib{
Agg(
ivy"$scalaOrganization::dotty-doc:$scalaVersion".forceVersion()
)
else if (mill.scalalib.api.Util.isScala3(scalaVersion))
Agg(
ivy"$scalaOrganization::scala3-doc:$scalaVersion".forceVersion()
)
else
// in Scala <= 2.13, the scaladoc tool is included in the compiler
scalaCompilerIvyDeps(scalaOrganization, scalaVersion)

def scalaRuntimeIvyDeps(scalaOrganization: String, scalaVersion: String) =
if (mill.scalalib.api.Util.isDotty(scalaVersion))
if (mill.scalalib.api.Util.isDotty(scalaVersion)) {
Agg(
// note that dotty-library has a binary version suffix, hence the :: is necessary here
ivy"$scalaOrganization::dotty-library:$scalaVersion".forceVersion()
)
}
else if (mill.scalalib.api.Util.isScala3(scalaVersion))
Agg(
// note that dotty-library has a binary version suffix, hence the :: is necessary here
ivy"$scalaOrganization::scala3-library:$scalaVersion".forceVersion()
)
else
Agg(
ivy"$scalaOrganization:scala-library:$scalaVersion".forceVersion()
Expand Down
14 changes: 8 additions & 6 deletions scalalib/src/ScalaModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import mill.define.{Command, Target, Task, TaskModule}
import mill.eval.{PathRef, Result}
import mill.modules.Jvm
import mill.modules.Jvm.createJar
import mill.scalalib.api.Util.isDotty
import mill.scalalib.api.Util.{ isDotty, isDottyOrScala3, isScala3 }
import Lib._
import mill.api.Loose.Agg
import mill.api.DummyInputStream
Expand Down Expand Up @@ -57,6 +57,8 @@ trait ScalaModule extends JavaModule { outer =>
val artifacts =
if (isDotty(scalaVersion()))
Set("dotty-library", "dotty-compiler")
else if (isScala3(scalaVersion()))
Set("scala3-library", "scala3-compiler")
else
Set("scala-library", "scala-compiler", "scala-reflect")
if (!artifacts(d.module.name.value)) d
Expand Down Expand Up @@ -93,7 +95,7 @@ trait ScalaModule extends JavaModule { outer =>
def scalacOptions = T{ Seq.empty[String] }

def scalaDocOptions: T[Seq[String]] = T{
val defaults = if (isDotty(scalaVersion())) Seq(
val defaults = if (isDottyOrScala3(scalaVersion())) Seq(
"-project", artifactName()
) else Seq()
scalacOptions() ++ defaults
Expand Down Expand Up @@ -168,7 +170,7 @@ trait ScalaModule extends JavaModule { outer =>
val javadocDir = outDir / 'javadoc
os.makeDir.all(javadocDir)

if (isDotty(scalaVersion())) {
if (isDottyOrScala3(scalaVersion())) {
// merge all docSources into one directory by copying all children
for {
ref <- docSources()
Expand All @@ -185,7 +187,7 @@ trait ScalaModule extends JavaModule { outer =>
val files = allSourceFiles().map(_.path.toString)

val outputOptions =
if (isDotty(scalaVersion()))
if (isDottyOrScala3(scalaVersion()))
Seq("-siteroot", javadocDir.toNIO.toString)
else
Seq("-d", javadocDir.toNIO.toString)
Expand All @@ -210,7 +212,7 @@ trait ScalaModule extends JavaModule { outer =>
) match{
case true =>
val inputPath =
if (isDotty(scalaVersion())) javadocDir / '_site
if (isDottyOrScala3(scalaVersion())) javadocDir / '_site
else javadocDir
Result.Success(createJar(Agg(inputPath))(outDir))
case false => Result.Failure("docJar generation failed")
Expand All @@ -228,7 +230,7 @@ trait ScalaModule extends JavaModule { outer =>
}else{
Jvm.runSubprocess(
mainClass =
if (isDotty(scalaVersion()))
if (isDottyOrScala3(scalaVersion()))
"dotty.tools.repl.Main"
else
"scala.tools.nsc.MainGenericRunner",
Expand Down
8 changes: 5 additions & 3 deletions scalalib/src/ZincWorkerModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mill.T
import mill.api.{Ctx, FixSizedCache, KeyedLockedCache}
import mill.define.{Command, Discover, ExternalModule, Worker}
import mill.scalalib.Lib.resolveDependencies
import mill.scalalib.api.Util.{isBinaryBridgeAvailable, isDotty}
import mill.scalalib.api.Util.{isBinaryBridgeAvailable, isDottyOrScala3, isDotty}
import mill.scalalib.api.ZincWorkerApi
import mill.util.JsonFormatters._

Expand Down Expand Up @@ -81,9 +81,11 @@ trait ZincWorkerModule extends mill.Module with OfflineSupportModule { self: Cou
}

val (bridgeDep, bridgeName, bridgeVersion) =
if (isDotty(scalaVersion0)) {
if (isDottyOrScala3(scalaVersion0)) {
val org = scalaOrganization
val name = "dotty-sbt-bridge"
val name =
if (isDotty(scalaVersion0)) "dotty-sbt-bridge"
else "scala3-sbt-bridge"
val version = scalaVersion
(ivy"$org:$name:$version", name, version)
} else {
Expand Down
10 changes: 6 additions & 4 deletions scalalib/worker/src/ZincWorkerImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import java.util.jar.JarFile

import mill.api.Loose.Agg
import mill.api.{BuildProblemReporter, IO, Info, KeyedLockedCache, PathRef, Problem, ProblemPosition, Severity, Warn}
import mill.scalalib.api.Util.{grepJar, isDotty, scalaBinaryVersion}
import mill.scalalib.api.Util.{grepJar, isDotty, isDottyOrScala3, isScala3, scalaBinaryVersion}
import mill.scalalib.api.{CompilationResult, ZincWorkerApi}
import sbt.internal.inc._
import sbt.internal.util.{ConsoleAppender, ConsoleLogger, ConsoleOut, MainAppender}
Expand Down Expand Up @@ -115,7 +115,7 @@ class ZincWorkerImpl(compilerBridge: Either[
compilerClasspath,
scalacPluginClasspath
) { compilers: Compilers =>
if (isDotty(scalaVersion)) {
if (isDottyOrScala3(scalaVersion)) {
val dottydocClass = compilers.scalac().scalaInstance().loader().loadClass("dotty.tools.dottydoc.DocDriver")
val dottydocMethod = dottydocClass.getMethod("process", classOf[Array[String]])
val reporter = dottydocMethod.invoke(dottydocClass.newInstance(), args.toArray)
Expand Down Expand Up @@ -160,7 +160,7 @@ class ZincWorkerImpl(compilerBridge: Either[
(Seq("javac") ++ argsArray).!
} else if (allScala) {
val compilerMain = classloader.loadClass(
if (isDotty(scalaVersion)) "dotty.tools.dotc.Main"
if (isDottyOrScala3(scalaVersion)) "dotty.tools.dotc.Main"
else "scala.tools.nsc.Main"
)
compilerMain
Expand Down Expand Up @@ -345,6 +345,8 @@ class ZincWorkerImpl(compilerBridge: Either[
val compilerJar =
if (isDotty(scalaVersion))
grepJar(compilerClasspath, s"dotty-compiler_${scalaBinaryVersion(scalaVersion)}", scalaVersion)
else if (isScala3(scalaVersion))
grepJar(compilerClasspath, s"scala3-compiler_${scalaBinaryVersion(scalaVersion)}", scalaVersion)
else
compilerJarNameGrep(compilerClasspath, scalaVersion)

Expand All @@ -355,7 +357,7 @@ class ZincWorkerImpl(compilerBridge: Either[
compilerClasspath,
// we don't support too outdated dotty versions
// and because there will be no scala 2.14, so hardcode "2.13." here is acceptable
if (isDotty(scalaVersion)) "2.13." else scalaVersion
if (isDottyOrScala3(scalaVersion)) "2.13." else scalaVersion
).toIO,
compilerJar = compilerJar.toIO,
allJars = combinedCompilerJars,
Expand Down

0 comments on commit 105f53b

Please sign in to comment.