Skip to content

Commit

Permalink
Change the annotation retention to BINARY to fix multimodules issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gregory Lureau authored and glureau committed Apr 22, 2022
1 parent 3e6c3aa commit d449148
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 24 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ plugins {

allprojects {
group = "deezer.kustomexport"
version = "0.5.0"
version = "0.6.0"

repositories {
mavenLocal()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.ksp.KotlinPoetKspPreview
import deezer.kustomexport.compiler.GenericsVisitor
import deezer.kustomexport.compiler.Logger
import deezer.kustomexport.compiler.js.FormatString
import deezer.kustomexport.compiler.js.TypeParameterDescriptor
import deezer.kustomexport.compiler.js.jsPackage
Expand All @@ -42,7 +41,7 @@ import deezer.kustomexport.compiler.js.toFormatString
class OriginTypeName(
private val originTypeName: TypeName,
private val concreteTypeParameters: List<TypeParameterDescriptor>,
val isKustomExportAnnotated: Boolean,
val isKustomExportAnnotated: Boolean,
private val typeArgs: List<OriginTypeName>,
) {
val concreteTypeName: TypeName by lazy { originTypeName.resolvedType(concreteTypeParameters) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,13 @@ fun parseClass(

val superTypes = classDeclaration.superTypes
.mapNotNull { superType ->
val typeName = superType.toTypeNamePatch(typeParamResolver)
// KSP 1.6.20-1.0.5 now returns kotlin.Any even if we're parsing an interface.
// That doesn't make sense for us, so we're just ignoring them
// https://github.com/google/ksp/issues/815#issuecomment-1105676539
val typeName = superType.toTypeNamePatch(typeParamResolver)
if (typeName == ANY) return@mapNotNull null
// End of trick


val isKustomExportAnnotated = superType.isKustomExportAnnotated()
val superTypeName = typeName.cached(concreteTypeParameters, isKustomExportAnnotated)

Expand Down Expand Up @@ -273,13 +272,6 @@ private fun KSFunctionDeclaration.toDescriptor(
val typeResolved = p.type.resolve()

val typeArgs = typeResolved.arguments.map {
// Just logging here
it.type?.let { t ->
t.resolve().declaration.annotations.forEach { a ->
val ksDeclaration = a.annotationType.resolve().declaration
}
}

it.toTypeName(typeParamResolver)
.cached(concreteTypeParameters, it.type?.isKustomExportAnnotated() ?: false)
}
Expand Down
5 changes: 3 additions & 2 deletions lib/src/commonMain/kotlin/deezer/kustomexport/KustomExport.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package deezer.kustomexport

import kotlin.reflect.KClass

@Retention(AnnotationRetention.SOURCE)
@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPEALIAS, AnnotationTarget.FUNCTION)
public annotation class KustomExport(
/**
Expand All @@ -36,13 +36,14 @@ public annotation class KustomExport(
val usedByKustomExportGeneric: Boolean = false
)

@Retention(AnnotationRetention.BINARY)
@Target(AnnotationTarget.FILE)
public annotation class KustomExportGenerics(
public val exportGenerics: Array<KustomGenerics> = []
)

@Retention(AnnotationRetention.BINARY)
@Target() // No target, only there for data container
@Retention(AnnotationRetention.RUNTIME) // TODO: to be reduced!
public annotation class KustomGenerics(
public val kClass: KClass<*>,
public val typeParameters: Array<KClass<*>>,
Expand Down
30 changes: 25 additions & 5 deletions samples/src/commonMain/kotlin/sample/_class/static/Statics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ package sample._class.static

import deezer.kustomexport.KustomExport
import deezer.kustomexport.KustomExportGenerics
//import sample.generics.GenericsImpl

fun createString() = "string from factory method"

Expand All @@ -34,10 +33,31 @@ object StaticFactory {
fun create(stuff: Long) = "string from factory object stuff=$stuff"
}

/* See generic


/**
* NOT SUPPORTED: Currently KustomExport cannot handle generics functions.
*
* When an annotation like `KustomGenerics(StaticGenericFactory::class, arrayOf(Long::class))` is found,
* it resolves the class type parameters with the given parameter (here [Long]), but the class doesn't need it.
* The generic functions can actually be used with multiple types so if we want to support it, we should handle
* multiple custom types for each method, generating as many functions as needed, on the wrappers.
* Also be able to split generics from the typed class and from the typed methods.
*
* ```kotlin
* class Foo<T : Any> {
* fun <T, V> bar(t: T, v: V) { // T from here is not the T from the class
* }
* }
* Foo<Int>().bar("a", "b") // Here "T" is a Int at the class level, and a String at the method level.
* ```
* So it can be tedious to provide a good solution for that (waiting for more adopters, not sure if we need
* this level of tooling right now...)
*/
/*
object StaticGenericFactory {
fun <T> create(): GenericsImpl<T> {
return GenericsImpl<T>()
}
fun <T> create(): GenericsImpl<T> {
return GenericsImpl<T>()
}
}
*/
23 changes: 22 additions & 1 deletion samples/src/commonMain/kotlin/sample/generics/Generics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,25 @@ class GenericsConsumer {
// (You should not use generics on TypeAlias.)
//@KustomExport
//typealias TypeAliasLong = TypeAliasInterface<Long>
// Unfortunately, typealias are not properly handled by KotlinJs rn
// Unfortunately, typealias are not properly handled by KotlinJs rn


/**
* NOT SUPPORTED: Currently KustomExport cannot handle generics functions.
*
* When an annotation like `KustomGenerics(GenericsStuff::class, arrayOf(Long::class))` is found,
* it resolves the class type parameters with the given parameter (here [Long]), but the class doesn't need it.
* The generic functions can actually be used with multiple types so if we want to support it, we should handle
* multiple custom types for each method, generating as many functions as needed, on the wrappers.
* Also be able to split generics from the typed class and from the typed methods.
*
* ```kotlin
* class Foo<T : Any> {
* fun <T, V> bar(t: T, v: V) { // T from here is not the T from the class
* }
* }
* Foo<Int>().bar("a", "b") // Here "T" is a Int at the class level, and a String at the method level.
* ```
* So it can be tedious to provide a good solution for that (waiting for more adopters, not sure if we need
* this level of tooling right now...)
*/
4 changes: 0 additions & 4 deletions samples/src/commonMain/kotlin/sample/generics/Generics.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// Disabling Generics support for now:
// - more complex when dealing with @JsExport and @KustomExport mixed
// - support is still not great enough, must be reworked

import { runTest } from "../shared_ts/RunTest"
import { assert, assertEquals, assertQuiet } from "../shared_ts/Assert"
import { Nullable, sample } from '@kustom/Samples'
Expand Down

0 comments on commit d449148

Please sign in to comment.