[kotlinp] Support rendering KLIB metadata using "kotlinp" format
This commit includes: 1. New subproject :tools:kotlinp-klib that contains the facade for rendering the metadata in "kotlinp" format given just KlibModuleMetadata 2. A tool for computing (external) IR signatures that are not directly available in metadata: KlibKotlinpExternalSignatureComputer ^KT-62340
This commit is contained in:
committed by
Space Team
parent
ed30221f42
commit
83cc0d75a7
@@ -345,6 +345,7 @@
|
|||||||
/libraries/tools/kotlin-tooling-metadata/ "Kotlin Build Tools"
|
/libraries/tools/kotlin-tooling-metadata/ "Kotlin Build Tools"
|
||||||
/libraries/tools/kotlinp/ "Kotlin JVM" "Kotlin Common Backend"
|
/libraries/tools/kotlinp/ "Kotlin JVM" "Kotlin Common Backend"
|
||||||
/libraries/tools/kotlinp/jvm/ "Kotlin JVM"
|
/libraries/tools/kotlinp/jvm/ "Kotlin JVM"
|
||||||
|
/libraries/tools/kotlinp/klib/ "Kotlin Common Backend"
|
||||||
/libraries/tools/maven-archetypes/ "Kotlin Build Tools"
|
/libraries/tools/maven-archetypes/ "Kotlin Build Tools"
|
||||||
/libraries/tools/mutability-annotations-compat/ "Kotlin Libraries"
|
/libraries/tools/mutability-annotations-compat/ "Kotlin Libraries"
|
||||||
/libraries/tools/script-runtime/ "Kotlin Compiler Core"
|
/libraries/tools/script-runtime/ "Kotlin Compiler Core"
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
id("jps-compatible")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly(project(":kotlinx-metadata"))
|
||||||
|
compileOnly(project(":kotlinx-metadata-klib"))
|
||||||
|
|
||||||
|
api(project(":tools:kotlinp"))
|
||||||
|
|
||||||
|
testApi(intellijCore())
|
||||||
|
|
||||||
|
testCompileOnly(project(":kotlinx-metadata"))
|
||||||
|
testCompileOnly(project(":kotlinx-metadata-klib"))
|
||||||
|
|
||||||
|
testImplementation(libs.junit4)
|
||||||
|
testImplementation(projectTests(":compiler:tests-common"))
|
||||||
|
testImplementation(projectTests(":generators:test-generator"))
|
||||||
|
|
||||||
|
testRuntimeOnly(project(":kotlinx-metadata-klib"))
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
"main" { projectDefault() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.kotlinp.klib
|
||||||
|
|
||||||
|
sealed interface DeclarationId
|
||||||
|
sealed interface ClassifierId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a class or a type alias.
|
||||||
|
*
|
||||||
|
* @param qualifiedName the fully qualified name. Examples: `Outer`, `Outer.Nested`, `org/sample/Outer.Nested`.
|
||||||
|
*/
|
||||||
|
data class ClassOrTypeAliasId(val qualifiedName: String) : DeclarationId, ClassifierId, Comparable<ClassOrTypeAliasId> {
|
||||||
|
override fun compareTo(other: ClassOrTypeAliasId) = qualifiedName.compareTo(other.qualifiedName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a class constructor.
|
||||||
|
*
|
||||||
|
* @param qualifiedName the fully qualified name. Examples: `Outer.<init>`, `Outer.Nested.<init>`, `org/sample/Outer.Nested.<init>`.
|
||||||
|
* @param parameters value parameters.
|
||||||
|
*/
|
||||||
|
data class ConstructorId(val qualifiedName: String, val parameters: List<ParameterId>) : DeclarationId, Comparable<ConstructorId> {
|
||||||
|
override fun compareTo(other: ConstructorId) = COMPARATOR.compare(this, other)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMPARATOR = compareBy(ConstructorId::qualifiedName)
|
||||||
|
.thenByList(ConstructorId::parameters)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a function or a property accessor.
|
||||||
|
*
|
||||||
|
* @param qualifiedName the fully qualified name. Examples: `foo`, `org/sample/foo`, `Outer.foo`, `Outer.Nested.foo`,
|
||||||
|
* `org/sample/Outer.Nested.foo`, `<get-bar>`, `org/sample/<get-bar>`, `Outer.<get-bar>`, `Outer.Nested.<get-bar>`,
|
||||||
|
* `org/sample/Outer.Nested.<get-bar>`.
|
||||||
|
* @param contextReceivers context receivers.
|
||||||
|
* @param extensionReceiver extension receiver.
|
||||||
|
* @param parameters value parameters.
|
||||||
|
*/
|
||||||
|
data class FunctionId(
|
||||||
|
val qualifiedName: String,
|
||||||
|
val contextReceivers: List<TypeId>,
|
||||||
|
val extensionReceiver: TypeId?,
|
||||||
|
val parameters: List<ParameterId>,
|
||||||
|
val returnType: TypeId,
|
||||||
|
) : DeclarationId, Comparable<FunctionId> {
|
||||||
|
override fun compareTo(other: FunctionId) = COMPARATOR.compare(this, other)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMPARATOR = compareBy(FunctionId::qualifiedName)
|
||||||
|
.thenByList(FunctionId::contextReceivers)
|
||||||
|
.thenBy(FunctionId::extensionReceiver)
|
||||||
|
.thenByList(FunctionId::parameters)
|
||||||
|
.thenBy(FunctionId::returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a property.
|
||||||
|
*
|
||||||
|
* @param qualifiedName the fully qualified name. Examples: `foo`, `org/sample/foo`, `Outer.foo`, `Outer.Nested.foo`,
|
||||||
|
* `org/sample/Outer.Nested.foo`.
|
||||||
|
* @param contextReceivers context receivers.
|
||||||
|
* @param extensionReceiver extension receiver.
|
||||||
|
*/
|
||||||
|
data class PropertyId(
|
||||||
|
val qualifiedName: String,
|
||||||
|
val contextReceivers: List<TypeId>,
|
||||||
|
val extensionReceiver: TypeId?,
|
||||||
|
val returnType: TypeId,
|
||||||
|
) : DeclarationId, Comparable<PropertyId> {
|
||||||
|
override fun compareTo(other: PropertyId) = COMPARATOR.compare(this, other)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMPARATOR = compareBy(PropertyId::qualifiedName)
|
||||||
|
.thenByList(PropertyId::contextReceivers)
|
||||||
|
.thenBy(PropertyId::extensionReceiver)
|
||||||
|
.thenBy(PropertyId::returnType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a value parameter.
|
||||||
|
*
|
||||||
|
* @param name value parameter name.
|
||||||
|
* @param type value parameter type.
|
||||||
|
* @param isVararg if it is a vararg.
|
||||||
|
*/
|
||||||
|
data class ParameterId(val name: String, val type: TypeId, val isVararg: Boolean) : Comparable<ParameterId> {
|
||||||
|
constructor(type: TypeId, isVararg: Boolean) : this(IGNORED_NAME, type, isVararg)
|
||||||
|
|
||||||
|
override fun compareTo(other: ParameterId) = COMPARATOR.compare(this, other)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val IGNORED_NAME = "?"
|
||||||
|
|
||||||
|
private val COMPARATOR = compareBy(
|
||||||
|
ParameterId::type,
|
||||||
|
ParameterId::isVararg,
|
||||||
|
ParameterId::name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a type parameter.
|
||||||
|
*
|
||||||
|
* @param index the type parameter index.
|
||||||
|
*/
|
||||||
|
data class TypeParameterId(val index: Int) : ClassifierId, Comparable<TypeParameterId> {
|
||||||
|
override fun compareTo(other: TypeParameterId) = index.compareTo(other.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a type.
|
||||||
|
*
|
||||||
|
* @param classifier the classifier.
|
||||||
|
* @param arguments type arguments.
|
||||||
|
*/
|
||||||
|
data class TypeId(val classifier: ClassifierId, val arguments: List<TypeArgumentId>) : Comparable<TypeId> {
|
||||||
|
override fun compareTo(other: TypeId) = COMPARATOR.compare(this, other)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val UNIT = TypeId(ClassOrTypeAliasId("kotlin/Unit"), emptyList())
|
||||||
|
|
||||||
|
private val COMPARATOR = compareBy<TypeId>(
|
||||||
|
{ it.classifier as? ClassOrTypeAliasId },
|
||||||
|
{ it.classifier as? TypeParameterId }
|
||||||
|
).thenByList(TypeId::arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a type argument.
|
||||||
|
*/
|
||||||
|
sealed class TypeArgumentId : Comparable<TypeArgumentId> {
|
||||||
|
final override fun compareTo(other: TypeArgumentId) = COMPARATOR.compare(this, other)
|
||||||
|
|
||||||
|
data object Star : TypeArgumentId()
|
||||||
|
data class Regular(val type: TypeId, val variance: VarianceId) : TypeArgumentId()
|
||||||
|
|
||||||
|
enum class VarianceId { INVARIANT, IN, OUT }
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val COMPARATOR = Comparator<TypeArgumentId> { left, right ->
|
||||||
|
when {
|
||||||
|
left is Regular && right is Regular -> REGULAR_ARGUMENT_COMPARATOR.compare(left, right)
|
||||||
|
left is Regular -> 1
|
||||||
|
right is Regular -> -1
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val REGULAR_ARGUMENT_COMPARATOR = compareBy(Regular::type, Regular::variance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun <T, R : Comparable<R>> Comparator<T>.thenByList(
|
||||||
|
crossinline selector: (T) -> List<R>,
|
||||||
|
): Comparator<T> = Comparator { left, right ->
|
||||||
|
compare(left, right).let { if (it != 0) return@Comparator it }
|
||||||
|
|
||||||
|
val leftList = selector(left)
|
||||||
|
val rightList = selector(right)
|
||||||
|
|
||||||
|
leftList.size.compareTo(rightList.size).let { if (it != 0) return@Comparator it }
|
||||||
|
|
||||||
|
for (index in leftList.indices) {
|
||||||
|
leftList[index].compareTo(rightList[index]).let { if (it != 0) return@Comparator it }
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.kotlinp.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.klib.KlibEnumEntry
|
||||||
|
import org.jetbrains.kotlin.kotlinp.klib.TypeArgumentId.VarianceId
|
||||||
|
|
||||||
|
private fun KmClassifier.classifierId(): ClassifierId = when (this) {
|
||||||
|
is KmClassifier.Class -> ClassOrTypeAliasId(name)
|
||||||
|
is KmClassifier.TypeAlias -> ClassOrTypeAliasId(name)
|
||||||
|
is KmClassifier.TypeParameter -> TypeParameterId(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KmVariance.varianceId(): VarianceId = when (this) {
|
||||||
|
KmVariance.INVARIANT -> VarianceId.INVARIANT
|
||||||
|
KmVariance.IN -> VarianceId.IN
|
||||||
|
KmVariance.OUT -> VarianceId.OUT
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KmTypeProjection.typeArgumentId(): TypeArgumentId =
|
||||||
|
if (this == KmTypeProjection.STAR) {
|
||||||
|
TypeArgumentId.Star
|
||||||
|
} else {
|
||||||
|
val (variance, type) = this
|
||||||
|
check(variance != null && type != null) { "Variance and type should not be null" }
|
||||||
|
TypeArgumentId.Regular(type.typeId(), variance.varianceId())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KmType.typeId(): TypeId = TypeId(classifier.classifierId(), arguments.map { it.typeArgumentId() })
|
||||||
|
|
||||||
|
private fun KmValueParameter.valueParameterId(): ParameterId = ParameterId(name, type.typeId(), varargElementType != null)
|
||||||
|
|
||||||
|
internal fun KmClass.classId(): ClassOrTypeAliasId = ClassOrTypeAliasId(name)
|
||||||
|
internal fun KmClass.enumEntryId(enumEntry: KlibEnumEntry): ClassOrTypeAliasId = ClassOrTypeAliasId("$name.${enumEntry.name}")
|
||||||
|
internal fun KmTypeAlias.typeAliasId(containerNamePrefix: String): ClassOrTypeAliasId = ClassOrTypeAliasId("$containerNamePrefix$name")
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
|
fun KmFunction.functionId(containerNamePrefix: String): FunctionId = FunctionId(
|
||||||
|
qualifiedName = "$containerNamePrefix$name",
|
||||||
|
contextReceivers = contextReceiverTypes.map { it.typeId() },
|
||||||
|
extensionReceiver = receiverParameterType?.typeId(),
|
||||||
|
parameters = valueParameters.map { it.valueParameterId() },
|
||||||
|
returnType = returnType.typeId()
|
||||||
|
)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContextReceivers::class)
|
||||||
|
fun KmProperty.propertyId(containerNamePrefix: String): PropertyId = PropertyId(
|
||||||
|
qualifiedName = "$containerNamePrefix$name",
|
||||||
|
contextReceivers = contextReceiverTypes.map { it.typeId() },
|
||||||
|
extensionReceiver = receiverParameterType?.typeId(),
|
||||||
|
returnType = returnType.typeId()
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun KmProperty.getterId(propertyId: PropertyId): FunctionId = FunctionId(
|
||||||
|
qualifiedName = "${propertyId.qualifiedName.dropLast(name.length)}<get-$name>",
|
||||||
|
contextReceivers = propertyId.contextReceivers,
|
||||||
|
extensionReceiver = propertyId.extensionReceiver,
|
||||||
|
parameters = emptyList(),
|
||||||
|
returnType = propertyId.returnType
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun KmProperty.setterId(propertyId: PropertyId, setterParameter: KmValueParameter?): FunctionId = FunctionId(
|
||||||
|
qualifiedName = "${propertyId.qualifiedName.dropLast(name.length)}<set-$name>",
|
||||||
|
contextReceivers = propertyId.contextReceivers,
|
||||||
|
extensionReceiver = propertyId.extensionReceiver,
|
||||||
|
parameters = listOf(ParameterId((setterParameter?.type ?: returnType).typeId(), false)),
|
||||||
|
returnType = TypeId.UNIT
|
||||||
|
)
|
||||||
|
|
||||||
|
fun KmConstructor.constructorId(containerNamePrefix: String): ConstructorId = ConstructorId(
|
||||||
|
qualifiedName = "$containerNamePrefix<init>",
|
||||||
|
parameters = valueParameters.map { it.valueParameterId() }
|
||||||
|
)
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.kotlinp.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.klib.KlibEnumEntry
|
||||||
|
import kotlinx.metadata.klib.KlibModuleMetadata
|
||||||
|
import kotlinx.metadata.klib.fqName
|
||||||
|
import kotlinx.metadata.klib.klibEnumEntries
|
||||||
|
import java.util.IdentityHashMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An auxiliary tool that allows computing and caching IR signatures for the metadata declarations rendered
|
||||||
|
* by [KlibKotlinp]. Such signatures are not available directly in the metadata, but they can be computed by
|
||||||
|
* descriptors (K1) or Lazy IR built over FIR (K2) and then properly mapped to the corresponding `Km*` entities.
|
||||||
|
*/
|
||||||
|
class ExternalSignatureComputer(module: KlibModuleMetadata, getExternallyComputedSignature: (DeclarationId) -> String?) {
|
||||||
|
/**
|
||||||
|
* Note on [IdentityHashMap]: It's presence here might look strange. But in fact this is an approach that allows memorizing
|
||||||
|
* externally computed signatures and then looking up them using `Km*` entities as keys. I.e. no context needs to be maintained
|
||||||
|
* while traversing the `Km*`-tree (like: what is the containing declaration of a particular [KmFunction]?).
|
||||||
|
*/
|
||||||
|
private val signatures = IdentityHashMap<Any, String>()
|
||||||
|
private val getterSignatures = IdentityHashMap<KmProperty, String>()
|
||||||
|
private val setterSignatures = IdentityHashMap<KmProperty, String>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
fun visitDeclarationContainer(containerNamePrefix: String, container: KmDeclarationContainer) {
|
||||||
|
container.functions.forEach { function ->
|
||||||
|
signatures[function] = getExternallyComputedSignature(function.functionId(containerNamePrefix))
|
||||||
|
}
|
||||||
|
container.properties.forEach { property ->
|
||||||
|
val propertyId = property.propertyId(containerNamePrefix)
|
||||||
|
signatures[property] = getExternallyComputedSignature(propertyId)
|
||||||
|
getterSignatures[property] = getExternallyComputedSignature(property.getterId(propertyId))
|
||||||
|
if (property.setter != null) {
|
||||||
|
setterSignatures[property] = getExternallyComputedSignature(property.setterId(propertyId, property.setterParameter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.typeAliases.forEach { typeAlias ->
|
||||||
|
signatures[typeAlias] = getExternallyComputedSignature(typeAlias.typeAliasId(containerNamePrefix))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.fragments.forEach { fragment ->
|
||||||
|
fragment.classes.forEach { clazz ->
|
||||||
|
signatures[clazz] = getExternallyComputedSignature(clazz.classId())
|
||||||
|
val classNamePrefix = "${clazz.name}."
|
||||||
|
clazz.constructors.forEach { constructor ->
|
||||||
|
signatures[constructor] = getExternallyComputedSignature(constructor.constructorId(classNamePrefix))
|
||||||
|
}
|
||||||
|
visitDeclarationContainer(classNamePrefix, clazz)
|
||||||
|
clazz.klibEnumEntries.forEach { enumEntry ->
|
||||||
|
signatures[enumEntry] = getExternallyComputedSignature(clazz.enumEntryId(enumEntry))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment.pkg?.let {
|
||||||
|
val packageName = fragment.fqName?.replace('.', '/').orEmpty()
|
||||||
|
visitDeclarationContainer(if (packageName.isNotEmpty()) "$packageName/" else "", it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun classSignature(clazz: KmClass): String? = signatures[clazz]
|
||||||
|
fun enumEntrySignature(enumEntry: KlibEnumEntry): String? = signatures[enumEntry]
|
||||||
|
fun constructorSignature(constructor: KmConstructor): String? = signatures[constructor]
|
||||||
|
fun functionSignature(function: KmFunction): String? = signatures[function]
|
||||||
|
fun propertySignature(property: KmProperty): String? = signatures[property]
|
||||||
|
fun propertyGetterSignature(property: KmProperty): String? = getterSignatures[property]
|
||||||
|
fun propertySetterSignature(property: KmProperty): String? = setterSignatures[property]
|
||||||
|
fun typeAliasSignature(typeAlias: KmTypeAlias): String? = signatures[typeAlias]
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.kotlinp.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.internal.common.KmModuleFragment
|
||||||
|
import kotlinx.metadata.klib.*
|
||||||
|
import org.jetbrains.kotlin.kotlinp.Kotlinp
|
||||||
|
import org.jetbrains.kotlin.kotlinp.Settings
|
||||||
|
import org.jetbrains.kotlin.kotlinp.Printer
|
||||||
|
|
||||||
|
class KlibKotlinp(
|
||||||
|
settings: Settings,
|
||||||
|
private val signatureComputer: ExternalSignatureComputer?,
|
||||||
|
) : Kotlinp(settings) {
|
||||||
|
fun renderModule(module: KlibModuleMetadata, printer: Printer): Unit = with(printer) {
|
||||||
|
appendLine("library {")
|
||||||
|
withIndent {
|
||||||
|
appendCommentedLine("module name: ", module.name)
|
||||||
|
module.fragments.forEach { renderModuleFragment(it, printer) }
|
||||||
|
}
|
||||||
|
appendLine("}")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderModuleFragment(moduleFragment: KmModuleFragment, printer: Printer): Unit = with(printer) {
|
||||||
|
appendLine()
|
||||||
|
appendLine("library fragment {")
|
||||||
|
withIndent {
|
||||||
|
moduleFragment.fqName?.let {
|
||||||
|
appendCommentedLine("package name: ", it.ifEmpty { "<root>" })
|
||||||
|
}
|
||||||
|
if (moduleFragment.className.isNotEmpty()) {
|
||||||
|
appendLine()
|
||||||
|
moduleFragment.className.sortIfNeeded { it }.forEach {
|
||||||
|
appendCommentedLine("class name: ", it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
moduleFragment.classes.forEach { appendLine(); renderClass(it, printer) }
|
||||||
|
moduleFragment.pkg?.let { appendLine(); renderPackage(it, printer) }
|
||||||
|
}
|
||||||
|
appendLine("}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAnnotations(clazz: KmClass) = clazz.annotations
|
||||||
|
override fun getAnnotations(constructor: KmConstructor) = constructor.annotations
|
||||||
|
override fun getAnnotations(function: KmFunction) = function.annotations
|
||||||
|
override fun getAnnotations(property: KmProperty) = property.annotations
|
||||||
|
override fun getGetterAnnotations(property: KmProperty) = property.getterAnnotations
|
||||||
|
override fun getSetterAnnotations(property: KmProperty) = property.setterAnnotations
|
||||||
|
override fun getAnnotations(typeParameter: KmTypeParameter) = typeParameter.annotations
|
||||||
|
override fun getAnnotations(type: KmType) = type.annotations
|
||||||
|
override fun getAnnotations(valueParameter: KmValueParameter) = valueParameter.annotations
|
||||||
|
|
||||||
|
override fun Printer.appendSignatures(clazz: KmClass) = appendSignature { classSignature(clazz) }
|
||||||
|
override fun Printer.appendSignatures(constructor: KmConstructor) = appendSignature { constructorSignature(constructor) }
|
||||||
|
override fun Printer.appendSignatures(function: KmFunction) = appendSignature { functionSignature(function) }
|
||||||
|
override fun Printer.appendSignatures(property: KmProperty) = appendSignature { propertySignature(property) }
|
||||||
|
override fun Printer.appendGetterSignatures(property: KmProperty) = appendSignature { propertyGetterSignature(property) }
|
||||||
|
override fun Printer.appendSetterSignatures(property: KmProperty) = appendSignature { propertySetterSignature(property) }
|
||||||
|
override fun Printer.appendSignatures(typeAlias: KmTypeAlias) = appendSignature { typeAliasSignature(typeAlias) }
|
||||||
|
|
||||||
|
private inline fun Printer.appendSignature(extractSignature: ExternalSignatureComputer.() -> String?) {
|
||||||
|
val signature = signatureComputer?.let(extractSignature) ?: return
|
||||||
|
appendCommentedLine("signature: ", signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Printer.appendEnumEntries(clazz: KmClass) {
|
||||||
|
clazz.klibEnumEntries.forEach { enumEntry ->
|
||||||
|
appendLine()
|
||||||
|
appendSignature { enumEntrySignature(enumEntry) }
|
||||||
|
appendAnnotations(hasAnnotations = null, enumEntry.annotations)
|
||||||
|
appendLine(enumEntry.name, ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun Printer.appendCompileTimeConstant(property: KmProperty): Printer {
|
||||||
|
val compileTimeValue = property.compileTimeValue
|
||||||
|
if (compileTimeValue != null) {
|
||||||
|
renderAnnotationArgument(compileTimeValue, this)
|
||||||
|
return this
|
||||||
|
} else {
|
||||||
|
return append("...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -207,6 +207,7 @@ include ":kotlin-imports-dumper-compiler-plugin",
|
|||||||
":generators:tree-generator-common",
|
":generators:tree-generator-common",
|
||||||
":tools:kotlinp",
|
":tools:kotlinp",
|
||||||
":tools:kotlinp-jvm",
|
":tools:kotlinp-jvm",
|
||||||
|
":tools:kotlinp-klib",
|
||||||
":kotlin-build-tools-enum-compat",
|
":kotlin-build-tools-enum-compat",
|
||||||
":kotlin-gradle-compiler-types",
|
":kotlin-gradle-compiler-types",
|
||||||
":kotlin-gradle-plugin-api",
|
":kotlin-gradle-plugin-api",
|
||||||
@@ -768,6 +769,7 @@ project(':kotlin-assignment-compiler-plugin.embeddable').projectDir = "$rootDir/
|
|||||||
|
|
||||||
project(':tools:kotlinp').projectDir = "$rootDir/libraries/tools/kotlinp" as File
|
project(':tools:kotlinp').projectDir = "$rootDir/libraries/tools/kotlinp" as File
|
||||||
project(':tools:kotlinp-jvm').projectDir = "$rootDir/libraries/tools/kotlinp/jvm" as File
|
project(':tools:kotlinp-jvm').projectDir = "$rootDir/libraries/tools/kotlinp/jvm" as File
|
||||||
|
project(':tools:kotlinp-klib').projectDir = "$rootDir/libraries/tools/kotlinp/klib" as File
|
||||||
project(":kotlin-build-tools-enum-compat").projectDir = "$rootDir/libraries/tools/kotlin-build-tools-enum-compat" as File
|
project(":kotlin-build-tools-enum-compat").projectDir = "$rootDir/libraries/tools/kotlin-build-tools-enum-compat" as File
|
||||||
project(':kotlin-gradle-compiler-types').projectDir = "$rootDir/libraries/tools/kotlin-gradle-compiler-types" as File
|
project(':kotlin-gradle-compiler-types').projectDir = "$rootDir/libraries/tools/kotlin-gradle-compiler-types" as File
|
||||||
project(':kotlin-gradle-plugin-api').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-api" as File
|
project(':kotlin-gradle-plugin-api').projectDir = "$rootDir/libraries/tools/kotlin-gradle-plugin-api" as File
|
||||||
|
|||||||
Reference in New Issue
Block a user