diff --git a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowEitherCallAdapter.kt b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowEitherCallAdapter.kt index 3c35273716b..fe6bfae31ff 100644 --- a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowEitherCallAdapter.kt +++ b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowEitherCallAdapter.kt @@ -68,8 +68,7 @@ internal class ArrowEitherCallAdapter( override fun cancel() = original.cancel() - override fun execute(): Response> = - throw UnsupportedOperationException("This adapter does not support sync execution") + override fun execute(): Response> = throw UnsupportedOperationException("This adapter does not support sync execution") override fun request(): Request = original.request() } diff --git a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowResponseECallAdapter.kt b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowResponseECallAdapter.kt index 72faaf5d491..7483374268c 100644 --- a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowResponseECallAdapter.kt +++ b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/ArrowResponseECallAdapter.kt @@ -67,8 +67,7 @@ internal class ArrowResponseECallAdapter( override fun cancel() = original.cancel() - override fun execute(): Response> = - throw UnsupportedOperationException("This adapter does not support sync execution") + override fun execute(): Response> = throw UnsupportedOperationException("This adapter does not support sync execution") override fun request(): Request = original.request() } diff --git a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/EitherCallAdapterFactory.kt b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/EitherCallAdapterFactory.kt index b277e0ee2ad..ab70e67769a 100644 --- a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/EitherCallAdapterFactory.kt +++ b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/EitherCallAdapterFactory.kt @@ -124,7 +124,6 @@ public class EitherCallAdapterFactory : CallAdapter.Factory() { } } -private fun parseTypeName(type: Type) = - type.toString() - .split(".") - .last() +private fun parseTypeName(type: Type) = type.toString() + .split(".") + .last() diff --git a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/networkhandling/NetworkEitherCallAdapter.kt b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/networkhandling/NetworkEitherCallAdapter.kt index d29b194496a..5d5e9d71c21 100644 --- a/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/networkhandling/NetworkEitherCallAdapter.kt +++ b/arrow-libs/core/arrow-core-retrofit/src/main/kotlin/arrow/retrofit/adapter/either/networkhandling/NetworkEitherCallAdapter.kt @@ -84,8 +84,7 @@ private class EitherCall( override fun cancel() = delegate.cancel() - override fun execute(): Response> = - throw UnsupportedOperationException("This adapter does not support sync execution") + override fun execute(): Response> = throw UnsupportedOperationException("This adapter does not support sync execution") override fun request(): Request = delegate.request() } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/test/JvmGenerators.kt b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/test/JvmGenerators.kt index 461949d6815..b8d1e46998f 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/test/JvmGenerators.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/java/arrow/core/test/JvmGenerators.kt @@ -5,8 +5,6 @@ import io.kotest.property.Arb import io.kotest.property.arbitrary.map import io.kotest.property.arbitrary.of -public fun Arb.Companion.suspendFunThatThrowsFatalThrowable(): Arb Either> = - fatalThrowable().map { suspend { throw it } } as Arb Either> +public fun Arb.Companion.suspendFunThatThrowsFatalThrowable(): Arb Either> = fatalThrowable().map { suspend { throw it } } as Arb Either> -public fun Arb.Companion.fatalThrowable(): Arb = - Arb.of(listOf(ThreadDeath(), StackOverflowError(), OutOfMemoryError(), InterruptedException())) +public fun Arb.Companion.fatalThrowable(): Arb = Arb.of(listOf(ThreadDeath(), StackOverflowError(), OutOfMemoryError(), InterruptedException())) diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt index ff66299e188..b37b75ec574 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt @@ -23,8 +23,7 @@ class OpticsProcessor( private val codegen: CodeGenerator, private val logger: KSPLogger, private val options: OpticsProcessorOptions, -) : - SymbolProcessor { +) : SymbolProcessor { override fun process(resolver: Resolver): List { val (resolved, deferred) = resolver .getSymbolsWithAnnotation("arrow.optics.optics") diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorOptions.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorOptions.kt index 7870606b203..d1b860b987e 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorOptions.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorOptions.kt @@ -6,9 +6,8 @@ data class OpticsProcessorOptions( val inlineText: String = if (useInline) "inline" else "" companion object { - fun from(options: Map): OpticsProcessorOptions = - OpticsProcessorOptions( - useInline = options.getOrDefault("inline", "false").toBooleanStrict(), - ) + fun from(options: Map): OpticsProcessorOptions = OpticsProcessorOptions( + useInline = options.getOrDefault("inline", "false").toBooleanStrict(), + ) } } diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorProvider.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorProvider.kt index 00b5e0cbfd9..9aabb4b61aa 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorProvider.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessorProvider.kt @@ -5,6 +5,5 @@ import com.google.devtools.ksp.processing.SymbolProcessorEnvironment import com.google.devtools.ksp.processing.SymbolProcessorProvider class OpticsProcessorProvider : SymbolProcessorProvider { - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = - OpticsProcessor(environment.codeGenerator, environment.logger, OpticsProcessorOptions.from(environment.options)) + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = OpticsProcessor(environment.codeGenerator, environment.logger, OpticsProcessorOptions.from(environment.options)) } diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/domain.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/domain.kt index 914aa757b77..0314f73096b 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/domain.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/domain.kt @@ -26,8 +26,7 @@ data class ADT(val pckg: KSName, val declaration: KSClassDeclaration, val target else -> "<${typeParameters.joinToString(separator = ",")}>" } - operator fun Snippet.plus(snippet: Snippet): Snippet = - copy(imports = imports + snippet.imports, content = "$content\n${snippet.content}") + operator fun Snippet.plus(snippet: Snippet): Snippet = copy(imports = imports + snippet.imports, content = "$content\n${snippet.content}") } @Suppress("RecursivePropertyAccessor") @@ -87,8 +86,7 @@ data class Focus( }?.map { it.qualifiedString() }.orEmpty() companion object { - operator fun invoke(fullName: String, paramName: String, subclasses: List = emptyList()): Focus = - Focus(fullName, paramName, null, subclasses = subclasses) + operator fun invoke(fullName: String, paramName: String, subclasses: List = emptyList()): Focus = Focus(fullName, paramName, null, subclasses = subclasses) } } diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/dsl.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/dsl.kt index f8994b33d49..7f1442a42ca 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/dsl.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/dsl.kt @@ -33,85 +33,81 @@ fun OpticsProcessorOptions.generateIsoDsl(ele: ADT, isoOptic: ValueClassDsl): Sn ) } -private fun OpticsProcessorOptions.processLensSyntax(ele: ADT, foci: List, className: String): String { - return if (ele.typeParameters.isEmpty()) { - foci.joinToString(separator = "\n") { focus -> - """ +private fun OpticsProcessorOptions.processLensSyntax(ele: ADT, foci: List, className: String): String = if (ele.typeParameters.isEmpty()) { + foci.joinToString(separator = "\n") { focus -> + """ |${ele.visibilityModifierName} $inlineText val <__S> $Lens<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Lens<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Optional<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Optional<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Traversal<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Traversal<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} | - """.trimMargin() - } - } else { - val sourceClassNameWithParams = "${ele.sourceClassName}${ele.angledTypeParameters}" - val joinedTypeParams = ele.typeParameters.joinToString(separator = ",") - foci.joinToString(separator = "\n") { focus -> - """ + """.trimMargin() + } +} else { + val sourceClassNameWithParams = "${ele.sourceClassName}${ele.angledTypeParameters}" + val joinedTypeParams = ele.typeParameters.joinToString(separator = ",") + foci.joinToString(separator = "\n") { focus -> + """ |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Lens<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Lens<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Optional<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Optional<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Traversal<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Traversal<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() | - """.trimMargin() - } + """.trimMargin() } } -private fun OpticsProcessorOptions.processPrismSyntax(ele: ADT, dsl: SealedClassDsl, className: String): String = - if (ele.typeParameters.isEmpty()) { - dsl.foci.joinToString(separator = "\n\n") { focus -> - """ +private fun OpticsProcessorOptions.processPrismSyntax(ele: ADT, dsl: SealedClassDsl, className: String): String = if (ele.typeParameters.isEmpty()) { + dsl.foci.joinToString(separator = "\n\n") { focus -> + """ |${ele.visibilityModifierName} $inlineText val <__S> $Optional<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Optional<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Prism<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Prism<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Traversal<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Traversal<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} | - """.trimMargin() + """.trimMargin() + } +} else { + dsl.foci.joinToString(separator = "\n\n") { focus -> + val sourceClassNameWithParams = focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}" + val joinedTypeParams = when { + focus.refinedArguments.isEmpty() -> "" + else -> focus.refinedArguments.joinToString(separator = ",") } - } else { - dsl.foci.joinToString(separator = "\n\n") { focus -> - val sourceClassNameWithParams = focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}" - val joinedTypeParams = when { - focus.refinedArguments.isEmpty() -> "" - else -> focus.refinedArguments.joinToString(separator = ",") - } - """ + """ |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Optional<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Optional<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Prism<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Prism<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Traversal<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Traversal<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() | - """.trimMargin() - } + """.trimMargin() } +} -private fun OpticsProcessorOptions.processIsoSyntax(ele: ADT, dsl: ValueClassDsl, className: String): String = - if (ele.typeParameters.isEmpty()) { - dsl.foci.joinToString(separator = "\n\n") { focus -> - """ +private fun OpticsProcessorOptions.processIsoSyntax(ele: ADT, dsl: ValueClassDsl, className: String): String = if (ele.typeParameters.isEmpty()) { + dsl.foci.joinToString(separator = "\n\n") { focus -> + """ |${ele.visibilityModifierName} $inlineText val <__S> $Iso<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Iso<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Lens<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Lens<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Optional<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Optional<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Prism<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Prism<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} |${ele.visibilityModifierName} $inlineText val <__S> $Traversal<__S, ${ele.sourceClassName}>.${focus.escapedParamName}: $Traversal<__S, ${focus.classNameWithParameters}> $inlineText get() = this + $className.${focus.escapedParamName} | - """.trimMargin() + """.trimMargin() + } +} else { + dsl.foci.joinToString(separator = "\n\n") { focus -> + val sourceClassNameWithParams = focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}" + val joinedTypeParams = when { + focus.refinedArguments.isEmpty() -> "" + else -> focus.refinedArguments.joinToString(separator = ",") } - } else { - dsl.foci.joinToString(separator = "\n\n") { focus -> - val sourceClassNameWithParams = focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}" - val joinedTypeParams = when { - focus.refinedArguments.isEmpty() -> "" - else -> focus.refinedArguments.joinToString(separator = ",") - } - """ + """ |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Iso<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Iso<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Lens<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Lens<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Optional<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Optional<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Prism<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Prism<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() |${ele.visibilityModifierName} $inlineText fun <__S,$joinedTypeParams> $Traversal<__S, $sourceClassNameWithParams>.${focus.escapedParamName}(): $Traversal<__S, ${focus.classNameWithParameters}> = this + $className.${focus.escapedParamName}() | - """.trimMargin() - } + """.trimMargin() } +} private fun resolveClassName(ele: ADT): Pair = if (hasPackageCollisions(ele)) { val classNameAlias = ele.sourceClassName.replace(".", "").replace("`", "").sanitize() @@ -121,11 +117,10 @@ private fun resolveClassName(ele: ADT): Pair = if (hasPackageCol ele.sourceClassName to "" } -private fun hasPackageCollisions(ele: ADT): Boolean = - ele.declaration.getDeclaredProperties().let { properties -> - ele.packageName - .split(".") - .any { p -> - properties.any { it.simpleName.asString() == p } - } - } +private fun hasPackageCollisions(ele: ADT): Boolean = ele.declaration.getDeclaredProperties().let { properties -> + ele.packageName + .split(".") + .any { p -> + properties.any { it.simpleName.asString() == p } + } +} diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/iso.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/iso.kt index bb8db8e7875..4dc3d2a514b 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/iso.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/iso.kt @@ -2,8 +2,7 @@ package arrow.optics.plugin.internals import arrow.optics.plugin.OpticsProcessorOptions -internal fun OpticsProcessorOptions.generateIsos(ele: ADT, target: IsoTarget) = - Snippet(`package` = ele.packageName, name = ele.simpleName, content = processElement(ele, target.foci.first())) +internal fun OpticsProcessorOptions.generateIsos(ele: ADT, target: IsoTarget) = Snippet(`package` = ele.packageName, name = ele.simpleName, content = processElement(ele, target.foci.first())) private fun OpticsProcessorOptions.processElement(adt: ADT, focus: Focus): String { val sourceClassNameWithParams = "${adt.sourceClassName}${adt.angledTypeParameters}" diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/lenses.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/lenses.kt index fed5eeb5f49..6c582583aa8 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/lenses.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/lenses.kt @@ -2,12 +2,11 @@ package arrow.optics.plugin.internals import arrow.optics.plugin.OpticsProcessorOptions -internal fun OpticsProcessorOptions.generateLenses(ele: ADT, target: LensTarget) = - Snippet( - `package` = ele.packageName, - name = ele.simpleName, - content = processElement(ele, target.foci), - ) +internal fun OpticsProcessorOptions.generateLenses(ele: ADT, target: LensTarget) = Snippet( + `package` = ele.packageName, + name = ele.simpleName, + content = processElement(ele, target.foci), +) private fun OpticsProcessorOptions.processElement(adt: ADT, foci: List): String { val sourceClassNameWithParams = "${adt.sourceClassName}${adt.angledTypeParameters}" diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/prism.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/prism.kt index 266f0ad8044..204aa5180ae 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/prism.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/prism.kt @@ -2,29 +2,26 @@ package arrow.optics.plugin.internals import arrow.optics.plugin.OpticsProcessorOptions -internal fun OpticsProcessorOptions.generatePrisms(ele: ADT, target: PrismTarget) = - Snippet( - `package` = ele.packageName, - name = ele.simpleName, - imports = - setOf("import arrow.core.left", "import arrow.core.right", "import arrow.core.identity"), - content = processElement(ele, target.foci), - ) +internal fun OpticsProcessorOptions.generatePrisms(ele: ADT, target: PrismTarget) = Snippet( + `package` = ele.packageName, + name = ele.simpleName, + imports = + setOf("import arrow.core.left", "import arrow.core.right", "import arrow.core.identity"), + content = processElement(ele, target.foci), +) -private fun OpticsProcessorOptions.processElement(ele: ADT, foci: List): String { - return foci.joinToString(separator = "\n\n") { focus -> - val sourceClassNameWithParams = - focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}" - val angledTypeParameters = when { - focus.refinedArguments.isEmpty() -> "" - else -> focus.refinedArguments.joinToString(prefix = "<", separator = ",", postfix = ">") - } - val firstLine = when { - ele.typeParameters.isEmpty() -> - "${ele.visibilityModifierName} $inlineText val ${ele.sourceClassName}.Companion.${focus.escapedParamName}: $Prism<${ele.sourceClassName}, ${focus.classNameWithParameters}> $inlineText get()" - else -> - "${ele.visibilityModifierName} $inlineText fun $angledTypeParameters ${ele.sourceClassName}.Companion.${focus.escapedParamName}(): $Prism<$sourceClassNameWithParams, ${focus.classNameWithParameters}>" - } - "$firstLine = $Prism.instanceOf()" +private fun OpticsProcessorOptions.processElement(ele: ADT, foci: List): String = foci.joinToString(separator = "\n\n") { focus -> + val sourceClassNameWithParams = + focus.refinedType?.qualifiedString() ?: "${ele.sourceClassName}${ele.angledTypeParameters}" + val angledTypeParameters = when { + focus.refinedArguments.isEmpty() -> "" + else -> focus.refinedArguments.joinToString(prefix = "<", separator = ",", postfix = ">") } + val firstLine = when { + ele.typeParameters.isEmpty() -> + "${ele.visibilityModifierName} $inlineText val ${ele.sourceClassName}.Companion.${focus.escapedParamName}: $Prism<${ele.sourceClassName}, ${focus.classNameWithParameters}> $inlineText get()" + else -> + "${ele.visibilityModifierName} $inlineText fun $angledTypeParameters ${ele.sourceClassName}.Companion.${focus.escapedParamName}(): $Prism<$sourceClassNameWithParams, ${focus.classNameWithParameters}>" + } + "$firstLine = $Prism.instanceOf()" } diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/processor.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/processor.kt index fedbc9d37fb..8cbc696473e 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/processor.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/processor.kt @@ -16,77 +16,73 @@ import com.google.devtools.ksp.symbol.Variance.INVARIANT import com.google.devtools.ksp.symbol.Variance.STAR import java.util.Locale -internal fun adt(c: KSClassDeclaration, logger: KSPLogger): ADT = - ADT( - c.packageName, - c, - c.targets().map { target -> - when (target) { - OpticsTarget.LENS -> - evalAnnotatedDataClass(c, c.qualifiedNameOrSimpleName.lensErrorMessage, logger) - .orEmpty() - .let(::LensTarget) - - OpticsTarget.ISO -> - evalAnnotatedValueClass(c, c.qualifiedNameOrSimpleName.isoErrorMessage, logger) - .let(::IsoTarget) - - OpticsTarget.PRISM -> - evalAnnotatedPrismElement(c, c.qualifiedNameOrSimpleName.prismErrorMessage, logger) - .let(::PrismTarget) - - OpticsTarget.DSL -> evalAnnotatedDslElement(c, logger) - } - }, - ) - -internal fun KSClassDeclaration.targets(): Set = - targetsFromOpticsAnnotation().let { targets -> - when { - isSealed -> targets intersect SEALED_TARGETS - isValue -> targets intersect VALUE_TARGETS - else -> targets intersect OTHER_TARGETS +internal fun adt(c: KSClassDeclaration, logger: KSPLogger): ADT = ADT( + c.packageName, + c, + c.targets().map { target -> + when (target) { + OpticsTarget.LENS -> + evalAnnotatedDataClass(c, c.qualifiedNameOrSimpleName.lensErrorMessage, logger) + .orEmpty() + .let(::LensTarget) + + OpticsTarget.ISO -> + evalAnnotatedValueClass(c, c.qualifiedNameOrSimpleName.isoErrorMessage, logger) + .let(::IsoTarget) + + OpticsTarget.PRISM -> + evalAnnotatedPrismElement(c, c.qualifiedNameOrSimpleName.prismErrorMessage, logger) + .let(::PrismTarget) + + OpticsTarget.DSL -> evalAnnotatedDslElement(c, logger) } + }, +) + +internal fun KSClassDeclaration.targets(): Set = targetsFromOpticsAnnotation().let { targets -> + when { + isSealed -> targets intersect SEALED_TARGETS + isValue -> targets intersect VALUE_TARGETS + else -> targets intersect OTHER_TARGETS } +} -internal fun KSClassDeclaration.targetsFromOpticsAnnotation(): Set = - annotations - .single { it.annotationType.resolve().declaration.qualifiedName?.asString() == "arrow.optics.optics" } - .arguments - .flatMap { (it.value as? ArrayList<*>).orEmpty().mapNotNull { it as? KSType } } - .mapNotNull { - when (it.qualifiedString()) { - "arrow.optics.OpticsTarget.ISO" -> OpticsTarget.ISO - "arrow.optics.OpticsTarget.LENS" -> OpticsTarget.LENS - "arrow.optics.OpticsTarget.PRISM" -> OpticsTarget.PRISM - "arrow.optics.OpticsTarget.DSL" -> OpticsTarget.DSL - else -> null - } - }.ifEmpty { ALL_TARGETS }.toSet() +internal fun KSClassDeclaration.targetsFromOpticsAnnotation(): Set = annotations + .single { it.annotationType.resolve().declaration.qualifiedName?.asString() == "arrow.optics.optics" } + .arguments + .flatMap { (it.value as? ArrayList<*>).orEmpty().mapNotNull { it as? KSType } } + .mapNotNull { + when (it.qualifiedString()) { + "arrow.optics.OpticsTarget.ISO" -> OpticsTarget.ISO + "arrow.optics.OpticsTarget.LENS" -> OpticsTarget.LENS + "arrow.optics.OpticsTarget.PRISM" -> OpticsTarget.PRISM + "arrow.optics.OpticsTarget.DSL" -> OpticsTarget.DSL + else -> null + } + }.ifEmpty { ALL_TARGETS }.toSet() internal fun evalAnnotatedPrismElement( element: KSClassDeclaration, errorMessage: String, logger: KSPLogger, -): List = - when { - element.isSealed -> { - val sealedSubclasses = element.getSealedSubclasses().toList() - sealedSubclasses.map { subclass -> - Focus( - subclass.qualifiedNameOrSimpleName, - subclass.simpleName.asString().replaceFirstChar { c -> c.lowercase(Locale.getDefault()) }, - subclass.superTypes.first().resolve(), - onlyOneSealedSubclass = sealedSubclasses.size == 1, - classNameWithParameters = subclass.qualifiedNameOrSimpleNameWithTypeParameters, - ) - } - } - else -> { - logger.error(errorMessage, element) - emptyList() +): List = when { + element.isSealed -> { + val sealedSubclasses = element.getSealedSubclasses().toList() + sealedSubclasses.map { subclass -> + Focus( + subclass.qualifiedNameOrSimpleName, + subclass.simpleName.asString().replaceFirstChar { c -> c.lowercase(Locale.getDefault()) }, + subclass.superTypes.first().resolve(), + onlyOneSealedSubclass = sealedSubclasses.size == 1, + classNameWithParameters = subclass.qualifiedNameOrSimpleNameWithTypeParameters, + ) } } + else -> { + logger.error(errorMessage, element) + emptyList() + } +} internal val KSDeclaration.qualifiedNameOrSimpleName: String get() = (qualifiedName ?: simpleName).asSanitizedString() @@ -162,48 +158,44 @@ internal fun evalAnnotatedDataClass( } } -fun KSPropertyDeclaration.sameInChildren(subclasses: Sequence): Boolean = - subclasses.all { subclass -> - val property = subclass.getAllProperties().singleOrNull { it.simpleName == this.simpleName } - when (property) { - null -> false - else -> property.type.resolve() == this.type.resolve() - } +fun KSPropertyDeclaration.sameInChildren(subclasses: Sequence): Boolean = subclasses.all { subclass -> + val property = subclass.getAllProperties().singleOrNull { it.simpleName == this.simpleName } + when (property) { + null -> false + else -> property.type.resolve() == this.type.resolve() } +} internal fun evalAnnotatedValueClass( element: KSClassDeclaration, errorMessage: String, logger: KSPLogger, -): List = - when { - element.isValue -> - listOf(Focus(element.getConstructorTypesNames().first(), element.getConstructorParamNames().first())) - else -> { - logger.error(errorMessage, element) - emptyList() - } +): List = when { + element.isValue -> + listOf(Focus(element.getConstructorTypesNames().first(), element.getConstructorParamNames().first())) + else -> { + logger.error(errorMessage, element) + emptyList() } +} -internal fun evalAnnotatedDslElement(element: KSClassDeclaration, logger: KSPLogger): Target = - when { - element.isDataClass -> - DataClassDsl( - element - .getConstructorTypesNames() - .zip(element.getConstructorParamNames(), Focus.Companion::invoke), - ) - element.isValue -> - ValueClassDsl( - Focus(element.getConstructorTypesNames().first(), element.getConstructorParamNames().first()), - ) - element.isSealed -> - SealedClassDsl(evalAnnotatedPrismElement(element, element.qualifiedNameOrSimpleName.prismErrorMessage, logger)) - else -> throw IllegalStateException("should only be sealed, data, or value by now") - } +internal fun evalAnnotatedDslElement(element: KSClassDeclaration, logger: KSPLogger): Target = when { + element.isDataClass -> + DataClassDsl( + element + .getConstructorTypesNames() + .zip(element.getConstructorParamNames(), Focus.Companion::invoke), + ) + element.isValue -> + ValueClassDsl( + Focus(element.getConstructorTypesNames().first(), element.getConstructorParamNames().first()), + ) + element.isSealed -> + SealedClassDsl(evalAnnotatedPrismElement(element, element.qualifiedNameOrSimpleName.prismErrorMessage, logger)) + else -> throw IllegalStateException("should only be sealed, data, or value by now") +} -internal fun KSClassDeclaration.getConstructorTypesNames(): List = - primaryConstructor?.parameters?.map { it.type.resolve().qualifiedString() }.orEmpty() +internal fun KSClassDeclaration.getConstructorTypesNames(): List = primaryConstructor?.parameters?.map { it.type.resolve().qualifiedString() }.orEmpty() internal fun KSType.qualifiedString(prefix: String = ""): String = when (declaration) { is KSTypeParameter -> { @@ -231,5 +223,4 @@ internal fun KSTypeArgument.qualifiedString(): String = when (val ty = type?.res } } -internal fun KSClassDeclaration.getConstructorParamNames(): List = - primaryConstructor?.parameters?.mapNotNull { it.name?.asString() }.orEmpty() +internal fun KSClassDeclaration.getConstructorParamNames(): List = primaryConstructor?.parameters?.mapNotNull { it.name?.asString() }.orEmpty() diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/snippets.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/snippets.kt index 78efa4f46d0..3b0de3302b3 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/snippets.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/snippets.kt @@ -2,17 +2,16 @@ package arrow.optics.plugin.internals import arrow.optics.plugin.OpticsProcessorOptions -internal fun ADT.snippets(options: OpticsProcessorOptions): List = - targets.map { - when (it) { - is IsoTarget -> options.generateIsos(this, it) - is PrismTarget -> options.generatePrisms(this, it) - is LensTarget -> options.generateLenses(this, it) - is SealedClassDsl -> options.generatePrismDsl(this, it) - is DataClassDsl -> options.generateLensDsl(this, it) - is ValueClassDsl -> options.generateIsoDsl(this, it) - } +internal fun ADT.snippets(options: OpticsProcessorOptions): List = targets.map { + when (it) { + is IsoTarget -> options.generateIsos(this, it) + is PrismTarget -> options.generatePrisms(this, it) + is LensTarget -> options.generateLenses(this, it) + is SealedClassDsl -> options.generatePrismDsl(this, it) + is DataClassDsl -> options.generateLensDsl(this, it) + is ValueClassDsl -> options.generateIsoDsl(this, it) } +} internal fun List.join() = reduce { acc, snippet -> acc.copy(imports = acc.imports + snippet.imports, content = "${acc.content}\n${snippet.content}") diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/utils.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/utils.kt index 772c9f32b51..7bdd3d07bab 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/utils.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/internals/utils.kt @@ -6,20 +6,17 @@ import com.google.devtools.ksp.symbol.KSName * From Eugenio's https://github.com/Takhion/kotlin-metadata If this [isNotBlank] then it adds the * optional [prefix] and [postfix]. */ -fun String.plusIfNotBlank(prefix: String = "", postfix: String = "") = - if (isNotBlank()) "$prefix${this}$postfix" else this +fun String.plusIfNotBlank(prefix: String = "", postfix: String = "") = if (isNotBlank()) "$prefix${this}$postfix" else this /** * Sanitizes each delimited section if it matches with Kotlin reserved keywords. */ -fun KSName.asSanitizedString(delimiter: String = ".", prefix: String = "") = - asString().sanitize(delimiter, prefix) +fun KSName.asSanitizedString(delimiter: String = ".", prefix: String = "") = asString().sanitize(delimiter, prefix) /** * Sanitizes each delimited section if it matches with Kotlin reserved keywords. */ -fun String.sanitize(delimiter: String = ".", prefix: String = "") = - splitToSequence(delimiter).joinToString(delimiter, prefix) { if (it in KOTLIN_KEYWORDS) "`$it`" else it } +fun String.sanitize(delimiter: String = ".", prefix: String = "") = splitToSequence(delimiter).joinToString(delimiter, prefix) { if (it in KOTLIN_KEYWORDS) "`$it`" else it } private val KOTLIN_KEYWORDS = setOf( // Hard keywords diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/test/kotlin/arrow/optics/plugin/Compilation.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/test/kotlin/arrow/optics/plugin/Compilation.kt index 5687ec0ece8..351377a7536 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/test/kotlin/arrow/optics/plugin/Compilation.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/test/kotlin/arrow/optics/plugin/Compilation.kt @@ -108,20 +108,19 @@ private fun dependenciesMatch(classpath: File, dependency: String): Boolean { return testdep == dependencyName } -private fun sanitizeClassPathFileName(dep: String): String = - buildList { - var skip = false - add(dep.first()) - dep.reduce { a, b -> - if (a == '-' && b.isDigit()) skip = true - if (!skip) add(b) - b - } - if (skip) removeLast() +private fun sanitizeClassPathFileName(dep: String): String = buildList { + var skip = false + add(dep.first()) + dep.reduce { a, b -> + if (a == '-' && b.isDigit()) skip = true + if (!skip) add(b) + b } - .joinToString("") - .replace("-jvm.jar", "") - .replace("-jvm", "") + if (skip) removeLast() +} + .joinToString("") + .replace("-jvm.jar", "") + .replace("-jvm", "") private val KotlinCompilation.kspGeneratedSourceFiles: List get() = @@ -140,11 +139,10 @@ private fun eval(expression: String, classesDirectory: File): Any? { return field.get(Object()) } -private fun getFullClassName(classesDirectory: File, className: String): String = - Files.walk(Paths.get(classesDirectory.toURI())) - .filter { it.toFile().name == "$className.class" } - .toArray()[0] - .toString() - .removePrefix(classesDirectory.absolutePath + File.separator) - .removeSuffix(".class") - .replace(File.separator, ".") +private fun getFullClassName(classesDirectory: File, className: String): String = Files.walk(Paths.get(classesDirectory.toURI())) + .filter { it.toFile().name == "$className.class" } + .toArray()[0] + .toString() + .removePrefix(classesDirectory.absolutePath + File.separator) + .removeSuffix(".class") + .replace(File.separator, ".") diff --git a/arrow-libs/optics/arrow-optics-reflect/src/main/kotlin/arrow/optics/Reflection.kt b/arrow-libs/optics/arrow-optics-reflect/src/main/kotlin/arrow/optics/Reflection.kt index dffe8763eab..c1af83304b6 100644 --- a/arrow-libs/optics/arrow-optics-reflect/src/main/kotlin/arrow/optics/Reflection.kt +++ b/arrow-libs/optics/arrow-optics-reflect/src/main/kotlin/arrow/optics/Reflection.kt @@ -12,20 +12,16 @@ import kotlin.reflect.full.memberFunctions import kotlin.reflect.safeCast /** Focuses on those elements of the specified [klass] */ -public fun instance(klass: KClass): Prism = - object : Prism { - override fun getOrModify(source: S): Either = - klass.safeCast(source)?.right() ?: source.left() - override fun reverseGet(focus: A): S = focus - } +public fun instance(klass: KClass): Prism = object : Prism { + override fun getOrModify(source: S): Either = klass.safeCast(source)?.right() ?: source.left() + override fun reverseGet(focus: A): S = focus +} /** Focuses on those elements of the specified class */ -public inline fun instance(): Prism = - object : Prism { - override fun getOrModify(source: S): Either = - (source as? A)?.right() ?: source.left() - override fun reverseGet(focus: A): S = focus - } +public inline fun instance(): Prism = object : Prism { + override fun getOrModify(source: S): Either = (source as? A)?.right() ?: source.left() + override fun reverseGet(focus: A): S = focus +} /** * [Lens] that focuses on a field in a data class diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a6fc3d52656..cdf7a8cc025 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ kotlinxSerialization = "1.8.0" mockWebServer = "4.12.0" retrofit = "2.11.0" moshi = "1.15.2" -spotlessVersion = "6.25.0" +spotlessVersion = "7.0.0" compose = "1.7.6" composePlugin = "1.8.0+check" agp = "8.8.0"