diff --git a/bin/test-release.sh b/bin/test-release.sh index 552ece164..2173bb6c0 100755 --- a/bin/test-release.sh +++ b/bin/test-release.sh @@ -6,7 +6,7 @@ version=$1 scala212=2.12.20 scala213=2.13.16 scala3LTS=3.3.5 -scala3Next=3.6.4 +scala3Next=3.7.0 cs resolve \ ch.epfl.scala:scalafix-interfaces:$version \ diff --git a/build.sbt b/build.sbt index a1455f2b1..b406cfade 100644 --- a/build.sbt +++ b/build.sbt @@ -35,6 +35,7 @@ lazy val properties = project props.put("scala33", scala33) props.put("scala35", scala35) props.put("scala36", scala36) + props.put("scala37", scala37) props.put("scala3LTS", scala3LTS) props.put("scala3Next", scala3Next) val out = diff --git a/docs/rules/RemoveUnused.md b/docs/rules/RemoveUnused.md index 3a39dc343..192ad1479 100644 --- a/docs/rules/RemoveUnused.md +++ b/docs/rules/RemoveUnused.md @@ -72,7 +72,10 @@ case class AB(a: Int, b: String) object Main { val example = AB(42, "lol") example match { - case AB(a, b) => println("Not used") + case AB(foo, bar) => println("Not used") + } + example match { + case AB(a, b) => println("Not used, but canonical names") } } // after @@ -81,16 +84,16 @@ object Main { example match { case AB(_, _) => println("Not used") } + example match { + case AB(a, b) => println("Not used, but canonical names") + } } ``` -On Scala 3, `-Wunused:unsafe-warn-patvars` is required. - -On Scala 2.13.15+, canonical patterns (vars with the same names as the -attributes) do not trigger unused warnings, so the input above will not -be rewritten. See https://github.com/scala/bug/issues/13035. +On Scala 3, an additional `-Wunused:unsafe-warn-patvars` option is required +until Scala 3.7.0. -### Remove unused function parameters (Scala 2 only) +### Remove unused function parameters ```scala // before @@ -103,6 +106,8 @@ object Main { } ``` +On Scala 3, this is only supported for 3.7.0+. + ## Formatting > This rule does a best-effort at preserving original formatting. In some cases, @@ -176,8 +181,7 @@ $ scala3 -W - nowarn, - all, - imports : - Warn if an import selector is not referenced. - NOTE : overrided by -Wunused:strict-no-implicit-warn, + Warn if an import selector is not referenced., - privates : Warn if a private member is unused, - locals : @@ -188,13 +192,13 @@ $ scala3 -W Warn if an implicit parameter is unused, - params : Enable -Wunused:explicits,implicits, + - patvars : + Warn if a variable bound in a pattern is unused, - linted : Enable -Wunused:imports,privates,locals,implicits, - strict-no-implicit-warn : Same as -Wunused:import, only for imports of explicit named members. - NOTE : This overrides -Wunused:imports and NOT set by -Wunused:all, + NOTE : This overrides -Wunused:imports and NOT set by -Wunused:all, - unsafe-warn-patvars : - (UNSAFE) Warn if a variable bound in a pattern is unused. - This warning can generate false positive, as warning cannot be - suppressed yet. + Deprecated alias for `patvars` ``` diff --git a/project/Dependencies.scala b/project/Dependencies.scala index c53428a35..2458840f0 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,12 +6,13 @@ import sbt._ object Dependencies { val scala212 = sys.props.getOrElse("scala212.nightly", "2.12.20") - val scala213 = sys.props.getOrElse("scala213.nightly", "2.13.16") + val scala213 = sys.props.getOrElse("scala213.nightly", "2.13.16") // remove 2.13.14 hack in RuleSuite when bumping val scala33 = "3.3.5" val scala35 = "3.5.2" val scala36 = "3.6.4" + val scala37 = "3.7.0" val scala3LTS = scala33 - val scala3Next = sys.props.getOrElse("scala3.nightly", scala36) + val scala3Next = sys.props.getOrElse("scala3.nightly", scala37) val bijectionCoreV = "0.9.8" val collectionCompatV = "2.13.0" diff --git a/project/Mima.scala b/project/Mima.scala index 8da382a07..97d140d0a 100644 --- a/project/Mima.scala +++ b/project/Mima.scala @@ -12,7 +12,8 @@ object Mima { ProblemFilters.exclude[DirectMissingMethodProblem]("scalafix.v0.Signature#Self.syntax"), ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala33"), ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala35"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala36") + ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala36"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("scalafix.interfaces.Scalafix.scala37") ) } } diff --git a/project/ScalafixBuild.scala b/project/ScalafixBuild.scala index ddf26398f..7b209f447 100644 --- a/project/ScalafixBuild.scala +++ b/project/ScalafixBuild.scala @@ -37,8 +37,8 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { val jdk = System.getProperty("java.specification.version").toDouble val scala3Versions = // Scala 3.5 will never support JDK 23 - if (jdk >= 23) Seq(scala33, scala36) - else Seq(scala33, scala35, scala36) + if (jdk >= 23) Seq(scala33, scala36, scala37) + else Seq(scala33, scala35, scala36, scala37) (coreScalaVersions ++ scala3Versions :+ scala3Next).distinct } lazy val cliScalaVersionsWithTargets: Seq[(String, TargetAxis)] = @@ -84,7 +84,11 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { scalaVersion.value.startsWith("2.12") } lazy val warnUnused = Def.setting { - if (isScala3.value) Seq("-Wunused:all", "-Wunused:unsafe-warn-patvars") + if (isScala3.value) + Seq( + "-Wunused:all", + "-Wunused:unsafe-warn-patvars" // only needed for <3.7.0 + ) else if (isScala213.value) Seq("-Wunused") else Seq("-Ywarn-unused") } @@ -144,6 +148,7 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { "scala33" -> scala33, "scala35" -> scala35, "scala36" -> scala36, + "scala37" -> scala37, "scala3LTS" -> scala3LTS, "scala3Next" -> scala3Next, sbtVersion @@ -239,7 +244,8 @@ object ScalafixBuild extends AutoPlugin with GhpagesKeys { ) private val PreviousScalaVersion: Map[String, Option[String]] = Map( - "3.6.4" -> Some("3.6.3") + "3.6.4" -> Some("3.6.3"), + scala37 -> None ) override def buildSettings: Seq[Setting[_]] = List( diff --git a/scalafix-cli/src/main/scala/scalafix/internal/interfaces/ScalafixImpl.scala b/scalafix-cli/src/main/scala/scalafix/internal/interfaces/ScalafixImpl.scala index 2b922d4d5..2e714f977 100644 --- a/scalafix-cli/src/main/scala/scalafix/internal/interfaces/ScalafixImpl.scala +++ b/scalafix-cli/src/main/scala/scalafix/internal/interfaces/ScalafixImpl.scala @@ -40,6 +40,8 @@ final class ScalafixImpl extends Scalafix { Versions.scala35 override def scala36(): String = Versions.scala36 + override def scala37(): String = + Versions.scala37 override def scala3LTS(): String = Versions.scala3LTS override def scala3Next(): String = diff --git a/scalafix-interfaces/src/main/java/scalafix/interfaces/Scalafix.java b/scalafix-interfaces/src/main/java/scalafix/interfaces/Scalafix.java index b22183855..3780f615a 100644 --- a/scalafix-interfaces/src/main/java/scalafix/interfaces/Scalafix.java +++ b/scalafix-interfaces/src/main/java/scalafix/interfaces/Scalafix.java @@ -85,6 +85,11 @@ public interface Scalafix { */ String scala36(); + /** + * The Scala 3.7 version in {@link #supportedScalaVersions()} + */ + String scala37(); + /** * The Scala 3 LTS version in {@link #supportedScalaVersions()} */ @@ -155,6 +160,8 @@ static Scalafix fetchAndClassloadInstance(String requestedScalaVersion, List params.collect { case param @ Term.Param(_, name, _, _) - if isUnusedParam(param.pos) => + if isUnusedParam(param.pos) || isUnusedParam(name.pos) => Patch.replaceTree(name, "_") }.asPatch }.asPatch diff --git a/scalafix-rules/src/main/scala/scalafix/internal/rule/RemoveUnusedConfig.scala b/scalafix-rules/src/main/scala/scalafix/internal/rule/RemoveUnusedConfig.scala index ab3bd34d7..39dad20b4 100644 --- a/scalafix-rules/src/main/scala/scalafix/internal/rule/RemoveUnusedConfig.scala +++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/RemoveUnusedConfig.scala @@ -14,7 +14,7 @@ case class RemoveUnusedConfig( locals: Boolean = true, @Description("Remove unused pattern match variables") patternvars: Boolean = true, - @Description("Remove unused function parameters (Scala 2 only)") + @Description("Remove unused function parameters") params: Boolean = true ) diff --git a/scalafix-tests/expect/src/test/scala/scalafix/tests/rule/RuleSuite.scala b/scalafix-tests/expect/src/test/scala/scalafix/tests/rule/RuleSuite.scala index b6f837ca7..74a23d933 100644 --- a/scalafix-tests/expect/src/test/scala/scalafix/tests/rule/RuleSuite.scala +++ b/scalafix-tests/expect/src/test/scala/scalafix/tests/rule/RuleSuite.scala @@ -36,16 +36,23 @@ class RuleSuite extends AbstractSemanticRuleSuite with AnyFunSuiteLike { override def runOn(diffTest: RuleTest): Unit = { def stripPatch(v: String) = v.split('.').take(2).mkString(".") + val inputSV = props.scalaVersion + val path = diffTest.path.input.toNIO.toString + val versionMismatch = - stripPatch(RulesBuildInfo.scalaVersion) != stripPatch(props.scalaVersion) + stripPatch(RulesBuildInfo.scalaVersion) != stripPatch(inputSV) val explicitResultTypesTest = - diffTest.path.input.toNIO.toString.contains( + path.contains( "explicitResultTypes" + java.io.File.separator // don't skip tests with a suffix ) - // ExplicitResultTypes can only run against sources compiled with the sam - // binary version as the one used to compile the rule - if (versionMismatch && explicitResultTypesTest) return + if ( + // ExplicitResultTypes can only run against sources compiled with the same + // binary version as the one used to compile the rule + (versionMismatch && explicitResultTypesTest) || + // RemoveUnusedPatternVars has the old 2.12.x behavior for 2.13.14 + (inputSV == "2.13.14" && path.endsWith("RemoveUnusedPatternVars.scala")) + ) return else super.runOn(diffTest) } diff --git a/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala b/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala index af7f6c09e..74e0e914b 100644 --- a/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala +++ b/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala @@ -19,18 +19,7 @@ object ExplicitResultTypesBase { private val g = 1 private def h(a: Int) = "" private var i = 22 - private implicit var j = 1 val k = (1, "msg") - implicit val L = List(1) - implicit val M = Map(1 -> "STRING") - implicit def D = 2 - implicit def tparam[T](e: T) = e - implicit def tparam2[T](e: T) = List(e) - implicit def tparam3[T](e: T) = Map(e -> e) - class implicitlytrick { - implicit val s: _root_.java.lang.String = "string" - implicit val x = implicitly[String] - } def comment(x: Int) = // comment x + 2 diff --git a/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesImplicit.scala b/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesImplicit.scala new file mode 100644 index 000000000..0a2953892 --- /dev/null +++ b/scalafix-tests/input/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesImplicit.scala @@ -0,0 +1,22 @@ +/* +rules = ExplicitResultTypes +ExplicitResultTypes.memberKind = [Val, Def, Var] +ExplicitResultTypes.memberVisibility = [Public, Protected] + */ +package test.explicitResultTypes + +import scala.language.implicitConversions + +object ExplicitResultTypesImplicit { + private implicit var j = 1 + implicit val L = List(1) + implicit val M = Map(1 -> "STRING") + implicit def D = 2 + implicit def tparam[T](e: T) = e + implicit def tparam2[T](e: T) = List(e) + implicit def tparam3[T](e: T) = Map(e -> e) + class implicitlytrick { + implicit val s: _root_.java.lang.String = "string" + implicit val x = implicitly[String] + } +} diff --git a/scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala b/scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala index 7d6cf1ddc..16e3a62ca 100644 --- a/scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala +++ b/scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala @@ -3,8 +3,6 @@ rule = RemoveUnused */ package test.removeUnused -// Not available as of Scala 3.4.1 -// https://github.com/scalacenter/scalafix/issues/1937 object UnusedParams { val f: String => Unit = unused => println("f") val ff = (unused: String) => println("f") diff --git a/scalafix-tests/input/src/main/scala/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedPatternVars.scala similarity index 98% rename from scalafix-tests/input/src/main/scala/test/removeUnused/RemoveUnusedPatternVars.scala rename to scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedPatternVars.scala index c2e5ebdd6..b4d14aeac 100644 --- a/scalafix-tests/input/src/main/scala/test/removeUnused/RemoveUnusedPatternVars.scala +++ b/scalafix-tests/input/src/main/scala-2/test/removeUnused/RemoveUnusedPatternVars.scala @@ -12,6 +12,9 @@ object ob { // Add code that needs fixing here. val example = AB(42, "lol") + example match { + case AB(aa, bb) => println("https://github.com/scala/bug/issues/13035") + } example match { case AB(_, _) => println("Not used, good") } diff --git a/scalafix-tests/input/src/main/scala-3lts/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/input/src/main/scala-3lts/test/removeUnused/RemoveUnusedPatternVars.scala new file mode 100644 index 000000000..b4d14aeac --- /dev/null +++ b/scalafix-tests/input/src/main/scala-3lts/test/removeUnused/RemoveUnusedPatternVars.scala @@ -0,0 +1,394 @@ +/* +rule = RemoveUnused + */ +package test.removeUnused + +case class AB(aa: Int, bb: String) + +case class XY(x: Int, y: Int) +case class YZ(xy: XY, z: String) + +object ob { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(aa, bb) => println("https://github.com/scala/bug/issues/13035") + } + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, b) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def pf(x: PartialFunction[Any, Unit]): Unit = ??? + case class A(a: Int) + pf{ + case string: String => ??? + case (i: Int) => ??? + case (a: Int, b) => println(b) + case a@A(v) => ??? + case x :: (y1, y2) :: Nil => println(x) + case (zz) => ??? + } + try ??? catch {case e: Exception => ???} + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } +} + +trait tr { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, b) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } +} + +class cl { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, b) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + def f(v: (Int, (Boolean, String))): Int = v match { + case t @ (i, v @ (_, _)) => i + } +} \ No newline at end of file diff --git a/scalafix-tests/input/src/main/scala-3next/test/explicitResultTypes/ExplicitResultTypesBase.scala b/scalafix-tests/input/src/main/scala-3next/test/explicitResultTypes/ExplicitResultTypesBase.scala new file mode 100644 index 000000000..665c02ab9 --- /dev/null +++ b/scalafix-tests/input/src/main/scala-3next/test/explicitResultTypes/ExplicitResultTypesBase.scala @@ -0,0 +1,45 @@ +/* +rules = ExplicitResultTypes +ExplicitResultTypes.memberKind = [Val, Def, Var] +ExplicitResultTypes.memberVisibility = [Public, Protected] + */ +package test.explicitResultTypes + +import scala.language.implicitConversions + +object ExplicitResultTypesBase { + def none[T] = None.asInstanceOf[Option[T]] + val a = 1 + 2 + def b() = "a" + "b" + var c = 1 == 1 + protected val d = 1.0f + protected def e(a: Int, b: Double) = a + b + protected var f = (x: Int) => x + 1 + val f0 = () => 42 + private val g = 1 + private def h(a: Int) = "" + private var i = 22 + val k = (1, "msg") + def comment(x: Int) = + // comment + x + 2 + object ExtraSpace { + def * = "abc".length + def ! = "abc".length + def `x` = "abc".length + def `x ` = "abc".length + } + locally { + implicit val Implicit = scala.concurrent.Future.successful(2) + val Var = scala.concurrent.Future.successful(2) + val Val = scala.concurrent.Future.successful(2) + def Def = scala.concurrent.Future.successful(2) + } + object unicode { + object `->` { + def unapply[S](in: (S, S)): Option[(S, S)] = Some(in) + } + val `→` = `->` + } + def tuple = null.asInstanceOf[((Int, String)) => String] +} diff --git a/scalafix-tests/input/src/main/scala-3next/test/removeUnused/RemoveUnusedParams.scala b/scalafix-tests/input/src/main/scala-3next/test/removeUnused/RemoveUnusedParams.scala new file mode 100644 index 000000000..16e3a62ca --- /dev/null +++ b/scalafix-tests/input/src/main/scala-3next/test/removeUnused/RemoveUnusedParams.scala @@ -0,0 +1,12 @@ +/* +rule = RemoveUnused + */ +package test.removeUnused + +object UnusedParams { + val f: String => Unit = unused => println("f") + val ff = (unused: String) => println("f") + val fs = (used: String, unused: Long) => println(used) + def g(x: String => Unit): Unit = ??? + g{implicit string => println("g")} +} diff --git a/scalafix-tests/input/src/main/scala-3next/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/input/src/main/scala-3next/test/removeUnused/RemoveUnusedPatternVars.scala new file mode 100644 index 000000000..b4d14aeac --- /dev/null +++ b/scalafix-tests/input/src/main/scala-3next/test/removeUnused/RemoveUnusedPatternVars.scala @@ -0,0 +1,394 @@ +/* +rule = RemoveUnused + */ +package test.removeUnused + +case class AB(aa: Int, bb: String) + +case class XY(x: Int, y: Int) +case class YZ(xy: XY, z: String) + +object ob { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(aa, bb) => println("https://github.com/scala/bug/issues/13035") + } + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, b) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def pf(x: PartialFunction[Any, Unit]): Unit = ??? + case class A(a: Int) + pf{ + case string: String => ??? + case (i: Int) => ??? + case (a: Int, b) => println(b) + case a@A(v) => ??? + case x :: (y1, y2) :: Nil => println(x) + case (zz) => ??? + } + try ??? catch {case e: Exception => ???} + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } +} + +trait tr { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, b) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } +} + +class cl { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, b) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(a, b) => println("Not used, wrong") + } + example match { + case AB(_, b) => println("b is not used, wrong") + } + example match { + case AB(a, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(a, _) => + val a = 5 + println(a) + } + } + + def f(v: (Int, (Boolean, String))): Int = v match { + case t @ (i, v @ (_, _)) => i + } +} \ No newline at end of file diff --git a/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala b/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala index 542477bf0..f614d4a53 100644 --- a/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala +++ b/scalafix-tests/integration/src/test/scala/scalafix/tests/interfaces/ScalafixSuite.scala @@ -48,6 +48,7 @@ class ScalafixSuite extends AnyFunSuite { assert(api.scala33() == Versions.scala33) assert(api.scala35() == Versions.scala35) assert(api.scala36() == Versions.scala36) + assert(api.scala37() == Versions.scala37) assert(api.scala3LTS() == Versions.scala3LTS) assert(api.scala3Next() == Versions.scala3Next) assert( @@ -131,12 +132,12 @@ class ScalafixSuite extends AnyFunSuite { } test("classload Scala 3 Next with full version") { - val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.6.2", repositories) + val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.7.0", repositories) assert(scalafixAPI.scalaVersion() == Versions.scala3Next) } test("classload Scala 3 Next with major.minor version") { - val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.6", repositories) + val scalafixAPI = Scalafix.fetchAndClassloadInstance("3.7", repositories) assert(scalafixAPI.scalaVersion() == Versions.scala3Next) } diff --git a/scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/output/src/main/scala-2.12/test/removeUnused/RemoveUnusedPatternVars.scala similarity index 98% rename from scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedPatternVars.scala rename to scalafix-tests/output/src/main/scala-2.12/test/removeUnused/RemoveUnusedPatternVars.scala index a8aca1c7a..f4e65cb0a 100644 --- a/scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedPatternVars.scala +++ b/scalafix-tests/output/src/main/scala-2.12/test/removeUnused/RemoveUnusedPatternVars.scala @@ -9,6 +9,9 @@ object ob { // Add code that needs fixing here. val example = AB(42, "lol") + example match { + case AB(_, _) => println("https://github.com/scala/bug/issues/13035") + } example match { case AB(_, _) => println("Not used, good") } diff --git a/scalafix-tests/output/src/main/scala-2.13/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/output/src/main/scala-2.13/test/removeUnused/RemoveUnusedPatternVars.scala new file mode 100644 index 000000000..0d13165e5 --- /dev/null +++ b/scalafix-tests/output/src/main/scala-2.13/test/removeUnused/RemoveUnusedPatternVars.scala @@ -0,0 +1,391 @@ +package test.removeUnused + +case class AB(aa: Int, bb: String) + +case class XY(x: Int, y: Int) +case class YZ(xy: XY, z: String) + +object ob { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(aa, bb) => println("https://github.com/scala/bug/issues/13035") + } + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, _) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def pf(x: PartialFunction[Any, Unit]): Unit = ??? + case class A(a: Int) + pf{ + case _: String => ??? + case (_: Int) => ??? + case (_: Int, b) => println(b) + case A(_) => ??? + case x :: (_, _) :: Nil => println(x) + case _ => ??? + } + try ??? catch {case _: Exception => ???} + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } +} + +trait tr { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, _) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } +} + +class cl { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, _) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + def f(v: (Int, (Boolean, String))): Int = v match { + case (i, (_, _)) => i + } +} \ No newline at end of file diff --git a/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala b/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala index 79c739500..2d037d08b 100644 --- a/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala +++ b/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesBase.scala @@ -15,18 +15,7 @@ object ExplicitResultTypesBase { private val g = 1 private def h(a: Int) = "" private var i = 22 - private implicit var j = 1 val k: (Int, String) = (1, "msg") - implicit val L: List[Int] = List(1) - implicit val M: Map[Int,String] = Map(1 -> "STRING") - implicit def D = 2 - implicit def tparam[T](e: T) = e - implicit def tparam2[T](e: T): List[T] = List(e) - implicit def tparam3[T](e: T): Map[T,T] = Map(e -> e) - class implicitlytrick { - implicit val s: _root_.java.lang.String = "string" - implicit val x = implicitly[String] - } def comment(x: Int): Int = // comment x + 2 diff --git a/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesImplicit.scala b/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesImplicit.scala new file mode 100644 index 000000000..d1ff993d3 --- /dev/null +++ b/scalafix-tests/output/src/main/scala-2/test/explicitResultTypes/ExplicitResultTypesImplicit.scala @@ -0,0 +1,18 @@ + +package test.explicitResultTypes + +import scala.language.implicitConversions + +object ExplicitResultTypesImplicit { + private implicit var j = 1 + implicit val L: List[Int] = List(1) + implicit val M: Map[Int,String] = Map(1 -> "STRING") + implicit def D = 2 + implicit def tparam[T](e: T) = e + implicit def tparam2[T](e: T): List[T] = List(e) + implicit def tparam3[T](e: T): Map[T,T] = Map(e -> e) + class implicitlytrick { + implicit val s: _root_.java.lang.String = "string" + implicit val x = implicitly[String] + } +} diff --git a/scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala b/scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala index a8084d054..a6cd47c05 100644 --- a/scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala +++ b/scalafix-tests/output/src/main/scala-2/test/removeUnused/RemoveUnusedParams.scala @@ -1,7 +1,5 @@ package test.removeUnused -// Not available as of Scala 3.4.1 -// https://github.com/scalacenter/scalafix/issues/1937 object UnusedParams { val f: String => Unit = _ => println("f") val ff = (_: String) => println("f") diff --git a/scalafix-tests/output/src/main/scala-3/test/explicitResultTypes/ExplicitResultTypesBase.scala b/scalafix-tests/output/src/main/scala-3/test/explicitResultTypes/ExplicitResultTypesBase.scala new file mode 100644 index 000000000..8fa911e05 --- /dev/null +++ b/scalafix-tests/output/src/main/scala-3/test/explicitResultTypes/ExplicitResultTypesBase.scala @@ -0,0 +1,42 @@ + +package test.explicitResultTypes + +import scala.language.implicitConversions +import scala.concurrent.Future + +object ExplicitResultTypesBase { + def none[T]: Option[T] = None.asInstanceOf[Option[T]] + val a: Int = 1 + 2 + def b(): String = "a" + "b" + var c: Boolean = 1 == 1 + protected val d = 1.0f + protected def e(a: Int, b: Double): Double = a + b + protected var f: Int => Int = (x: Int) => x + 1 + val f0: () => Int = () => 42 + private val g = 1 + private def h(a: Int) = "" + private var i = 22 + val k: (Int, String) = (1, "msg") + def comment(x: Int): Int = + // comment + x + 2 + object ExtraSpace { + def * : Int = "abc".length + def ! : Int = "abc".length + def `x`: Int = "abc".length + def `x `: Int = "abc".length + } + locally { + implicit val Implicit: Future[Int] = scala.concurrent.Future.successful(2) + val Var = scala.concurrent.Future.successful(2) + val Val = scala.concurrent.Future.successful(2) + def Def = scala.concurrent.Future.successful(2) + } + object unicode { + object `->` { + def unapply[S](in: (S, S)): Option[(S, S)] = Some(in) + } + val `→` = `->` + } + def tuple: ((Int, String)) => String = null.asInstanceOf[((Int, String)) => String] +} diff --git a/scalafix-tests/output/src/main/scala-3/test/removeUnused/RemoveUnusedParams.scala b/scalafix-tests/output/src/main/scala-3/test/removeUnused/RemoveUnusedParams.scala new file mode 100644 index 000000000..c08d6694e --- /dev/null +++ b/scalafix-tests/output/src/main/scala-3/test/removeUnused/RemoveUnusedParams.scala @@ -0,0 +1,9 @@ +package test.removeUnused + +object UnusedParams { + val f: String => Unit = _ => println("f") + val ff = (_: String) => println("f") + val fs = (used: String, _: Long) => println(used) + def g(x: String => Unit): Unit = ??? + g{implicit string => println("g")} +} diff --git a/scalafix-tests/output/src/main/scala-3/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/output/src/main/scala-3lts/test/removeUnused/RemoveUnusedPatternVars.scala similarity index 98% rename from scalafix-tests/output/src/main/scala-3/test/removeUnused/RemoveUnusedPatternVars.scala rename to scalafix-tests/output/src/main/scala-3lts/test/removeUnused/RemoveUnusedPatternVars.scala index 6bd47ae77..0f5f2fe3b 100644 --- a/scalafix-tests/output/src/main/scala-3/test/removeUnused/RemoveUnusedPatternVars.scala +++ b/scalafix-tests/output/src/main/scala-3lts/test/removeUnused/RemoveUnusedPatternVars.scala @@ -9,6 +9,9 @@ object ob { // Add code that needs fixing here. val example = AB(42, "lol") + example match { + case AB(_, _) => println("https://github.com/scala/bug/issues/13035") + } example match { case AB(_, _) => println("Not used, good") } @@ -385,4 +388,4 @@ class cl { def f(v: (Int, (Boolean, String))): Int = v match { case _ @ (i, _ @ (_, _)) => i } -} \ No newline at end of file +} diff --git a/scalafix-tests/output/src/main/scala-3next/test/removeUnused/RemoveUnusedPatternVars.scala b/scalafix-tests/output/src/main/scala-3next/test/removeUnused/RemoveUnusedPatternVars.scala new file mode 100644 index 000000000..e371a0afe --- /dev/null +++ b/scalafix-tests/output/src/main/scala-3next/test/removeUnused/RemoveUnusedPatternVars.scala @@ -0,0 +1,391 @@ +package test.removeUnused + +case class AB(aa: Int, bb: String) + +case class XY(x: Int, y: Int) +case class YZ(xy: XY, z: String) + +object ob { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(aa, bb) => println("https://github.com/scala/bug/issues/13035") + } + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, _) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def pf(x: PartialFunction[Any, Unit]): Unit = ??? + case class A(a: Int) + pf{ + case _: String => ??? + case (_: Int) => ??? + case (_: Int, b) => println(b) + case _@A(_) => ??? + case x :: (_, _) :: Nil => println(x) + case _ => ??? + } + try ??? catch {case _: Exception => ???} + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } +} + +trait tr { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, _) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } +} + +class cl { + // Add code that needs fixing here. + val example = AB(42, "lol") + + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + + val anotherExample = YZ(XY(1, 2), "3") + + anotherExample match { + case YZ(el, _) => + el match { + case XY(b, _) => { + println(b) + } + } + } + + def a: Unit = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + val b = { + example match { + case AB(_, _) => println("Not used, good") + } + example match { + case AB(_, _) => println("Not used, wrong") + } + example match { + case AB(_, _) => println("b is not used, wrong") + } + example match { + case AB(_, _) => println("a is not used, wrong") + } + + example match { + case AB(a, b) => println(s"$a $b used, good") + } + example match { + case AB(_, b) => println(s"$b is used, good") + } + example match { + case AB(a, _) => println(s"$a is used, good") + } + + example match { + case AB(a, _) if a < Int.MaxValue => + println("Do not delete") + } + + example match { + case AB(_, _) => + val a = 5 + println(a) + } + } + + def f(v: (Int, (Boolean, String))): Int = v match { + case _ @ (i, _ @ (_, _)) => i + } +} diff --git a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/InterfacesPropertiesSuite.scala b/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/InterfacesPropertiesSuite.scala index 80b83aa4d..1e2baa35b 100644 --- a/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/InterfacesPropertiesSuite.scala +++ b/scalafix-tests/unit/src/test/scala/scalafix/tests/cli/InterfacesPropertiesSuite.scala @@ -28,6 +28,7 @@ class InterfacesPropertiesSuite extends AnyFunSuite with BeforeAndAfterAll { check("scala33", Versions.scala33) check("scala35", Versions.scala35) check("scala36", Versions.scala36) + check("scala37", Versions.scala37) check("scala3LTS", Versions.scala3LTS) check("scala3Next", Versions.scala3Next)