diff --git a/interop/kotlinx-metadata/specs-tests/build.gradle.kts b/interop/kotlinx-metadata/specs-tests/build.gradle.kts index f586543b7..57d23c79a 100644 --- a/interop/kotlinx-metadata/specs-tests/build.gradle.kts +++ b/interop/kotlinx-metadata/specs-tests/build.gradle.kts @@ -15,9 +15,10 @@ */ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -val compileTestKotlin: KotlinCompile by tasks -compileTestKotlin.kotlinOptions { - freeCompilerArgs = listOf("-Xjvm-default=all") +tasks.withType().named("compileTestKotlin") { + kotlinOptions { + freeCompilerArgs = listOf("-Xjvm-default=all") + } } dependencies { diff --git a/kotlinpoet/build.gradle.kts b/kotlinpoet/build.gradle.kts index 8bb202ed5..a83350af9 100644 --- a/kotlinpoet/build.gradle.kts +++ b/kotlinpoet/build.gradle.kts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + val GROUP: String by project val VERSION_NAME: String by project @@ -25,6 +27,12 @@ tasks.named("jar") { } } +tasks.withType().named("compileTestKotlin") { + kotlinOptions { + freeCompilerArgs = listOf("-Xopt-in=com.squareup.kotlinpoet.DelicateKotlinPoetApi") + } +} + dependencies { implementation(deps.kotlin.reflect) testImplementation(deps.kotlin.junit) diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/AnnotationSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/AnnotationSpec.kt index d6c139cfd..d956425af 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/AnnotationSpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/AnnotationSpec.kt @@ -23,7 +23,6 @@ import javax.lang.model.element.TypeElement import javax.lang.model.element.VariableElement import javax.lang.model.type.TypeMirror import javax.lang.model.util.SimpleAnnotationValueVisitor7 -import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass /** A generated annotation on a declaration. */ @@ -181,7 +180,13 @@ public class AnnotationSpec private constructor( } public companion object { - @JvmStatic @JvmOverloads public fun get( + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + @JvmOverloads + public fun get( annotation: Annotation, includeDefaultValues: Boolean = false ): AnnotationSpec { @@ -223,10 +228,9 @@ public class AnnotationSpec private constructor( } } - @Deprecated( + @DelicateKotlinPoetApi( message = "Mirror APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmStatic public fun get(annotation: AnnotationMirror): AnnotationSpec { @@ -248,7 +252,12 @@ public class AnnotationSpec private constructor( @JvmStatic public fun builder(type: ParameterizedTypeName): Builder = Builder(type) - @JvmStatic public fun builder(type: Class): Builder = + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + public fun builder(type: Class): Builder = builder(type.asClassName()) @JvmStatic public fun builder(type: KClass): Builder = diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ClassName.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ClassName.kt index 8a5ce5105..ad3943f31 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ClassName.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ClassName.kt @@ -23,7 +23,6 @@ import javax.lang.model.element.NestingKind.MEMBER import javax.lang.model.element.NestingKind.TOP_LEVEL import javax.lang.model.element.PackageElement import javax.lang.model.element.TypeElement -import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass /** A fully-qualified class name for top-level and member classes. */ @@ -209,6 +208,10 @@ public class ClassName internal constructor( } } +@DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider using" + + " the kotlinpoet-metadata APIs instead." +) @JvmName("get") public fun Class<*>.asClassName(): ClassName { require(!isPrimitive) { "primitive types cannot be represented as a ClassName" } @@ -235,10 +238,9 @@ public fun KClass<*>.asClassName(): ClassName { } /** Returns the class name for `element`. */ -@Deprecated( +@DelicateKotlinPoetApi( message = "Element APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmName("get") public fun TypeElement.asClassName(): ClassName { diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/DelicateKotlinPoetApi.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/DelicateKotlinPoetApi.kt new file mode 100644 index 000000000..3d0608389 --- /dev/null +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/DelicateKotlinPoetApi.kt @@ -0,0 +1,17 @@ +package com.squareup.kotlinpoet + +/** + * Marks declarations in the KotlinPoet API that are **delicate** — + * they have limited use-case and shall be used with care in general code. + * Any use of a delicate declaration has to be carefully reviewed to make sure it is + * properly used and does not create problems like lossy Java -> Kotlin type parsing. + * Carefully read documentation and [message] of any declaration marked as `DelicateKotlinPoetApi`. + */ +@MustBeDocumented +@Retention(value = AnnotationRetention.BINARY) +@RequiresOptIn( + level = RequiresOptIn.Level.WARNING, + message = "This is a delicate API and its use requires care." + + " Make sure you fully read and understand documentation of the declaration that is marked as a delicate API." +) +public annotation class DelicateKotlinPoetApi(val message: String) diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt index 0ab3ea1b8..121146fba 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/FunSpec.kt @@ -555,10 +555,9 @@ public class FunSpec private constructor( @JvmStatic public fun setterBuilder(): Builder = Builder(SETTER) - @Deprecated( + @DelicateKotlinPoetApi( message = "Element APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmStatic public fun overriding(method: ExecutableElement): Builder { diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/MemberName.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/MemberName.kt index 2f370533c..c330d66fb 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/MemberName.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/MemberName.kt @@ -81,7 +81,14 @@ public data class MemberName internal constructor( MemberName(this, simpleName) @JvmStatic @JvmName("get") public fun KClass<*>.member(simpleName: String): MemberName = asClassName().member(simpleName) - @JvmStatic @JvmName("get") public fun Class<*>.member(simpleName: String): MemberName = + + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + @JvmName("get") + public fun Class<*>.member(simpleName: String): MemberName = asClassName().member(simpleName) } } diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt index a1983e907..9e8375ac8 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt @@ -19,7 +19,6 @@ import java.lang.reflect.Type import javax.lang.model.element.ExecutableElement import javax.lang.model.element.Modifier import javax.lang.model.element.VariableElement -import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass /** A generated parameter declaration. */ @@ -146,10 +145,9 @@ public class ParameterSpec private constructor( } public companion object { - @Deprecated( + @DelicateKotlinPoetApi( message = "Element APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmStatic public fun get(element: VariableElement): ParameterSpec { @@ -160,10 +158,9 @@ public class ParameterSpec private constructor( .build() } - @Deprecated( + @DelicateKotlinPoetApi( message = "Element APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmStatic public fun parametersOf(method: ExecutableElement): List = diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterizedTypeName.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterizedTypeName.kt index 757241a1b..dd722d4d9 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterizedTypeName.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterizedTypeName.kt @@ -194,6 +194,10 @@ public class ParameterizedTypeName internal constructor( } /** Returns a parameterized type equivalent to `type`. */ +@DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." +) @JvmName("get") public fun ParameterizedType.asParameterizedTypeName(): ParameterizedTypeName = ParameterizedTypeName.get(this, mutableMapOf()) diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt index c19f5f063..2748c0ed0 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/PropertySpec.kt @@ -206,6 +206,10 @@ public class PropertySpec private constructor( annotations += AnnotationSpec.builder(annotation).build() } + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun addAnnotation(annotation: Class<*>): Builder = addAnnotation(annotation.asClassName()) @@ -258,6 +262,10 @@ public class PropertySpec private constructor( this.receiverType = receiverType } + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun receiver(receiverType: Type): Builder = receiver(receiverType.asTypeName()) public fun receiver(receiverType: KClass<*>): Builder = receiver(receiverType.asTypeName()) @@ -302,7 +310,12 @@ public class PropertySpec private constructor( return Builder(name, type).addModifiers(modifiers) } - @JvmStatic public fun builder( + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + public fun builder( name: String, type: Type, modifiers: Iterable diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeAliasSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeAliasSpec.kt index 2bbf01e1a..1fdd81e78 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeAliasSpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeAliasSpec.kt @@ -117,6 +117,10 @@ public class TypeAliasSpec private constructor( annotations += AnnotationSpec.builder(annotation).build() } + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun addAnnotation(annotation: Class<*>): Builder = addAnnotation(annotation.asClassName()) @@ -140,7 +144,12 @@ public class TypeAliasSpec private constructor( public companion object { @JvmStatic public fun builder(name: String, type: TypeName): Builder = Builder(name, type) - @JvmStatic public fun builder(name: String, type: Type): Builder = + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + public fun builder(name: String, type: Type): Builder = builder(name, type.asTypeName()) @JvmStatic public fun builder(name: String, type: KClass<*>): Builder = diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeName.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeName.kt index 260000309..7f8dd45d2 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeName.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeName.kt @@ -34,7 +34,6 @@ import javax.lang.model.type.PrimitiveType import javax.lang.model.type.TypeKind import javax.lang.model.type.TypeMirror import javax.lang.model.util.SimpleTypeVisitor7 -import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass import kotlin.reflect.typeOf @@ -276,10 +275,9 @@ public sealed class TypeName constructor( @JvmField public val DYNAMIC: Dynamic = Dynamic /** Returns a [TypeName] equivalent to this [TypeMirror]. */ -@Deprecated( +@DelicateKotlinPoetApi( message = "Mirror APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmName("get") public fun TypeMirror.asTypeName(): TypeName = TypeName.get(this, mutableMapOf()) diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt index 4e89df5d8..2a060f6a7 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt @@ -500,6 +500,10 @@ public class TypeSpec private constructor( public fun addAnnotation(annotation: ClassName): Builder = addAnnotation(AnnotationSpec.builder(annotation).build()) + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun addAnnotation(annotation: Class<*>): Builder = addAnnotation(annotation.asClassName()) @@ -566,6 +570,10 @@ public class TypeSpec private constructor( } } + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun superclass(superclass: Type): Builder = superclass(superclass.asTypeName()) public fun superclass(superclass: KClass<*>): Builder = superclass(superclass.asTypeName()) @@ -607,6 +615,10 @@ public class TypeSpec private constructor( } } + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun addSuperinterface( superinterface: Type, delegate: CodeBlock = CodeBlock.EMPTY @@ -662,6 +674,10 @@ public class TypeSpec private constructor( public fun addProperty(name: String, type: TypeName, vararg modifiers: KModifier): Builder = addProperty(PropertySpec.builder(name, type, *modifiers).build()) + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun addProperty(name: String, type: Type, vararg modifiers: KModifier): Builder = addProperty(name, type.asTypeName(), *modifiers) @@ -671,6 +687,10 @@ public class TypeSpec private constructor( public fun addProperty(name: String, type: TypeName, modifiers: Iterable): Builder = addProperty(PropertySpec.builder(name, type, modifiers).build()) + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) public fun addProperty(name: String, type: Type, modifiers: Iterable): Builder = addProperty(name, type.asTypeName(), modifiers) diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeVariableName.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeVariableName.kt index b3caeff65..6bb013aa5 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeVariableName.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeVariableName.kt @@ -222,11 +222,19 @@ public class TypeVariableName private constructor( } /** Returns type variable equivalent to `mirror`. */ +@DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider using" + + " the kotlinpoet-metadata APIs instead." +) @JvmName("get") public fun TypeVariable.asTypeVariableName(): TypeVariableName = (asElement() as TypeParameterElement).asTypeVariableName() /** Returns type variable equivalent to `element`. */ +@DelicateKotlinPoetApi( + message = "Element APIs don't give complete information on Kotlin types. Consider using" + + " the kotlinpoet-metadata APIs instead." +) @JvmName("get") public fun TypeParameterElement.asTypeVariableName(): TypeVariableName { val name = simpleName.toString() diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/WildcardTypeName.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/WildcardTypeName.kt index 08c86532c..40745151a 100644 --- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/WildcardTypeName.kt +++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/WildcardTypeName.kt @@ -20,7 +20,6 @@ package com.squareup.kotlinpoet import java.lang.reflect.Type import java.lang.reflect.WildcardType import javax.lang.model.element.TypeParameterElement -import kotlin.DeprecationLevel.WARNING import kotlin.reflect.KClass public class WildcardTypeName private constructor( @@ -62,7 +61,12 @@ public class WildcardTypeName private constructor( @JvmStatic public fun producerOf(outType: TypeName): WildcardTypeName = WildcardTypeName(listOf(outType), emptyList()) - @JvmStatic public fun producerOf(outType: Type): WildcardTypeName = + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + public fun producerOf(outType: Type): WildcardTypeName = producerOf(outType.asTypeName()) @JvmStatic public fun producerOf(outType: KClass<*>): WildcardTypeName = @@ -75,7 +79,12 @@ public class WildcardTypeName private constructor( @JvmStatic public fun consumerOf(inType: TypeName): WildcardTypeName = WildcardTypeName(listOf(ANY), listOf(inType)) - @JvmStatic public fun consumerOf(inType: Type): WildcardTypeName = + @DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider " + + "using the kotlinpoet-metadata APIs instead." + ) + @JvmStatic + public fun consumerOf(inType: Type): WildcardTypeName = consumerOf(inType.asTypeName()) @JvmStatic public fun consumerOf(inType: KClass<*>): WildcardTypeName = @@ -110,15 +119,18 @@ public class WildcardTypeName private constructor( } } -@Deprecated( +@DelicateKotlinPoetApi( message = "Mirror APIs don't give complete information on Kotlin types. Consider using" + - " the kotlinpoet-metadata APIs instead.", - level = WARNING + " the kotlinpoet-metadata APIs instead." ) @JvmName("get") public fun javax.lang.model.type.WildcardType.asWildcardTypeName(): TypeName = WildcardTypeName.get(this, mutableMapOf()) +@DelicateKotlinPoetApi( + message = "Java reflection APIs don't give complete information on Kotlin types. Consider using" + + " the kotlinpoet-metadata APIs instead." +) @JvmName("get") public fun WildcardType.asWildcardTypeName(): TypeName = WildcardTypeName.get(this, mutableMapOf())