Skip to content

Commit

Permalink
deprecate old annotations api
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeshustoff committed Feb 5, 2023
1 parent b14e1c8 commit 2d69e9e
Show file tree
Hide file tree
Showing 11 changed files with 49 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <T> resolve(): T = throw Exception("Incorrect use of DI.kt. Did you call this function outside of kotlin code?")
Original file line number Diff line number Diff line change
@@ -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<*>
)
Original file line number Diff line number Diff line change
@@ -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<*>
)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ 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 {
private val createAnnotation = FqName("dev.shustoff.dikt.Create")
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<IrType> {
val annotation = descriptor.getAnnotation(useModulesAnnotation)
Expand Down Expand Up @@ -57,7 +57,7 @@ object Annotations {
}

fun getProvidedByConstructor(descriptor: IrAnnotationContainer): List<IrType> {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder

class UseConstructorsTest {
class InjectByConstructorsTest {

@Rule
@JvmField
Expand All @@ -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
}
Expand All @@ -49,15 +49,15 @@ 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)
class MyModule {
@UseConstructors(Dependency::class)
@InjectByConstructors(Dependency::class)
@Create fun injectable(): Injectable
}
"""
Expand All @@ -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
Expand Down

0 comments on commit 2d69e9e

Please sign in to comment.