Skip to content

Commit

Permalink
Update kotlinx-metadata APIs for changes (#1766)
Browse files Browse the repository at this point in the history
* Update to kotlinx-metadata 0.8.0

* Propagate lenient param

* Update API

* Remove redundant asClassHeader()

* Update CHANGELOG

* PR number chicken and egg problem
  • Loading branch information
ZacSweers committed Apr 17, 2024
1 parent e454b8a commit cdb5426
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 97 deletions.
1 change: 1 addition & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Change Log
* Fix: Omit implicit modifiers on FileSpec.scriptBuilder (#1813).
* Fix: Fix trailing newline in PropertySpec (#1827).
* Change: kotlinx-metadata 0.9.0. Note that the `KotlinClassMetadata .read` is deprecated in 0.9.0 and replaced with `readStrict` (#1830).
* Note: we now also `lenient` parameters to map to the underlying `readStrict()` and `readLenient()` calls (#1766).
* Fix: `KSAnnotation.toAnnotationSpec` writes varargs in place instead of making them an array to work around a Kotlin
issue with `OptIn` annotations (#1831).
* Fix: `MemberName`s without a package are now correctly imported (#1841)
Expand Down
48 changes: 24 additions & 24 deletions interop/kotlinx-metadata/api/kotlinx-metadata.api
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
public final class com/squareup/kotlinpoet/metadata/KotlinPoetMetadata {
public static final fun readKotlinClassMetadata (Lkotlin/Metadata;)Lkotlinx/metadata/jvm/KotlinClassMetadata;
public static final fun toKmClass (Ljava/lang/Class;)Lkotlinx/metadata/KmClass;
public static final fun toKmClass (Ljavax/lang/model/element/TypeElement;)Lkotlinx/metadata/KmClass;
public static final fun toKmClass (Lkotlin/Metadata;)Lkotlinx/metadata/KmClass;
public static final fun toKmClass (Lkotlin/reflect/KClass;)Lkotlinx/metadata/KmClass;
public static final fun readKotlinClassMetadata (Lkotlin/Metadata;Z)Lkotlinx/metadata/jvm/KotlinClassMetadata;
public static final fun toKmClass (Ljava/lang/Class;Z)Lkotlinx/metadata/KmClass;
public static final fun toKmClass (Ljavax/lang/model/element/TypeElement;Z)Lkotlinx/metadata/KmClass;
public static final fun toKmClass (Lkotlin/Metadata;Z)Lkotlinx/metadata/KmClass;
public static final fun toKmClass (Lkotlin/reflect/KClass;Z)Lkotlinx/metadata/KmClass;
}

public abstract interface annotation class com/squareup/kotlinpoet/metadata/KotlinPoetMetadataPreview : java/lang/annotation/Annotation {
}

public final class com/squareup/kotlinpoet/metadata/classinspectors/ElementsClassInspector : com/squareup/kotlinpoet/metadata/specs/ClassInspector {
public static final field Companion Lcom/squareup/kotlinpoet/metadata/classinspectors/ElementsClassInspector$Companion;
public synthetic fun <init> (Ljavax/lang/model/util/Elements;Ljavax/lang/model/util/Types;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (ZLjavax/lang/model/util/Elements;Ljavax/lang/model/util/Types;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun containerData (Lkotlinx/metadata/KmDeclarationContainer;Lcom/squareup/kotlinpoet/ClassName;Lcom/squareup/kotlinpoet/ClassName;)Lcom/squareup/kotlinpoet/metadata/specs/ContainerData;
public static final fun create (Ljavax/lang/model/util/Elements;Ljavax/lang/model/util/Types;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public static final fun create (ZLjavax/lang/model/util/Elements;Ljavax/lang/model/util/Types;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public fun declarationContainerFor (Lcom/squareup/kotlinpoet/ClassName;)Lkotlinx/metadata/KmDeclarationContainer;
public fun enumEntry (Lcom/squareup/kotlinpoet/ClassName;Ljava/lang/String;)Lcom/squareup/kotlinpoet/metadata/specs/EnumEntryData;
public fun getSupportsNonRuntimeRetainedAnnotations ()Z
Expand All @@ -22,14 +22,14 @@ public final class com/squareup/kotlinpoet/metadata/classinspectors/ElementsClas
}

public final class com/squareup/kotlinpoet/metadata/classinspectors/ElementsClassInspector$Companion {
public final fun create (Ljavax/lang/model/util/Elements;Ljavax/lang/model/util/Types;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public final fun create (ZLjavax/lang/model/util/Elements;Ljavax/lang/model/util/Types;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
}

public final class com/squareup/kotlinpoet/metadata/classinspectors/ReflectiveClassInspector : com/squareup/kotlinpoet/metadata/specs/ClassInspector {
public static final field Companion Lcom/squareup/kotlinpoet/metadata/classinspectors/ReflectiveClassInspector$Companion;
public synthetic fun <init> (Ljava/lang/ClassLoader;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (ZLjava/lang/ClassLoader;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun containerData (Lkotlinx/metadata/KmDeclarationContainer;Lcom/squareup/kotlinpoet/ClassName;Lcom/squareup/kotlinpoet/ClassName;)Lcom/squareup/kotlinpoet/metadata/specs/ContainerData;
public static final fun create (Ljava/lang/ClassLoader;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public static final fun create (ZLjava/lang/ClassLoader;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public fun declarationContainerFor (Lcom/squareup/kotlinpoet/ClassName;)Lkotlinx/metadata/KmDeclarationContainer;
public fun enumEntry (Lcom/squareup/kotlinpoet/ClassName;Ljava/lang/String;)Lcom/squareup/kotlinpoet/metadata/specs/EnumEntryData;
public fun getSupportsNonRuntimeRetainedAnnotations ()Z
Expand All @@ -38,8 +38,8 @@ public final class com/squareup/kotlinpoet/metadata/classinspectors/ReflectiveCl
}

public final class com/squareup/kotlinpoet/metadata/classinspectors/ReflectiveClassInspector$Companion {
public final fun create (Ljava/lang/ClassLoader;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public static synthetic fun create$default (Lcom/squareup/kotlinpoet/metadata/classinspectors/ReflectiveClassInspector$Companion;Ljava/lang/ClassLoader;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public final fun create (ZLjava/lang/ClassLoader;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
public static synthetic fun create$default (Lcom/squareup/kotlinpoet/metadata/classinspectors/ReflectiveClassInspector$Companion;ZLjava/lang/ClassLoader;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;
}

public final class com/squareup/kotlinpoet/metadata/specs/ClassData : com/squareup/kotlinpoet/metadata/specs/ContainerData {
Expand Down Expand Up @@ -196,22 +196,22 @@ public final class com/squareup/kotlinpoet/metadata/specs/KmTypesKt {

public final class com/squareup/kotlinpoet/metadata/specs/KotlinPoetMetadataSpecs {
public static final fun getPackageName (Ljavax/lang/model/element/Element;)Ljava/lang/String;
public static final fun toFileSpec (Ljava/lang/Class;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Ljavax/lang/model/element/TypeElement;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Lkotlin/reflect/KClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Ljava/lang/Class;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Ljavax/lang/model/element/TypeElement;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Lkotlin/reflect/KClass;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Lkotlinx/metadata/KmClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;Lcom/squareup/kotlinpoet/ClassName;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toFileSpec (Lkotlinx/metadata/KmPackage;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;Lcom/squareup/kotlinpoet/ClassName;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Ljava/lang/Class;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Ljavax/lang/model/element/TypeElement;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Lkotlin/reflect/KClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Ljava/lang/Class;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Ljavax/lang/model/element/TypeElement;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Lkotlin/reflect/KClass;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static synthetic fun toFileSpec$default (Lkotlinx/metadata/KmClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;Lcom/squareup/kotlinpoet/ClassName;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/FileSpec;
public static final fun toTypeSpec (Ljava/lang/Class;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/TypeSpec;
public static final fun toTypeSpec (Ljavax/lang/model/element/TypeElement;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/TypeSpec;
public static final fun toTypeSpec (Lkotlin/reflect/KClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/TypeSpec;
public static final fun toTypeSpec (Ljava/lang/Class;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/TypeSpec;
public static final fun toTypeSpec (Ljavax/lang/model/element/TypeElement;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/TypeSpec;
public static final fun toTypeSpec (Lkotlin/reflect/KClass;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;)Lcom/squareup/kotlinpoet/TypeSpec;
public static final fun toTypeSpec (Lkotlinx/metadata/KmClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;Lcom/squareup/kotlinpoet/ClassName;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Ljava/lang/Class;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Ljavax/lang/model/element/TypeElement;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Lkotlin/reflect/KClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Ljava/lang/Class;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Ljavax/lang/model/element/TypeElement;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Lkotlin/reflect/KClass;ZLcom/squareup/kotlinpoet/metadata/specs/ClassInspector;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
public static synthetic fun toTypeSpec$default (Lkotlinx/metadata/KmClass;Lcom/squareup/kotlinpoet/metadata/specs/ClassInspector;Lcom/squareup/kotlinpoet/ClassName;ILjava/lang/Object;)Lcom/squareup/kotlinpoet/TypeSpec;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,45 @@ import kotlinx.metadata.jvm.Metadata
@Target(CLASS, FUNCTION, PROPERTY)
public annotation class KotlinPoetMetadataPreview

/** @return a new [KmClass] representation of the Kotlin metadata for [this] class. */
/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
* @return a new [KmClass] representation of the Kotlin metadata for [this] class.
*/
@KotlinPoetMetadataPreview
public fun KClass<*>.toKmClass(): KmClass = java.toKmClass()
public fun KClass<*>.toKmClass(lenient: Boolean): KmClass = java.toKmClass(lenient)

/** @return a new [KmClass] representation of the Kotlin metadata for [this] class. */
/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
* @return a new [KmClass] representation of the Kotlin metadata for [this] class.
*/
@KotlinPoetMetadataPreview
public fun Class<*>.toKmClass(): KmClass = readMetadata(::getAnnotation).toKmClass()
public fun Class<*>.toKmClass(lenient: Boolean): KmClass = readMetadata(::getAnnotation).toKmClass(lenient)

/** @return a new [KmClass] representation of the Kotlin metadata for [this] type. */
/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
* @return a new [KmClass] representation of the Kotlin metadata for [this] type.
*/
@KotlinPoetMetadataPreview
public fun TypeElement.toKmClass(): KmClass = readMetadata(::getAnnotation).toKmClass()
public fun TypeElement.toKmClass(lenient: Boolean): KmClass = readMetadata(::getAnnotation).toKmClass(lenient)

/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
*/
@KotlinPoetMetadataPreview
public fun Metadata.toKmClass(): KmClass {
return toKotlinClassMetadata<KotlinClassMetadata.Class>()
public fun Metadata.toKmClass(lenient: Boolean): KmClass {
return toKotlinClassMetadata<KotlinClassMetadata.Class>(lenient)
.kmClass
}

/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
*/
@KotlinPoetMetadataPreview
public inline fun <reified T : KotlinClassMetadata> Metadata.toKotlinClassMetadata(): T {
public inline fun <reified T : KotlinClassMetadata> Metadata.toKotlinClassMetadata(
lenient: Boolean,
): T {
val expectedType = T::class
val metadata = readKotlinClassMetadata()
val metadata = readKotlinClassMetadata(lenient)
return when (expectedType) {
KotlinClassMetadata.Class::class -> {
check(metadata is KotlinClassMetadata.Class)
Expand All @@ -82,30 +99,20 @@ public inline fun <reified T : KotlinClassMetadata> Metadata.toKotlinClassMetada
* Returns the [KotlinClassMetadata] this represents. In general you should only use this function
* when you don't know what the underlying [KotlinClassMetadata] subtype is, otherwise you should
* use one of the more direct functions like [toKmClass].
*
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
*/
@KotlinPoetMetadataPreview
public fun Metadata.readKotlinClassMetadata(): KotlinClassMetadata {
val metadata = KotlinClassMetadata.readStrict(asClassHeader())
checkNotNull(metadata) {
"Could not parse metadata! Try bumping kotlinpoet and/or kotlinx-metadata version."
public fun Metadata.readKotlinClassMetadata(lenient: Boolean): KotlinClassMetadata {
return if (lenient) {
KotlinClassMetadata.readLenient(this)
} else {
KotlinClassMetadata.readStrict(this)
}
return metadata
}

private inline fun readMetadata(lookup: ((Class<Metadata>) -> Metadata?)): Metadata {
return checkNotNull(lookup.invoke(Metadata::class.java)) {
"No Metadata annotation found! Must be Kotlin code built with the standard library on the classpath."
}
}

private fun Metadata.asClassHeader(): Metadata {
return Metadata(
kind = kind,
metadataVersion = metadataVersion,
data1 = data1,
data2 = data2,
extraString = extraString,
packageName = packageName,
extraInt = extraInt,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private typealias ElementsModifier = javax.lang.model.element.Modifier
*/
@KotlinPoetMetadataPreview
public class ElementsClassInspector private constructor(
private val lenient: Boolean,
private val elements: Elements,
private val types: Types,
) : ClassInspector {
Expand All @@ -115,7 +116,7 @@ public class ElementsClassInspector private constructor(
?: error("No type element found for: $className.")

val metadata = typeElement.getAnnotation(Metadata::class.java)
return when (val kotlinClassMetadata = metadata.readKotlinClassMetadata()) {
return when (val kotlinClassMetadata = metadata.readKotlinClassMetadata(lenient)) {
is KotlinClassMetadata.Class -> kotlinClassMetadata.kmClass
is KotlinClassMetadata.FileFacade -> kotlinClassMetadata.kmPackage
else -> TODO("Not implemented yet: ${kotlinClassMetadata.javaClass.simpleName}")
Expand Down Expand Up @@ -207,7 +208,7 @@ public class ElementsClassInspector private constructor(
.filter { types.isSubtype(enumTypeAsType, it.superclass) }
.find { it.simpleName.contentEquals(memberName) }.toOptional()
}.nullableValue
val declarationContainer = member?.getAnnotation(Metadata::class.java)?.toKmClass()
val declarationContainer = member?.getAnnotation(Metadata::class.java)?.toKmClass(lenient)

val entry = ElementFilter.fieldsIn(enumType.enclosedElements)
.find { it.simpleName.contentEquals(memberName) }
Expand Down Expand Up @@ -571,11 +572,14 @@ public class ElementsClassInspector private constructor(
}

public companion object {
/** @return an [Elements]-based implementation of [ClassInspector]. */
/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
* @return an [Elements]-based implementation of [ClassInspector].
*/
@JvmStatic
@KotlinPoetMetadataPreview
public fun create(elements: Elements, types: Types): ClassInspector {
return ElementsClassInspector(elements, types)
public fun create(lenient: Boolean, elements: Elements, types: Types): ClassInspector {
return ElementsClassInspector(lenient, elements, types)
}

private val JVM_STATIC = JvmStatic::class.asClassName()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import kotlinx.metadata.kind

@KotlinPoetMetadataPreview
public class ReflectiveClassInspector private constructor(
private val lenient: Boolean,
private val classLoader: ClassLoader?,
) : ClassInspector {

Expand Down Expand Up @@ -105,7 +106,7 @@ public class ReflectiveClassInspector private constructor(
?: error("No type element found for: $className.")

val metadata = clazz.getAnnotation(Metadata::class.java)
return when (val kotlinClassMetadata = metadata.readKotlinClassMetadata()) {
return when (val kotlinClassMetadata = metadata.readKotlinClassMetadata(lenient)) {
is KotlinClassMetadata.Class -> kotlinClassMetadata.kmClass
is KotlinClassMetadata.FileFacade -> kotlinClassMetadata.kmPackage
else -> TODO("Not implemented yet: ${kotlinClassMetadata.javaClass.simpleName}")
Expand Down Expand Up @@ -251,7 +252,7 @@ public class ReflectiveClassInspector private constructor(
// class.
null
} else {
enumEntry.javaClass.getAnnotation(Metadata::class.java)?.toKmClass()
enumEntry.javaClass.getAnnotation(Metadata::class.java)?.toKmClass(lenient)
},
annotations = clazz.getField(enumEntry.name).annotationSpecs(),
)
Expand Down Expand Up @@ -542,10 +543,13 @@ public class ReflectiveClassInspector private constructor(
}

public companion object {
/**
* @param lenient see docs on [KotlinClassMetadata.readStrict] and [KotlinClassMetadata.readLenient] for more details.
*/
@JvmStatic
@KotlinPoetMetadataPreview
public fun create(classLoader: ClassLoader? = null): ClassInspector {
return ReflectiveClassInspector(classLoader)
public fun create(lenient: Boolean, classLoader: ClassLoader? = null): ClassInspector {
return ReflectiveClassInspector(lenient, classLoader)
}

private val Class<*>.descriptor: String
Expand Down

0 comments on commit cdb5426

Please sign in to comment.