From 2d69e9eb3e08b3c91b07e89a6280f22f56915818 Mon Sep 17 00:00:00 2001 From: serge shustoff Date: Sun, 5 Feb 2023 16:50:01 +0100 Subject: [PATCH] deprecate old annotations api --- .../commonMain/kotlin/dev/shustoff/dikt/Create.kt | 1 + .../kotlin/dev/shustoff/dikt/CreateSingle.kt | 1 + .../src/commonMain/kotlin/dev/shustoff/dikt/DI.kt | 3 +-- .../dev/shustoff/dikt/InjectByConstructors.kt | 15 +++++++++++++++ .../shustoff/dikt/InjectSingleByConstructors.kt | 15 +++++++++++++++ .../kotlin/dev/shustoff/dikt/ModuleSingletons.kt | 14 -------------- .../kotlin/dev/shustoff/dikt/Provide.kt | 3 ++- .../kotlin/dev/shustoff/dikt/UseConstructors.kt | 1 + .../dev/shustoff/dikt/core/DiOldApiTransformer.kt | 5 ++--- .../kotlin/dev/shustoff/dikt/utils/Annotations.kt | 8 ++++---- ...ructorsTest.kt => InjectByConstructorsTest.kt} | 14 +++++++------- 11 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectByConstructors.kt create mode 100644 dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectSingleByConstructors.kt delete mode 100644 dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/ModuleSingletons.kt rename dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/{UseConstructorsTest.kt => InjectByConstructorsTest.kt} (85%) diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Create.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Create.kt index a451506..e645740 100644 --- a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Create.kt +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Create.kt @@ -2,6 +2,7 @@ package dev.shustoff.dikt @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.SOURCE) +@Deprecated("Call resolve() function instead and add @InjectByConstructors annotation with list of types that can be created by constructor. This annotation will be deleted in version 1.1.1") /** * DI.kt plugin will generate body for function with this annotation using returned type's primary constructor. * Values for constructor parameters will be retrieved from function parameters and from functions and properties of containing class. diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/CreateSingle.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/CreateSingle.kt index 67dd5a5..c76ea56 100644 --- a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/CreateSingle.kt +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/CreateSingle.kt @@ -2,6 +2,7 @@ package dev.shustoff.dikt @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.SOURCE) +@Deprecated("Call resolve() function instead and add @InjectSingleByConstructors annotation with list of types that can be created by constructor and should be singletons inside given module. This annotation will be deleted in version 1.1.1") /** * Same as @Create, but tells compiler to create a lazy property in containing class and return value from that property. * diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/DI.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/DI.kt index fff9423..6d0ab39 100644 --- a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/DI.kt +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/DI.kt @@ -4,7 +4,6 @@ package dev.shustoff.dikt * DI.kt compiler plugin will generate expression instead of this function call. * Returned value is retrieved from available dependencies (parent class properties and functions, parameters of a function where it's called). * - * It's useful for elevating dependencies from nested modules. - * Generated code doesn't call constructor for returned type unless it's listed in @UseConstructors. + * Generated code doesn't call constructor for returned type unless it's listed in @InjectByConstructors or @InjectSingleByConstructors. */ fun resolve(): T = throw Exception("Incorrect use of DI.kt. Did you call this function outside of kotlin code?") \ No newline at end of file diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectByConstructors.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectByConstructors.kt new file mode 100644 index 0000000..e03bc36 --- /dev/null +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectByConstructors.kt @@ -0,0 +1,15 @@ +package dev.shustoff.dikt + +import kotlin.reflect.KClass + +@Target(AnnotationTarget.CLASS, AnnotationTarget.FILE, AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.SOURCE) +/** + * Tells compiler that dependencies of listed types should be created by constructor when needed. + * + * Primary constructor is called for creating dependencies of listed types. + * Di functions inside module will return the new instances for listed types on each call. + */ +annotation class InjectByConstructors( + vararg val types: KClass<*> +) \ No newline at end of file diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectSingleByConstructors.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectSingleByConstructors.kt new file mode 100644 index 0000000..a1e26f9 --- /dev/null +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/InjectSingleByConstructors.kt @@ -0,0 +1,15 @@ +package dev.shustoff.dikt + +import kotlin.reflect.KClass + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +/** + * Tells compiler to create a lazy properties initialized with constructor calls for listed types and use that property in di functions. + * + * Primary constructor is called for creating dependencies of listed types. + * Di functions inside module will return the same instances for listed types. + */ +annotation class InjectSingleByConstructors( + vararg val types: KClass<*> +) diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/ModuleSingletons.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/ModuleSingletons.kt deleted file mode 100644 index 06e1398..0000000 --- a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/ModuleSingletons.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.shustoff.dikt - -import kotlin.reflect.KClass - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -/** - * Tells compiler to create a lazy properties for listed types and use that property in di functions. - * - * Di functions inside module will return the same instances for listed types. - */ -annotation class ModuleSingletons( - vararg val types: KClass<*> -) diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Provide.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Provide.kt index 51da0a5..29c27fc 100644 --- a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Provide.kt +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/Provide.kt @@ -2,10 +2,11 @@ package dev.shustoff.dikt @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.SOURCE) +@Deprecated("Call resolve() function instead. This annotation will be deleted in version 1.1.1") /** * DI.kt compiler plugin will generate body for function with this annotation. Returned value is retrieved from available dependencies. * * It's useful for elevating dependencies from nested modules. - * Generated code doesn't call constructor for returned type unless it's listed in @UseConstructors. + * Generated code doesn't call constructor for returned type unless it's listed in @InjectByConstructors or @InjectSingleByConstructors. */ annotation class Provide diff --git a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/UseConstructors.kt b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/UseConstructors.kt index 1fe0f2a..09c1c2c 100644 --- a/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/UseConstructors.kt +++ b/dikt-annotations/src/commonMain/kotlin/dev/shustoff/dikt/UseConstructors.kt @@ -4,6 +4,7 @@ import kotlin.reflect.KClass @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.FILE) @Retention(AnnotationRetention.SOURCE) +@Deprecated("Use InjectByConstructors or InjectSingleByConstructors instead. This annotation will be deleted in version 1.1.1") /** * Dependencies of types listed in this annotation parameters will be provided by constructor when required in generated function body. * Annotation might be applied to file, class, or @Create, @Provide and @CreateSingle function. diff --git a/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/core/DiOldApiTransformer.kt b/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/core/DiOldApiTransformer.kt index eb783e1..c057f8e 100644 --- a/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/core/DiOldApiTransformer.kt +++ b/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/core/DiOldApiTransformer.kt @@ -23,14 +23,13 @@ class DiOldApiTransformer( private val pluginContext: IrPluginContext, ) : IrElementTransformerVoid(), ErrorCollector by errorCollector { private val resolveFunction = pluginContext.referenceFunctions(CallableId(DiNewApiCodeGenerator.diktPackage, Name.identifier(DiNewApiCodeGenerator.diFunctionName))).firstOrNull() - private val useConstructorAnnotationConstructor= pluginContext.referenceConstructors(ClassId(FqName("dev.shustoff.dikt"), Name.identifier("UseConstructors"))) + private val useConstructorAnnotationConstructor= pluginContext.referenceConstructors(ClassId(FqName("dev.shustoff.dikt"), Name.identifier("InjectByConstructors"))) .firstOrNull() - private val moduleSingletonsAnnotationConstructor= pluginContext.referenceConstructors(ClassId(FqName("dev.shustoff.dikt"), Name.identifier("ModuleSingletons"))) + private val moduleSingletonsAnnotationConstructor= pluginContext.referenceConstructors(ClassId(FqName("dev.shustoff.dikt"), Name.identifier("InjectSingleByConstructors"))) .firstOrNull() private val klassType = pluginContext.referenceClass(ClassId(FqName("kotlin.reflect"), Name.identifier("KClass"))) override fun visitFunction(declaration: IrFunction): IrStatement { - //TODO: add errors for null stuff val declarationIrBuilder = DeclarationIrBuilder(pluginContext, declaration.symbol) if (Annotations.isByDi(declaration)) { if ((declaration as? IrSimpleFunction)?.modality != Modality.FINAL) { diff --git a/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/utils/Annotations.kt b/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/utils/Annotations.kt index e68d3fe..77574e0 100644 --- a/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/utils/Annotations.kt +++ b/dikt-compiler-plugin/src/main/kotlin/dev/shustoff/dikt/utils/Annotations.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.getAnnotation import org.jetbrains.kotlin.ir.util.hasAnnotation import org.jetbrains.kotlin.ir.util.isAnnotation -import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.name.FqName object Annotations { @@ -17,8 +16,9 @@ object Annotations { private val CreateSingleAnnotation = FqName("dev.shustoff.dikt.CreateSingle") private val providedAnnotation = FqName("dev.shustoff.dikt.Provide") private val useModulesAnnotation = FqName("dev.shustoff.dikt.UseModules") - val useConstructorsAnnotation = FqName("dev.shustoff.dikt.UseConstructors") - private val moduleSingletonsAnnotation = FqName("dev.shustoff.dikt.ModuleSingletons") + private val injectByConstructorsAnnotation = FqName("dev.shustoff.dikt.InjectByConstructors") + private val oldUseConstructorsAnnotation = FqName("dev.shustoff.dikt.UseConstructors") + private val moduleSingletonsAnnotation = FqName("dev.shustoff.dikt.InjectSingleByConstructors") fun getUsedModules(descriptor: IrAnnotationContainer): List { val annotation = descriptor.getAnnotation(useModulesAnnotation) @@ -57,7 +57,7 @@ object Annotations { } fun getProvidedByConstructor(descriptor: IrAnnotationContainer): List { - return descriptor.annotations.filter { it.isAnnotation(useConstructorsAnnotation) } + return descriptor.annotations.filter { it.isAnnotation(injectByConstructorsAnnotation) || it.isAnnotation(oldUseConstructorsAnnotation) } .flatMap { annotation -> (annotation.getValueArgument(0) as? IrVararg) ?.elements diff --git a/dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/UseConstructorsTest.kt b/dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/InjectByConstructorsTest.kt similarity index 85% rename from dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/UseConstructorsTest.kt rename to dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/InjectByConstructorsTest.kt index dfa120b..c1810dc 100644 --- a/dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/UseConstructorsTest.kt +++ b/dikt-compiler-plugin/src/test/kotlin/dev/shustoff/dikt/compiler/InjectByConstructorsTest.kt @@ -9,7 +9,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder -class UseConstructorsTest { +class InjectByConstructorsTest { @Rule @JvmField @@ -24,13 +24,13 @@ class UseConstructorsTest { """ package dev.shustoff.dikt.compiler import dev.shustoff.dikt.Create - import dev.shustoff.dikt.UseConstructors + import dev.shustoff.dikt.InjectByConstructors class Dependency class Injectable(val dependency: Dependency) - @UseConstructors(Dependency::class) + @InjectByConstructors(Dependency::class) class MyModule { @Create fun injectable(): Injectable } @@ -49,7 +49,7 @@ class UseConstructorsTest { """ package dev.shustoff.dikt.compiler import dev.shustoff.dikt.Create - import dev.shustoff.dikt.UseConstructors + import dev.shustoff.dikt.InjectByConstructors class Dependency @@ -57,7 +57,7 @@ class UseConstructorsTest { class MyModule { - @UseConstructors(Dependency::class) + @InjectByConstructors(Dependency::class) @Create fun injectable(): Injectable } """ @@ -73,10 +73,10 @@ class UseConstructorsTest { SourceFile.kotlin( "MyModule.kt", """ - @file:UseConstructors(Dependency::class) + @file:InjectByConstructors(Dependency::class) package dev.shustoff.dikt.compiler import dev.shustoff.dikt.Create - import dev.shustoff.dikt.UseConstructors + import dev.shustoff.dikt.InjectByConstructors class Dependency