Skip to content

Commit

Permalink
Merge pull request #4 from mblink/given-using
Browse files Browse the repository at this point in the history
Rule to suggest `given` and `using` instead of `implicit`
  • Loading branch information
mrdziuban authored Oct 7, 2024
2 parents bcac189 + fd5a3bc commit 85e972a
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
21 changes: 21 additions & 0 deletions scalafix/input/src/main/scala-3/fix/GivenUsing.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
rule = GivenUsing
*/
package fix

object GivenUsing {
implicit val i: Int = 1/* assert: GivenUsing
^^^^^^^^
Use `given` instead of `implicit val` */
implicit val j: Int = 1 // scalafix:ok GivenUsing

implicit def s: String = ""/* assert: GivenUsing
^^^^^^^^
Use `given` instead of `implicit def` */

implicit def conversion(i: Int): String = i.toString

def implicitArg(implicit i: Int): Int = i/* assert: GivenUsing
^^^^^^^^
Use `using` instead of `implicit` */
}
12 changes: 12 additions & 0 deletions scalafix/output/src/main/scala-3/fix/GivenUsing.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fix

object GivenUsing {
implicit val i: Int = 1
implicit val j: Int = 1 // scalafix:ok GivenUsing

implicit def s: String = ""

implicit def conversion(i: Int): String = i.toString

def implicitArg(implicit i: Int): Int = i
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
fix.GivenUsing
fix.NoUnnecessaryCase
fix.NoUnnecessaryForComprehension
fix.StrictSubclassAccess
Expand Down
41 changes: 41 additions & 0 deletions scalafix/rules/src/main/scala/fix/GivenUsing.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package fix

import scalafix.v1._
import scala.meta._

case class UseGiven(kw: String, position: Position) extends Diagnostic {
override lazy val message = s"Use `given` instead of `implicit $kw`"
}

case class UseUsing(position: Position) extends Diagnostic {
override lazy val message = "Use `using` instead of `implicit`"
}

private case class ParsedParams(allImplicitGroups: Boolean, implicitMods: List[Mod])

class GivenUsing extends SyntacticRule("GivenUsing") {
private def implicitMod(mods: List[Mod]): Option[Mod] = mods.find(_.is[Mod.Implicit])

private def parseParams(paramGroups: List[Member.ParamClauseGroup]): ParsedParams =
paramGroups.foldRight(ParsedParams(true, Nil))((group, acc) =>
group.paramClauses.foldRight(acc) {
case (clause, ParsedParams(accAll, accImplicitMods)) =>
implicitMod(clause.mod.toList).map(m => ParsedParams(accAll, m :: accImplicitMods))
.orElse(clause.mod.find(_.is[Mod.Using]).map(_ => ParsedParams(accAll, accImplicitMods)))
.getOrElse(ParsedParams(false, accImplicitMods))
}
)

override def fix(implicit doc: SyntacticDocument): Patch =
doc.tree.collect {
case Defn.Val(mods, _, _, _) => implicitMod(mods).fold(Patch.empty)(m => Patch.lint(UseGiven("val", m.pos)))

case Defn.Def.After_4_7_3(mods, _, paramGroups, _, _) =>
val parsed = parseParams(paramGroups)
val givenPatch = implicitMod(mods)
.filter(_ => parsed.allImplicitGroups)
.fold(Patch.empty)(m => Patch.lint(UseGiven("def", m.pos)))
val usingPatch = parsed.implicitMods.map(m => Patch.lint(UseUsing(m.pos))).asPatch
givenPatch + usingPatch
}.asPatch
}

0 comments on commit 85e972a

Please sign in to comment.