Skip to content

Commit

Permalink
Add option to disable inline when using @optics (#3078)
Browse files Browse the repository at this point in the history
  • Loading branch information
serras authored Jul 6, 2023
1 parent 5a47722 commit 17d8d9e
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration

class OpticsProcessor(private val codegen: CodeGenerator, private val logger: KSPLogger) :
class OpticsProcessor(
private val codegen: CodeGenerator,
private val logger: KSPLogger,
private val options: OpticsProcessorOptions,
) :
SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
resolver
Expand Down Expand Up @@ -44,7 +48,7 @@ class OpticsProcessor(private val codegen: CodeGenerator, private val logger: KS
}

val adts = adt(klass, logger)
val snippets = adts.snippets()
val snippets = adts.snippets(options)
snippets.groupBy(Snippet::fqName).values.map(List<Snippet>::join).forEach {
val writer =
codegen
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package arrow.optics.plugin

data class OpticsProcessorOptions(
val useInline: Boolean,
) {
val inlineText: String = if (useInline) "inline" else ""

companion object {
fun from(options: Map<String, String>): OpticsProcessorOptions =
OpticsProcessorOptions(
useInline = options.getOrDefault("inline", "true").toBooleanStrict(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import com.google.devtools.ksp.processing.SymbolProcessorProvider

class OpticsProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor =
OpticsProcessor(environment.codeGenerator, environment.logger)
OpticsProcessor(environment.codeGenerator, environment.logger, OpticsProcessorOptions.from(environment.options))
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package arrow.optics.plugin.internals

import arrow.optics.plugin.OpticsProcessorOptions
import arrow.optics.plugin.isValue

internal fun generateIsos(ele: ADT, target: IsoTarget) =
internal fun OpticsProcessorOptions.generateIsos(ele: ADT, target: IsoTarget) =
Snippet(`package` = ele.packageName, name = ele.simpleName, content = processElement(ele, target))

inline val Target.targetNames
inline get() = foci.map(Focus::className)

private fun processElement(iso: ADT, target: Target): String {
private fun OpticsProcessorOptions.processElement(iso: ADT, target: Target): String {
val foci = target.foci
val letters = listOf(
"first",
Expand Down Expand Up @@ -69,9 +70,9 @@ private fun processElement(iso: ADT, target: Target): String {
val sourceClassNameWithParams = "${iso.sourceClassName}${iso.angledTypeParameters}"
val firstLine = when {
iso.typeParameters.isEmpty() ->
"${iso.visibilityModifierName} inline val ${iso.sourceClassName}.Companion.$isoName: $Iso<${iso.sourceClassName}, ${focusType()}> inline get()"
"${iso.visibilityModifierName} $inlineText val ${iso.sourceClassName}.Companion.$isoName: $Iso<${iso.sourceClassName}, ${focusType()}> $inlineText get()"
else ->
"${iso.visibilityModifierName} inline fun ${iso.angledTypeParameters} ${iso.sourceClassName}.Companion.$isoName(): $Iso<$sourceClassNameWithParams, ${focusType()}>"
"${iso.visibilityModifierName} $inlineText fun ${iso.angledTypeParameters} ${iso.sourceClassName}.Companion.$isoName(): $Iso<$sourceClassNameWithParams, ${focusType()}>"
}

return """
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package arrow.optics.plugin.internals

import arrow.optics.plugin.OpticsProcessorOptions
import java.util.Locale

internal fun generateLenses(ele: ADT, target: LensTarget) =
internal fun OpticsProcessorOptions.generateLenses(ele: ADT, target: LensTarget) =
Snippet(
`package` = ele.packageName,
name = ele.simpleName,
Expand All @@ -20,14 +21,14 @@ private fun String.toUpperCamelCase(): String =
},
)

private fun processElement(adt: ADT, foci: List<Focus>): String {
private fun OpticsProcessorOptions.processElement(adt: ADT, foci: List<Focus>): String {
val sourceClassNameWithParams = "${adt.sourceClassName}${adt.angledTypeParameters}"
return foci.joinToString(separator = "\n") { focus ->
val firstLine = when {
adt.typeParameters.isEmpty() ->
"${adt.visibilityModifierName} inline val ${adt.sourceClassName}.Companion.${focus.lensParamName()}: $Lens<${adt.sourceClassName}, ${focus.className}> inline get()"
"${adt.visibilityModifierName} $inlineText val ${adt.sourceClassName}.Companion.${focus.lensParamName()}: $Lens<${adt.sourceClassName}, ${focus.className}> $inlineText get()"
else ->
"${adt.visibilityModifierName} inline fun ${adt.angledTypeParameters} ${adt.sourceClassName}.Companion.${focus.lensParamName()}(): $Lens<$sourceClassNameWithParams, ${focus.className}>"
"${adt.visibilityModifierName} $inlineText fun ${adt.angledTypeParameters} ${adt.sourceClassName}.Companion.${focus.lensParamName()}(): $Lens<$sourceClassNameWithParams, ${focus.className}>"
}
"""
|$firstLine = $Lens(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package arrow.optics.plugin.internals

internal fun generateOptionals(ele: ADT, target: OptionalTarget) =
import arrow.optics.plugin.OpticsProcessorOptions

internal fun OpticsProcessorOptions.generateOptionals(ele: ADT, target: OptionalTarget) =
Snippet(
`package` = ele.packageName,
name = ele.simpleName,
Expand All @@ -9,7 +11,7 @@ internal fun generateOptionals(ele: ADT, target: OptionalTarget) =
content = processElement(ele, target.foci),
)

private fun processElement(ele: ADT, foci: List<Focus>): String =
private fun OpticsProcessorOptions.processElement(ele: ADT, foci: List<Focus>): String =
foci.joinToString(separator = "\n") { focus ->

val targetClassName = when (focus) {
Expand All @@ -21,9 +23,9 @@ private fun processElement(ele: ADT, foci: List<Focus>): String =
val sourceClassNameWithParams = "${ele.sourceClassName}${ele.angledTypeParameters}"
val firstLine = when {
ele.typeParameters.isEmpty() ->
"${ele.visibilityModifierName} inline val ${ele.sourceClassName}.Companion.${focus.paramName}: $Optional<${ele.sourceClassName}, $targetClassName> inline get()"
"${ele.visibilityModifierName} $inlineText val ${ele.sourceClassName}.Companion.${focus.paramName}: $Optional<${ele.sourceClassName}, $targetClassName> $inlineText get()"
else ->
"${ele.visibilityModifierName} inline fun ${ele.angledTypeParameters} ${ele.sourceClassName}.Companion.${focus.paramName}(): $Optional<$sourceClassNameWithParams, $targetClassName>"
"${ele.visibilityModifierName} $inlineText fun ${ele.angledTypeParameters} ${ele.sourceClassName}.Companion.${focus.paramName}(): $Optional<$sourceClassNameWithParams, $targetClassName>"
}

fun getOrModifyF(toNullable: String = "") =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package arrow.optics.plugin.internals

internal fun generatePrisms(ele: ADT, target: PrismTarget) =
import arrow.optics.plugin.OpticsProcessorOptions

internal fun OpticsProcessorOptions.generatePrisms(ele: ADT, target: PrismTarget) =
Snippet(
`package` = ele.packageName,
name = ele.simpleName,
Expand All @@ -9,7 +11,7 @@ internal fun generatePrisms(ele: ADT, target: PrismTarget) =
content = processElement(ele, target.foci),
)

private fun processElement(ele: ADT, foci: List<Focus>): String {
private fun OpticsProcessorOptions.processElement(ele: ADT, foci: List<Focus>): String {
return foci.joinToString(separator = "\n\n") { focus ->
val sourceClassNameWithParams =
focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}"
Expand All @@ -19,9 +21,9 @@ private fun processElement(ele: ADT, foci: List<Focus>): String {
}
val firstLine = when {
ele.typeParameters.isEmpty() ->
"${ele.visibilityModifierName} inline val ${ele.sourceClassName}.Companion.${focus.paramName}: $Prism<${ele.sourceClassName}, ${focus.className}> inline get()"
"${ele.visibilityModifierName} $inlineText val ${ele.sourceClassName}.Companion.${focus.paramName}: $Prism<${ele.sourceClassName}, ${focus.className}> $inlineText get()"
else ->
"${ele.visibilityModifierName} inline fun $angledTypeParameters ${ele.sourceClassName}.Companion.${focus.paramName}(): $Prism<$sourceClassNameWithParams, ${focus.className}>"
"${ele.visibilityModifierName} $inlineText fun $angledTypeParameters ${ele.sourceClassName}.Companion.${focus.paramName}(): $Prism<$sourceClassNameWithParams, ${focus.className}>"
}

val elseBranch = if (focus.onlyOneSealedSubclass) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package arrow.optics.plugin.internals

internal fun ADT.snippets(): List<Snippet> =
import arrow.optics.plugin.OpticsProcessorOptions

internal fun ADT.snippets(options: OpticsProcessorOptions): List<Snippet> =
targets.map {
when (it) {
is IsoTarget -> generateIsos(this, it)
is PrismTarget -> generatePrisms(this, it)
is LensTarget -> generateLenses(this, it)
is OptionalTarget -> generateOptionals(this, it)
is IsoTarget -> options.generateIsos(this, it)
is PrismTarget -> options.generatePrisms(this, it)
is LensTarget -> options.generateLenses(this, it)
is OptionalTarget -> options.generateOptionals(this, it)
is SealedClassDsl -> generatePrismDsl(this, it)
is DataClassDsl -> generateOptionalDsl(this, it) + generateLensDsl(this, it)
is ValueClassDsl -> generateIsoDsl(this, it)
Expand Down

0 comments on commit 17d8d9e

Please sign in to comment.