diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e7e76ee2..aa43033aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,62 +6,38 @@ on: pull_request: jobs: test: - name: ${{ matrix.command }} - runs-on: ubuntu-latest strategy: fail-fast: false matrix: - command: - - "ci-212" - - "ci-213" - - "ci-3" - steps: - - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 - - run: sbt ${{ matrix.command }} - jdk11_212: - name: JDK11/scala_2.12 tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 - with: - java-version: adopt@1.11 - - run: sbt ci-212 - jdk11_213: - name: JDK11/scala_2.13 tests - runs-on: ubuntu-latest + os: ["ubuntu"] + jvm: ["8", "11", "17"] + include: + - os: windows + jvm: 17 + name: ${{ matrix.os }} / JDK${{ matrix.jvm }} + runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 with: - java-version: adopt@1.11 - - run: sbt ci-213 - - jdk17_213: - name: JDK17/scala_2.13 tests + jvm: temurin:${{ matrix.jvm }} + - if: ${{ matrix.os != 'windows' }} + run: sbt test + - if: ${{ matrix.os == 'windows' }} + run: sbt testWindows + docs: + name: Compile docs runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 - with: - java-version: 17 - - run: sbt ci-213 - - windows_213: - name: Windows/scala_2.13 tests - runs-on: windows-latest - steps: - - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 - - run: sbt ci-213-windows - shell: bash - checks: + - uses: coursier/setup-action@v1 + - run: sbt ci-docs + formatting: name: Scalafmt and Scalafix runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 - run: sbt "scalafixAll --check" - run: ./bin/scalafmt --test mima: @@ -69,6 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 - - run: git fetch --unshallow + with: + fetch-depth: 0 + - uses: coursier/setup-action@v1 - run: sbt versionPolicyCheck diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml index 9e0680a8e..725d5670d 100644 --- a/.github/workflows/deploy-website.yml +++ b/.github/workflows/deploy-website.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - - uses: olafurpg/setup-scala@v14 + - uses: coursier/setup-action@v1 - name: Publish ${{ github.ref }} run: sbt docs2_13/docusaurusPublishGhpages env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc14bf72a..822de3a07 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,9 +8,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: olafurpg/setup-scala@v14 + with: + fetch-depth: 0 + - uses: coursier/setup-action@v1 - uses: olafurpg/setup-gpg@v3 - - run: git fetch --unshallow - name: Check that major or minor was bumped upon compatibility breakage if: startsWith(github.ref, 'refs/tags/v') run: sbt versionCheck diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6a56731b9..3b3f5d92e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,8 +19,8 @@ hesitate to ask in the [Discord channel](https://discord.gg/8AHaqGx3Qj). The project should import normally into IntelliJ and there should not be any false red squiggles. To use the debugger or run tests from within IntelliJ, run -at least once `sbt unit2_13Target2_13/test` to generate a `BuildInfo` file and -property files for Scalafix testkit. +at least once tests through sbt to generate a `BuildInfo` file and property +files for Scalafix testkit. ## Testing @@ -28,19 +28,28 @@ Start the SBT shell with `$ sbt`. The commands below assume you have a running sbt shell. ```sh -# Fast unit tests for rules, cli, core. Contains a lot -# of different test suites, so it's recommended to use testOnly. -> unit2_13Target2_13/test +# Fast unit tests for rules, cli, core. +> unit2_13/test -# Only run tests for rules, using scalafix-testkit. -> unit2_13Target2_13/testOnly *RuleSuite +# Integration tests for rules, cli, core. Contains a lot +# of different test suites, so it's recommended to use testOnly +# and/or testQuick. +> integration2_13/test -# Only run only ProcedureSyntax unit test. -> unit2_13Target2_13/testOnly *RuleSuite -- -z ProcedureSyntax +# Use testWindows to exclude tests that are not expected to succeed +# on that OS. +> unit2_13/testWindows +> integration2_13/testWindows + +# Only run tests for built-in rules, using scalafix-testkit. +> expect2_13Target2_13_10/test + +# Only run ProcedureSyntax unit tests. +> expect2_13Target2_13_10/testOnly -- -z ProcedureSyntax ``` [sbt-projectmatrix](https://github.com/sbt/sbt-projectmatrix) is used to -generate several sbt projects `unitXTargetY` with the same source code, +generate several sbt projects `expectTargetY` with the same source code, but for a combination of Scala versions: - used for compiling the framework and rules (`X`) - used for compiling and generating SemanticDB files for the test input (`Y`) @@ -49,10 +58,14 @@ Unit tests for rules are written using scalafix-testkit ``` scalafix-tests +| +├── unit # Unit test suites +| +├── integration # Integration test suites +| ├── input # Source files to be analyzed and fixed by rules ├── output # Expected output from running rewrite rules -├── shared # Code that is shared between input and unit projects -└── unit # Unit test suites. +└── expect # Verify expectations defined in input/output using testkit ``` ## Formatting diff --git a/build.sbt b/build.sbt index 7cc353e3d..35dc5ca49 100644 --- a/build.sbt +++ b/build.sbt @@ -1,10 +1,10 @@ import Dependencies._ +import TargetAxis.TargetProjectMatrix import sbt.Keys.scalacOptions inThisBuild( List( onLoadMessage := s"Welcome to scalafix ${version.value}", - fork := true, semanticdbEnabled := true, semanticdbVersion := scalametaV, scalafixScalaBinaryVersion := "2.13", @@ -162,17 +162,19 @@ lazy val cli = projectMatrix .jvmPlatform(buildScalaVersions) .dependsOn(reflect, interfaces, rules) -lazy val testsShared = projectMatrix - .in(file("scalafix-tests/shared")) +lazy val testkit = projectMatrix + .in(file("scalafix-testkit")) .settings( - noPublishAndNoMima, - coverageEnabled := false + moduleName := "scalafix-testkit", + isFullCrossVersion, + libraryDependencies += googleDiff, + libraryDependencies += scalatestDep.value ) .defaultAxes(VirtualAxis.jvm) .jvmPlatform(buildScalaVersions) - .disablePlugins(ScalafixPlugin) + .dependsOn(cli) -lazy val testsInput = projectMatrix +lazy val input = projectMatrix .in(file("scalafix-tests/input")) .settings( noPublishAndNoMima, @@ -185,10 +187,10 @@ lazy val testsInput = projectMatrix coverageEnabled := false ) .defaultAxes(VirtualAxis.jvm) - .jvmPlatform(buildScalaVersions) + .jvmPlatformFull(buildWithTargetVersions.map(_._2)) .disablePlugins(ScalafixPlugin) -lazy val testsOutput = projectMatrix +lazy val output = projectMatrix .in(file("scalafix-tests/output")) .settings( noPublishAndNoMima, @@ -200,61 +202,101 @@ lazy val testsOutput = projectMatrix .jvmPlatform(buildScalaVersions) .disablePlugins(ScalafixPlugin) -lazy val testkit = projectMatrix - .in(file("scalafix-testkit")) - .settings( - moduleName := "scalafix-testkit", - isFullCrossVersion, - libraryDependencies += googleDiff, - libraryDependencies += scalatestDep.value - ) - .defaultAxes(VirtualAxis.jvm) - .jvmPlatform(buildScalaVersions) - .dependsOn(cli) - lazy val unit = projectMatrix .in(file("scalafix-tests/unit")) .settings( noPublishAndNoMima, - // Change working directory to match when `fork := false`. - Test / baseDirectory := (ThisBuild / baseDirectory).value, - // Prevent issues with scalatest serialization - Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat, - javaOptions := Nil, libraryDependencies ++= List( jgit, munit, scalatest.withRevision(scalatestLatestV) ), - libraryDependencies ++= { + libraryDependencies += { if (!isScala3.value) { - List( - coursier, - scalametaTeskit - ) + scalametaTeskit } else { // exclude _2.13 artifacts that have their _3 counterpart in the classpath - List( - coursier - .exclude("org.scala-lang.modules", "scala-xml_2.13") - .exclude("org.scala-lang.modules", "scala-collection-compat_2.13"), - scalametaTeskit - .exclude("com.lihaoyi", "sourcecode_2.13") - .exclude("org.scala-lang.modules", "scala-collection-compat_2.13") - .exclude("org.scalameta", "munit_2.13") - ) + scalametaTeskit + .exclude("com.lihaoyi", "sourcecode_2.13") + .exclude("org.scala-lang.modules", "scala-collection-compat_2.13") + .exclude("org.scalameta", "munit_2.13") } }, - Compile / compile / compileInputs := { - (Compile / compile / compileInputs) - .dependsOn( - TargetAxis.resolve(testsInput, Compile / compile), - TargetAxis.resolve(testsOutput, Compile / compile), - TargetAxis.resolve(testsShared, Compile / compile) - ) - .value + buildInfoPackage := "scalafix.tests", + buildInfoKeys := Seq[BuildInfoKey]( + "scalaVersion" -> scalaVersion.value + ) + ) + .defaultAxes(VirtualAxis.jvm) + .jvmPlatform(buildScalaVersions) + .enablePlugins(BuildInfoPlugin) + .dependsOn(testkit % Test) + +lazy val integration = projectMatrix + .in(file("scalafix-tests/integration")) + .settings( + noPublishAndNoMima, + Test / parallelExecution := false, + libraryDependencies += { + if (!isScala3.value) { + coursier + } else { + // exclude _2.13 artifacts that have their _3 counterpart in the classpath + coursier + .exclude("org.scala-lang.modules", "scala-xml_2.13") + .exclude("org.scala-lang.modules", "scala-collection-compat_2.13") + } }, + buildInfoPackage := "scalafix.tests", + buildInfoObject := "BuildInfo", + // create a local alias for input / Compile / fullClasspath at an + // arbitrary, unused scope to be able to reference it (as a TaskKey) in + // buildInfoKeys (since the macro only accepts TaskKeys) + buildInfoKeys / fullClasspath := + resolve(input, Compile / fullClasspath).value, + buildInfoKeys := Seq[BuildInfoKey]( + "scalametaVersion" -> scalametaV, + "scalaVersion" -> scalaVersion.value, + "baseDirectory" -> + (ThisBuild / baseDirectory).value, + "resourceDirectory" -> + (Compile / resourceDirectory).value, + "semanticClasspath" -> + Seq((Compile / semanticdbTargetRoot).value), + "sourceroot" -> + (Compile / sourceDirectory).value, + "classDirectory" -> + (Compile / classDirectory).value, + BuildInfoKey.map(buildInfoKeys / fullClasspath) { case (_, v) => + "inputClasspath" -> v + }, + "inputSemanticClasspath" -> + Seq(resolve(input, Compile / semanticdbTargetRoot).value), + "inputSourceroot" -> + resolve(input, Compile / sourceDirectory).value, + "outputSourceroot" -> + resolve(output, Compile / sourceDirectory).value + ), + Test / test := (Test / test) + .dependsOn(cli.projectRefs.map(_ / publishLocalTransitive): _*) + .value, + Test / testWindows := (Test / testWindows) + .dependsOn(cli.projectRefs.map(_ / publishLocalTransitive): _*) + .value + ) + .defaultAxes(VirtualAxis.jvm) + .jvmPlatform(buildScalaVersions) + .enablePlugins(BuildInfoPlugin) + .dependsOn(unit % "compile->test") + +lazy val expect = projectMatrix + .in(file("scalafix-tests/expect")) + .settings( + noPublishAndNoMima, Test / resourceGenerators += Def.task { + // make sure the output can be compiled + val _ = TargetAxis.resolve(output, Compile / compile).value + // copy-pasted code from ScalafixTestkitPlugin to avoid cyclic dependencies between build and sbt-scalafix. val props = new java.util.Properties() def put(key: String, files: Seq[File]): Unit = { @@ -266,30 +308,30 @@ lazy val unit = projectMatrix put( "inputClasspath", TargetAxis - .resolve(testsInput, Compile / fullClasspath) + .resolve(input, Compile / fullClasspath) .value .map(_.data) ) put( "inputSourceDirectories", TargetAxis - .resolve(testsInput, Compile / unmanagedSourceDirectories) + .resolve(input, Compile / unmanagedSourceDirectories) .value ) put( "outputSourceDirectories", TargetAxis - .resolve(testsOutput, Compile / unmanagedSourceDirectories) + .resolve(output, Compile / unmanagedSourceDirectories) .value ) props.put( "scalaVersion", - TargetAxis.resolve(testsInput, Compile / scalaVersion).value + TargetAxis.resolve(input, Compile / scalaVersion).value ) props.put( "scalacOptions", TargetAxis - .resolve(testsInput, Compile / scalacOptions) + .resolve(input, Compile / scalacOptions) .value .mkString("|") ) @@ -298,73 +340,17 @@ lazy val unit = projectMatrix "scalafix-testkit.properties" IO.write(props, "Input data for scalafix testkit", out) List(out) - }, - buildInfoPackage := "scalafix.tests", - buildInfoObject := "BuildInfo", - buildInfoKeys := Seq[BuildInfoKey]( - "scalametaVersion" -> scalametaV, - "scalaVersion" -> scalaVersion.value, - "baseDirectory" -> - (ThisBuild / baseDirectory).value, - "unitResourceDirectory" -> (Compile / resourceDirectory).value, - "semanticClasspath" -> - Seq( - TargetAxis.resolve(testsInput, Compile / semanticdbTargetRoot).value, - TargetAxis.resolve(testsShared, Compile / semanticdbTargetRoot).value - ), - "sharedSourceroot" -> - (ThisBuild / baseDirectory).value / - "scalafix-tests" / "shared" / "src" / "main", - "sharedClasspath" -> - TargetAxis.resolve(testsShared, Compile / classDirectory).value - ), - Test / test := (Test / test) - .dependsOn(cli.projectRefs.map(_ / publishLocalTransitive): _*) - .value, - Test / unmanagedSourceDirectories ++= { - val sourceDir = (Test / sourceDirectory).value - val maybeTargetScalaVersion = - TargetAxis - .targetScalaVersion(virtualAxes.value) - .flatMap(CrossVersion.partialVersion(_)) - maybeTargetScalaVersion match { - case Some((n, m)) => - Seq( - sourceDir / s"scala-target$n", - sourceDir / s"scala-target$n.$m" - ) - case _ => Seq() - } } ) .defaultAxes(VirtualAxis.jvm) - .jvmPlatform( - scalaVersions = Seq(scala3), - axisValues = Seq(TargetAxis(scala3)), - settings = Seq() - ) - .jvmPlatform( - scalaVersions = Seq(scala212), - axisValues = Seq(TargetAxis(scala3)), - settings = Seq() - ) - .jvmPlatform( - scalaVersions = Seq(scala213), - axisValues = Seq(TargetAxis(scala213)), - settings = Seq() - ) - .jvmPlatform( - scalaVersions = Seq(scala212), - axisValues = Seq(TargetAxis(scala212)), - settings = Seq() - ) - .enablePlugins(BuildInfoPlugin) - .dependsOn(testkit) + .jvmPlatformWithTargets(buildWithTargetVersions) + .dependsOn(integration) lazy val docs = projectMatrix .in(file("scalafix-docs")) .settings( noPublishAndNoMima, + fork := true, run / baseDirectory := (ThisBuild / baseDirectory).value, moduleName := "scalafix-docs", scalacOptions += "-Wconf:msg='match may not be exhaustive':s", // silence exhaustive pattern matching warning for documentation diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f3c7b6d6c..6e6b7afad 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -12,11 +12,10 @@ object Dependencies { val scala3 = "3.2.2" val buildScalaVersions = Seq(scala212, scala213, scala3) - val testTargetScalaVersions = Seq(scala212, scala213, scala3) - - // we support 3 last binary versions of scala212 and scala213 - val testedPreviousScalaVersions: Map[String, List[String]] = - List(scala213, scala212).map(version => version -> previousVersions(version)).toMap + val buildWithTargetVersions: Seq[(String, String)] = + buildScalaVersions.map(sv => (sv, sv)) ++ + Seq(scala213, scala212).flatMap(sv => previousVersions(sv).map(prev => (sv, prev))) ++ + Seq(scala213, scala212).map(sv => (sv, scala3)) val bijectionCoreV = "0.9.7" val collectionCompatV = "2.10.0" @@ -59,12 +58,12 @@ object Dependencies { val munit = "org.scalameta" %% "munit" % munitV val semanticdbScalacCore = "org.scalameta" % "semanticdb-scalac-core" % scalametaV cross CrossVersion.full - private def previousVersions(scalaVersion: String): List[String] = { + private def previousVersions(scalaVersion: String): Seq[String] = { val split = scalaVersion.split('.') val binaryVersion = split.take(2).mkString(".") val compilerVersion = Try(split.last.toInt).toOption val previousPatchVersions = - compilerVersion.map(version => List.range(version - 7, version).filter(_ >= 0)).getOrElse(Nil) + compilerVersion.map(version => List.range(version - 2, version).filter(_ >= 0)).getOrElse(Nil) previousPatchVersions.map(v => s"$binaryVersion.$v") } } diff --git a/project/ScalafixBuild.scala b/project/ScalafixBuild.scala index e1105ea9d..ff82e4a44 100644 --- a/project/ScalafixBuild.scala +++ b/project/ScalafixBuild.scala @@ -2,6 +2,7 @@ import Dependencies._ import sbt._ import sbt.Classpaths import sbt.Keys._ +import sbt.internal.ProjectMatrix import sbt.nio.Keys._ import sbt.plugins.JvmPlugin import com.typesafe.tools.mima.plugin.MimaPlugin.autoImport._ @@ -121,6 +122,37 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { if (isScala3.value) scalatest.withRevision(scalatestLatestV) else scalatest } + + lazy val testWindows = + taskKey[Unit]("run tests, excluding those incompatible with Windows") + + /** + * Lookup a setting key for the project of the same scala version in the + * given matrix + */ + def resolve[T]( + matrix: ProjectMatrix, + key: SettingKey[T] + ): Def.Initialize[T] = + Def.settingDyn { + val sv = scalaVersion.value + val project = matrix.jvm(sv) + Def.setting((project / key).value) + } + + /** + * Lookup a task key for the project of the same scala version in the given + * matrix + */ + def resolve[T]( + matrix: ProjectMatrix, + key: TaskKey[T] + ): Def.Initialize[Task[T]] = + Def.taskDyn { + val sv = scalaVersion.value + val project = matrix.jvm(sv) + Def.task((project / key).value) + } } import autoImport._ @@ -135,32 +167,15 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { updateOptions := updateOptions.value.withCachedResolution(true), ThisBuild / watchTriggeredMessage := Watch.clearScreenOnTrigger, commands += Command.command("save-expect") { s => - "unit2_13Target2_13/test:runMain scalafix.tests.util.SaveExpect" :: - "unit3Target3/test:runMain scalafix.tests.util.SaveExpect" :: - s - }, - commands += Command.command("ci-3") { s => - "unit2_12Target3/test" :: - "unit3Target3/test" :: + "integration2_13/test:runMain scalafix.tests.util.SaveExpect" :: + "integration3/test:runMain scalafix.tests.util.SaveExpect" :: s }, - commands += Command.command("ci-213") { s => - "unit2_13Target2_13/test" :: - "docs2_13/run" :: + commands += Command.command("ci-docs") { s => + "docs2_13/run" :: // reduce risk of errors on deploy-website.yml "interfaces/doc" :: - testRulesAgainstPreviousScalaVersions(scala213, s) - }, - commands += Command.command("ci-212") { s => - "unit2_12Target2_12/test" :: - testRulesAgainstPreviousScalaVersions(scala212, s) - }, - commands += Command.command("ci-213-windows") { s => - "publishLocalTransitive" :: // scalafix.tests.interfaces.ScalafixSuite - s"unit2_13Target2_13/testOnly -- -l scalafix.internal.tests.utils.SkipWindows" :: s }, - // There is flakyness in CliGitDiffTests and CliSemanticTests - Test / parallelExecution := false, Test / publishArtifact := false, licenses := Seq( "Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0") @@ -195,6 +210,11 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { ) override def projectSettings: Seq[Def.Setting[_]] = List( + // Prevent issues with scalatest serialization + Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat, + Test / testWindows := (Test / testOnly) + .toTask(" -- -l scalafix.internal.tests.utils.SkipWindows") + .value, // avoid "missing dependency" on artifacts with full scala version when bumping scala versionPolicyIgnored ++= { PreviousScalaVersion.get(scalaVersion.value) match { @@ -211,6 +231,8 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { // don't publish scala 3 artifacts for now publish / skip := (if ((publish / skip).value) true else scalaBinaryVersion.value == "3"), + publishLocal / skip := (if ((publishLocal / skip).value) true + else scalaBinaryVersion.value == "3"), versionPolicyIntention := Compatibility.BinaryCompatible, scalacOptions ++= compilerOptions.value, scalacOptions ++= semanticdbSyntheticsCompilerOption.value, @@ -265,21 +287,4 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { } } ) - - private def testRulesAgainstPreviousScalaVersions( - scalaVersion: String, - state: State - ): State = { - val projectSuffix = scalaVersion.split('.').take(2).mkString("_") - testedPreviousScalaVersions - .getOrElse(scalaVersion, Nil) - .flatMap { v => - List( - s"""set Project("testsInput${projectSuffix}", file(".")) / scalaVersion := "$v"""", - s"show testsInput${projectSuffix} / scalaVersion", - s"unit${projectSuffix}Target${projectSuffix} / testOnly scalafix.tests.rule.RuleSuite" - ) - } - .foldRight(state)(_ :: _) - } } diff --git a/project/TargetAxis.scala b/project/TargetAxis.scala index 753c6160f..1506905d3 100644 --- a/project/TargetAxis.scala +++ b/project/TargetAxis.scala @@ -5,10 +5,8 @@ import sbtprojectmatrix.ProjectMatrixPlugin.autoImport._ /** Use on ProjectMatrix rows to tag an affinity to a custom scalaVersion */ case class TargetAxis(scalaVersion: String) extends VirtualAxis.WeakAxis { - private val scalaBinaryVersion = CrossVersion.binaryScalaVersion(scalaVersion) - - override val idSuffix = s"Target${scalaBinaryVersion.replace('.', '_')}" - override val directorySuffix = s"target$scalaBinaryVersion" + override val idSuffix = s"Target${scalaVersion.replace('.', '_')}" + override val directorySuffix = s"target$scalaVersion" override val suffixOrder = VirtualAxis.scalaABIVersion("any").suffixOrder + 1 } @@ -28,7 +26,7 @@ object TargetAxis { ): Def.Initialize[Task[T]] = Def.taskDyn { val sv = targetScalaVersion(virtualAxes.value).get - val project = matrix.finder().apply(sv) + val project = exactOrBinaryScalaVersionMatch(matrix, sv) Def.task((project / key).value) } @@ -43,8 +41,59 @@ object TargetAxis { ): Def.Initialize[T] = Def.settingDyn { val sv = targetScalaVersion(virtualAxes.value).get - val project = matrix.finder().apply(sv) + val project = exactOrBinaryScalaVersionMatch(matrix, sv) Def.setting((project / key).value) } + private def exactOrBinaryScalaVersionMatch( + matrix: ProjectMatrix, + scalaVersion: String + ): Project = { + val projectsWithAxisValues = matrix.allProjects().flatMap { + case (p, axisValues) => axisValues.map(v => (p, v)) + } + + projectsWithAxisValues.collectFirst { + case (p, VirtualAxis.ScalaVersionAxis(_, value)) + if value == scalaVersion || + value == CrossVersion.binaryScalaVersion(scalaVersion) => + p + }.get + } + + implicit class TargetProjectMatrix(projectMatrix: ProjectMatrix) { + + /** Like jvmPlatform but with the full scala version attached */ + def jvmPlatformFull(scalaVersions: Seq[String]): ProjectMatrix = { + scalaVersions.foldLeft(projectMatrix) { (acc, sv) => + acc.customRow( + autoScalaLibrary = true, + axisValues = Seq( + VirtualAxis.jvm, + VirtualAxis.scalaVersionAxis(sv, sv) + ), + process = p => p + ) + } + } + + /** + * Like jvmPlatform but adding a target axis with the scala version provided + * as the second element of the tuple + */ + def jvmPlatformWithTargets( + buildWithTargetVersions: Seq[(String, String)] + ): ProjectMatrix = { + buildWithTargetVersions.foldLeft(projectMatrix) { + case (acc, (build, target)) => + acc.jvmPlatform( + scalaVersions = Seq(build), + axisValues = Seq(TargetAxis(target)), + settings = Seq() + ) + } + } + + } + } diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/rule/RuleSuite.scala b/scalafix-tests/expect/src/test/scala/scalafix/tests/rule/RuleSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/rule/RuleSuite.scala rename to scalafix-tests/expect/src/test/scala/scalafix/tests/rule/RuleSuite.scala diff --git a/scalafix-tests/input/src/main/scala-2/test/PatchWithEmptyRange.scala b/scalafix-tests/input/src/main/scala-2/test/PatchWithEmptyRange.scala index a3c791f63..152342c4d 100644 --- a/scalafix-tests/input/src/main/scala-2/test/PatchWithEmptyRange.scala +++ b/scalafix-tests/input/src/main/scala-2/test/PatchWithEmptyRange.scala @@ -1,5 +1,5 @@ /* -rules = "scala:banana.rule.PatchTokenWithEmptyRange" +rules = "scala:scalafix.test.PatchTokenWithEmptyRange" */ package test diff --git a/scalafix-tests/integration/src/main/resources-2/expect/Pretty.expect b/scalafix-tests/integration/src/main/resources-2/expect/Pretty.expect new file mode 100644 index 000000000..b30aeaa29 --- /dev/null +++ b/scalafix-tests/integration/src/main/resources-2/expect/Pretty.expect @@ -0,0 +1,139 @@ +[7:7..7:17]: test/PrettyTest# => class PrettyTest extends AnyRef { +4 decls } +[7:18..7:18]: test/PrettyTest#``(). => primary ctor () +[8:3..8:14]: *[Int] +[8:3..8:7]: *.apply[Int] +[9:3..13:12]: orig(1.to(10)).flatMap[Int]( + { (i) => + orig(2.to(20)).withFilter( + { (j) => orig(i > i) } + ).map[Int]({ (j) => orig(j) }) + } + ) +[10:10..10:11]: intWrapper(*) +[11:10..11:11]: intWrapper(*) +[14:3..18:15]: orig(Future(1.to(10)))(global).foreach[Unit]( + { (i) => + orig(Future(2.to(i.length)))(global).foreach[Unit]( + { (j) => orig(println(j)) } + )(global) + } + )(global) +[15:10..15:16]: *.apply[Inclusive] +[15:17..15:18]: intWrapper(*) +[16:10..16:16]: *.apply[Inclusive] +[16:17..16:18]: intWrapper(*) +[21:9..21:14]: test/PrettyTest#Inner# => class Inner extends AnyRef { +1 decls } +[21:14..21:14]: test/PrettyTest#Inner#``(). => primary ctor () +[22:7..22:8]: test/PrettyTest#a. => val method a: PrettyTest +[23:7..23:8]: test/PrettyTest#b. => val method b: a.Inner +[25:3..25:9]: *.apply[AnyRef { + local4 => abstract method bar(a: Int): Int + local6 => abstract method foo(a: Int): Int + }] +[30:3..30:9]: *.apply[a.Inner] +[31:3..31:9]: *.apply[Int with String {}] +[32:3..32:9]: *.apply[PrettyTest] +[39:7..39:10]: test/ann# => class ann[T] extends Annotation with StaticAnnotation { +2 decls } +[39:11..39:12]: test/ann#[T] => typeparam T +[39:13..39:13]: test/ann#``(). => primary ctor (x: T) +[39:14..39:15]: test/ann#x. => private[this] val method x: T +[40:7..40:11]: test/ann1# => class ann1 extends Annotation with StaticAnnotation { +1 decls } +[40:12..40:12]: test/ann1#``(). => primary ctor () +[41:7..41:11]: test/ann2# => class ann2 extends Annotation with StaticAnnotation { +1 decls } +[41:12..41:12]: test/ann2#``(). => primary ctor () +[43:7..43:8]: test/B# => class B extends AnyRef { +1 decls } +[45:7..45:8]: test/C# => class C extends AnyRef { +1 decls } +[47:7..47:8]: test/P# => class P extends AnyRef { +4 decls } +[47:9..47:9]: test/P#``(). => primary ctor () +[48:9..48:10]: test/P#C# => class C extends AnyRef { +1 decls } +[48:10..48:10]: test/P#C#``(). => primary ctor () +[49:9..49:10]: test/P#X# => class X extends AnyRef { +1 decls } +[49:10..49:10]: test/P#X#``(). => primary ctor () +[50:7..50:8]: test/P#x. => val method x: X +[53:7..53:8]: test/T# => class T extends AnyRef { +4 decls } +[53:9..53:9]: test/T#``(). => primary ctor () +[54:9..54:10]: test/T#C# => class C extends AnyRef { +1 decls } +[54:10..54:10]: test/T#C#``(). => primary ctor () +[55:9..55:10]: test/T#X# => class X extends AnyRef { +1 decls } +[55:10..55:10]: test/T#X#``(). => primary ctor () +[56:7..56:8]: test/T#x. => val method x: X +[59:8..59:12]: test/Test. => final object Test extends AnyRef { +4 decls } +[60:9..60:10]: test/Test.M# => class M extends AnyRef { +2 decls } +[60:11..60:11]: test/Test.M#``(). => primary ctor () +[61:9..61:10]: test/Test.M#m(). => method m: Int +[64:9..64:10]: test/Test.N# => trait N extends AnyRef { +1 decls } +[65:9..65:10]: test/Test.N#n(). => method n: Int +[68:9..68:10]: test/Test.C# => class C extends M { +35 decls } +[68:11..68:11]: test/Test.C#``(). => primary ctor () +[69:9..69:10]: test/Test.C#p. => val method p: P +[70:9..70:10]: test/Test.C#x. => val method x: p.X +[72:9..72:17]: test/Test.C#typeRef1. => val method typeRef1: C +[73:9..73:17]: test/Test.C#typeRef2. => val method typeRef2: p.C +[74:9..74:17]: test/Test.C#typeRef3. => val method typeRef3: T#C +[75:9..75:17]: test/Test.C#typeRef4. => val method typeRef4: List[Int] +[77:9..77:20]: test/Test.C#singleType1. => val method singleType1: x.type +[78:9..78:20]: test/Test.C#singleType2. => val method singleType2: p.x.type +[79:9..79:15]: test/Test.C#Either. => val method Either: Either.type +[81:9..81:18]: test/Test.C#thisType1. => val method thisType1: C.this.type +[82:9..82:18]: test/Test.C#thisType2. => val method thisType2: C.this.type +[84:9..84:19]: test/Test.C#superType1. => val method superType1: Int +[85:9..85:19]: test/Test.C#superType2. => val method superType2: Int +[86:9..86:19]: test/Test.C#superType3. => val method superType3: Int +[88:9..88:22]: test/Test.C#compoundType1. => val method compoundType1: AnyRef { def k: Int } +[89:9..89:22]: test/Test.C#compoundType2. => val method compoundType2: M with N {} +[90:9..90:22]: test/Test.C#compoundType3. => val method compoundType3: M with N { def k: Int } +[91:9..91:22]: test/Test.C#compoundType4. => val method compoundType4: AnyRef { def k: Int } +[92:9..92:22]: test/Test.C#compoundType5. => val method compoundType5: M with N {} +[93:9..93:22]: test/Test.C#compoundType6. => val method compoundType6: M with N { def k: Int } +[95:9..95:17]: test/Test.C#annType1. => val method annType1: T @ann[Int] +[96:9..96:17]: test/Test.C#annType2. => val method annType2: T @ann1 @ann2 +[98:9..98:25]: test/Test.C#existentialType2. => val method existentialType2: List[_] forSome { type _ } +[99:9..99:25]: test/Test.C#existentialType3. => val method existentialType3: Class[?0] forSome { type ?0 } +[100:9..100:25]: test/Test.C#existentialType4. => val method existentialType4: Class[?0] forSome { type ?0 } +[102:9..102:20]: test/Test.C#typeLambda1(). => method typeLambda1[M[_]]: Nothing +[102:21..102:22]: test/Test.C#typeLambda1().[M] => typeparam M[_] +[105:12..105:26]: test/Test.C#ClassInfoType1. => final object ClassInfoType1 extends AnyRef +[106:11..106:25]: test/Test.C#ClassInfoType2# => class ClassInfoType2 extends B { +2 decls } +[106:26..106:26]: test/Test.C#ClassInfoType2#``(). => primary ctor () +[106:42..106:43]: test/Test.C#ClassInfoType2#x(). => method x: Int +[107:11..107:25]: test/Test.C#ClassInfoType3# => trait ClassInfoType3[T] extends AnyRef +[107:26..107:27]: test/Test.C#ClassInfoType3#[T] => typeparam T +[109:12..109:22]: test/Test.C#MethodType. => final object MethodType extends AnyRef { +6 decls } +[110:11..110:13]: test/Test.C#MethodType.x1(). => method x1: Int +[111:11..111:13]: test/Test.C#MethodType.x2(). => method x2: Int +[112:11..112:13]: test/Test.C#MethodType.m3(). => method m3: Int +[113:11..113:13]: test/Test.C#MethodType.m4(). => method m4(): Int +[114:11..114:13]: test/Test.C#MethodType.m5(). => method m5(x: Int): Int +[114:14..114:15]: test/Test.C#MethodType.m5().(x) => param x: Int +[115:11..115:13]: test/Test.C#MethodType.m6(). => method m6[T](x: T): T +[115:14..115:15]: test/Test.C#MethodType.m6().[T] => typeparam T +[115:17..115:18]: test/Test.C#MethodType.m6().(x) => param x: T +[118:12..118:22]: test/Test.C#ByNameType. => final object ByNameType extends AnyRef { +1 decls } +[119:11..119:13]: test/Test.C#ByNameType.m1(). => method m1(x: => Int): Int +[119:14..119:15]: test/Test.C#ByNameType.m1().(x) => param x: => Int +[122:16..122:28]: test/Test.C#RepeatedType# => case class RepeatedType extends AnyRef with Product with Serializable { +12 decls } +[122:28..122:28]: test/Test.C#RepeatedType#``(). => primary ctor (val s: String*) +[122:29..122:30]: test/Test.C#RepeatedType#s. => val method s: String* +[123:11..123:13]: test/Test.C#RepeatedType#m1(). => method m1(x: Int*): Int +[123:14..123:15]: test/Test.C#RepeatedType#m1().(x) => param x: Int* +[126:12..126:20]: test/Test.C#TypeType. => final object TypeType extends AnyRef { +5 decls } +[127:12..127:14]: test/Test.C#TypeType.T1# => abstract type T1 +[128:11..128:13]: test/Test.C#TypeType.m2(). => method m2[T2 = C]: Nothing +[128:14..128:16]: test/Test.C#TypeType.m2().[T2] => typeparam T2 = C +[129:11..129:13]: test/Test.C#TypeType.m3(). => method m3[M3[_]]: Nothing +[129:14..129:16]: test/Test.C#TypeType.m3().[M3] => typeparam M3[_] +[130:12..130:14]: test/Test.C#TypeType.T4# => type T4 = C +[131:12..131:14]: test/Test.C#TypeType.T5# => type T5[U] = U +[131:15..131:16]: test/Test.C#TypeType.T5#[U] => typeparam U +[135:10..135:17]: test/Test.Literal. => final object Literal extends AnyRef { +11 decls } +[136:15..136:18]: test/Test.Literal.int. => final val method int: 1 +[137:15..137:19]: test/Test.Literal.long. => final val method long: 1L +[138:15..138:20]: test/Test.Literal.float. => final val method float: 1.0f +[139:15..139:21]: test/Test.Literal.double. => final val method double: 2.0 +[140:15..140:18]: test/Test.Literal.nil. => final val method nil: null +[141:15..141:19]: test/Test.Literal.char. => final val method char: 'a' +[142:15..142:21]: test/Test.Literal.string. => final val method string: "a" +[143:15..143:19]: test/Test.Literal.bool. => final val method bool: true +[144:15..144:19]: test/Test.Literal.unit. => final val method unit: Unit +[145:15..145:23]: test/Test.Literal.javaEnum. => final val method javaEnum: NOFOLLOW_LINKS.type +[146:15..146:22]: test/Test.Literal.clazzOf. => final val method clazzOf: Class[Option[Int]] \ No newline at end of file diff --git a/scalafix-tests/integration/src/main/resources-3/expect/Pretty.expect b/scalafix-tests/integration/src/main/resources-3/expect/Pretty.expect new file mode 100644 index 000000000..0eb5d72e5 --- /dev/null +++ b/scalafix-tests/integration/src/main/resources-3/expect/Pretty.expect @@ -0,0 +1,111 @@ +[7:7..7:17]: test/PrettyTest# => class PrettyTest extends Object { self: PrettyTest => +6 decls } +[8:3..8:14]: *[Int] +[8:3..8:7]: *.apply[Int] +[10:10..10:11]: intWrapper(*) +[11:10..11:11]: intWrapper(*) +[15:10..15:16]: *.apply[Inclusive] +[15:10..15:26]: *(global) +[15:17..15:18]: intWrapper(*) +[16:10..16:16]: *.apply[Inclusive] +[16:10..16:32]: *(global) +[16:17..16:18]: intWrapper(*) +[21:9..21:14]: test/PrettyTest#Inner# => class Inner extends Object { self: Inner => +1 decls } +[22:7..22:8]: test/PrettyTest#a. => val method aPrettyTest +[23:7..23:8]: test/PrettyTest#b. => val method ba.Inner +[25:3..25:9]: *.apply[Object { + local4 => abstract method foo(a: Int): Int + local5 => abstract method bar(a: Int): Int + }] +[31:3..31:9]: *.apply[Int & String] +[39:7..39:10]: test/ann# => class ann[T] extends Annotation with StaticAnnotation { self: ann[T] => +3 decls } +[39:11..39:12]: test/ann#[T] => typeparam T +[39:14..39:15]: test/ann#x. => private[this] val method xT +[40:7..40:11]: test/ann1# => class ann1 extends Annotation with StaticAnnotation { self: ann1 => +1 decls } +[41:7..41:11]: test/ann2# => class ann2 extends Annotation with StaticAnnotation { self: ann2 => +1 decls } +[43:7..43:8]: test/B# => class B extends Object { self: B => +1 decls } +[45:7..45:8]: test/C# => class C extends Object { self: C => +1 decls } +[47:7..47:8]: test/P# => class P extends Object { self: P => +8 decls } +[48:9..48:10]: test/P#C# => class C extends Object { self: C => +1 decls } +[49:9..49:10]: test/P#X# => class X extends Object { self: X => +1 decls } +[50:7..50:8]: test/P#x. => val method xX +[53:7..53:8]: test/T# => class T extends Object { self: T => +8 decls } +[54:9..54:10]: test/T#C# => class C extends Object { self: C => +1 decls } +[55:9..55:10]: test/T#X# => class X extends Object { self: X => +1 decls } +[56:7..56:8]: test/T#x. => val method xX +[59:8..59:12]: test/Test. => final object Test extends Object { self: Test.type => +10 decls } +[60:9..60:10]: test/Test.M# => class M extends Object { self: M => +2 decls } +[61:9..61:10]: test/Test.M#m(). => method m=> Int +[64:9..64:10]: test/Test.N# => trait N extends Object { self: N => +2 decls } +[65:9..65:10]: test/Test.N#n(). => method n=> Int +[68:9..68:10]: test/Test.C# => class C extends M { self: C => +42 decls } +[69:9..69:10]: test/Test.C#p. => val method pP +[70:9..70:10]: test/Test.C#x. => val method xp.X +[72:9..72:17]: test/Test.C#typeRef1. => val method typeRef1C +[73:9..73:17]: test/Test.C#typeRef2. => val method typeRef2p.C +[74:9..74:17]: test/Test.C#typeRef3. => val method typeRef3T#C +[75:9..75:17]: test/Test.C#typeRef4. => val method typeRef4List[Int] +[77:9..77:20]: test/Test.C#singleType1. => val method singleType1x.type +[78:9..78:20]: test/Test.C#singleType2. => val method singleType2p.x.type +[79:9..79:15]: test/Test.C#Either. => val method EitherEither.type +[81:9..81:18]: test/Test.C#thisType1. => val method thisType1C.this.type +[82:9..82:18]: test/Test.C#thisType2. => val method thisType2C.this.type +[84:9..84:19]: test/Test.C#superType1. => val method superType1Int +[85:9..85:19]: test/Test.C#superType2. => val method superType2Int +[86:9..86:19]: test/Test.C#superType3. => val method superType3Int +[88:9..88:22]: test/Test.C#compoundType1. => val method compoundType1Object { def k=> Int } +[89:9..89:22]: test/Test.C#compoundType2. => val method compoundType2M & N +[90:9..90:22]: test/Test.C#compoundType3. => val method compoundType3M & N { def k=> Int } +[91:9..91:22]: test/Test.C#compoundType4. => val method compoundType4Object +[92:9..92:22]: test/Test.C#compoundType5. => val method compoundType5M & N +[93:9..93:22]: test/Test.C#compoundType6. => val method compoundType6M & N +[95:9..95:17]: test/Test.C#annType1. => val method annType1T @ann[T] +[95:21..95:25]: [Int] +[96:9..96:17]: test/Test.C#annType2. => val method annType2T @ann1 @ann2 +[98:9..98:25]: test/Test.C#existentialType2. => val method existentialType2List[_] forSome { type _ } +[99:9..99:25]: test/Test.C#existentialType3. => val method existentialType3Class[_] forSome { type _ } +[100:9..100:25]: test/Test.C#existentialType4. => val method existentialType4Class[_] forSome { type _ } +[102:9..102:20]: test/Test.C#typeLambda1(). => method typeLambda1[M[type _]]: Nothing +[102:21..102:22]: test/Test.C#typeLambda1().[M] => typeparam M[type _] +[105:12..105:26]: test/Test.C#ClassInfoType1. => final object ClassInfoType1 extends Object { self: ClassInfoType1.type => +1 decls } +[106:11..106:25]: test/Test.C#ClassInfoType2# => class ClassInfoType2 extends B { self: ClassInfoType2 => +2 decls } +[106:42..106:43]: test/Test.C#ClassInfoType2#x(). => method x=> Int +[107:11..107:25]: test/Test.C#ClassInfoType3# => trait ClassInfoType3[T] extends Object { self: ClassInfoType3[T] => +2 decls } +[107:26..107:27]: test/Test.C#ClassInfoType3#[T] => typeparam T +[109:12..109:22]: test/Test.C#MethodType. => final object MethodType extends Object { self: MethodType.type => +7 decls } +[110:11..110:13]: test/Test.C#MethodType.x1(). => method x1=> Int +[111:11..111:13]: test/Test.C#MethodType.x2(). => method x2=> Int +[112:11..112:13]: test/Test.C#MethodType.m3(). => method m3=> Int +[113:11..113:13]: test/Test.C#MethodType.m4(). => method m4(): Int +[114:11..114:13]: test/Test.C#MethodType.m5(). => method m5(x: Int): Int +[114:14..114:15]: test/Test.C#MethodType.m5().(x) => param x: Int +[115:11..115:13]: test/Test.C#MethodType.m6(). => method m6[T](x: T): T +[115:14..115:15]: test/Test.C#MethodType.m6().[T] => typeparam T +[115:17..115:18]: test/Test.C#MethodType.m6().(x) => param x: T +[118:12..118:22]: test/Test.C#ByNameType. => final object ByNameType extends Object { self: ByNameType.type => +2 decls } +[119:11..119:13]: test/Test.C#ByNameType.m1(). => method m1(x: => Int): Int +[119:14..119:15]: test/Test.C#ByNameType.m1().(x) => param x: => Int +[122:16..122:28]: test/Test.C#RepeatedType# => case class RepeatedType extends Object with Product with Serializable { self: RepeatedType => +4 decls } +[122:29..122:30]: test/Test.C#RepeatedType#s. => val method sString* +[123:11..123:13]: test/Test.C#RepeatedType#m1(). => method m1(x: Int*): Int +[123:14..123:15]: test/Test.C#RepeatedType#m1().(x) => param x: Int* +[126:12..126:20]: test/Test.C#TypeType. => final object TypeType extends Object { self: TypeType.type => +6 decls } +[127:12..127:14]: test/Test.C#TypeType.T1# => type T1 +[128:11..128:13]: test/Test.C#TypeType.m2(). => method m2[T2 = C]: Nothing +[128:14..128:16]: test/Test.C#TypeType.m2().[T2] => typeparam T2 = C +[129:11..129:13]: test/Test.C#TypeType.m3(). => method m3[M3[type _]]: Nothing +[129:14..129:16]: test/Test.C#TypeType.m3().[M3] => typeparam M3[type _] +[130:12..130:14]: test/Test.C#TypeType.T4# => type T4 = C +[131:12..131:14]: test/Test.C#TypeType.T5# => type T5[U] = U +[131:15..131:16]: test/Test.C#TypeType.T5#[U] => typeparam U +[135:10..135:17]: test/Test.Literal. => final object Literal extends Object { self: Literal.type => +12 decls } +[136:15..136:18]: test/Test.Literal.int. => final val method int1 +[137:15..137:19]: test/Test.Literal.long. => final val method long1L +[138:15..138:20]: test/Test.Literal.float. => final val method float1.0f +[139:15..139:21]: test/Test.Literal.double. => final val method double2.0 +[140:15..140:18]: test/Test.Literal.nil. => final val method nilNull +[141:15..141:19]: test/Test.Literal.char. => final val method char'a' +[142:15..142:21]: test/Test.Literal.string. => final val method string"a" +[143:15..143:19]: test/Test.Literal.bool. => final val method booltrue +[144:15..144:19]: test/Test.Literal.unit. => final val method unitUnit +[145:15..145:23]: test/Test.Literal.javaEnum. => final val method javaEnumLinkOption +[146:15..146:22]: test/Test.Literal.clazzOf. => final val method clazzOfOption[Int] \ No newline at end of file diff --git a/scalafix-tests/integration/src/main/resources/META-INF/services/scalafix.v1.Rule b/scalafix-tests/integration/src/main/resources/META-INF/services/scalafix.v1.Rule new file mode 100644 index 000000000..392c8eae9 --- /dev/null +++ b/scalafix-tests/integration/src/main/resources/META-INF/services/scalafix.v1.Rule @@ -0,0 +1,13 @@ +scalafix.test.SemanticRuleV1 +scalafix.test.SyntacticRuleV1 +scalafix.test.CommentFileNonAtomic +scalafix.test.CommentFileAtomic +scalafix.test.AddCommentEndOfFile +scalafix.test.ScalatestAutofixRule +scalafix.test.ExplicitSynthetic +scalafix.test.cli.CrashingRule +scalafix.test.cli.NoOpRule +scalafix.test.cli.DeprecatedName +scalafix.test.cli.Scala2_9 +scalafix.test.cli.AvailableRule +scalafix.test.cli.Disable diff --git a/scalafix-tests/shared/src/main/scala-2.12/test/LegacySyntheticsTest.scala b/scalafix-tests/integration/src/main/scala-2.12/test/LegacySyntheticsTest.scala similarity index 100% rename from scalafix-tests/shared/src/main/scala-2.12/test/LegacySyntheticsTest.scala rename to scalafix-tests/integration/src/main/scala-2.12/test/LegacySyntheticsTest.scala diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/ExplicitSynthetic.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/ExplicitSynthetic.scala similarity index 100% rename from scalafix-tests/unit/src/main/scala/scalafix/test/ExplicitSynthetic.scala rename to scalafix-tests/integration/src/main/scala/scalafix/test/ExplicitSynthetic.scala diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/FqnRule.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/FqnRule.scala similarity index 99% rename from scalafix-tests/unit/src/main/scala/scalafix/test/FqnRule.scala rename to scalafix-tests/integration/src/main/scala/scalafix/test/FqnRule.scala index 3262ca516..23b0e821f 100644 --- a/scalafix-tests/unit/src/main/scala/scalafix/test/FqnRule.scala +++ b/scalafix-tests/integration/src/main/scala/scalafix/test/FqnRule.scala @@ -1,4 +1,4 @@ -package banana.rule +package scalafix.test import scala.meta._ import scala.meta.contrib._ diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/Generic.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/Generic.scala similarity index 100% rename from scalafix-tests/unit/src/main/scala/scalafix/test/Generic.scala rename to scalafix-tests/integration/src/main/scala/scalafix/test/Generic.scala diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/NoDummy.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/NoDummy.scala similarity index 100% rename from scalafix-tests/unit/src/main/scala/scalafix/test/NoDummy.scala rename to scalafix-tests/integration/src/main/scala/scalafix/test/NoDummy.scala diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/NoNull.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/NoNull.scala similarity index 100% rename from scalafix-tests/unit/src/main/scala/scalafix/test/NoNull.scala rename to scalafix-tests/integration/src/main/scala/scalafix/test/NoNull.scala diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/ScalatestAutofixRule.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/ScalatestAutofixRule.scala similarity index 100% rename from scalafix-tests/unit/src/main/scala/scalafix/test/ScalatestAutofixRule.scala rename to scalafix-tests/integration/src/main/scala/scalafix/test/ScalatestAutofixRule.scala diff --git a/scalafix-tests/integration/src/main/scala/scalafix/test/cli/Rules.scala b/scalafix-tests/integration/src/main/scala/scalafix/test/cli/Rules.scala new file mode 100644 index 000000000..ed70ae8d2 --- /dev/null +++ b/scalafix-tests/integration/src/main/scala/scalafix/test/cli/Rules.scala @@ -0,0 +1,91 @@ +package scalafix.test.cli + +import scala.meta._ + +import metaconfig.Configured +import scalafix.internal.util.PositionSyntax._ +import scalafix.internal.util.SymbolOps +import scalafix.v0.LintCategory +import scalafix.v1 +import scalafix.v1._ + +class CrashingRule extends SyntacticRule("CrashingRule") { + override def fix(implicit doc: SyntacticDocument): _root_.scalafix.v1.Patch = + throw new MissingSymbolException(Symbol("local63")) +} + +class NoOpRule extends SyntacticRule("NoOpRule") { + override def fix(implicit doc: SyntacticDocument): _root_.scalafix.v1.Patch = + Patch.empty +} + +class DeprecatedName + extends SyntacticRule( + RuleName("DeprecatedName").withDeprecatedName( + "OldDeprecatedName", + "Use DeprecatedName instead", + "1.0" + ) + ) { + override def fix(implicit doc: SyntacticDocument): _root_.scalafix.v1.Patch = + Patch.empty +} + +class Scala2_9 extends SyntacticRule("Scala2_9") { + override def withConfiguration(config: Configuration): Configured[Rule] = + if (!config.scalaVersion.startsWith("2.9")) { + Configured.error("scalaVersion must start with 2.9") + } else if (!config.scalacOptions.contains("-Ysource:2.9")) { + Configured.error("scalacOptions must contain -Ysource:2.9") + } else { + Configured.ok(this) + } +} + +class AvailableRule + extends v1.SemanticRule( + v1.RuleName("AvailableRule") + .withDeprecatedName("DeprecatedAvailableRule", "", "") + ) + +class Disable(symbols: List[Symbol]) extends SemanticRule("Disable") { + def this() = this(Nil) + override def withConfiguration(config: Configuration): Configured[Rule] = + Configured.ok( + new Disable( + config.conf.dynamic.Disable.symbols.as[List[Symbol]].getOrElse(Nil) + ) + ) + override def fix(implicit doc: SemanticDocument): Patch = { + doc.internal.textDocument.occurrences.collect { + case o if symbols.contains(SymbolOps.normalize(Symbol(o.symbol))) => + val r = o.range.get + val pos = Position.Range( + doc.input, + r.startLine, + r.startCharacter, + r.endLine, + r.endCharacter + ) + if (pos.lineContent.contains("import")) { + Patch.empty + } else { + Patch.lint(Diagnostic(Symbol(o.symbol).displayName, "disabled", pos)) + } + }.asPatch + } +} + +class LintError extends SyntacticRule("LintError") { + override def fix(implicit doc: SyntacticDocument): Patch = { + val failure = LintCategory.error("failure", "Error!") + Patch.lint(failure.at(doc.tree.pos)) + } +} + +class LintWarning extends SyntacticRule("LintWarning") { + override def fix(implicit doc: SyntacticDocument): Patch = { + val failure = LintCategory.warning("warning", "Warning!") + Patch.lint(failure.at(doc.tree.pos)) + } +} diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/core/Classpaths.scala b/scalafix-tests/integration/src/main/scala/scalafix/tests/core/Classpaths.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/core/Classpaths.scala rename to scalafix-tests/integration/src/main/scala/scalafix/tests/core/Classpaths.scala diff --git a/scalafix-tests/shared/src/main/scala/test/DenotationOpsTest.scala b/scalafix-tests/integration/src/main/scala/test/DenotationOpsTest.scala similarity index 89% rename from scalafix-tests/shared/src/main/scala/test/DenotationOpsTest.scala rename to scalafix-tests/integration/src/main/scala/test/DenotationOpsTest.scala index 29e6544f0..7afa73f8e 100644 --- a/scalafix-tests/shared/src/main/scala/test/DenotationOpsTest.scala +++ b/scalafix-tests/integration/src/main/scala/test/DenotationOpsTest.scala @@ -1,3 +1,4 @@ +// scalafix:off package test object DenotationOpsTest { diff --git a/scalafix-tests/shared/src/main/scala/test/LegacyDenotationTest.scala b/scalafix-tests/integration/src/main/scala/test/LegacyDenotationTest.scala similarity index 96% rename from scalafix-tests/shared/src/main/scala/test/LegacyDenotationTest.scala rename to scalafix-tests/integration/src/main/scala/test/LegacyDenotationTest.scala index a6287672f..666ddd852 100644 --- a/scalafix-tests/shared/src/main/scala/test/LegacyDenotationTest.scala +++ b/scalafix-tests/integration/src/main/scala/test/LegacyDenotationTest.scala @@ -1,3 +1,4 @@ +// scalafix:off import scala.collection import scala.collection.immutable import scala.collection.mutable.{ diff --git a/scalafix-tests/shared/src/main/scala/test/PrettyTest.scala b/scalafix-tests/integration/src/main/scala/test/PrettyTest.scala similarity index 97% rename from scalafix-tests/shared/src/main/scala/test/PrettyTest.scala rename to scalafix-tests/integration/src/main/scala/test/PrettyTest.scala index 67704471a..43104d54d 100644 --- a/scalafix-tests/shared/src/main/scala/test/PrettyTest.scala +++ b/scalafix-tests/integration/src/main/scala/test/PrettyTest.scala @@ -1,3 +1,4 @@ +// scalafix:off package test import scala.concurrent.ExecutionContext.Implicits.global @@ -22,9 +23,10 @@ class PrettyTest { val b = new a.Inner Option(null.asInstanceOf[{ - def bar(a: Int): Int - def foo(a: Int): Int - }]) + def bar(a: Int): Int + def foo(a: Int): Int + } + ]) Option(b) Option(null.asInstanceOf[Int with String]) Option(null.asInstanceOf[this.type]) diff --git a/scalafix-tests/shared/src/main/scala/test/SemanticdbIndexTest.scala b/scalafix-tests/integration/src/main/scala/test/SemanticdbIndexTest.scala similarity index 100% rename from scalafix-tests/shared/src/main/scala/test/SemanticdbIndexTest.scala rename to scalafix-tests/integration/src/main/scala/test/SemanticdbIndexTest.scala diff --git a/scalafix-tests/shared/src/main/scala/test/SymbolMatcherTest.scala b/scalafix-tests/integration/src/main/scala/test/SymbolMatcherTest.scala similarity index 100% rename from scalafix-tests/shared/src/main/scala/test/SymbolMatcherTest.scala rename to scalafix-tests/integration/src/main/scala/test/SymbolMatcherTest.scala diff --git a/scalafix-tests/shared/src/main/scala/test/SymbolTest.scala b/scalafix-tests/integration/src/main/scala/test/SymbolTest.scala similarity index 94% rename from scalafix-tests/shared/src/main/scala/test/SymbolTest.scala rename to scalafix-tests/integration/src/main/scala/test/SymbolTest.scala index 33a4ea0cb..63ab91077 100644 --- a/scalafix-tests/shared/src/main/scala/test/SymbolTest.scala +++ b/scalafix-tests/integration/src/main/scala/test/SymbolTest.scala @@ -1,3 +1,4 @@ +// scalafix:off package test import a.`b.c`.d diff --git a/scalafix-tests/shared/src/main/scala/test/TypeToTreeInput.scala b/scalafix-tests/integration/src/main/scala/test/TypeToTreeInput.scala similarity index 99% rename from scalafix-tests/shared/src/main/scala/test/TypeToTreeInput.scala rename to scalafix-tests/integration/src/main/scala/test/TypeToTreeInput.scala index 77a45e0fc..e36001fac 100644 --- a/scalafix-tests/shared/src/main/scala/test/TypeToTreeInput.scala +++ b/scalafix-tests/integration/src/main/scala/test/TypeToTreeInput.scala @@ -1,6 +1,7 @@ package test import java.util.Map + import scala.collection.immutable.TreeMap import scala.language.higherKinds diff --git a/scalafix-tests/shared/src/main/scala/test/TypesTest.scala b/scalafix-tests/integration/src/main/scala/test/TypesTest.scala similarity index 93% rename from scalafix-tests/shared/src/main/scala/test/TypesTest.scala rename to scalafix-tests/integration/src/main/scala/test/TypesTest.scala index aef86a88e..55ca2ce32 100644 --- a/scalafix-tests/shared/src/main/scala/test/TypesTest.scala +++ b/scalafix-tests/integration/src/main/scala/test/TypesTest.scala @@ -1,3 +1,4 @@ +// scalafix:off package test class TypesTest { diff --git a/scalafix-tests/unit/src/test/scala-target2.12/scalafix/tests/v0/LegacySyntheticsSuite.scala b/scalafix-tests/integration/src/test/scala-2.12/scalafix/tests/v0/LegacySyntheticsSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala-target2.12/scalafix/tests/v0/LegacySyntheticsSuite.scala rename to scalafix-tests/integration/src/test/scala-2.12/scalafix/tests/v0/LegacySyntheticsSuite.scala diff --git a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/BaseCliSuite.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/BaseCliSuite.scala similarity index 68% rename from scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/BaseCliSuite.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/BaseCliSuite.scala index d35911f2b..775420137 100644 --- a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/BaseCliSuite.scala +++ b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/BaseCliSuite.scala @@ -12,6 +12,7 @@ import java.nio.file.attribute.BasicFileAttributes import scala.meta.internal.io.FileIO import scala.meta.io.AbsolutePath +import scala.meta.io.Classpath import scala.meta.io.RelativePath import org.scalatest.funsuite.AnyFunSuite @@ -19,8 +20,6 @@ import scalafix.cli.ExitStatus import scalafix.internal.tests.utils.SkipWindows import scalafix.test.StringFS import scalafix.testkit.DiffAssertions -import scalafix.testkit.SemanticRuleSuite -import scalafix.testkit.TestkitProperties import scalafix.tests.BuildInfo import scalafix.tests.util.ScalaVersions import scalafix.v1.Main @@ -43,16 +42,17 @@ trait BaseCliSuite extends AnyFunSuite with DiffAssertions { val cwd: Path = Files.createTempDirectory("scalafix-cli") val ps = new PrintStream(new ByteArrayOutputStream()) - val semanticRoot: RelativePath = RelativePath("test") val removeImportsPath: RelativePath = - semanticRoot.resolve("removeUnused/RemoveUnusedImports.scala") + RelativePath("scala-2/test/removeUnused/RemoveUnusedImports.scala") val explicitResultTypesPath: RelativePath = - semanticRoot - .resolve("explicitResultTypes") - .resolve("ExplicitResultTypesBase.scala") - val props: TestkitProperties = TestkitProperties.loadFromResources() - def defaultClasspath: String = - props.inputClasspath.syntax + RelativePath( + "scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala" + ) + + def inputClasspath: Classpath = new Classpath( + BuildInfo.inputClasspath.toList.map(f => AbsolutePath(f.getAbsolutePath)) + ) + def defaultClasspath: String = inputClasspath.syntax def check( name: String, @@ -111,26 +111,12 @@ trait BaseCliSuite extends AnyFunSuite with DiffAssertions { ) } - def writeTestkitConfiguration( - root: AbsolutePath, - path: AbsolutePath - ): Unit = { - import scala.meta._ - val code = slurp(path) - val comment = SemanticRuleSuite.findTestkitComment(code.tokenize.get) - val content = comment.syntax.stripPrefix("/*").stripSuffix("*/") - Files.write( - root.resolve(".scalafix.conf").toNIO, - content.getBytes(StandardCharsets.UTF_8) - ) - } - def slurp(path: AbsolutePath): String = FileIO.slurp(path, StandardCharsets.UTF_8) def slurpInput(path: RelativePath): String = - slurp(props.resolveInput(path)) + slurp(inputSourceroot.resolve(path)) def slurpOutput(path: RelativePath): String = - slurp(props.resolveOutput(path)) + slurp(outputSourceroot.resolve(path)) def copyRecursively(source: AbsolutePath, target: AbsolutePath): Unit = { Files.walkFileTree( @@ -159,21 +145,10 @@ trait BaseCliSuite extends AnyFunSuite with DiffAssertions { ) } - // The defaults of this helper expect to find test input which is currently - // built only on scala 2.x since building them for Scala 3 would trigger - // test failures as the rules they exercise are not supported on Scala 3. - // TODO: switch defaults to rely on much more simple test input/rules so - // that we don't need to hardcode a scala version here. - val sourceDir = "scalafix-tests/input/src/main/scala-2" - - def sourceDirectory: AbsolutePath = - props.inputSourceDirectories - .find(dir => dir.toNIO.endsWith(sourceDir)) - .getOrElse { - throw new IllegalArgumentException( - props.inputSourceDirectories.toString() - ) - } + val inputSourceroot: AbsolutePath = + AbsolutePath(BuildInfo.inputSourceroot) + val outputSourceroot: AbsolutePath = + AbsolutePath(BuildInfo.inputSourceroot) case class Result( exit: ExitStatus, @@ -185,30 +160,25 @@ trait BaseCliSuite extends AnyFunSuite with DiffAssertions { name: String, args: Array[String], targetroots: Seq[String] = - BuildInfo.semanticClasspath.map(_.getAbsolutePath), + BuildInfo.inputSemanticClasspath.map(_.getAbsolutePath), expectedExit: ExitStatus, preprocess: AbsolutePath => Unit = _ => (), outputAssert: String => Unit = _ => (), rule: String = "RemoveUnused", path: RelativePath = removeImportsPath, - files: String = removeImportsPath.toString(), - assertObtained: Result => Unit = { result => - if (result.exit.isOk) { - assertNoDiff(result.obtained, result.expected) - } - } + files: String = removeImportsPath.toString() ): Unit = { test(name, SkipWindows) { val fileIsFixed = expectedExit.isOk val cwd = Files.createTempDirectory("scalafix") + val sourceDir = + inputSourceroot.toRelative(AbsolutePath(BuildInfo.baseDirectory)).toNIO val inputSourceDirectory = cwd.resolve(sourceDir) Files.createDirectories(inputSourceDirectory) val root = AbsolutePath(inputSourceDirectory) val out = new ByteArrayOutputStream() root.toFile.deleteOnExit() - copyRecursively(source = sourceDirectory, target = root) - val rootNIO = root - writeTestkitConfiguration(rootNIO, rootNIO.resolve(path)) + copyRecursively(source = inputSourceroot, target = root) preprocess(root) val sourceroot = if (args.contains("--sourceroot")) Array[String]() @@ -227,23 +197,9 @@ trait BaseCliSuite extends AnyFunSuite with DiffAssertions { files ) val exit = Main.run(allArguments, root.toNIO, new PrintStream(out)) - val original = slurpInput(path) - val obtained = { - val fixed = slurp(root.resolve(path)) - if (fileIsFixed && fixed.startsWith("/*")) { - SemanticRuleSuite.stripTestkitComments(fixed) - } else { - fixed - } - } - val expected = - if (fileIsFixed) slurpOutput(path) - else original val output = fansi.Str(out.toString()).plainText assert(exit == expectedExit, output) outputAssert(output) - val result = Result(exit, original, obtained, expected) - assertObtained(result) } } diff --git a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSemanticSuite.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSemanticSuite.scala similarity index 97% rename from scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSemanticSuite.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSemanticSuite.scala index 5075e016e..072f8d1f8 100644 --- a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSemanticSuite.scala +++ b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSemanticSuite.scala @@ -156,23 +156,20 @@ class CliSemanticSuite extends BaseCliSuite { args = Array( "--classpath", Classpath( - props.inputClasspath.entries + inputClasspath.entries .filterNot(_.toString().contains("scala-library")) ).syntax ), // Errors in ExplicitResultTypes are suppressed. expectedExit = ExitStatus.Ok, rule = "ExplicitResultTypes", - path = explicitResultTypesPath, - assertObtained = { _ => - // Do nothing - } + path = explicitResultTypesPath ) checkSemantic( name = "-P:semanticdb:targetroot", args = { - val jars = props.inputClasspath.entries.filter(_.isDirectory) + val jars = inputClasspath.entries.filter(_.isDirectory) val targetroot = BuildInfo.semanticClasspath.last.getAbsolutePath Array( s"--scalacOptions", diff --git a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSuppressSuite.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSuppressSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSuppressSuite.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSuppressSuite.scala diff --git a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSyntacticSuite.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSyntacticSuite.scala similarity index 99% rename from scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSyntacticSuite.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSyntacticSuite.scala index 68c5e2031..30eb5e273 100644 --- a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/cli/CliSyntacticSuite.scala +++ b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/cli/CliSyntacticSuite.scala @@ -199,7 +199,7 @@ class CliSyntacticSuite extends BaseCliSuite { |$original""".stripMargin, args = Array( "-r", - "scala:scalafix.tests.cli.LintError", + "scala:scalafix.test.cli.LintError", "foobar.scala" ), expectedLayout = s"""/foobar.scala @@ -218,7 +218,7 @@ class CliSyntacticSuite extends BaseCliSuite { "--settings.lint.error", "LintWarning.warning", "-r", - "scala:scalafix.tests.cli.LintWarning", + "scala:scalafix.test.cli.LintWarning", "foobar.scala" ), expectedLayout = s"""/foobar.scala diff --git a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/util/PrettyTypeSuite.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/core/PrettyTypeSuite.scala similarity index 97% rename from scalafix-tests/unit/src/test/scala-target2/scalafix/tests/util/PrettyTypeSuite.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/core/PrettyTypeSuite.scala index 817293406..ef89d3615 100644 --- a/scalafix-tests/unit/src/test/scala-target2/scalafix/tests/util/PrettyTypeSuite.scala +++ b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/core/PrettyTypeSuite.scala @@ -23,9 +23,11 @@ import scalafix.internal.util.QualifyStrategy class BasePrettyTypeSuite extends BaseSemanticSuite("TypeToTreeInput") { super.beforeAll() val classDir: m.AbsolutePath = - m.AbsolutePath(scalafix.tests.BuildInfo.sharedClasspath) + m.AbsolutePath(scalafix.tests.BuildInfo.classDirectory) val semanticdbTargetRoots: List[AbsolutePath] = - scalafix.tests.BuildInfo.semanticClasspath.map(m.AbsolutePath.apply).toList + scalafix.tests.BuildInfo.semanticClasspath + .map(m.AbsolutePath.apply) + .toList val classpath: Classpath = Classpaths.withDirectories(semanticdbTargetRoots :+ classDir) diff --git a/scalafix-tests/unit/src/test/scala-2/scalafix/tests/util/compat/CompatSemanticdb.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/util/compat/CompatSemanticdb.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala-2/scalafix/tests/util/compat/CompatSemanticdb.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/util/compat/CompatSemanticdb.scala diff --git a/scalafix-tests/unit/src/test/scala-2/scalafix/tests/util/compat/SemanticdbPlugin.scala b/scalafix-tests/integration/src/test/scala-2/scalafix/tests/util/compat/SemanticdbPlugin.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala-2/scalafix/tests/util/compat/SemanticdbPlugin.scala rename to scalafix-tests/integration/src/test/scala-2/scalafix/tests/util/compat/SemanticdbPlugin.scala diff --git a/scalafix-tests/unit/src/test/scala-3/scalafix/tests/util/compat/CompatSemanticdb.scala b/scalafix-tests/integration/src/test/scala-3/scalafix/tests/util/compat/CompatSemanticdb.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala-3/scalafix/tests/util/compat/CompatSemanticdb.scala rename to scalafix-tests/integration/src/test/scala-3/scalafix/tests/util/compat/CompatSemanticdb.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/ScalafixImplSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/cli/ScalafixImplSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/cli/ScalafixImplSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/cli/ScalafixImplSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/config/GitHubUrlRuleSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/config/GitHubUrlRuleSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/config/GitHubUrlRuleSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/config/GitHubUrlRuleSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/core/BaseSemanticSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/core/BaseSemanticSuite.scala similarity index 93% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/core/BaseSemanticSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/core/BaseSemanticSuite.scala index 0237c8808..b614c8a1b 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/core/BaseSemanticSuite.scala +++ b/scalafix-tests/integration/src/test/scala/scalafix/tests/core/BaseSemanticSuite.scala @@ -19,11 +19,11 @@ object BaseSemanticSuite { val scalaVersion = ScalaVersion.scala2 // For tests lazy val symtab: SymbolTable = { val classpath = - Classpaths.withDirectory(AbsolutePath(BuildInfo.sharedClasspath)) + Classpaths.withDirectory(AbsolutePath(BuildInfo.classDirectory)) ClasspathOps.newSymbolTable(classpath) } def loadDoc(filename: String): SemanticDocument = { - val root = AbsolutePath(BuildInfo.sharedSourceroot).resolve("scala/test") + val root = AbsolutePath(BuildInfo.sourceroot).resolve("scala/test") val abspath = root.resolve(filename) val relpath = abspath.toRelative(AbsolutePath(BuildInfo.baseDirectory)) val input = Input.File(abspath) diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/core/DenotationOpsSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/core/DenotationOpsSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/core/DenotationOpsSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/core/DenotationOpsSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/core/SemanticdbIndexSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/core/SemanticdbIndexSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/core/SemanticdbIndexSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/core/SemanticdbIndexSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/interfaces/ScalafixArgumentsSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixArgumentsSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/interfaces/ScalafixArgumentsSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixArgumentsSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala similarity index 98% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala index 524d3bd02..089b2dd58 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala +++ b/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala @@ -16,7 +16,7 @@ import scalafix.internal.tests.utils.SkipWindows /** * Tests in this suite require scalafix-cli & its dependencies to be * cross-published so that Coursier can fetch them. That is done automatically - * as part of `sbt unitXTargetY/test`, so make sure to run that once if you want + * as part of `sbt integrationX/test`, so make sure to run that once if you want * to run the test with testOnly or through BSP. */ class ScalafixSuite extends AnyFunSuite { diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/reflect/RuleDecoderSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/reflect/RuleDecoderSuite.scala similarity index 95% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/reflect/RuleDecoderSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/reflect/RuleDecoderSuite.scala index 6a04c59d1..6ae04f043 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/reflect/RuleDecoderSuite.scala +++ b/scalafix-tests/integration/src/test/scala/scalafix/tests/reflect/RuleDecoderSuite.scala @@ -16,7 +16,7 @@ import scalafix.v1.RuleDecoder class RuleDecoderSuite extends AnyFunSuite { val cwd: AbsolutePath = AbsolutePath(BuildInfo.baseDirectory) .resolve("scalafix-tests") - .resolve("unit") + .resolve("integration") .resolve("src") .resolve("main") .resolve("scala") @@ -34,7 +34,7 @@ class RuleDecoderSuite extends AnyFunSuite { assert(expectedName == rules.name.value) } - test("relative resolves from custom working directory") { + test("relative resolves from custom working directory", SkipWindows) { val rules = decoder.read(Conf.Str(s"file:$relpath")).get assert(expectedName == rules.name.value) } diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/reflect/ToolClasspathSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/reflect/ToolClasspathSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/reflect/ToolClasspathSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/reflect/ToolClasspathSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/util/ExpectSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/util/ExpectSuite.scala similarity index 92% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/util/ExpectSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/util/ExpectSuite.scala index b5620e678..f14ba0787 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/util/ExpectSuite.scala +++ b/scalafix-tests/integration/src/test/scala/scalafix/tests/util/ExpectSuite.scala @@ -17,7 +17,7 @@ trait ExpectSuite extends AnyFunSuite with DiffAssertions { final def path: AbsolutePath = { val scalaMajorVersion = Versions.scalaVersion.split("\\.")(0) - AbsolutePath(s"${BuildInfo.unitResourceDirectory}-${scalaMajorVersion}") + AbsolutePath(s"${BuildInfo.resourceDirectory}-${scalaMajorVersion}") .resolve("expect") .resolve(filename.stripSuffix("Test.scala") + ".expect") } diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/util/PrettyExpectSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/util/PrettyExpectSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/util/PrettyExpectSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/util/PrettyExpectSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/util/SaveExpect.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/util/SaveExpect.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/util/SaveExpect.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/util/SaveExpect.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/v0/LegacyDenotationSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/v0/LegacyDenotationSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/v0/LegacyDenotationSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/v0/LegacyDenotationSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/v0/SymbolMatcherSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/v0/SymbolMatcherSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/v0/SymbolMatcherSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/v0/SymbolMatcherSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/v1/SymbolMatcherSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/v1/SymbolMatcherSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/v1/SymbolMatcherSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/v1/SymbolMatcherSuite.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/v1/SymbolSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/v1/SymbolSuite.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/v1/SymbolSuite.scala rename to scalafix-tests/integration/src/test/scala/scalafix/tests/v1/SymbolSuite.scala diff --git a/scalafix-tests/unit/src/main/resources-2/expect/Pretty.expect b/scalafix-tests/unit/src/main/resources-2/expect/Pretty.expect deleted file mode 100644 index 500557a83..000000000 --- a/scalafix-tests/unit/src/main/resources-2/expect/Pretty.expect +++ /dev/null @@ -1,139 +0,0 @@ -[6:7..6:17]: test/PrettyTest# => class PrettyTest extends AnyRef { +4 decls } -[6:18..6:18]: test/PrettyTest#``(). => primary ctor () -[7:3..7:14]: *[Int] -[7:3..7:7]: *.apply[Int] -[8:3..12:12]: orig(1.to(10)).flatMap[Int]( - { (i) => - orig(2.to(20)).withFilter( - { (j) => orig(i > i) } - ).map[Int]({ (j) => orig(j) }) - } - ) -[9:10..9:11]: intWrapper(*) -[10:10..10:11]: intWrapper(*) -[13:3..17:15]: orig(Future(1.to(10)))(global).foreach[Unit]( - { (i) => - orig(Future(2.to(i.length)))(global).foreach[Unit]( - { (j) => orig(println(j)) } - )(global) - } - )(global) -[14:10..14:16]: *.apply[Inclusive] -[14:17..14:18]: intWrapper(*) -[15:10..15:16]: *.apply[Inclusive] -[15:17..15:18]: intWrapper(*) -[20:9..20:14]: test/PrettyTest#Inner# => class Inner extends AnyRef { +1 decls } -[20:14..20:14]: test/PrettyTest#Inner#``(). => primary ctor () -[21:7..21:8]: test/PrettyTest#a. => val method a: PrettyTest -[22:7..22:8]: test/PrettyTest#b. => val method b: a.Inner -[24:3..24:9]: *.apply[AnyRef { - local4 => abstract method bar(a: Int): Int - local6 => abstract method foo(a: Int): Int - }] -[28:3..28:9]: *.apply[a.Inner] -[29:3..29:9]: *.apply[Int with String {}] -[30:3..30:9]: *.apply[PrettyTest] -[37:7..37:10]: test/ann# => class ann[T] extends Annotation with StaticAnnotation { +2 decls } -[37:11..37:12]: test/ann#[T] => typeparam T -[37:13..37:13]: test/ann#``(). => primary ctor (x: T) -[37:14..37:15]: test/ann#x. => private[this] val method x: T -[38:7..38:11]: test/ann1# => class ann1 extends Annotation with StaticAnnotation { +1 decls } -[38:12..38:12]: test/ann1#``(). => primary ctor () -[39:7..39:11]: test/ann2# => class ann2 extends Annotation with StaticAnnotation { +1 decls } -[39:12..39:12]: test/ann2#``(). => primary ctor () -[41:7..41:8]: test/B# => class B extends AnyRef { +1 decls } -[43:7..43:8]: test/C# => class C extends AnyRef { +1 decls } -[45:7..45:8]: test/P# => class P extends AnyRef { +4 decls } -[45:9..45:9]: test/P#``(). => primary ctor () -[46:9..46:10]: test/P#C# => class C extends AnyRef { +1 decls } -[46:10..46:10]: test/P#C#``(). => primary ctor () -[47:9..47:10]: test/P#X# => class X extends AnyRef { +1 decls } -[47:10..47:10]: test/P#X#``(). => primary ctor () -[48:7..48:8]: test/P#x. => val method x: X -[51:7..51:8]: test/T# => class T extends AnyRef { +4 decls } -[51:9..51:9]: test/T#``(). => primary ctor () -[52:9..52:10]: test/T#C# => class C extends AnyRef { +1 decls } -[52:10..52:10]: test/T#C#``(). => primary ctor () -[53:9..53:10]: test/T#X# => class X extends AnyRef { +1 decls } -[53:10..53:10]: test/T#X#``(). => primary ctor () -[54:7..54:8]: test/T#x. => val method x: X -[57:8..57:12]: test/Test. => final object Test extends AnyRef { +4 decls } -[58:9..58:10]: test/Test.M# => class M extends AnyRef { +2 decls } -[58:11..58:11]: test/Test.M#``(). => primary ctor () -[59:9..59:10]: test/Test.M#m(). => method m: Int -[62:9..62:10]: test/Test.N# => trait N extends AnyRef { +1 decls } -[63:9..63:10]: test/Test.N#n(). => method n: Int -[66:9..66:10]: test/Test.C# => class C extends M { +35 decls } -[66:11..66:11]: test/Test.C#``(). => primary ctor () -[67:9..67:10]: test/Test.C#p. => val method p: P -[68:9..68:10]: test/Test.C#x. => val method x: p.X -[70:9..70:17]: test/Test.C#typeRef1. => val method typeRef1: C -[71:9..71:17]: test/Test.C#typeRef2. => val method typeRef2: p.C -[72:9..72:17]: test/Test.C#typeRef3. => val method typeRef3: T#C -[73:9..73:17]: test/Test.C#typeRef4. => val method typeRef4: List[Int] -[75:9..75:20]: test/Test.C#singleType1. => val method singleType1: x.type -[76:9..76:20]: test/Test.C#singleType2. => val method singleType2: p.x.type -[77:9..77:15]: test/Test.C#Either. => val method Either: Either.type -[79:9..79:18]: test/Test.C#thisType1. => val method thisType1: C.this.type -[80:9..80:18]: test/Test.C#thisType2. => val method thisType2: C.this.type -[82:9..82:19]: test/Test.C#superType1. => val method superType1: Int -[83:9..83:19]: test/Test.C#superType2. => val method superType2: Int -[84:9..84:19]: test/Test.C#superType3. => val method superType3: Int -[86:9..86:22]: test/Test.C#compoundType1. => val method compoundType1: AnyRef { def k: Int } -[87:9..87:22]: test/Test.C#compoundType2. => val method compoundType2: M with N {} -[88:9..88:22]: test/Test.C#compoundType3. => val method compoundType3: M with N { def k: Int } -[89:9..89:22]: test/Test.C#compoundType4. => val method compoundType4: AnyRef { def k: Int } -[90:9..90:22]: test/Test.C#compoundType5. => val method compoundType5: M with N {} -[91:9..91:22]: test/Test.C#compoundType6. => val method compoundType6: M with N { def k: Int } -[93:9..93:17]: test/Test.C#annType1. => val method annType1: T @ann[Int] -[94:9..94:17]: test/Test.C#annType2. => val method annType2: T @ann1 @ann2 -[96:9..96:25]: test/Test.C#existentialType2. => val method existentialType2: List[_] forSome { type _ } -[97:9..97:25]: test/Test.C#existentialType3. => val method existentialType3: Class[?0] forSome { type ?0 } -[98:9..98:25]: test/Test.C#existentialType4. => val method existentialType4: Class[?0] forSome { type ?0 } -[100:9..100:20]: test/Test.C#typeLambda1(). => method typeLambda1[M[_]]: Nothing -[100:21..100:22]: test/Test.C#typeLambda1().[M] => typeparam M[_] -[103:12..103:26]: test/Test.C#ClassInfoType1. => final object ClassInfoType1 extends AnyRef -[104:11..104:25]: test/Test.C#ClassInfoType2# => class ClassInfoType2 extends B { +2 decls } -[104:26..104:26]: test/Test.C#ClassInfoType2#``(). => primary ctor () -[104:42..104:43]: test/Test.C#ClassInfoType2#x(). => method x: Int -[105:11..105:25]: test/Test.C#ClassInfoType3# => trait ClassInfoType3[T] extends AnyRef -[105:26..105:27]: test/Test.C#ClassInfoType3#[T] => typeparam T -[107:12..107:22]: test/Test.C#MethodType. => final object MethodType extends AnyRef { +6 decls } -[108:11..108:13]: test/Test.C#MethodType.x1(). => method x1: Int -[109:11..109:13]: test/Test.C#MethodType.x2(). => method x2: Int -[110:11..110:13]: test/Test.C#MethodType.m3(). => method m3: Int -[111:11..111:13]: test/Test.C#MethodType.m4(). => method m4(): Int -[112:11..112:13]: test/Test.C#MethodType.m5(). => method m5(x: Int): Int -[112:14..112:15]: test/Test.C#MethodType.m5().(x) => param x: Int -[113:11..113:13]: test/Test.C#MethodType.m6(). => method m6[T](x: T): T -[113:14..113:15]: test/Test.C#MethodType.m6().[T] => typeparam T -[113:17..113:18]: test/Test.C#MethodType.m6().(x) => param x: T -[116:12..116:22]: test/Test.C#ByNameType. => final object ByNameType extends AnyRef { +1 decls } -[117:11..117:13]: test/Test.C#ByNameType.m1(). => method m1(x: => Int): Int -[117:14..117:15]: test/Test.C#ByNameType.m1().(x) => param x: => Int -[120:16..120:28]: test/Test.C#RepeatedType# => case class RepeatedType extends AnyRef with Product with Serializable { +12 decls } -[120:28..120:28]: test/Test.C#RepeatedType#``(). => primary ctor (val s: String*) -[120:29..120:30]: test/Test.C#RepeatedType#s. => val method s: String* -[121:11..121:13]: test/Test.C#RepeatedType#m1(). => method m1(x: Int*): Int -[121:14..121:15]: test/Test.C#RepeatedType#m1().(x) => param x: Int* -[124:12..124:20]: test/Test.C#TypeType. => final object TypeType extends AnyRef { +5 decls } -[125:12..125:14]: test/Test.C#TypeType.T1# => abstract type T1 -[126:11..126:13]: test/Test.C#TypeType.m2(). => method m2[T2 = C]: Nothing -[126:14..126:16]: test/Test.C#TypeType.m2().[T2] => typeparam T2 = C -[127:11..127:13]: test/Test.C#TypeType.m3(). => method m3[M3[_]]: Nothing -[127:14..127:16]: test/Test.C#TypeType.m3().[M3] => typeparam M3[_] -[128:12..128:14]: test/Test.C#TypeType.T4# => type T4 = C -[129:12..129:14]: test/Test.C#TypeType.T5# => type T5[U] = U -[129:15..129:16]: test/Test.C#TypeType.T5#[U] => typeparam U -[133:10..133:17]: test/Test.Literal. => final object Literal extends AnyRef { +11 decls } -[134:15..134:18]: test/Test.Literal.int. => final val method int: 1 -[135:15..135:19]: test/Test.Literal.long. => final val method long: 1L -[136:15..136:20]: test/Test.Literal.float. => final val method float: 1.0f -[137:15..137:21]: test/Test.Literal.double. => final val method double: 2.0 -[138:15..138:18]: test/Test.Literal.nil. => final val method nil: null -[139:15..139:19]: test/Test.Literal.char. => final val method char: 'a' -[140:15..140:21]: test/Test.Literal.string. => final val method string: "a" -[141:15..141:19]: test/Test.Literal.bool. => final val method bool: true -[142:15..142:19]: test/Test.Literal.unit. => final val method unit: Unit -[143:15..143:23]: test/Test.Literal.javaEnum. => final val method javaEnum: NOFOLLOW_LINKS.type -[144:15..144:22]: test/Test.Literal.clazzOf. => final val method clazzOf: Class[Option[Int]] \ No newline at end of file diff --git a/scalafix-tests/unit/src/main/resources-3/expect/Pretty.expect b/scalafix-tests/unit/src/main/resources-3/expect/Pretty.expect deleted file mode 100644 index d91a1948a..000000000 --- a/scalafix-tests/unit/src/main/resources-3/expect/Pretty.expect +++ /dev/null @@ -1,111 +0,0 @@ -[6:7..6:17]: test/PrettyTest# => class PrettyTest extends Object { self: PrettyTest => +6 decls } -[7:3..7:14]: *[Int] -[7:3..7:7]: *.apply[Int] -[9:10..9:11]: intWrapper(*) -[10:10..10:11]: intWrapper(*) -[14:10..14:16]: *.apply[Inclusive] -[14:10..14:26]: *(global) -[14:17..14:18]: intWrapper(*) -[15:10..15:16]: *.apply[Inclusive] -[15:10..15:32]: *(global) -[15:17..15:18]: intWrapper(*) -[20:9..20:14]: test/PrettyTest#Inner# => class Inner extends Object { self: Inner => +1 decls } -[21:7..21:8]: test/PrettyTest#a. => val method aPrettyTest -[22:7..22:8]: test/PrettyTest#b. => val method ba.Inner -[24:3..24:9]: *.apply[Object { - local4 => abstract method foo(a: Int): Int - local5 => abstract method bar(a: Int): Int - }] -[29:3..29:9]: *.apply[Int & String] -[37:7..37:10]: test/ann# => class ann[T] extends Annotation with StaticAnnotation { self: ann[T] => +3 decls } -[37:11..37:12]: test/ann#[T] => typeparam T -[37:14..37:15]: test/ann#x. => private[this] val method xT -[38:7..38:11]: test/ann1# => class ann1 extends Annotation with StaticAnnotation { self: ann1 => +1 decls } -[39:7..39:11]: test/ann2# => class ann2 extends Annotation with StaticAnnotation { self: ann2 => +1 decls } -[41:7..41:8]: test/B# => class B extends Object { self: B => +1 decls } -[43:7..43:8]: test/C# => class C extends Object { self: C => +1 decls } -[45:7..45:8]: test/P# => class P extends Object { self: P => +8 decls } -[46:9..46:10]: test/P#C# => class C extends Object { self: C => +1 decls } -[47:9..47:10]: test/P#X# => class X extends Object { self: X => +1 decls } -[48:7..48:8]: test/P#x. => val method xX -[51:7..51:8]: test/T# => class T extends Object { self: T => +8 decls } -[52:9..52:10]: test/T#C# => class C extends Object { self: C => +1 decls } -[53:9..53:10]: test/T#X# => class X extends Object { self: X => +1 decls } -[54:7..54:8]: test/T#x. => val method xX -[57:8..57:12]: test/Test. => final object Test extends Object { self: Test.type => +10 decls } -[58:9..58:10]: test/Test.M# => class M extends Object { self: M => +2 decls } -[59:9..59:10]: test/Test.M#m(). => method m=> Int -[62:9..62:10]: test/Test.N# => trait N extends Object { self: N => +2 decls } -[63:9..63:10]: test/Test.N#n(). => method n=> Int -[66:9..66:10]: test/Test.C# => class C extends M { self: C => +42 decls } -[67:9..67:10]: test/Test.C#p. => val method pP -[68:9..68:10]: test/Test.C#x. => val method xp.X -[70:9..70:17]: test/Test.C#typeRef1. => val method typeRef1C -[71:9..71:17]: test/Test.C#typeRef2. => val method typeRef2p.C -[72:9..72:17]: test/Test.C#typeRef3. => val method typeRef3T#C -[73:9..73:17]: test/Test.C#typeRef4. => val method typeRef4List[Int] -[75:9..75:20]: test/Test.C#singleType1. => val method singleType1x.type -[76:9..76:20]: test/Test.C#singleType2. => val method singleType2p.x.type -[77:9..77:15]: test/Test.C#Either. => val method EitherEither.type -[79:9..79:18]: test/Test.C#thisType1. => val method thisType1C.this.type -[80:9..80:18]: test/Test.C#thisType2. => val method thisType2C.this.type -[82:9..82:19]: test/Test.C#superType1. => val method superType1Int -[83:9..83:19]: test/Test.C#superType2. => val method superType2Int -[84:9..84:19]: test/Test.C#superType3. => val method superType3Int -[86:9..86:22]: test/Test.C#compoundType1. => val method compoundType1Object { def k=> Int } -[87:9..87:22]: test/Test.C#compoundType2. => val method compoundType2M & N -[88:9..88:22]: test/Test.C#compoundType3. => val method compoundType3M & N { def k=> Int } -[89:9..89:22]: test/Test.C#compoundType4. => val method compoundType4Object -[90:9..90:22]: test/Test.C#compoundType5. => val method compoundType5M & N -[91:9..91:22]: test/Test.C#compoundType6. => val method compoundType6M & N -[93:9..93:17]: test/Test.C#annType1. => val method annType1T @ann[T] -[93:21..93:25]: [Int] -[94:9..94:17]: test/Test.C#annType2. => val method annType2T @ann1 @ann2 -[96:9..96:25]: test/Test.C#existentialType2. => val method existentialType2List[_] forSome { type _ } -[97:9..97:25]: test/Test.C#existentialType3. => val method existentialType3Class[_] forSome { type _ } -[98:9..98:25]: test/Test.C#existentialType4. => val method existentialType4Class[_] forSome { type _ } -[100:9..100:20]: test/Test.C#typeLambda1(). => method typeLambda1[M[type _]]: Nothing -[100:21..100:22]: test/Test.C#typeLambda1().[M] => typeparam M[type _] -[103:12..103:26]: test/Test.C#ClassInfoType1. => final object ClassInfoType1 extends Object { self: ClassInfoType1.type => +1 decls } -[104:11..104:25]: test/Test.C#ClassInfoType2# => class ClassInfoType2 extends B { self: ClassInfoType2 => +2 decls } -[104:42..104:43]: test/Test.C#ClassInfoType2#x(). => method x=> Int -[105:11..105:25]: test/Test.C#ClassInfoType3# => trait ClassInfoType3[T] extends Object { self: ClassInfoType3[T] => +2 decls } -[105:26..105:27]: test/Test.C#ClassInfoType3#[T] => typeparam T -[107:12..107:22]: test/Test.C#MethodType. => final object MethodType extends Object { self: MethodType.type => +7 decls } -[108:11..108:13]: test/Test.C#MethodType.x1(). => method x1=> Int -[109:11..109:13]: test/Test.C#MethodType.x2(). => method x2=> Int -[110:11..110:13]: test/Test.C#MethodType.m3(). => method m3=> Int -[111:11..111:13]: test/Test.C#MethodType.m4(). => method m4(): Int -[112:11..112:13]: test/Test.C#MethodType.m5(). => method m5(x: Int): Int -[112:14..112:15]: test/Test.C#MethodType.m5().(x) => param x: Int -[113:11..113:13]: test/Test.C#MethodType.m6(). => method m6[T](x: T): T -[113:14..113:15]: test/Test.C#MethodType.m6().[T] => typeparam T -[113:17..113:18]: test/Test.C#MethodType.m6().(x) => param x: T -[116:12..116:22]: test/Test.C#ByNameType. => final object ByNameType extends Object { self: ByNameType.type => +2 decls } -[117:11..117:13]: test/Test.C#ByNameType.m1(). => method m1(x: => Int): Int -[117:14..117:15]: test/Test.C#ByNameType.m1().(x) => param x: => Int -[120:16..120:28]: test/Test.C#RepeatedType# => case class RepeatedType extends Object with Product with Serializable { self: RepeatedType => +4 decls } -[120:29..120:30]: test/Test.C#RepeatedType#s. => val method sString* -[121:11..121:13]: test/Test.C#RepeatedType#m1(). => method m1(x: Int*): Int -[121:14..121:15]: test/Test.C#RepeatedType#m1().(x) => param x: Int* -[124:12..124:20]: test/Test.C#TypeType. => final object TypeType extends Object { self: TypeType.type => +6 decls } -[125:12..125:14]: test/Test.C#TypeType.T1# => type T1 -[126:11..126:13]: test/Test.C#TypeType.m2(). => method m2[T2 = C]: Nothing -[126:14..126:16]: test/Test.C#TypeType.m2().[T2] => typeparam T2 = C -[127:11..127:13]: test/Test.C#TypeType.m3(). => method m3[M3[type _]]: Nothing -[127:14..127:16]: test/Test.C#TypeType.m3().[M3] => typeparam M3[type _] -[128:12..128:14]: test/Test.C#TypeType.T4# => type T4 = C -[129:12..129:14]: test/Test.C#TypeType.T5# => type T5[U] = U -[129:15..129:16]: test/Test.C#TypeType.T5#[U] => typeparam U -[133:10..133:17]: test/Test.Literal. => final object Literal extends Object { self: Literal.type => +12 decls } -[134:15..134:18]: test/Test.Literal.int. => final val method int1 -[135:15..135:19]: test/Test.Literal.long. => final val method long1L -[136:15..136:20]: test/Test.Literal.float. => final val method float1.0f -[137:15..137:21]: test/Test.Literal.double. => final val method double2.0 -[138:15..138:18]: test/Test.Literal.nil. => final val method nilNull -[139:15..139:19]: test/Test.Literal.char. => final val method char'a' -[140:15..140:21]: test/Test.Literal.string. => final val method string"a" -[141:15..141:19]: test/Test.Literal.bool. => final val method booltrue -[142:15..142:19]: test/Test.Literal.unit. => final val method unitUnit -[143:15..143:23]: test/Test.Literal.javaEnum. => final val method javaEnumLinkOption -[144:15..144:22]: test/Test.Literal.clazzOf. => final val method clazzOfOption[Int] \ No newline at end of file diff --git a/scalafix-tests/unit/src/main/resources/META-INF/services/scalafix.v1.Rule b/scalafix-tests/unit/src/main/resources/META-INF/services/scalafix.v1.Rule deleted file mode 100644 index ccf9d4d60..000000000 --- a/scalafix-tests/unit/src/main/resources/META-INF/services/scalafix.v1.Rule +++ /dev/null @@ -1,13 +0,0 @@ -banana.rule.SemanticRuleV1 -banana.rule.SyntacticRuleV1 -banana.rule.CommentFileNonAtomic -banana.rule.CommentFileAtomic -banana.rule.AddCommentEndOfFile -scalafix.test.ScalatestAutofixRule -scalafix.test.ExplicitSynthetic -scalafix.tests.cli.CrashingRule -scalafix.tests.cli.NoOpRule -scalafix.tests.cli.DeprecatedName -scalafix.tests.cli.Scala2_9 -scalafix.tests.cli.AvailableRule -scalafix.tests.cli.Disable diff --git a/scalafix-tests/unit/src/main/scala/scalafix/test/cli/Rules.scala b/scalafix-tests/unit/src/main/scala/scalafix/test/cli/Rules.scala deleted file mode 100644 index 2eee4b0b2..000000000 --- a/scalafix-tests/unit/src/main/scala/scalafix/test/cli/Rules.scala +++ /dev/null @@ -1,44 +0,0 @@ -package scalafix.tests.cli - -import metaconfig._ -import scalafix.v1 -import scalafix.v1._ - -class CrashingRule extends SyntacticRule("CrashingRule") { - override def fix(implicit doc: SyntacticDocument): _root_.scalafix.v1.Patch = - throw new MissingSymbolException(Symbol("local63")) -} - -class NoOpRule extends SyntacticRule("NoOpRule") { - override def fix(implicit doc: SyntacticDocument): _root_.scalafix.v1.Patch = - Patch.empty -} - -class DeprecatedName - extends SyntacticRule( - RuleName("DeprecatedName").withDeprecatedName( - "OldDeprecatedName", - "Use DeprecatedName instead", - "1.0" - ) - ) { - override def fix(implicit doc: SyntacticDocument): _root_.scalafix.v1.Patch = - Patch.empty -} - -class Scala2_9 extends SyntacticRule("Scala2_9") { - override def withConfiguration(config: Configuration): Configured[Rule] = - if (!config.scalaVersion.startsWith("2.9")) { - Configured.error("scalaVersion must start with 2.9") - } else if (!config.scalacOptions.contains("-Ysource:2.9")) { - Configured.error("scalacOptions must contain -Ysource:2.9") - } else { - Configured.ok(this) - } -} - -class AvailableRule - extends v1.SemanticRule( - v1.RuleName("AvailableRule") - .withDeprecatedName("DeprecatedAvailableRule", "", "") - ) diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/util/ScalaVersions.scala b/scalafix-tests/unit/src/main/scala/scalafix/tests/util/ScalaVersions.scala similarity index 100% rename from scalafix-tests/unit/src/test/scala/scalafix/tests/util/ScalaVersions.scala rename to scalafix-tests/unit/src/main/scala/scalafix/tests/util/ScalaVersions.scala diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/Disable.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/Disable.scala deleted file mode 100644 index bfba59568..000000000 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/Disable.scala +++ /dev/null @@ -1,38 +0,0 @@ -package scalafix.tests.cli - -import scala.meta._ - -import metaconfig.Configured -import scalafix.internal.util.PositionSyntax._ -import scalafix.internal.util.SymbolOps -import scalafix.v1._ - -// -class Disable(symbols: List[Symbol]) extends SemanticRule("Disable") { - def this() = this(Nil) - override def withConfiguration(config: Configuration): Configured[Rule] = - Configured.ok( - new Disable( - config.conf.dynamic.Disable.symbols.as[List[Symbol]].getOrElse(Nil) - ) - ) - override def fix(implicit doc: SemanticDocument): Patch = { - doc.internal.textDocument.occurrences.collect { - case o if symbols.contains(SymbolOps.normalize(Symbol(o.symbol))) => - val r = o.range.get - val pos = Position.Range( - doc.input, - r.startLine, - r.startCharacter, - r.endLine, - r.endCharacter - ) - if (pos.lineContent.contains("import")) { - Patch.empty - } else { - Patch.lint(Diagnostic(Symbol(o.symbol).displayName, "disabled", pos)) - } - }.asPatch - } - -} diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/TestRules.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/TestRules.scala deleted file mode 100644 index 0384e39c3..000000000 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/TestRules.scala +++ /dev/null @@ -1,18 +0,0 @@ -package scalafix.tests.cli - -import scalafix.v0.LintCategory -import scalafix.v1._ - -class LintError extends SyntacticRule("LintError") { - override def fix(implicit doc: SyntacticDocument): Patch = { - val failure = LintCategory.error("failure", "Error!") - Patch.lint(failure.at(doc.tree.pos)) - } -} - -class LintWarning extends SyntacticRule("LintWarning") { - override def fix(implicit doc: SyntacticDocument): Patch = { - val failure = LintCategory.warning("warning", "Warning!") - Patch.lint(failure.at(doc.tree.pos)) - } -}