diff --git a/build.gradle.kts b/build.gradle.kts index ce7642d..2ea442b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,7 +24,7 @@ plugins { allprojects { group = "deezer.kustomexport" - version = "0.5.0" + version = "0.6.0" repositories { mavenLocal() diff --git a/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/mapping/TypeMapping.kt b/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/mapping/TypeMapping.kt index aeb39f5..1219635 100644 --- a/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/mapping/TypeMapping.kt +++ b/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/mapping/TypeMapping.kt @@ -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 @@ -42,7 +41,7 @@ import deezer.kustomexport.compiler.js.toFormatString class OriginTypeName( private val originTypeName: TypeName, private val concreteTypeParameters: List, - val isKustomExportAnnotated: Boolean, + val isKustomExportAnnotated: Boolean, private val typeArgs: List, ) { val concreteTypeName: TypeName by lazy { originTypeName.resolvedType(concreteTypeParameters) } diff --git a/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/pattern/ClassDeclarationParser.kt b/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/pattern/ClassDeclarationParser.kt index 73054bc..d523d16 100644 --- a/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/pattern/ClassDeclarationParser.kt +++ b/compiler/src/main/kotlin/deezer/kustomexport/compiler/js/pattern/ClassDeclarationParser.kt @@ -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) @@ -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) } diff --git a/lib/src/commonMain/kotlin/deezer/kustomexport/KustomExport.kt b/lib/src/commonMain/kotlin/deezer/kustomexport/KustomExport.kt index 1fd0846..78f3383 100644 --- a/lib/src/commonMain/kotlin/deezer/kustomexport/KustomExport.kt +++ b/lib/src/commonMain/kotlin/deezer/kustomexport/KustomExport.kt @@ -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( /** @@ -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 = [] ) +@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>, diff --git a/samples/src/commonMain/kotlin/sample/_class/static/Statics.kt b/samples/src/commonMain/kotlin/sample/_class/static/Statics.kt index 7623d26..47c544b 100644 --- a/samples/src/commonMain/kotlin/sample/_class/static/Statics.kt +++ b/samples/src/commonMain/kotlin/sample/_class/static/Statics.kt @@ -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" @@ -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 { + * fun bar(t: T, v: V) { // T from here is not the T from the class + * } + * } + * Foo().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 create(): GenericsImpl { - return GenericsImpl() - } +fun create(): GenericsImpl { +return GenericsImpl() +} } */ \ No newline at end of file diff --git a/samples/src/commonMain/kotlin/sample/generics/Generics.kt b/samples/src/commonMain/kotlin/sample/generics/Generics.kt index bba244e..c48d4fe 100644 --- a/samples/src/commonMain/kotlin/sample/generics/Generics.kt +++ b/samples/src/commonMain/kotlin/sample/generics/Generics.kt @@ -84,4 +84,25 @@ class GenericsConsumer { // (You should not use generics on TypeAlias.) //@KustomExport //typealias TypeAliasLong = TypeAliasInterface -// Unfortunately, typealias are not properly handled by KotlinJs rn \ No newline at end of file +// 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 { + * fun bar(t: T, v: V) { // T from here is not the T from the class + * } + * } + * Foo().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...) + */ \ No newline at end of file diff --git a/samples/src/commonMain/kotlin/sample/generics/Generics.ts b/samples/src/commonMain/kotlin/sample/generics/Generics.ts index 6b966bb..be3ab4e 100644 --- a/samples/src/commonMain/kotlin/sample/generics/Generics.ts +++ b/samples/src/commonMain/kotlin/sample/generics/Generics.ts @@ -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'