[kotlinp] Refactor to separate common part from JVM-specific part

This refactoring includes the following:
1. Separate backend-neutral part of the metadata printer `Kotlinp`
   from the part that accesses JVM-specifics: `JvmKotlinp`.
2. Introduce `org.jetbrains.kotlin.kotlinp.Printer`: The component
   that renders both individual `Km*` nodes and the whole metadata
   tree, and does so with the proper indentation.

^KT-62340
This commit is contained in:
Dmitriy Dolovov
2024-02-02 17:24:39 +01:00
committed by Space Team
parent d769328311
commit eec76865a7
14 changed files with 979 additions and 924 deletions
@@ -12,7 +12,6 @@ import kotlinx.metadata.jvm.localDelegatedProperties
import kotlinx.metadata.jvm.signature
import org.jetbrains.kotlin.abicmp.reports.MetadataPropertyReport
import org.jetbrains.kotlin.abicmp.tasks.GenericMetadataTask
import org.jetbrains.kotlin.kotlinp.*
fun loadProperties(container: KmDeclarationContainer) = container.properties.associateBy { it.getterSignature?.toString() ?: it.name }
@@ -28,27 +27,6 @@ fun loadLocalDelegatedProperties(kmPackage: KmPackage) =
fun loadLocalDelegatedProperties(clazz: KotlinClassMetadata.Class) =
clazz.kmClass.localDelegatedProperties.associateBy { it.getterSignature?.toString() ?: it.name }
fun List<KmVersionRequirement>.stringifyRelevantRequirements() =
// older versions of requirements are redundant for compiler with version 1.9 or newer
filter { it.version.major >= 2 || (it.version.major == 1 && it.version.minor >= 8) }
.map(::printVersionRequirement).sorted().joinToString(prefix = "[", postfix = "]")
fun List<KmType>.stringifyTypeListSorted() = map(::printType).sorted().joinToString(prefix = "[", postfix = "]")
fun List<KmTypeParameter>.stringifyTypeParameters() = joinToString(prefix = "<", postfix = ">") { typeParam ->
printTypeParameter(
typeParam,
KotlinpSettings(
isVerbose = true,
sortDeclarations = true
)
)
}
fun List<KmValueParameter>.stringifyValueParameters() = joinToString(prefix = "(", postfix = ")", transform = ::printValueParameter)
fun List<KmAnnotation>.stringifyAnnotations() = joinToString(prefix = "[", postfix = "]", transform = ::renderAnnotation)
inline fun <R, T> checkMetadataMembers(
metadata1: R,
metadata2: R,
@@ -5,11 +5,8 @@
package org.jetbrains.kotlin.abicmp.tasks
import kotlinx.metadata.ExperimentalContextReceivers
import kotlinx.metadata.hasConstant
import kotlinx.metadata.isVar
import kotlinx.metadata.*
import kotlinx.metadata.jvm.*
import kotlinx.metadata.visibility
import org.jetbrains.kotlin.abicmp.*
import org.jetbrains.kotlin.abicmp.checkers.*
import org.jetbrains.kotlin.kotlinp.*
@@ -65,7 +62,7 @@ private val allFunctionMetadataCheckers = listOf(
functionMetadataPropertyChecker("modifiers") { printFunctionModifiers(it) },
functionMetadataPropertyChecker("typeParameters") { it.typeParameters.stringifyTypeParameters() },
functionMetadataPropertyChecker("receiverParameterType") {
it.receiverParameterType?.let { type -> printType(type) } ?: PROPERTY_VAL_STUB
it.receiverParameterType?.let(::printType) ?: PROPERTY_VAL_STUB
},
functionMetadataPropertyChecker("valueParameters") { it.valueParameters.stringifyValueParameters() },
functionMetadataPropertyChecker("contract") {
@@ -90,13 +87,13 @@ private val allPropertyMetadataCheckers = listOf(
propertyMetadataPropertyChecker("isVar") { it.isVar.toString() },
propertyMetadataPropertyChecker("typeParameters") { it.typeParameters.stringifyTypeParameters() },
propertyMetadataPropertyChecker("receiverParameterType") {
it.receiverParameterType?.let { type -> printType(type) } ?: PROPERTY_VAL_STUB
it.receiverParameterType?.let(::printType) ?: PROPERTY_VAL_STUB
},
propertyMetadataPropertyChecker("returnType") { printType(it.returnType) },
propertyMetadataPropertyChecker("hasConstant") { it.hasConstant.toString() },
propertyMetadataPropertyChecker("getterModifiers") { printPropertyAccessorModifiers(it.getter) },
propertyMetadataPropertyChecker("setterModifiers") {
it.setter?.let { setter -> printPropertyAccessorModifiers(setter) } ?: PROPERTY_VAL_STUB
it.setter?.let(::printPropertyAccessorModifiers) ?: PROPERTY_VAL_STUB
},
propertyMetadataPropertyChecker("setterValueParameter") {
it.setterParameter?.let { param -> printValueParameter(param) } ?: PROPERTY_VAL_STUB
@@ -134,12 +131,12 @@ private val allClassMetadataCheckers = listOf(
classMetadataPropertyChecker("typeParameters") { it.kmClass.typeParameters.stringifyTypeParameters() },
classMetadataPropertyChecker("superTypes") {
it.kmClass.supertypes.map { type -> printType(type) }.sorted().joinToString(prefix = "[", postfix = "]")
it.kmClass.supertypes.map(::printType).sorted().joinToString(prefix = "[", postfix = "]")
},
classMetadataPropertyChecker("companionObject") { it.kmClass.companionObject.toString() },
classMetadataPropertyChecker("inlineClassUnderlyingPropertyName") { it.kmClass.inlineClassUnderlyingPropertyName.toString() },
classMetadataPropertyChecker("inlineClassUnderlyingType") {
it.kmClass.inlineClassUnderlyingType?.let { type -> printType(type) } ?: "---"
it.kmClass.inlineClassUnderlyingType?.let(::printType) ?: "---"
},
classMetadataPropertyChecker("contextReceiverTypes") {
@OptIn(ExperimentalContextReceivers::class)
@@ -166,15 +163,7 @@ private val allMultifileClassPartMetadataCheckers = listOf(
private val allSyntheticClassMetadataCheckers = listOf(
syntheticClassMetadataPropertyChecker("isLambda") { it.isLambda.toString() },
syntheticClassMetadataPropertyChecker("function") {
it.kmLambda?.function?.let { function ->
printFunction(
function,
KotlinpSettings(
isVerbose = true,
sortDeclarations = true
)
)
} ?: PROPERTY_VAL_STUB
it.kmLambda?.function?.let(::printFunction) ?: PROPERTY_VAL_STUB
}
)
@@ -221,4 +210,39 @@ class CheckerConfiguration(private val enabledExclusively: Set<String>, private
if (enabledExclusively.isNotEmpty() && name !in enabledExclusively) return false
return name !in disabled
}
}
}
private val kotlinp = JvmKotlinp(Settings(isVerbose = true, sortDeclarations = true))
private fun renderAnnotation(annotation: KmAnnotation) = printString { kotlinp.renderAnnotation(annotation, this) }
private fun List<KmAnnotation>.stringifyAnnotations() = joinToString(prefix = "[", postfix = "]", transform = ::renderAnnotation)
private fun printFunction(function: KmFunction) = printString { kotlinp.renderFunction(function, this) }
private fun printConstructorModifiers(constructor: KmConstructor) = printString { kotlinp.renderConstructorModifiers(constructor, this) }
private fun printFunctionModifiers(function: KmFunction) = printString { kotlinp.renderFunctionModifiers(function, this) }
private fun printPropertyModifiers(property: KmProperty) = printString { kotlinp.renderPropertyModifiers(property, this) }
private fun printPropertyAccessorModifiers(accessorAttributes: KmPropertyAccessorAttributes) =
printString { kotlinp.renderPropertyAccessorModifiers(accessorAttributes, this) }
private fun printType(type: KmType) = printString { kotlinp.renderType(type, this) }
private fun List<KmType>.stringifyTypeListSorted() = map(::printType).sorted().joinToString(prefix = "[", postfix = "]")
private fun printTypeParameter(typeParameter: KmTypeParameter) =
printString { kotlinp.renderTypeParameter(typeParameter, this) }
private fun List<KmTypeParameter>.stringifyTypeParameters() = joinToString(prefix = "<", postfix = ">", transform = ::printTypeParameter)
private fun printValueParameter(valueParameter: KmValueParameter) = printString { kotlinp.renderValueParameter(valueParameter, this) }
private fun List<KmValueParameter>.stringifyValueParameters() = joinToString(prefix = "(", postfix = ")", transform = ::printValueParameter)
@OptIn(ExperimentalContracts::class)
private fun printContract(contract: KmContract) = printString { kotlinp.renderContract(contract, this) }
private fun printVersionRequirement(versionRequirement: KmVersionRequirement) =
printString { kotlinp.renderVersionRequirement(versionRequirement, this) }
private fun List<KmVersionRequirement>.stringifyRelevantRequirements() =
// older versions of requirements are redundant for compiler with version 1.9 or newer
filter { it.version.major >= 2 || (it.version.major == 1 && it.version.minor >= 8) }
.map(::printVersionRequirement).sorted().joinToString(prefix = "[", postfix = "]")
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.abicmp.isSynthetic
import org.jetbrains.kotlin.abicmp.reports.ClassReport
import org.jetbrains.kotlin.abicmp.reports.ListEntryDiff
import org.jetbrains.kotlin.abicmp.tag
import org.jetbrains.kotlin.kotlinp.Kotlinp
import org.jetbrains.kotlin.kotlinp.KotlinpSettings
import org.jetbrains.kotlin.kotlinp.Settings
import org.jetbrains.kotlin.kotlinp.JvmKotlinp
import org.jetbrains.kotlin.kotlinp.readKotlinClassHeader
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassWriter
@@ -50,7 +50,7 @@ class ClassTask(
return classReader.readKotlinClassHeader()?.run { KotlinClassMetadata.readStrict(this) }
}
val kotlinp = Kotlinp(KotlinpSettings(isVerbose = false, sortDeclarations = true))
val kotlinp = JvmKotlinp(Settings(isVerbose = false, sortDeclarations = true))
val metadata1 = class1.getMetadata()
val metadata2 = class2.getMetadata()
@@ -59,8 +59,8 @@ class ClassTask(
if (metadata1 == null || metadata2 == null) {
report.addMetadataDiff(
ListEntryDiff(
metadata1?.run { kotlinp.renderClassFile(metadata1) },
metadata2?.run { kotlinp.renderClassFile(metadata2) })
metadata1?.run { kotlinp.printClassFile(metadata1) },
metadata2?.run { kotlinp.printClassFile(metadata2) })
)
return
}