-
Notifications
You must be signed in to change notification settings - Fork 437
/
domain.kt
107 lines (83 loc) · 3.27 KB
/
domain.kt
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package arrow.optics.plugin.internals
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSName
import java.util.Locale
data class ADT(val pckg: KSName, val declaration: KSClassDeclaration, val targets: List<Target>) {
val sourceClassName = declaration.qualifiedNameOrSimpleName
val sourceName = declaration.simpleName.asString().replaceFirstChar { it.lowercase(Locale.getDefault()) }
val simpleName = declaration.simpleName.asString()
val packageName = pckg.asString()
operator fun Snippet.plus(snippet: Snippet): Snippet =
copy(imports = imports + snippet.imports, content = "$content\n${snippet.content}")
}
enum class OpticsTarget {
ISO,
LENS,
PRISM,
OPTIONAL,
DSL
}
typealias IsoTarget = Target.Iso
typealias PrismTarget = Target.Prism
typealias LensTarget = Target.Lens
typealias OptionalTarget = Target.Optional
typealias SealedClassDsl = Target.SealedClassDsl
typealias DataClassDsl = Target.DataClassDsl
sealed class Target {
abstract val foci: List<Focus>
data class Iso(override val foci: List<Focus>) : Target()
data class Prism(override val foci: List<Focus>) : Target()
data class Lens(override val foci: List<Focus>) : Target()
data class Optional(override val foci: List<Focus>) : Target()
data class SealedClassDsl(override val foci: List<Focus>) : Target()
data class DataClassDsl(override val foci: List<Focus>) : Target()
}
typealias NonNullFocus = Focus.NonNull
typealias OptionFocus = Focus.Option
typealias NullableFocus = Focus.Nullable
sealed class Focus {
companion object {
operator fun invoke(fullName: String, paramName: String): Focus =
when {
fullName.endsWith("?") -> Nullable(fullName, paramName)
fullName.startsWith("`arrow`.`core`.`Option`") -> Option(fullName, paramName)
else -> NonNull(fullName, paramName)
}
}
abstract val className: String
abstract val paramName: String
data class Nullable(override val className: String, override val paramName: String) : Focus() {
val nonNullClassName = className.dropLast(1)
}
data class Option(override val className: String, override val paramName: String) : Focus() {
val nestedClassName =
Regex("`arrow`.`core`.`Option`<(.*)>$").matchEntire(className)!!.groupValues[1]
}
data class NonNull(override val className: String, override val paramName: String) : Focus()
}
const val Lens = "arrow.optics.Lens"
const val Iso = "arrow.optics.Iso"
const val Optional = "arrow.optics.Optional"
const val Prism = "arrow.optics.Prism"
const val Getter = "arrow.optics.Getter"
const val Setter = "arrow.optics.Setter"
const val Traversal = "arrow.optics.Traversal"
const val Fold = "arrow.optics.Fold"
const val Every = "arrow.optics.Every"
const val Tuple = "arrow.core.Tuple"
const val Pair = "kotlin.Pair"
const val Triple = "kotlin.Triple"
data class Snippet(
val `package`: String,
val name: String,
val imports: Set<String> = emptySet(),
val content: String
) {
val fqName = "$`package`.$name"
}
fun Snippet.asFileText(): String =
"""
|${if (`package`.isNotBlank() && `package` != "`unnamed package`") "package $`package`" else ""}
|${imports.joinToString(prefix = "\n", separator = "\n", postfix = "\n")}
|$content
""".trimMargin()