-
Notifications
You must be signed in to change notification settings - Fork 10
/
KindProjector.scala
57 lines (48 loc) · 1.63 KB
/
KindProjector.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package fix
import metaconfig.ConfDecoder
import metaconfig.Configured
import metaconfig.generic.Surface
import scalafix.Patch
import scalafix.v1.Configuration
import scalafix.v1.Rule
import scalafix.v1.SyntacticDocument
import scalafix.v1.SyntacticRule
import scala.meta.Type
case class KindProjectorConfig(
rewriteInfixTypes: Set[String]
)
object KindProjectorConfig {
val default: KindProjectorConfig = KindProjectorConfig(
rewriteInfixTypes = Set.empty
)
implicit val surface: Surface[KindProjectorConfig] =
metaconfig.generic.deriveSurface[KindProjectorConfig]
implicit val decoder: ConfDecoder[KindProjectorConfig] =
metaconfig.generic.deriveDecoder(default)
}
/**
* [[https://github.com/lampepfl/dotty-feature-requests/issues/117]]
*/
class KindProjector(config: KindProjectorConfig) extends SyntacticRule("KindProjector") {
def this() = this(KindProjectorConfig.default)
override def withConfiguration(config: Configuration): Configured[Rule] = {
config.conf.getOrElse("KindProjector")(this.config).map(newConfig => new KindProjector(newConfig))
}
private[this] object InfixOpExtractor {
def unapply(name: Type.Name): Option[String] = {
if (config.rewriteInfixTypes.isEmpty) {
// rewrite all if config isEmpty
Some(name.value)
} else if (config.rewriteInfixTypes(name.value)) {
Some(name.value)
} else {
None
}
}
}
override def fix(implicit doc: SyntacticDocument): Patch = {
doc.tree.collect { case t @ Type.ApplyInfix(left, InfixOpExtractor(opName), Type.Name("*")) =>
Patch.replaceTree(t, s"${opName}[${left}, *]")
}.asPatch
}
}