From 84619ea31751eb5921a0c504187e3c5d68fb044f Mon Sep 17 00:00:00 2001 From: Teodor Grigor Date: Thu, 15 Feb 2024 18:41:26 +0200 Subject: [PATCH] Enhanced Operation Generation Filtering based on Level --- .../stitch/core/database/dao/SavedGameDao.kt | 2 + codegen/api/codegen.api | 30 ++++------ codegen/build.gradle.kts | 1 + .../teogor/stitch/codegen/CodeGenerator.kt | 2 +- .../stitch/codegen/model/CodeGenConfig.kt | 5 +- .../teogor/stitch/codegen/model/DaoData.kt | 3 +- .../servicelocator/ServiceLocatorAccessor.kt | 2 +- .../codegen/writers/OperationOutputWriter.kt | 15 ++++- common/api/common.api | 4 ++ .../kotlin/dev/teogor/stitch/RawOperation.kt | 38 ++++++++++++ gradle-plugin-api/api/gradle-plugin-api.api | 20 ++++++- .../stitch/api/OperationGenerationLevel.kt | 58 +++++++++++++++++++ .../dev/teogor/stitch/api/StitchExtension.kt | 55 ++++++++++++++---- gradle-plugin/api/gradle-plugin.api | 8 ++- .../dev/teogor/stitch/StitchExtensionImpl.kt | 23 +++++++- .../teogor/stitch/StitchSchemaArgProvider.kt | 10 +++- ksp/build.gradle.kts | 2 +- .../stitch/ksp/processors/ConfigParser.kt | 17 +++++- .../teogor/stitch/ksp/processors/Processor.kt | 5 ++ 19 files changed, 252 insertions(+), 48 deletions(-) create mode 100644 common/src/main/kotlin/dev/teogor/stitch/RawOperation.kt create mode 100644 gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/OperationGenerationLevel.kt diff --git a/app/src/main/kotlin/dev/teogor/stitch/core/database/dao/SavedGameDao.kt b/app/src/main/kotlin/dev/teogor/stitch/core/database/dao/SavedGameDao.kt index 4a02cfe..4cbfb9f 100644 --- a/app/src/main/kotlin/dev/teogor/stitch/core/database/dao/SavedGameDao.kt +++ b/app/src/main/kotlin/dev/teogor/stitch/core/database/dao/SavedGameDao.kt @@ -22,11 +22,13 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update +import dev.teogor.stitch.RawOperation import dev.teogor.stitch.core.database.model.SavedGame import kotlinx.coroutines.flow.Flow @Dao interface SavedGameDao { + @RawOperation @Query("SELECT * FROM saved_games") fun getAll(): Flow> diff --git a/codegen/api/codegen.api b/codegen/api/codegen.api index 813b74a..719db1a 100644 --- a/codegen/api/codegen.api +++ b/codegen/api/codegen.api @@ -60,16 +60,18 @@ public final class dev/teogor/stitch/codegen/facades/Logger$Companion { } public final class dev/teogor/stitch/codegen/model/CodeGenConfig { - public fun (ZZLjava/lang/String;)V + public fun (ZZLjava/lang/String;Ldev/teogor/stitch/api/OperationGenerationLevel;)V public final fun component1 ()Z public final fun component2 ()Z public final fun component3 ()Ljava/lang/String; - public final fun copy (ZZLjava/lang/String;)Ldev/teogor/stitch/codegen/model/CodeGenConfig; - public static synthetic fun copy$default (Ldev/teogor/stitch/codegen/model/CodeGenConfig;ZZLjava/lang/String;ILjava/lang/Object;)Ldev/teogor/stitch/codegen/model/CodeGenConfig; + public final fun component4 ()Ldev/teogor/stitch/api/OperationGenerationLevel; + public final fun copy (ZZLjava/lang/String;Ldev/teogor/stitch/api/OperationGenerationLevel;)Ldev/teogor/stitch/codegen/model/CodeGenConfig; + public static synthetic fun copy$default (Ldev/teogor/stitch/codegen/model/CodeGenConfig;ZZLjava/lang/String;Ldev/teogor/stitch/api/OperationGenerationLevel;ILjava/lang/Object;)Ldev/teogor/stitch/codegen/model/CodeGenConfig; public fun equals (Ljava/lang/Object;)Z public final fun getAddDocumentation ()Z - public final fun getGenerateOperations ()Z + public final fun getEnableOperationGeneration ()Z public final fun getGeneratedPackageName ()Ljava/lang/String; + public final fun getOperationGenerationLevel ()Ldev/teogor/stitch/api/OperationGenerationLevel; public fun hashCode ()I public fun toString ()Ljava/lang/String; } @@ -102,26 +104,18 @@ public final class dev/teogor/stitch/codegen/model/FieldKind { public fun toString ()Ljava/lang/String; } -public final class dev/teogor/stitch/codegen/model/FunctionData { - public fun (Ljava/lang/String;)V - public final fun component1 ()Ljava/lang/String; - public final fun copy (Ljava/lang/String;)Ldev/teogor/stitch/codegen/model/FunctionData; - public static synthetic fun copy$default (Ldev/teogor/stitch/codegen/model/FunctionData;Ljava/lang/String;ILjava/lang/Object;)Ldev/teogor/stitch/codegen/model/FunctionData; - public fun equals (Ljava/lang/Object;)Z - public final fun getName ()Ljava/lang/String; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - public final class dev/teogor/stitch/codegen/model/FunctionKind { - public fun (Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;)V + public fun (Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;Z)V + public synthetic fun (Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Z public final fun component3 ()Lcom/squareup/kotlinpoet/TypeName; public final fun component4 ()Ljava/util/List; - public final fun copy (Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;)Ldev/teogor/stitch/codegen/model/FunctionKind; - public static synthetic fun copy$default (Ldev/teogor/stitch/codegen/model/FunctionKind;Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;ILjava/lang/Object;)Ldev/teogor/stitch/codegen/model/FunctionKind; + public final fun component5 ()Z + public final fun copy (Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;Z)Ldev/teogor/stitch/codegen/model/FunctionKind; + public static synthetic fun copy$default (Ldev/teogor/stitch/codegen/model/FunctionKind;Ljava/lang/String;ZLcom/squareup/kotlinpoet/TypeName;Ljava/util/List;ZILjava/lang/Object;)Ldev/teogor/stitch/codegen/model/FunctionKind; public fun equals (Ljava/lang/Object;)Z + public final fun getEnableRawOperationGeneration ()Z public final fun getName ()Ljava/lang/String; public final fun getParameters ()Ljava/util/List; public final fun getReturnType ()Lcom/squareup/kotlinpoet/TypeName; diff --git a/codegen/build.gradle.kts b/codegen/build.gradle.kts index 14b2232..ba077c4 100644 --- a/codegen/build.gradle.kts +++ b/codegen/build.gradle.kts @@ -32,6 +32,7 @@ tasks.withType().configureEach dependencies { api(project(mapOf("path" to ":common"))) + api(project(mapOf("path" to ":gradle-plugin-api"))) api(libs.kotlin.poet) api(libs.kotlin.poet.ksp) diff --git a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/CodeGenerator.kt b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/CodeGenerator.kt index fcec6e5..9fbf82a 100644 --- a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/CodeGenerator.kt +++ b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/CodeGenerator.kt @@ -44,7 +44,7 @@ class CodeGenerator( stitchModuleOutputWriter.write(databaseModels, roomModels) - if (codeGenConfig.generateOperations) { + if (codeGenConfig.enableOperationGeneration) { operationOutputWriter.write(databaseModels, roomModels) } } diff --git a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/CodeGenConfig.kt b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/CodeGenConfig.kt index 6e4d90d..2d7894f 100644 --- a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/CodeGenConfig.kt +++ b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/CodeGenConfig.kt @@ -16,8 +16,11 @@ package dev.teogor.stitch.codegen.model +import dev.teogor.stitch.api.OperationGenerationLevel + data class CodeGenConfig( val addDocumentation: Boolean, - val generateOperations: Boolean, + val enableOperationGeneration: Boolean, val generatedPackageName: String?, + val operationGenerationLevel: OperationGenerationLevel, ) diff --git a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/DaoData.kt b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/DaoData.kt index 1436989..dd0e2d3 100644 --- a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/DaoData.kt +++ b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/model/DaoData.kt @@ -18,8 +18,6 @@ package dev.teogor.stitch.codegen.model import com.squareup.kotlinpoet.TypeName -data class FunctionData(val name: String) - data class DatabaseModel( val entities: List, val type: TypeName, @@ -45,6 +43,7 @@ data class FunctionKind( val isSuspend: Boolean, val returnType: TypeName, val parameters: List, + val enableRawOperationGeneration: Boolean = false, ) data class ParameterKind( diff --git a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/servicelocator/ServiceLocatorAccessor.kt b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/servicelocator/ServiceLocatorAccessor.kt index 9079465..fbc1f2f 100644 --- a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/servicelocator/ServiceLocatorAccessor.kt +++ b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/servicelocator/ServiceLocatorAccessor.kt @@ -33,7 +33,7 @@ internal interface ServiceLocatorAccessor { } abstract class OutputWriter( - private val codeGenConfig: CodeGenConfig, + internal val codeGenConfig: CodeGenConfig, ) { fun RoomModel.getPackageName() = codeGenConfig.generatedPackageName ?: packageName diff --git a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/writers/OperationOutputWriter.kt b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/writers/OperationOutputWriter.kt index 6f98c69..f520ed0 100644 --- a/codegen/src/main/kotlin/dev/teogor/stitch/codegen/writers/OperationOutputWriter.kt +++ b/codegen/src/main/kotlin/dev/teogor/stitch/codegen/writers/OperationOutputWriter.kt @@ -24,6 +24,7 @@ import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.UNIT import dev.teogor.stitch.Operation import dev.teogor.stitch.OperationSignature +import dev.teogor.stitch.api.OperationGenerationLevel import dev.teogor.stitch.codegen.commons.JAVAX_INJECT import dev.teogor.stitch.codegen.commons.fileBuilder import dev.teogor.stitch.codegen.commons.titleCase @@ -46,7 +47,19 @@ class OperationOutputWriter( roomModels.forEach { room -> val generatedClasses = mutableMapOf>() - room.functions.forEach { function -> + val filteredFunctions = when (codeGenConfig.operationGenerationLevel) { + OperationGenerationLevel.ALL -> room.functions + OperationGenerationLevel.EXPLICIT -> room.functions.filter { + it.enableRawOperationGeneration + } + + OperationGenerationLevel.AUTOMATIC -> room.functions.filter { + it.enableRawOperationGeneration + } + + OperationGenerationLevel.DISABLED -> emptyList() + } + filteredFunctions.forEach { function -> val existingFunctions = generatedClasses.getOrDefault( function.name, mutableListOf(), diff --git a/common/api/common.api b/common/api/common.api index 5222078..9c689a2 100644 --- a/common/api/common.api +++ b/common/api/common.api @@ -7,3 +7,7 @@ public abstract interface annotation class dev/teogor/stitch/Operation : java/la public abstract interface annotation class dev/teogor/stitch/OperationSignature : java/lang/annotation/Annotation { } +public abstract interface annotation class dev/teogor/stitch/RawOperation : java/lang/annotation/Annotation { + public abstract fun generate ()Z +} + diff --git a/common/src/main/kotlin/dev/teogor/stitch/RawOperation.kt b/common/src/main/kotlin/dev/teogor/stitch/RawOperation.kt new file mode 100644 index 0000000..363c44c --- /dev/null +++ b/common/src/main/kotlin/dev/teogor/stitch/RawOperation.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2024 teogor (Teodor Grigor) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.teogor.stitch + +/** + * An annotation for marking DAO methods that should be generated as raw + * operations. + * + * This annotation instructs the Stitch plugin to generate separate operation + * classes for annotated methods in your DAOs. These operation classes provide + * a convenient way to invoke and manage the corresponding database queries + * directly. + * + * @param generate [Boolean] (default: `true`) Whether to generate the operation + * class for this method. + * + * @see Operation + * @see OperationSignature + */ +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.BINARY) +annotation class RawOperation( + val generate: Boolean = true, +) diff --git a/gradle-plugin-api/api/gradle-plugin-api.api b/gradle-plugin-api/api/gradle-plugin-api.api index 254937a..900b657 100644 --- a/gradle-plugin-api/api/gradle-plugin-api.api +++ b/gradle-plugin-api/api/gradle-plugin-api.api @@ -1,9 +1,25 @@ +public final class dev/teogor/stitch/api/OperationGenerationLevel : java/lang/Enum { + public static final field ALL Ldev/teogor/stitch/api/OperationGenerationLevel; + public static final field AUTOMATIC Ldev/teogor/stitch/api/OperationGenerationLevel; + public static final field Companion Ldev/teogor/stitch/api/OperationGenerationLevel$Companion; + public static final field DISABLED Ldev/teogor/stitch/api/OperationGenerationLevel; + public static final field EXPLICIT Ldev/teogor/stitch/api/OperationGenerationLevel; + public static fun valueOf (Ljava/lang/String;)Ldev/teogor/stitch/api/OperationGenerationLevel; + public static fun values ()[Ldev/teogor/stitch/api/OperationGenerationLevel; +} + +public final class dev/teogor/stitch/api/OperationGenerationLevel$Companion { + public final fun from (Ljava/lang/String;)Ldev/teogor/stitch/api/OperationGenerationLevel; +} + public abstract interface class dev/teogor/stitch/api/StitchExtension { public abstract fun getAddDocumentation ()Z - public abstract fun getGenerateOperations ()Z + public abstract fun getEnableOperationGeneration ()Z public abstract fun getGeneratedPackageName ()Ljava/lang/String; + public abstract fun getOperationGenerationLevel ()Ldev/teogor/stitch/api/OperationGenerationLevel; public abstract fun setAddDocumentation (Z)V - public abstract fun setGenerateOperations (Z)V + public abstract fun setEnableOperationGeneration (Z)V public abstract fun setGeneratedPackageName (Ljava/lang/String;)V + public abstract fun setOperationGenerationLevel (Ldev/teogor/stitch/api/OperationGenerationLevel;)V } diff --git a/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/OperationGenerationLevel.kt b/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/OperationGenerationLevel.kt new file mode 100644 index 0000000..5799d99 --- /dev/null +++ b/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/OperationGenerationLevel.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2024 teogor (Teodor Grigor) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.teogor.stitch.api + +/** + * Defines the level of generation for Stitch operation classes. + * + * This enum controls how the plugin generates operation classes from DAO + * methods. + * You can configure the desired level through plugin options or environment + * variables. + * + * @see dev.teogor.stitch.RawOperation + * + * @property ALL Generate operations for all methods in DAOs. + * @property EXPLICIT Generate operations only for methods annotated with + * [dev.teogor.stitch.RawOperation]. + * @property AUTOMATIC Automatically choose whether to generate based on heuristics + * or rules. + * @property DISABLED Do not generate any operation classes, even for annotated + * methods. + */ +enum class OperationGenerationLevel { + ALL, + EXPLICIT, + AUTOMATIC, + DISABLED, + ; + + companion object { + /** + * Converts a string representation to the corresponding [OperationGenerationLevel]. + * + * This function supports case-insensitive matching and throws an exception for invalid input. + * + * @param string The string to convert. + * @return The corresponding [OperationGenerationLevel] or throws an [IllegalArgumentException]. + */ + fun from(string: String): OperationGenerationLevel { + return values().firstOrNull { it.name.lowercase() == string.lowercase() } + ?: throw IllegalArgumentException("Invalid OperationGenerationLevel: $string") + } + } +} diff --git a/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/StitchExtension.kt b/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/StitchExtension.kt index ae67fb0..92071ea 100644 --- a/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/StitchExtension.kt +++ b/gradle-plugin-api/src/main/kotlin/dev/teogor/stitch/api/StitchExtension.kt @@ -17,33 +17,66 @@ package dev.teogor.stitch.api /** - * Interface for configuring Stitch's behavior and features. + * Defines configuration options for Stitch code generation within your project. * - * This interface allows you to: + * This interface provides properties that control various aspects of the generation + * process. You can extend this interface and implement it in your plugin to customize Stitch + * functionalities. * - * - Enable or disable documentation generation. - * - Control the generation of operations (plugins or similar functionality). - * - Set the base package name for generated code or artifacts. + * @see dev.teogor.stitch.Plugin */ interface StitchExtension { /** - * Enables or disables the generation of documentation. + * Controls whether to generate documentation comments in the generated code. * - * Set to `true` to generate documentation, `false` to disable it. + * By default, this is set to `true`. Setting it to `false` will disable documentation + * generation. + * + * @return `true` if documentation is generated, `false` otherwise. */ var addDocumentation: Boolean /** - * Enables or disables the generation of operations. + * Controls the overall generation of operation classes for DAO methods. + * + * Use this property to enable or disable operation generation entirely. + * By default, this is set to `true`. Setting it to `false` will disable operation generation + * even for methods annotated with [dev.teogor.stitch.RawOperation]. + * + * For more granular control over operation generation, consider using the + * [operationGenerationLevel] property. * - * Set to `true` to generate operations, `false` to disable it. + * @return `true` to enable operation generation, `false` to disable it. */ - var generateOperations: Boolean + var enableOperationGeneration: Boolean + + /** + * Defines the level of generation for Stitch operation classes. + * + * This property offers more fine-grained control over how operation classes are generated. + * You can choose from the following options: + * + * - **[OperationGenerationLevel.ALL]:** Generate operations for all methods in DAOs. + * - **[OperationGenerationLevel.EXPLICIT]:** Generate operations only for methods annotated + * with [dev.teogor.stitch.RawOperation]. + * - **[OperationGenerationLevel.AUTOMATIC]:** Use heuristics or rules to automatically choose + * whether to generate for each method. + * - **[OperationGenerationLevel.DISABLED]:** Do not generate any operation classes, even for + * annotated methods. + * + * By default, this is set to [OperationGenerationLevel.EXPLICIT]. + * + * @return The desired level of operation generation. + */ + var operationGenerationLevel: OperationGenerationLevel /** * Specifies the base package name for generated code or artifacts. * - * Ensure this matches your project's package structure. + * This property defines the root package where your Stitch-generated code will be placed. + * Ensure it aligns with your project's package structure to avoid conflicts. + * + * @return The base package name for generated code. */ var generatedPackageName: String } diff --git a/gradle-plugin/api/gradle-plugin.api b/gradle-plugin/api/gradle-plugin.api index 9088db6..e3e7890 100644 --- a/gradle-plugin/api/gradle-plugin.api +++ b/gradle-plugin/api/gradle-plugin.api @@ -18,16 +18,18 @@ public final class dev/teogor/stitch/Plugin$apply$1$1$inlined$sam$i$org_gradle_a public abstract class dev/teogor/stitch/StitchExtensionImpl : dev/teogor/stitch/api/StitchExtension { public fun ()V public fun getAddDocumentation ()Z - public fun getGenerateOperations ()Z + public fun getEnableOperationGeneration ()Z public fun getGeneratedPackageName ()Ljava/lang/String; + public fun getOperationGenerationLevel ()Ldev/teogor/stitch/api/OperationGenerationLevel; public fun setAddDocumentation (Z)V - public fun setGenerateOperations (Z)V + public fun setEnableOperationGeneration (Z)V public fun setGeneratedPackageName (Ljava/lang/String;)V + public fun setOperationGenerationLevel (Ldev/teogor/stitch/api/OperationGenerationLevel;)V } public final class dev/teogor/stitch/StitchSchemaArgProvider : org/gradle/process/CommandLineArgumentProvider { public static final field Companion Ldev/teogor/stitch/StitchSchemaArgProvider$Companion; - public fun (ZZLjava/lang/String;)V + public fun (ZZLjava/lang/String;Ldev/teogor/stitch/api/OperationGenerationLevel;)V public synthetic fun asArguments ()Ljava/lang/Iterable; public fun asArguments ()Ljava/util/List; } diff --git a/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchExtensionImpl.kt b/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchExtensionImpl.kt index af21daa..5f7c6a9 100644 --- a/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchExtensionImpl.kt +++ b/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchExtensionImpl.kt @@ -16,6 +16,7 @@ package dev.teogor.stitch +import dev.teogor.stitch.api.OperationGenerationLevel import dev.teogor.stitch.api.StitchExtension /** @@ -43,7 +44,27 @@ abstract class StitchExtensionImpl : StitchExtension { * * By default, this is set to `true`. */ - override var generateOperations: Boolean = true + override var enableOperationGeneration: Boolean = true + + /** + * Defines the level of generation for Stitch operation classes. + * + * This property offers more fine-grained control over how operation classes are generated. + * You can choose from the following options: + * + * - **[OperationGenerationLevel.ALL]:** Generate operations for all methods in DAOs. + * - **[OperationGenerationLevel.EXPLICIT]:** Generate operations only for methods annotated + * with [dev.teogor.stitch.RawOperation]. + * - **[OperationGenerationLevel.AUTOMATIC]:** Use heuristics or rules to automatically choose + * whether to generate for each method. + * - **[OperationGenerationLevel.DISABLED]:** Do not generate any operation classes, even for + * annotated methods. + * + * By default, this is set to [OperationGenerationLevel.EXPLICIT]. + * + * @return The desired level of operation generation. + */ + override var operationGenerationLevel: OperationGenerationLevel = OperationGenerationLevel.EXPLICIT /** * Specifies the base package name for generated code or artifacts. diff --git a/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchSchemaArgProvider.kt b/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchSchemaArgProvider.kt index 00150ad..a72c6db 100644 --- a/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchSchemaArgProvider.kt +++ b/gradle-plugin/src/main/kotlin/dev/teogor/stitch/StitchSchemaArgProvider.kt @@ -16,26 +16,30 @@ package dev.teogor.stitch +import dev.teogor.stitch.api.OperationGenerationLevel import dev.teogor.stitch.api.StitchExtension import org.gradle.process.CommandLineArgumentProvider class StitchSchemaArgProvider( private val addDocumentation: Boolean, - private val generateOperations: Boolean, + private val enableOperationGeneration: Boolean, private val generatedPackageName: String, + private val operationGenerationLevel: OperationGenerationLevel, ) : CommandLineArgumentProvider { override fun asArguments() = listOf( "stitch.addDocumentation=$addDocumentation", - "stitch.generateOperations=$generateOperations", + "stitch.enableOperationGeneration=$enableOperationGeneration", "stitch.generatedPackageName=$generatedPackageName", + "stitch.operationGenerationLevel=$operationGenerationLevel", ) companion object { fun from(stitchExtension: StitchExtension) = StitchSchemaArgProvider( addDocumentation = stitchExtension.addDocumentation, - generateOperations = stitchExtension.generateOperations, + enableOperationGeneration = stitchExtension.enableOperationGeneration, generatedPackageName = stitchExtension.generatedPackageName, + operationGenerationLevel = stitchExtension.operationGenerationLevel, ) } } diff --git a/ksp/build.gradle.kts b/ksp/build.gradle.kts index 9c51ffb..19cb35a 100644 --- a/ksp/build.gradle.kts +++ b/ksp/build.gradle.kts @@ -32,8 +32,8 @@ tasks.withType().configureEach } dependencies { - implementation(project(mapOf("path" to ":codegen"))) api(project(mapOf("path" to ":common"))) + implementation(project(mapOf("path" to ":codegen"))) implementation(libs.ksp.api) } diff --git a/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/ConfigParser.kt b/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/ConfigParser.kt index 7342c10..0915cee 100644 --- a/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/ConfigParser.kt +++ b/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/ConfigParser.kt @@ -18,6 +18,7 @@ package dev.teogor.stitch.ksp.processors +import dev.teogor.stitch.api.OperationGenerationLevel import dev.teogor.stitch.codegen.model.CodeGenConfig class ConfigParser( @@ -29,22 +30,32 @@ class ConfigParser( // Configs private const val ADD_DOCUMENTATION = "$PREFIX.addDocumentation" - private const val GENERATE_OPERATIONS = "$PREFIX.generateOperations" + private const val ENABLE_OPERATION_GENERATION = "$PREFIX.enableOperationGeneration" private const val GENERATED_PACKAGE_NAME = "$PREFIX.generatedPackageName" + private const val OPERATION_GENERATION_LEVEL = "$PREFIX.operationGenerationLevel" } fun parse(): CodeGenConfig { val addDocumentation = parseBoolean(ADD_DOCUMENTATION) ?: true - val generateOperations = parseBoolean(GENERATE_OPERATIONS) ?: true + val enableOperationGeneration = parseBoolean(ENABLE_OPERATION_GENERATION) ?: true val generatedPackageName = options[GENERATED_PACKAGE_NAME]?.trim()?.removeSuffix(".") + val operationGenerationLevel = getOperationGenerationLevel() return CodeGenConfig( addDocumentation = addDocumentation, - generateOperations = generateOperations, + enableOperationGeneration = enableOperationGeneration, generatedPackageName = generatedPackageName, + operationGenerationLevel = operationGenerationLevel, ) } + private fun getOperationGenerationLevel(): OperationGenerationLevel { + val stringValue = options[OPERATION_GENERATION_LEVEL]?.trim() + stringValue ?: return OperationGenerationLevel.EXPLICIT + + return OperationGenerationLevel.from(stringValue) + } + private fun parseBoolean(key: String): Boolean? { return options[key]?.runCatching { toBooleanStrict() diff --git a/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/Processor.kt b/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/Processor.kt index 89ecad8..4e4be03 100644 --- a/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/Processor.kt +++ b/ksp/src/main/kotlin/dev/teogor/stitch/ksp/processors/Processor.kt @@ -20,6 +20,7 @@ import androidx.room.Dao import androidx.room.Database import androidx.room.Entity import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType import com.google.devtools.ksp.getDeclaredFunctions import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver @@ -32,6 +33,7 @@ import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.UNIT import com.squareup.kotlinpoet.ksp.toClassName import com.squareup.kotlinpoet.ksp.toTypeName +import dev.teogor.stitch.RawOperation import dev.teogor.stitch.codegen.CodeGenerator import dev.teogor.stitch.codegen.commons.findCommonBase import dev.teogor.stitch.codegen.facades.Logger @@ -141,6 +143,8 @@ class Processor( ) } val functions = dao.getDeclaredFunctions().toList().map { function -> + val rawOperation = function.getAnnotationsByType(RawOperation::class) + .firstOrNull() val fieldName = function.simpleName.asString() val fieldType = function.returnType?.resolve().let { it?.toTypeName() ?: UNIT @@ -157,6 +161,7 @@ class Processor( returnType = fieldType, parameters = parameters, isSuspend = isSuspend, + enableRawOperationGeneration = rawOperation?.generate ?: false, ) } RoomModel(