Skip to content

Commit

Permalink
if mismatching minor versions, protect PC dynamic loading behind a flag
Browse files Browse the repository at this point in the history
  • Loading branch information
bjaglin committed Sep 27, 2024
1 parent ed58c8a commit eeb0235
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,34 @@ final class ExplicitResultTypes(
"To fix this problem, either remove ExplicitResultTypes from .scalafix.conf or upgrade the compiler in your build."
)
} else {
config.conf // Support deprecated explicitReturnTypes config
.getOrElse("explicitReturnTypes", "ExplicitResultTypes")(
ExplicitResultTypesConfig.default
)
.map(c =>
new ExplicitResultTypes(
c,
Option {
if (
stripPatchVersion(config.scalaVersion) ==
stripPatchVersion(compilerScalaVersion)
)
PresentationCompilerTypeInferrer
.static(config, new ScalaPresentationCompiler())
config.conf.getOrElse("ExplicitResultTypes")(this.config).andThen {
conf =>
val majorMinorCompilerScalaVersion =
stripPatchVersion(compilerScalaVersion)

val matchingMinors =
majorMinorScalaVersion == majorMinorCompilerScalaVersion

if (!matchingMinors && !conf.fetchScala3CompilerIfNeeded) {
Configured.error(
s"The ExplicitResultTypes rule was compiled with a different Scala 3 minor ($majorMinorCompilerScalaVersion) " +
s"than the target sources ($majorMinorScalaVersion). To fix this problem, either enable " +
"ExplicitResultTypes.fetchScala3CompilerIfNeeded in .scalafix.conf or check if Scalafix can be " +
s"loaded with $majorMinorCompilerScalaVersion."
)
} else {
val pcTypeInferrer =
if (matchingMinors)
PresentationCompilerTypeInferrer.static(
config,
new ScalaPresentationCompiler()
)
else
PresentationCompilerTypeInferrer.dynamic(config)
}
)
)

Configured.Ok(new ExplicitResultTypes(conf, Some(pcTypeInferrer)))
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ case class ExplicitResultTypesConfig(
rewriteStructuralTypesToNamedSubclass: Boolean = true,
@Description("If true, adds result types only to implicit definitions.")
onlyImplicits: Boolean = false,
@Description(
"If true and the Scalafix minor Scala 3 version differs from the target files," +
"attempts to resolve and download compiler artifacts dynamically via Coursier. " +
"Disabled by default as this introduces a performance overhead and might not work."
)
fetchScala3CompilerIfNeeded: Boolean = false,
@Hidden()
symbolReplacements: Map[String, String] = Map.empty
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package scalafix.tests.rules

import scala.meta.io.AbsolutePath

import metaconfig.typesafeconfig._
import metaconfig.Configured
import metaconfig.Conf
import org.scalatest.funsuite.AnyFunSuite
import scalafix.internal.rule.ExplicitResultTypes
import scalafix.v1.Configuration
Expand Down Expand Up @@ -34,4 +36,29 @@ class ExplicitResultTypesSuite extends AnyFunSuite {
assert(rule.withConfiguration(earlyScala3) == Configured.error(expected))
}

test("Other Scala 3 minor versions are not supported by default") {
val neitherLTSNorNext =
config.withScalaVersion("3.5.0")

val v = buildinfo.RulesBuildInfo.scalaVersion.split('.').take(2).mkString(".")

val expected =
s"The ExplicitResultTypes rule was compiled with a different Scala 3 minor ($v) than the target sources (3.5). " +
s"To fix this problem, either enable ExplicitResultTypes.fetchScala3CompilerIfNeeded in .scalafix.conf or check if Scalafix can be loaded with $v."

assert(
rule.withConfiguration(neitherLTSNorNext) == Configured.error(expected)
)
}

test("fetchScala3CompilerIfNeeded enables dynamic loading") {
val neitherLTSNorNext =
config.withScalaVersion("3.5.0")

val conf = Conf
.parseString("ExplicitResultTypes.fetchScala3CompilerIfNeeded = true")
.get
assert(rule.withConfiguration(neitherLTSNorNext.withConf(conf)).isOk)
}

}

0 comments on commit eeb0235

Please sign in to comment.