A Kotlin library for reading and modifying binary metadata in Kotlin/JVM compiler-generated files.
—
System for representing JVM method and field signatures used in metadata processing and reflection operations. JVM member signatures provide a way to uniquely identify and reference methods and fields using JVM descriptor strings.
Base sealed class for all JVM member signature types.
/**
* Base sealed class representing JVM member signatures
*/
sealed class JvmMemberSignature {
/**
* The name of the member (method or field name)
*/
abstract val name: String
/**
* The JVM descriptor string for this member
* For methods: (parameter_types)return_type
* For fields: field_type
*/
abstract val descriptor: String
}Data class representing JVM method signatures.
/**
* Represents a JVM method signature with name and descriptor
* @param name The method name
* @param descriptor The JVM method descriptor (e.g., "(Ljava/lang/String;)V")
*/
data class JvmMethodSignature(
override val name: String,
override val descriptor: String
) : JvmMemberSignature() {
/**
* Returns string representation in format "name descriptor"
*/
override fun toString(): String
}Usage Examples:
import kotlin.metadata.jvm.JvmMethodSignature
// Create method signatures
val mainMethod = JvmMethodSignature(
name = "main",
descriptor = "([Ljava/lang/String;)V"
)
val stringLength = JvmMethodSignature(
name = "length",
descriptor = "()I"
)
val substring = JvmMethodSignature(
name = "substring",
descriptor = "(II)Ljava/lang/String;"
)
// Access signature components
println("Method name: ${mainMethod.name}") // "main"
println("Method descriptor: ${mainMethod.descriptor}") // "([Ljava/lang/String;)V"
println("Full signature: $mainMethod") // "main ([Ljava/lang/String;)V"
// Compare signatures
val anotherMain = JvmMethodSignature("main", "([Ljava/lang/String;)V")
println(mainMethod == anotherMain) // true (data class equality)Data class representing JVM field signatures.
/**
* Represents a JVM field signature with name and descriptor
* @param name The field name
* @param descriptor The JVM field descriptor (e.g., "Ljava/lang/String;")
*/
data class JvmFieldSignature(
override val name: String,
override val descriptor: String
) : JvmMemberSignature() {
/**
* Returns string representation in format "name descriptor"
*/
override fun toString(): String
}Usage Examples:
import kotlin.metadata.jvm.JvmFieldSignature
// Create field signatures
val stringField = JvmFieldSignature(
name = "value",
descriptor = "Ljava/lang/String;"
)
val intField = JvmFieldSignature(
name = "count",
descriptor = "I"
)
val booleanField = JvmFieldSignature(
name = "isActive",
descriptor = "Z"
)
// Access signature components
println("Field name: ${stringField.name}") // "value"
println("Field descriptor: ${stringField.descriptor}") // "Ljava/lang/String;"
println("Full signature: $stringField") // "value Ljava/lang/String;"
// Working with primitive types
val primitiveFields = listOf(
JvmFieldSignature("byteValue", "B"), // byte
JvmFieldSignature("shortValue", "S"), // short
JvmFieldSignature("intValue", "I"), // int
JvmFieldSignature("longValue", "J"), // long
JvmFieldSignature("floatValue", "F"), // float
JvmFieldSignature("doubleValue", "D"), // double
JvmFieldSignature("charValue", "C"), // char
JvmFieldSignature("booleanValue", "Z") // boolean
)Common operations and patterns when working with JVM member signatures.
// Pattern matching on signature types
fun processSignature(signature: JvmMemberSignature) {
when (signature) {
is JvmMethodSignature -> {
println("Processing method: ${signature.name}")
// Parse method descriptor for parameter types
if (signature.descriptor.startsWith("(")) {
val paramEnd = signature.descriptor.indexOf(')')
val paramTypes = signature.descriptor.substring(1, paramEnd)
val returnType = signature.descriptor.substring(paramEnd + 1)
println(" Parameters: $paramTypes")
println(" Return type: $returnType")
}
}
is JvmFieldSignature -> {
println("Processing field: ${signature.name}")
println(" Type: ${signature.descriptor}")
}
}
}
// Create signature collections
val methodSignatures = mutableSetOf<JvmMethodSignature>()
methodSignatures.add(JvmMethodSignature("toString", "()Ljava/lang/String;"))
methodSignatures.add(JvmMethodSignature("equals", "(Ljava/lang/Object;)Z"))
methodSignatures.add(JvmMethodSignature("hashCode", "()I"))
val fieldSignatures = mutableSetOf<JvmFieldSignature>()
fieldSignatures.add(JvmFieldSignature("serialVersionUID", "J"))Understanding JVM descriptor format for methods and fields.
Method descriptors have the format (parameter_types)return_type:
// Examples of method descriptors
val methodExamples = mapOf(
"()V" to "No parameters, void return",
"(I)I" to "One int parameter, int return",
"(Ljava/lang/String;)V" to "String parameter, void return",
"(II)Ljava/lang/String;" to "Two int parameters, String return",
"([Ljava/lang/String;)V" to "String array parameter, void return",
"(Ljava/util/List;I)Ljava/util/Optional;" to "List and int parameters, Optional return"
)
// Create signatures with complex descriptors
val complexMethod = JvmMethodSignature(
name = "processData",
descriptor = "(Ljava/util/Map;[Ljava/lang/String;I)Ljava/util/List;"
)Field descriptors are simpler, just the type descriptor:
// Examples of field descriptors
val fieldExamples = mapOf(
"I" to "int",
"Ljava/lang/String;" to "String",
"[I" to "int array",
"[[Ljava/lang/Object;" to "2D Object array",
"Ljava/util/List;" to "List (raw type)",
"Ljava/util/Map;" to "Map (raw type)"
)
// Create signatures with various field types
val arrayField = JvmFieldSignature("items", "[Ljava/lang/String;")
val mapField = JvmFieldSignature("properties", "Ljava/util/Map;")Using member signatures in metadata processing contexts.
// Example of using signatures in metadata analysis
fun analyzeClassMetadata(metadata: KotlinClassMetadata.Class) {
val klass = metadata.kmClass
// Collect method signatures from class metadata
val methodSignatures = mutableListOf<JvmMethodSignature>()
klass.functions.forEach { kmFunction ->
// Convert KmFunction to JvmMethodSignature
// (This would require additional metadata processing)
val signature = JvmMethodSignature(
name = kmFunction.name,
descriptor = buildMethodDescriptor(kmFunction)
)
methodSignatures.add(signature)
}
// Collect field signatures from properties
val fieldSignatures = mutableListOf<JvmFieldSignature>()
klass.properties.forEach { kmProperty ->
// Convert KmProperty to JvmFieldSignature
val signature = JvmFieldSignature(
name = kmProperty.name,
descriptor = buildFieldDescriptor(kmProperty)
)
fieldSignatures.add(signature)
}
println("Found ${methodSignatures.size} methods and ${fieldSignatures.size} fields")
}
// Helper functions (implementation would depend on kotlinx-metadata-core)
// These are example placeholders - actual implementation would analyze KmFunction/KmProperty
// to generate proper JVM descriptors based on parameter and return types
fun buildMethodDescriptor(kmFunction: KmFunction): String {
// Example: analyze kmFunction.valueParameters and kmFunction.returnType
// to build descriptor like "(Ljava/lang/String;I)V"
return "(...)" // Implementation specific to kotlinx-metadata-core
}
fun buildFieldDescriptor(kmProperty: KmProperty): String {
// Example: analyze kmProperty.returnType to build descriptor like "Ljava/lang/String;"
return "..." // Implementation specific to kotlinx-metadata-core
}JVM member signatures are commonly used for:
Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-metadata-jvm