Skip to content

Commit

Permalink
Merge pull request #1409 from bjaglin/2136
Browse files Browse the repository at this point in the history
support parsing scala 2.13.6 / 2.12.14 -Xsource:3 dialect
  • Loading branch information
github-brice-jaglin authored May 18, 2021
2 parents 67a68c4 + 72c61bd commit 22626c7
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 28 deletions.
3 changes: 2 additions & 1 deletion project/Mima.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ object Mima {
ProblemFilters.exclude[Problem]("scalafix.testkit.SemanticRuleSuite.*"),
ProblemFilters.exclude[MissingClassProblem]("scalafix.testkit.SyntacticRuleSuite$"),
ProblemFilters.exclude[Problem]("scalafix.testkit.SyntacticRuleSuite"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.ScalafixArguments.withSemanticdbTargetroots")
ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.ScalafixArguments.withSemanticdbTargetroots"),
ProblemFilters.exclude[IncompatibleMethTypeProblem]("scalafix.testkit.RuleTest.fromPath") // private[scalafix]
)
}
}
27 changes: 19 additions & 8 deletions scalafix-cli/src/main/scala/scalafix/internal/v1/Args.scala
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,18 @@ case class Args(
}
}

def configureScalaVersion(
def sourceScalaVersion: Option[ScalaVersion] =
extractLastScalacOption("-Xsource:").flatMap(ScalaVersion.from(_).toOption)

def configureScalaVersions(
conf: ScalafixConfig
): Configured[ScalafixConfig] = {
Configured.Ok(conf.copy(scalaVersion = scalaVersion))
Configured.ok(
conf.copy(
scalaVersion = scalaVersion,
sourceScalaVersion = sourceScalaVersion
)
)
}

def configuredSourceroot: Configured[AbsolutePath] = {
Expand Down Expand Up @@ -369,16 +377,19 @@ case class Args(
def classLoader: ClassLoader =
ClasspathOps.toOrphanClassLoader(validatedClasspath)

private def extractLastScalacOption(flag: String) = {
scalacOptions
.filter(_.startsWith(flag))
.lastOption
.map(_.stripPrefix(flag))
}

private def semanticdbOption(
settingInScala2: String,
settingInScala3Opt: Option[String]
): Option[String] = {
if (scalaVersion.isScala2) {
val flag = s"-P:semanticdb:$settingInScala2:"
scalacOptions
.filter(_.startsWith(flag))
.lastOption
.map(_.stripPrefix(flag))
extractLastScalacOption(s"-P:semanticdb:$settingInScala2:")
} else {
settingInScala3Opt.flatMap { settingInScala3 =>
scalacOptions
Expand Down Expand Up @@ -409,7 +420,7 @@ case class Args(
configuredRules(base, scalafixConfig) |@|
resolvedPathReplace |@|
configuredDiffDisable |@|
configureScalaVersion(scalafixConfig)
configureScalaVersions(scalafixConfig)
).map {
case (
((((root, symtab), rulez), pathReplace), diffDisable),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import scala.util.Success
import scala.util.Try

import scala.meta.Dialect
import scala.meta.dialects

import scalafix.internal.config.ScalaVersion._

Expand All @@ -16,10 +17,13 @@ sealed trait ScalaVersion {
val major: MajorVersion
val minor: Option[Int]
val patch: Option[Int]
val dialect: Dialect = major match {
case ScalaVersion.Major.Scala2 => scala.meta.dialects.Scala213
case ScalaVersion.Major.Scala3 => scala.meta.dialects.Scala3
}

def dialect(sourceScalaVersion: Option[ScalaVersion]): Dialect =
(major, sourceScalaVersion.map(_.major)) match {
case (Major.Scala3, _) => dialects.Scala3
case (Major.Scala2, Some(Major.Scala3)) => dialects.Scala213Source3
case (Major.Scala2, _) => dialects.Scala213
}

def isScala2: Boolean = major == Major.Scala2
def isScala3: Boolean = major == Major.Scala3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ case class ScalafixConfig(
reporter: ScalafixReporter = ScalafixReporter.default,
patches: ConfigRulePatches = ConfigRulePatches.default,
scalaVersion: ScalaVersion = ScalaVersion.scala2,
sourceScalaVersion: Option[ScalaVersion] = None,
lint: LintConfig = LintConfig.default
) {
val dialect = scalaVersion.dialect
val dialect = scalaVersion.dialect(sourceScalaVersion)

def dialectForFile(path: String): Dialect =
if (path.endsWith(".sbt")) DefaultSbtDialect
Expand All @@ -41,7 +42,5 @@ object ScalafixConfig {
implicit lazy val ScalafixConfigDecoder: ConfDecoder[ScalafixConfig] =
decoder(default)

val Scala2: Dialect = scala.meta.dialects.Scala213
val Scala3: Dialect = scala.meta.dialects.Scala3
val DefaultSbtDialect: Dialect = scala.meta.dialects.Sbt1
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import scala.meta._
import metaconfig.ConfError
import metaconfig.Configured
import scalafix.internal.config.MetaconfigOps._
import scalafix.internal.config.ScalafixConfig.Scala2

object RuleInstrumentation {

Expand Down Expand Up @@ -39,7 +38,7 @@ object RuleInstrumentation {
case _ => false
}
}
(Scala2, code).parse[Source] match {
(dialects.Scala213, code).parse[Source] match {
case parsers.Parsed.Error(pos, msg, details) =>
ConfError.parseError(pos.toMetaconfig, msg).notOk
case parsers.Parsed.Success(ast) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ abstract class AbstractSemanticRuleSuite(
val classLoader = ClasspathOps.toClassLoader(args.validatedClasspath)
val tests = TestkitPath.fromProperties(props)
tests.map { test =>
RuleTest.fromPath(props, test, classLoader, symtab)
RuleTest.fromPath(args, test, classLoader, symtab)
}
}
def runAllTests(): Unit = {
Expand Down
15 changes: 6 additions & 9 deletions scalafix-testkit/src/main/scala/scalafix/testkit/RuleTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import metaconfig.internal.ConfGet
import metaconfig.typesafeconfig.typesafeConfigMetaconfigParser
import scalafix.internal.config.ScalafixConfig
import scalafix.internal.diff.DiffDisable
import scalafix.internal.v1.Args
import scalafix.internal.v1.LazyValue
import scalafix.internal.v1.Rules
import scalafix.v1
Expand All @@ -21,14 +22,14 @@ final class RuleTest(

object RuleTest {
private[scalafix] def fromPath(
props: TestkitProperties,
args: Args,
test: TestkitPath,
classLoader: ClassLoader,
symtab: SymbolTable
): RuleTest = {
val run: () => (Rules, v1.SemanticDocument) = { () =>
val input = test.toInput
val dialect = getDialectFromScalaV(props.scalaVersion)
val dialect = args.scalaVersion.dialect(args.sourceScalaVersion)
val tree = dialect(input).parse[Source].get
val comment = SemanticRuleSuite.findTestkitComment(tree.tokens)
val syntax = comment.syntax.stripPrefix("/*").stripSuffix("*/")
Expand All @@ -55,17 +56,13 @@ object RuleTest {
.getOrElse(Conf.Lst(Nil))
val config = Configuration()
.withConf(conf)
.withScalaVersion(props.scalaVersion)
.withScalacOptions(props.scalacOptions)
.withScalacClasspath(props.inputClasspath.entries)
.withScalaVersion(args.scalaVersion.value)
.withScalacOptions(args.scalacOptions)
.withScalacClasspath(args.classpath.entries)
val rules = decoder.read(rulesConf).get.withConfiguration(config).get
(rules, sdoc)
}

new RuleTest(test, run)
}

def getDialectFromScalaV(scalaV: String): Dialect =
if (scalaV.startsWith("3")) ScalafixConfig.Scala3
else ScalafixConfig.Scala2
}
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,32 @@ class ScalafixArgumentsSuite extends AnyFunSuite with DiffAssertions {
assert(fileEvaluation.getErrorMessage.get.contains("SemanticDB not found"))
}

test("Scala2 source with Scala3 syntax can only be parsed with -Xsource:3") {
val cwd = StringFS
.string2dir(
s"""|/src/Scala2Source3.scala
|open class Scala2Source3""".stripMargin,
charset
)
.toNIO
val src = cwd.resolve("src")
val args = api
.withScalaVersion("2.13.6")
.withRules(List("DisableSyntax").asJava)
.withSourceroot(src)

val withoutSource3 = args.evaluate().getFileEvaluations.head
assert(!withoutSource3.isSuccessful)

val withSource3 =
args
.withScalacOptions(Collections.singletonList("-Xsource:3"))
.evaluate()
.getFileEvaluations
.head
assert(withSource3.isSuccessful)
}

test("Source with Scala3 syntax can be parsed with dialect Scala3") {
val content =
"""|
Expand Down

0 comments on commit 22626c7

Please sign in to comment.