Skip to content

Commit

Permalink
Merge pull request #2087 from bjaglin/scalaversion-moreliberal
Browse files Browse the repository at this point in the history
scalafix-interfaces: improve docs & be more liberal in parsing
  • Loading branch information
bjaglin authored Sep 29, 2024
2 parents 74f9fe0 + 733099f commit 17d3fd7
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 17 deletions.
36 changes: 21 additions & 15 deletions scalafix-interfaces/src/main/java/scalafix/interfaces/Scalafix.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,13 @@ public interface Scalafix {
* <p>
* The custom classloader optionally provided with {@link ScalafixArguments#withToolClasspath} to compile and
* classload external rules must have the classloader of the returned instance as ancestor to share a common
* loaded instance of `scalafix-core`, and therefore have been compiled against the requested Scala binary version.
* loaded instance of `scalafix-core`, and therefore have been compiled against the requested Scala version.
*
* @param requestedScalaVersion The Scala version ("3.3.4" for example) available in the classloader of the
* @param requestedScalaVersion A full Scala version (i.e. "3.3.4") or a major.minor one (i.e. "3.3") to infer
* the major.minor Scala version that should be available in the classloader of the
* returned instance. To be able to run advanced semantic rules using the Scala
* Presentation Compiler such as ExplicitResultTypes, this must match the version
* that the target classpath was built with, as provided with
* Presentation Compiler such as ExplicitResultTypes, this must be source-compatible
* with the version that the target classpath is built with, as provided with
* {@link ScalafixArguments#withScalaVersion}.
* @return An implementation of the {@link Scalafix} interface.
* @throws ScalafixException in case of errors during artifact resolution/fetching.
Expand All @@ -106,12 +107,13 @@ static Scalafix fetchAndClassloadInstance(String scalaBinaryVersion) throws Scal
* <p>
* The custom classloader optionally provided with {@link ScalafixArguments#withToolClasspath} to compile and
* classload external rules must have the classloader of the returned instance as ancestor to share a common
* loaded instance of `scalafix-core`, and therefore have been compiled against the requested Scala binary version.
* loaded instance of `scalafix-core`, and therefore have been compiled against the requested Scala version.
*
* @param requestedScalaVersion The Scala version ("3.3.4" for example) available in the classloader of the
* @param requestedScalaVersion A full Scala version (i.e. "3.3.4") or a major.minor one (i.e. "3.3") to infer
* the major.minor Scala version that should be available in the classloader of the
* returned instance. To be able to run advanced semantic rules using the Scala
* Presentation Compiler such as ExplicitResultTypes, this must match the version
* that the target classpath was built with, as provided with
* Presentation Compiler such as ExplicitResultTypes, this must be source-compatible
* with the version that the target classpath is built with, as provided with
* {@link ScalafixArguments#withScalaVersion}.
* @param repositories Maven/Ivy repositories to fetch the JARs from.
* @return An implementation of the {@link Scalafix} interface.
Expand All @@ -120,17 +122,21 @@ static Scalafix fetchAndClassloadInstance(String scalaBinaryVersion) throws Scal
static Scalafix fetchAndClassloadInstance(String requestedScalaVersion, List<Repository> repositories)
throws ScalafixException {

String requestedScalaMajorMinorOrMajorVersion =
requestedScalaVersion.replaceAll("^(\\d+\\.\\d+).*", "$1");

String scalaVersionKey;
if (requestedScalaVersion.startsWith("2.12")) {
if (requestedScalaMajorMinorOrMajorVersion.equals("2.12")) {
scalaVersionKey = "scala212";
} else if (requestedScalaVersion.startsWith("2.13")) {
} else if (requestedScalaMajorMinorOrMajorVersion.equals("2.13") ||
requestedScalaMajorMinorOrMajorVersion.equals("2")) {
scalaVersionKey = "scala213";
} else if (requestedScalaVersion.startsWith("3.0") ||
requestedScalaVersion.startsWith("3.1") ||
requestedScalaVersion.startsWith("3.2") ||
requestedScalaVersion.startsWith("3.3")) {
} else if (requestedScalaMajorMinorOrMajorVersion.equals("3.0") ||
requestedScalaMajorMinorOrMajorVersion.equals("3.1") ||
requestedScalaMajorMinorOrMajorVersion.equals("3.2") ||
requestedScalaMajorMinorOrMajorVersion.equals("3.3")) {
scalaVersionKey = "scala3LTS";
} else if (requestedScalaVersion.startsWith("3")) {
} else if (requestedScalaMajorMinorOrMajorVersion.startsWith("3")) {
scalaVersionKey = "scala3Next";
} else {
throw new IllegalArgumentException("Unsupported scala version " + requestedScalaVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,80 @@ class ScalafixSuite extends AnyFunSuite {
assert(help.contains("Usage: scalafix"))
}

test("classload Scala 3 LTS as a fallback for pre-LTS versions") {
test("fail to classload Scala 2.11 with full version") {
assertThrows[IllegalArgumentException](
Scalafix.fetchAndClassloadInstance("2.11.0", repositories)
)
}

test("fail to classload Scala 2.11 with minor version") {
assertThrows[IllegalArgumentException](
Scalafix.fetchAndClassloadInstance("2.11", repositories)
)
}

test("classload Scala 2.12 with full version") {
val scalafixAPI =
Scalafix.fetchAndClassloadInstance("2.12.20", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala212)
}

test("classload Scala 2.12 with major.minor version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("2.12", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala212)
}

test("classload Scala 2.13 with full version") {
val scalafixAPI =
Scalafix.fetchAndClassloadInstance("2.13.15", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala213)
}

test("classload Scala 2.13 with major.minor version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("2.13", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala213)
}

test("classload Scala 2.13 with major version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("2", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala213)
}

test("classload Scala 3 LTS with full pre-LTS version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.0.0", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3LTS)
}

test("classload Scala 3 Next as a fallback for post-LTS versions") {
test("classload Scala 3 LTS with major.minor pre-LTS version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.2", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3LTS)
}

test("classload Scala 3 LTS with full LTS version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.3.4", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3LTS)
}

test("classload Scala 3 LTS with major.minor LTS version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.3", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3LTS)
}

test("classload Scala 3 Next with full post-LTS version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.4.0", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3Next)
}

test("classload Scala 3 Next with major.minor post-LTS version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.5", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3Next)
}

test("classload Scala 3 Next with major version") {
val scalafixAPI = Scalafix.fetchAndClassloadInstance("3", repositories)
assert(scalafixAPI.scalaVersion() == Versions.scala3Next)
}

test("invalid class loader") {
val cl = new URLClassLoader(Array(), null)
val ex = intercept[ScalafixException] {
Expand Down

0 comments on commit 17d3fd7

Please sign in to comment.