Last active
October 25, 2024 22:36
-
-
Save xuwei-k/ec14900c3539fe71fbe9c0fe4c94eb25 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fix | |
import scala.meta._ | |
import scalafix.v1._ | |
class ImplicitClassExtension extends SyntacticRule("ImplicitClassExtension") { | |
val exclude: Seq[String] = Seq( | |
// 書き換えるとoverload衝突する場合や、呼び出しの優先順位変わってエラーになるものなど、 | |
// 下記の条件で除外しきれなかった例外的なものをfile単位で除くためにここに記述 | |
) | |
override def fix(implicit doc: SyntacticDocument): Patch = { | |
doc.input match { | |
case f: Input.VirtualFile if exclude.exists(f.path.contains) => | |
Patch.empty | |
case _ => | |
doc.tree.collect { | |
case t: Defn.Class | |
if (t.mods.sizeIs == 1) && // implicit以外のmodあると失敗する場合がある(詳細未検証)なので一旦除外 | |
t.mods.exists(_.is[Mod.Implicit]) && // implicitが付与されているか?を確認 | |
(t.ctor.paramClauses.sizeIs == 1) && // 複数のparam clauseがあるとダメだっけ? | |
t.tparamClause.values.map(_.tbounds).forall(x => x.lo.isEmpty && x.hi.isEmpty) && // context boundなどはダメ? | |
t.tparamClause.values.forall(_.cbounds.isEmpty) && | |
t.templ.stats.nonEmpty && // 滅多にないが何故か稀にbodyが空のもの書き換えるとエラーになるので | |
t.templ.stats.forall( | |
_.is[Defn.Def] // 詳細な正確な条件は深く考えてないが、implicit class内部には置けてもextensionにおけないものがあるので、とりあえずdefだけで絞る | |
) => | |
Seq( | |
Patch.removeTokens(t.name.tokens), | |
t.ctor.paramClauses | |
.flatMap(_.values).map(p => | |
p.mods.collect { | |
case m: Mod.ValParam => | |
Patch.removeTokens(m.tokens) | |
case m: Mod.Private => | |
Patch.removeTokens(m.tokens) | |
}.asPatch | |
).asPatch, | |
Option | |
.when(t.templ.inits.nonEmpty) { | |
Seq( | |
Patch.removeToken( | |
t.templ.tokens.find(_.is[Token.KwExtends]).get | |
), | |
t.templ.inits.map(_.tokens).map(Patch.removeTokens).asPatch | |
).asPatch | |
}.asPatch, | |
Patch.removeToken( | |
t.tokens.find(_.is[Token.KwImplicit]).get | |
), | |
Patch.replaceToken( | |
t.tokens.find(_.is[Token.KwClass]).get, | |
"extension" | |
) | |
).asPatch | |
}.asPatch | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment