[Commonizer] Log stats during building metadata
This commit is contained in:
-6
@@ -30,9 +30,6 @@ internal fun CirClassNode.buildDescriptors(
|
||||
}
|
||||
|
||||
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, classId, isExpect = true)
|
||||
|
||||
// log stats
|
||||
components.statsCollector?.logStats(output)
|
||||
}
|
||||
|
||||
internal fun CirClass.buildDescriptor(
|
||||
@@ -86,9 +83,6 @@ internal fun CirClassConstructorNode.buildDescriptors(
|
||||
}
|
||||
|
||||
commonConstructor?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = true)
|
||||
|
||||
// log stats
|
||||
components.statsCollector?.logStats(output)
|
||||
}
|
||||
|
||||
private fun CirClassConstructor.buildDescriptor(
|
||||
|
||||
+2
-4
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.createKotlinNativeForwardDeclarationsModule
|
||||
@@ -121,8 +120,7 @@ class DeclarationsBuilderCache(private val dimension: Int) {
|
||||
class GlobalDeclarationsBuilderComponents(
|
||||
val storageManager: StorageManager,
|
||||
val targetComponents: List<TargetDeclarationsBuilderComponents>,
|
||||
val cache: DeclarationsBuilderCache,
|
||||
val statsCollector: StatsCollector?
|
||||
val cache: DeclarationsBuilderCache
|
||||
) {
|
||||
init {
|
||||
check(targetComponents.size > 1)
|
||||
@@ -274,7 +272,7 @@ fun CirRootNode.createGlobalBuilderComponents(
|
||||
)
|
||||
}
|
||||
|
||||
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache, parameters.statsCollector)
|
||||
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache)
|
||||
}
|
||||
|
||||
interface TypeParameterResolver {
|
||||
|
||||
-3
@@ -28,9 +28,6 @@ internal fun CirFunctionNode.buildDescriptors(
|
||||
}
|
||||
|
||||
commonFunction?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
|
||||
|
||||
// log stats
|
||||
components.statsCollector?.logStats(output)
|
||||
}
|
||||
|
||||
private fun CirFunction.buildDescriptor(
|
||||
|
||||
-3
@@ -20,9 +20,6 @@ internal fun CirModuleNode.buildDescriptors(
|
||||
}
|
||||
|
||||
commonDeclaration()?.buildDescriptor(components, output, indexOfCommon)
|
||||
|
||||
// log stats
|
||||
components.statsCollector?.logStats(output)
|
||||
}
|
||||
|
||||
private fun CirModule.buildDescriptor(
|
||||
|
||||
-3
@@ -37,9 +37,6 @@ internal fun CirPropertyNode.buildDescriptors(
|
||||
}
|
||||
|
||||
commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
|
||||
|
||||
// log stats
|
||||
components.statsCollector?.logStats(output)
|
||||
}
|
||||
|
||||
private fun CirProperty.buildDescriptor(
|
||||
|
||||
-3
@@ -41,9 +41,6 @@ internal fun CirTypeAliasNode.buildDescriptors(
|
||||
} else if (commonClassifier != null && commonClassifier is CirClass) {
|
||||
commonClassifier.buildDescriptor(components, output, indexOfCommon, containingDeclarations, classId, isExpect = true)
|
||||
}
|
||||
|
||||
// log stats
|
||||
components.statsCollector?.logStats(output)
|
||||
}
|
||||
|
||||
private fun CirTypeAlias.buildDescriptor(
|
||||
|
||||
@@ -43,7 +43,7 @@ fun runCommonization(parameters: CommonizerParameters): CommonizerResult {
|
||||
// optional part for generating descriptors: end
|
||||
|
||||
for (targetIndex in 0 until mergedTree.dimension) {
|
||||
val (target, metadataModules) = MetadataBuilder.build(mergedTree, targetIndex)
|
||||
val (target, metadataModules) = MetadataBuilder.build(mergedTree, targetIndex, parameters.statsCollector)
|
||||
|
||||
// optional part for generating descriptors: begin
|
||||
val moduleDescriptors: Map<String, ModuleDescriptor>? = components?.targetComponents?.get(targetIndex)?.let { component ->
|
||||
|
||||
+24
-24
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.backend.common.serialization.metadata.metadataVersio
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.konan.NativeDistributionCommonizer.StatsType.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.AggregatedStatsCollector
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.FileStatsOutput
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.RawStatsCollector
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.ResettableClockMark
|
||||
import org.jetbrains.kotlin.konan.library.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
@@ -132,36 +130,38 @@ class NativeDistributionCommonizer(
|
||||
|
||||
private fun commonize(allLibraries: AllNativeLibraries): CommonizerResult {
|
||||
val statsCollector = when (statsType) {
|
||||
RAW -> RawStatsCollector(targets, FileStatsOutput(destination, "raw"))
|
||||
AGGREGATED -> AggregatedStatsCollector(targets, FileStatsOutput(destination, "aggregated"))
|
||||
RAW -> RawStatsCollector(targets)
|
||||
AGGREGATED -> AggregatedStatsCollector(targets)
|
||||
NONE -> null
|
||||
}
|
||||
statsCollector.use {
|
||||
val parameters = CommonizerParameters(statsCollector, ::logProgress).apply {
|
||||
val storageManager = LockBasedStorageManager("Commonized modules")
|
||||
|
||||
val stdlibProvider = NativeDistributionStdlibProvider(storageManager, allLibraries.stdlib)
|
||||
dependeeModulesProvider = stdlibProvider
|
||||
val parameters = CommonizerParameters(statsCollector, ::logProgress).apply {
|
||||
val storageManager = LockBasedStorageManager("Commonized modules")
|
||||
|
||||
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
|
||||
if (librariesToCommonize.libraries.isEmpty()) return@forEach
|
||||
val stdlibProvider = NativeDistributionStdlibProvider(storageManager, allLibraries.stdlib)
|
||||
dependeeModulesProvider = stdlibProvider
|
||||
|
||||
val modulesProvider = NativeDistributionModulesProvider(storageManager, librariesToCommonize)
|
||||
allLibraries.librariesByTargets.forEach { (target, librariesToCommonize) ->
|
||||
if (librariesToCommonize.libraries.isEmpty()) return@forEach
|
||||
|
||||
addTarget(
|
||||
TargetProvider(
|
||||
target = target,
|
||||
builtInsClass = KonanBuiltIns::class.java,
|
||||
builtInsProvider = stdlibProvider,
|
||||
modulesProvider = modulesProvider,
|
||||
dependeeModulesProvider = null // stdlib is already set as common dependency
|
||||
)
|
||||
val modulesProvider = NativeDistributionModulesProvider(storageManager, librariesToCommonize)
|
||||
|
||||
addTarget(
|
||||
TargetProvider(
|
||||
target = target,
|
||||
builtInsClass = KonanBuiltIns::class.java,
|
||||
builtInsProvider = stdlibProvider,
|
||||
modulesProvider = modulesProvider,
|
||||
dependeeModulesProvider = null // stdlib is already set as common dependency
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return runCommonization(parameters)
|
||||
}
|
||||
|
||||
val result = runCommonization(parameters)
|
||||
statsCollector?.writeTo(FileStatsOutput(destination, statsType.name.toLowerCase()))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun saveModules(originalLibraries: AllNativeLibraries, result: CommonizerResult) {
|
||||
|
||||
+6
-6
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.name.Name
|
||||
|
||||
/** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */
|
||||
data class PropertyApproximationKey(
|
||||
private val name: Name,
|
||||
private val extensionReceiverParameterType: CirTypeSignature?
|
||||
val name: Name,
|
||||
val extensionReceiverParameterType: CirTypeSignature?
|
||||
) {
|
||||
constructor(property: PropertyDescriptor) : this(
|
||||
property.name.intern(),
|
||||
@@ -26,10 +26,10 @@ data class PropertyApproximationKey(
|
||||
|
||||
/** Used for approximation of [SimpleFunctionDescriptor]s before running concrete [Commonizer]s */
|
||||
data class FunctionApproximationKey(
|
||||
private val name: Name,
|
||||
private val valueParametersTypes: Array<CirTypeSignature>,
|
||||
val name: Name,
|
||||
val valueParametersTypes: Array<CirTypeSignature>,
|
||||
private val additionalValueParametersNamesHash: Int,
|
||||
private val extensionReceiverParameterType: CirTypeSignature?
|
||||
val extensionReceiverParameterType: CirTypeSignature?
|
||||
) {
|
||||
constructor(function: SimpleFunctionDescriptor) : this(
|
||||
function.name.intern(),
|
||||
@@ -56,7 +56,7 @@ data class FunctionApproximationKey(
|
||||
|
||||
/** Used for approximation of [ConstructorDescriptor]s before running concrete [Commonizer]s */
|
||||
data class ConstructorApproximationKey(
|
||||
private val valueParametersTypes: Array<CirTypeSignature>,
|
||||
val valueParametersTypes: Array<CirTypeSignature>,
|
||||
private val additionalValueParametersNamesHash: Int
|
||||
) {
|
||||
constructor(constructor: ConstructorDescriptor) : this(
|
||||
|
||||
+15
-16
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirValueParameterImp
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.metadata.TypeAliasExpansion.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.DEFAULT_SETTER_VALUE_NAME
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.strip
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -72,7 +73,7 @@ internal fun addEmptyFragments(fragments: MutableCollection<KmModuleFragment>) {
|
||||
}
|
||||
|
||||
internal fun CirClass.buildClass(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
className: ClassName,
|
||||
directNestedClasses: Collection<KmClass>,
|
||||
nestedConstructors: Collection<KmConstructor>,
|
||||
@@ -122,7 +123,7 @@ internal fun linkSealedClassesWithSubclasses(packageFqName: FqName, classConsume
|
||||
}
|
||||
|
||||
internal fun CirClassConstructor.buildClassConstructor(
|
||||
context: VisitingContext
|
||||
context: MetadataBuildingVisitorContext
|
||||
): KmConstructor = KmConstructor(
|
||||
flags = classConstructorFlags()
|
||||
).also { constructor ->
|
||||
@@ -131,7 +132,7 @@ internal fun CirClassConstructor.buildClassConstructor(
|
||||
}
|
||||
|
||||
internal fun CirTypeAlias.buildTypeAlias(
|
||||
context: VisitingContext
|
||||
context: MetadataBuildingVisitorContext
|
||||
): KmTypeAlias = KmTypeAlias(
|
||||
flags = typeAliasFlags(),
|
||||
name = name.asString()
|
||||
@@ -143,7 +144,7 @@ internal fun CirTypeAlias.buildTypeAlias(
|
||||
}
|
||||
|
||||
internal fun CirProperty.buildProperty(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
): KmProperty = KmProperty(
|
||||
flags = propertyFlags(isExpect = context.isCommon && !isLiftedUp),
|
||||
name = name.asString(),
|
||||
@@ -162,7 +163,7 @@ internal fun CirProperty.buildProperty(
|
||||
setter?.takeIf { !it.isDefault }?.let { setter ->
|
||||
property.setterParameter = CirValueParameterImpl(
|
||||
annotations = setter.parameterAnnotations,
|
||||
name = SETTER_VALUE_NAME,
|
||||
name = DEFAULT_SETTER_VALUE_NAME,
|
||||
returnType = returnType,
|
||||
varargElementType = null,
|
||||
declaresDefaultValue = false,
|
||||
@@ -174,7 +175,7 @@ internal fun CirProperty.buildProperty(
|
||||
}
|
||||
|
||||
internal fun CirFunction.buildFunction(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
): KmFunction = KmFunction(
|
||||
flags = functionFlags(isExpect = context.isCommon),
|
||||
name = name.asString()
|
||||
@@ -231,7 +232,7 @@ private fun ConstantValue<*>.buildAnnotationArgument(): KmAnnotationArgument<*>
|
||||
}
|
||||
|
||||
private fun CirValueParameter.buildValueParameter(
|
||||
context: VisitingContext
|
||||
context: MetadataBuildingVisitorContext
|
||||
): KmValueParameter = KmValueParameter(
|
||||
flags = valueParameterFlags(),
|
||||
name = name.asString()
|
||||
@@ -244,7 +245,7 @@ private fun CirValueParameter.buildValueParameter(
|
||||
}
|
||||
|
||||
private fun List<CirTypeParameter>.buildTypeParameters(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
output: MutableList<KmTypeParameter>
|
||||
) {
|
||||
mapIndexedTo(output) { index, cirTypeParameter ->
|
||||
@@ -261,7 +262,7 @@ private fun List<CirTypeParameter>.buildTypeParameters(
|
||||
}
|
||||
|
||||
private fun CirType.buildType(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
expansion: TypeAliasExpansion = FOR_TOP_LEVEL_TYPE
|
||||
): KmType = when (this) {
|
||||
is CirClassType -> buildType(context, expansion)
|
||||
@@ -283,7 +284,7 @@ private fun CirTypeParameterType.buildType(): KmType =
|
||||
}
|
||||
|
||||
private fun CirClassType.buildType(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
expansion: TypeAliasExpansion
|
||||
): KmType = KmType(typeFlags()).also { type ->
|
||||
type.classifier = KmClassifier.Class(classifierId.asString())
|
||||
@@ -292,7 +293,7 @@ private fun CirClassType.buildType(
|
||||
}
|
||||
|
||||
private fun CirTypeAliasType.buildType(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
expansion: TypeAliasExpansion
|
||||
): KmType = when (expansion) {
|
||||
ONLY_ABBREVIATIONS -> buildAbbreviationType(context, expansion)
|
||||
@@ -306,7 +307,7 @@ private fun CirTypeAliasType.buildType(
|
||||
}
|
||||
|
||||
private fun CirTypeAliasType.buildAbbreviationType(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
expansion: TypeAliasExpansion
|
||||
): KmType {
|
||||
val abbreviationType = KmType(typeFlags())
|
||||
@@ -317,7 +318,7 @@ private fun CirTypeAliasType.buildAbbreviationType(
|
||||
|
||||
@Suppress("UnnecessaryVariable")
|
||||
private fun CirTypeAliasType.buildExpandedType(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
expansion: TypeAliasExpansion
|
||||
): KmType {
|
||||
val cirExpandedType = computeExpandedType(underlyingType)
|
||||
@@ -326,7 +327,7 @@ private fun CirTypeAliasType.buildExpandedType(
|
||||
}
|
||||
|
||||
private fun CirTypeProjection.buildArgument(
|
||||
context: VisitingContext,
|
||||
context: MetadataBuildingVisitorContext,
|
||||
expansion: TypeAliasExpansion
|
||||
): KmTypeProjection {
|
||||
val effectiveExpansion = if (expansion == FOR_TOP_LEVEL_TYPE) FOR_NESTED_TYPE else expansion
|
||||
@@ -353,5 +354,3 @@ private enum class TypeAliasExpansion {
|
||||
FOR_TOP_LEVEL_TYPE,
|
||||
FOR_NESTED_TYPE
|
||||
}
|
||||
|
||||
private val SETTER_VALUE_NAME = Name.identifier("value")
|
||||
|
||||
+452
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.descriptors.commonizer.metadata
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import kotlinx.metadata.klib.KlibModuleMetadata
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.DeclarationType
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector.StatsKey
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.DEFAULT_CONSTRUCTOR_NAME
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.strip
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.metadata.MetadataBuildingVisitorContext.Path
|
||||
|
||||
internal object MetadataBuilder {
|
||||
fun build(
|
||||
node: CirRootNode,
|
||||
targetIndex: Int,
|
||||
statsCollector: StatsCollector?
|
||||
): Pair<CommonizerTarget, Collection<KlibModuleMetadata>> {
|
||||
return node.accept(
|
||||
MetadataBuildingVisitor(statsCollector),
|
||||
MetadataBuildingVisitorContext.rootContext(node, targetIndex)
|
||||
).cast()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
private class MetadataBuildingVisitor(private val statsCollector: StatsCollector?) : CirNodeVisitor<MetadataBuildingVisitorContext, Any?> {
|
||||
private val classConsumer = ClassConsumer()
|
||||
|
||||
override fun visitRootNode(
|
||||
node: CirRootNode,
|
||||
rootContext: MetadataBuildingVisitorContext
|
||||
): Pair<CommonizerTarget, Collection<KlibModuleMetadata>> {
|
||||
val modules: List<KlibModuleMetadata> = node.modules.mapNotNull { (moduleName, moduleNode) ->
|
||||
val moduleContext = rootContext.moduleContext(moduleName)
|
||||
val module: KlibModuleMetadata? = moduleNode.accept(this, moduleContext)?.cast()
|
||||
statsCollector?.logModule(moduleContext)
|
||||
module
|
||||
}
|
||||
|
||||
return rootContext.target to modules
|
||||
}
|
||||
|
||||
override fun visitModuleNode(
|
||||
node: CirModuleNode,
|
||||
moduleContext: MetadataBuildingVisitorContext
|
||||
): KlibModuleMetadata? {
|
||||
val cirModule = moduleContext.get<CirModule>(node) ?: return null
|
||||
|
||||
val fragments: MutableCollection<KmModuleFragment> = mutableListOf()
|
||||
node.packages.mapNotNullTo(fragments) { (packageFqName, packageNode) ->
|
||||
val packageContext = moduleContext.packageContext(packageFqName)
|
||||
packageNode.accept(this, packageContext)?.cast()
|
||||
}
|
||||
|
||||
addEmptyFragments(fragments)
|
||||
|
||||
return cirModule.buildModule(fragments)
|
||||
}
|
||||
|
||||
override fun visitPackageNode(
|
||||
node: CirPackageNode,
|
||||
packageContext: MetadataBuildingVisitorContext
|
||||
): KmModuleFragment? {
|
||||
val cirPackage = packageContext.get<CirPackage>(node) ?: return null
|
||||
|
||||
try {
|
||||
node.classes.forEach { (className, classNode) ->
|
||||
val classContext = packageContext.classifierContext(className)
|
||||
val clazz: KmClass = classNode.accept(this, classContext)?.cast() ?: return@forEach
|
||||
classConsumer.consume(clazz)
|
||||
statsCollector?.logClass(clazz, classContext)
|
||||
}
|
||||
|
||||
val topLevelTypeAliases = mutableListOf<KmTypeAlias>()
|
||||
node.typeAliases.forEach { (typeAliasName, typeAliasNode) ->
|
||||
val typeAliasContext = packageContext.classifierContext(typeAliasName)
|
||||
when (val classifier = typeAliasNode.accept(this, typeAliasContext)) {
|
||||
null -> Unit
|
||||
is KmClass -> {
|
||||
classConsumer.consume(classifier)
|
||||
statsCollector?.logClass(classifier, typeAliasContext)
|
||||
}
|
||||
is KmTypeAlias -> {
|
||||
topLevelTypeAliases += classifier
|
||||
statsCollector?.logTypeAlias(typeAliasContext)
|
||||
}
|
||||
else -> error("Unexpected classifier: ${classifier::class.java}, $classifier")
|
||||
}
|
||||
}
|
||||
|
||||
linkSealedClassesWithSubclasses(cirPackage.fqName, classConsumer)
|
||||
|
||||
val topLevelFunctions: Collection<KmFunction> = node.functions.mapNotNull { (functionKey, functionNode) ->
|
||||
val functionContext = packageContext.callableMemberContext(functionKey.name)
|
||||
val function: KmFunction = functionNode.accept(this, functionContext)?.cast() ?: return@mapNotNull null
|
||||
statsCollector?.logFunction(function, functionContext, functionKey)
|
||||
function
|
||||
}
|
||||
|
||||
val topLevelProperties: Collection<KmProperty> = node.properties.mapNotNull { (propertyKey, propertyNode) ->
|
||||
val propertyContext = packageContext.callableMemberContext(propertyKey.name)
|
||||
val property: KmProperty = propertyNode.accept(this, propertyContext)?.cast() ?: return@mapNotNull null
|
||||
statsCollector?.logProperty(propertyContext, propertyKey, propertyNode)
|
||||
property
|
||||
}
|
||||
|
||||
return cirPackage.buildModuleFragment(classConsumer.allClasses, topLevelTypeAliases, topLevelFunctions, topLevelProperties)
|
||||
} finally {
|
||||
// Important: clean-up class consumer every time when leaving package
|
||||
classConsumer.reset()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPropertyNode(
|
||||
node: CirPropertyNode,
|
||||
propertyContext: MetadataBuildingVisitorContext
|
||||
): KmProperty? {
|
||||
return propertyContext.get<CirProperty>(node)?.buildProperty(propertyContext)
|
||||
}
|
||||
|
||||
override fun visitFunctionNode(
|
||||
node: CirFunctionNode,
|
||||
functionContext: MetadataBuildingVisitorContext
|
||||
): KmFunction? {
|
||||
return functionContext.get<CirFunction>(node)?.buildFunction(functionContext)
|
||||
}
|
||||
|
||||
override fun visitClassNode(
|
||||
node: CirClassNode,
|
||||
classContext: MetadataBuildingVisitorContext
|
||||
): KmClass? {
|
||||
val cirClass = classContext.get<CirClass>(node) ?: return null
|
||||
val classTypeParametersCount = cirClass.typeParameters.size
|
||||
val fullClassName = classContext.currentPath.toString()
|
||||
|
||||
val directNestedClasses: Collection<KmClass> = node.classes.mapNotNull { (nestedClassName, nestedClassNode) ->
|
||||
val isInnerClass = classContext.get<CirClass>(nestedClassNode)?.isInner ?: return@mapNotNull null
|
||||
val outerClassTypeParametersCount = if (isInnerClass) classTypeParametersCount else 0
|
||||
val nestedClassContext = classContext.classifierContext(nestedClassName, isInnerClass, outerClassTypeParametersCount)
|
||||
val nestedClass: KmClass = nestedClassNode.accept(this, nestedClassContext)?.cast() ?: return@mapNotNull null
|
||||
classConsumer.consume(nestedClass)
|
||||
statsCollector?.logClass(nestedClass, nestedClassContext)
|
||||
nestedClass
|
||||
}
|
||||
|
||||
val nestedConstructors: Collection<KmConstructor> = node.constructors.mapNotNull { (constructorKey, constructorNode) ->
|
||||
val constructorContext = classContext.callableMemberContext(DEFAULT_CONSTRUCTOR_NAME, classTypeParametersCount)
|
||||
val constructor: KmConstructor = constructorNode.accept(this, constructorContext)?.cast() ?: return@mapNotNull null
|
||||
statsCollector?.logClassConstructor(constructor, constructorContext, constructorKey)
|
||||
constructor
|
||||
}
|
||||
|
||||
val nestedFunctions: Collection<KmFunction> = node.functions.mapNotNull { (functionKey, functionNode) ->
|
||||
val functionContext = classContext.callableMemberContext(functionKey.name, classTypeParametersCount)
|
||||
val function: KmFunction = functionNode.accept(this, functionContext)?.cast() ?: return@mapNotNull null
|
||||
statsCollector?.logFunction(function, functionContext, functionKey)
|
||||
function
|
||||
}
|
||||
|
||||
val nestedProperties: Collection<KmProperty> = node.properties.mapNotNull { (propertyKey, propertyNode) ->
|
||||
val propertyContext = classContext.callableMemberContext(propertyKey.name, classTypeParametersCount)
|
||||
val property: KmProperty = propertyNode.accept(this, propertyContext)?.cast() ?: return@mapNotNull null
|
||||
statsCollector?.logProperty(propertyContext, propertyKey, propertyNode)
|
||||
property
|
||||
}
|
||||
|
||||
return cirClass.buildClass(classContext, fullClassName, directNestedClasses, nestedConstructors, nestedFunctions, nestedProperties)
|
||||
}
|
||||
|
||||
override fun visitClassConstructorNode(
|
||||
node: CirClassConstructorNode,
|
||||
constructorContext: MetadataBuildingVisitorContext
|
||||
): KmConstructor? {
|
||||
return constructorContext.get<CirClassConstructor>(node)?.buildClassConstructor(constructorContext)
|
||||
}
|
||||
|
||||
override fun visitTypeAliasNode(
|
||||
node: CirTypeAliasNode,
|
||||
typeAliasContext: MetadataBuildingVisitorContext
|
||||
): Any? {
|
||||
val cirClassifier = typeAliasContext.get<CirClassifier>(node) ?: return null
|
||||
|
||||
return when (cirClassifier) {
|
||||
is CirTypeAlias -> cirClassifier.buildTypeAlias(typeAliasContext)
|
||||
is CirClass -> {
|
||||
val fullClassName = typeAliasContext.currentPath.toString()
|
||||
cirClassifier.buildClass(typeAliasContext, fullClassName, emptyList(), emptyList(), emptyList(), emptyList())
|
||||
}
|
||||
else -> error("Unexpected CIR classifier: ${cirClassifier::class.java}, $cirClassifier")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun StatsCollector.logModule(
|
||||
moduleContext: MetadataBuildingVisitorContext
|
||||
) = logDeclaration(moduleContext.targetIndex) {
|
||||
StatsKey(moduleContext.currentPath.toString(), DeclarationType.MODULE)
|
||||
}
|
||||
|
||||
private fun StatsCollector.logClass(
|
||||
clazz: KmClass,
|
||||
classContext: MetadataBuildingVisitorContext
|
||||
) = logDeclaration(classContext.targetIndex) {
|
||||
val declarationType = when {
|
||||
Flag.Class.IS_ENUM_CLASS(clazz.flags) -> DeclarationType.ENUM_CLASS
|
||||
Flag.Class.IS_ENUM_ENTRY(clazz.flags) -> DeclarationType.ENUM_ENTRY
|
||||
Flag.Class.IS_INTERFACE(clazz.flags) -> when {
|
||||
(classContext.currentPath as Path.Classifier).classifierId.isNestedClass -> DeclarationType.NESTED_INTERFACE
|
||||
else -> DeclarationType.TOP_LEVEL_INTERFACE
|
||||
}
|
||||
else -> when {
|
||||
Flag.Class.IS_COMPANION_OBJECT(clazz.flags) -> DeclarationType.COMPANION_OBJECT
|
||||
(classContext.currentPath as Path.Classifier).classifierId.isNestedClass -> DeclarationType.NESTED_CLASS
|
||||
else -> DeclarationType.TOP_LEVEL_CLASS
|
||||
}
|
||||
}
|
||||
|
||||
StatsKey(classContext.currentPath.toString(), declarationType)
|
||||
}
|
||||
|
||||
private fun StatsCollector.logTypeAlias(
|
||||
typeAliasContext: MetadataBuildingVisitorContext
|
||||
) = logDeclaration(typeAliasContext.targetIndex) {
|
||||
StatsKey(typeAliasContext.currentPath.toString(), DeclarationType.TYPE_ALIAS)
|
||||
}
|
||||
|
||||
private fun StatsCollector.logProperty(
|
||||
propertyContext: MetadataBuildingVisitorContext,
|
||||
propertyKey: PropertyApproximationKey,
|
||||
propertyNode: CirPropertyNode
|
||||
) = logDeclaration(propertyContext.targetIndex) {
|
||||
val declarationType = when {
|
||||
(propertyContext.currentPath as Path.CallableMember).memberId.isNestedClass -> DeclarationType.NESTED_VAL
|
||||
propertyNode.targetDeclarations.firstNonNull().isConst -> DeclarationType.TOP_LEVEL_CONST_VAL
|
||||
else -> DeclarationType.TOP_LEVEL_VAL
|
||||
}
|
||||
|
||||
StatsKey(
|
||||
id = propertyContext.currentPath.toString(),
|
||||
extensionReceiver = propertyKey.extensionReceiverParameterType,
|
||||
parameterNames = emptyList(),
|
||||
parameterTypes = emptyList(),
|
||||
declarationType = declarationType
|
||||
)
|
||||
}
|
||||
|
||||
private fun StatsCollector.logFunction(
|
||||
function: KmFunction,
|
||||
functionContext: MetadataBuildingVisitorContext,
|
||||
functionKey: FunctionApproximationKey
|
||||
) = logDeclaration(functionContext.targetIndex) {
|
||||
val declarationType = when {
|
||||
(functionContext.currentPath as Path.CallableMember).memberId.isNestedClass -> DeclarationType.NESTED_FUN
|
||||
else -> DeclarationType.TOP_LEVEL_FUN
|
||||
}
|
||||
|
||||
StatsKey(
|
||||
id = functionContext.currentPath.toString(),
|
||||
extensionReceiver = functionKey.extensionReceiverParameterType,
|
||||
parameterNames = function.valueParameters.map { it.name },
|
||||
parameterTypes = functionKey.valueParametersTypes.asList(),
|
||||
declarationType = declarationType
|
||||
)
|
||||
}
|
||||
|
||||
private fun StatsCollector.logClassConstructor(
|
||||
constructor: KmConstructor,
|
||||
constructorContext: MetadataBuildingVisitorContext,
|
||||
constructorKey: ConstructorApproximationKey
|
||||
) = logDeclaration(constructorContext.targetIndex) {
|
||||
StatsKey(
|
||||
id = constructorContext.currentPath.toString(),
|
||||
extensionReceiver = null,
|
||||
parameterNames = constructor.valueParameters.map { it.name },
|
||||
parameterTypes = constructorKey.valueParametersTypes.asList(),
|
||||
declarationType = DeclarationType.CLASS_CONSTRUCTOR
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal data class MetadataBuildingVisitorContext(
|
||||
val targetIndex: Int,
|
||||
val target: CommonizerTarget,
|
||||
val isCommon: Boolean,
|
||||
val typeParameterIndexOffset: Int,
|
||||
val currentPath: Path
|
||||
) {
|
||||
sealed class Path {
|
||||
object Empty : Path() {
|
||||
override fun toString() = ""
|
||||
}
|
||||
|
||||
class Module(val moduleName: Name) : Path() {
|
||||
override fun toString() = moduleName.strip()
|
||||
}
|
||||
|
||||
class Package(val packageFqName: FqName) : Path() {
|
||||
fun nestedClassifier(classifierName: Name) = Classifier(ClassId(packageFqName, classifierName))
|
||||
fun nestedCallableMember(memberName: Name) = CallableMember(ClassId(packageFqName, memberName))
|
||||
|
||||
override fun toString() = packageFqName.asString()
|
||||
}
|
||||
|
||||
class Classifier(val classifierId: ClassId) : Path() {
|
||||
fun nestedClassifier(classifierName: Name) = Classifier(classifierId.createNestedClassId(classifierName))
|
||||
fun nestedCallableMember(memberName: Name) = CallableMember(classifierId.createNestedClassId(memberName))
|
||||
|
||||
override fun toString() = classifierId.asString()
|
||||
}
|
||||
|
||||
class CallableMember(val memberId: ClassId) : Path() {
|
||||
override fun toString() = memberId.asString()
|
||||
}
|
||||
}
|
||||
|
||||
fun moduleContext(moduleName: Name): MetadataBuildingVisitorContext {
|
||||
check(moduleName.isSpecial)
|
||||
check(currentPath is Path.Empty)
|
||||
|
||||
return MetadataBuildingVisitorContext(
|
||||
targetIndex = targetIndex,
|
||||
target = target,
|
||||
isCommon = isCommon,
|
||||
typeParameterIndexOffset = 0,
|
||||
currentPath = Path.Module(moduleName)
|
||||
)
|
||||
}
|
||||
|
||||
fun packageContext(packageFqName: FqName): MetadataBuildingVisitorContext {
|
||||
check(currentPath is Path.Module)
|
||||
|
||||
return MetadataBuildingVisitorContext(
|
||||
targetIndex = targetIndex,
|
||||
target = target,
|
||||
isCommon = isCommon,
|
||||
typeParameterIndexOffset = 0,
|
||||
currentPath = Path.Package(packageFqName)
|
||||
)
|
||||
}
|
||||
|
||||
fun classifierContext(
|
||||
classifierName: Name,
|
||||
isInner: Boolean = false,
|
||||
outerClassTypeParametersCount: Int = 0
|
||||
): MetadataBuildingVisitorContext {
|
||||
val newPath = when (currentPath) {
|
||||
is Path.Package -> {
|
||||
check(!isInner)
|
||||
check(outerClassTypeParametersCount == 0)
|
||||
currentPath.nestedClassifier(classifierName)
|
||||
}
|
||||
is Path.Classifier -> {
|
||||
check((isInner && outerClassTypeParametersCount >= 0) || (!isInner && outerClassTypeParametersCount == 0))
|
||||
currentPath.nestedClassifier(classifierName)
|
||||
}
|
||||
else -> error("Illegal state")
|
||||
}
|
||||
|
||||
return MetadataBuildingVisitorContext(
|
||||
targetIndex = targetIndex,
|
||||
target = target,
|
||||
isCommon = isCommon,
|
||||
typeParameterIndexOffset = if (isInner) typeParameterIndexOffset + outerClassTypeParametersCount else 0,
|
||||
currentPath = newPath
|
||||
)
|
||||
}
|
||||
|
||||
fun callableMemberContext(
|
||||
memberName: Name,
|
||||
ownerClassTypeParametersCount: Int = 0
|
||||
): MetadataBuildingVisitorContext {
|
||||
val newPath = when (currentPath) {
|
||||
is Path.Package -> {
|
||||
check(ownerClassTypeParametersCount == 0)
|
||||
currentPath.nestedCallableMember(memberName)
|
||||
}
|
||||
is Path.Classifier -> {
|
||||
check(ownerClassTypeParametersCount >= 0)
|
||||
currentPath.nestedCallableMember(memberName)
|
||||
}
|
||||
else -> error("Illegal state")
|
||||
}
|
||||
|
||||
return MetadataBuildingVisitorContext(
|
||||
targetIndex = targetIndex,
|
||||
target = target,
|
||||
isCommon = isCommon,
|
||||
typeParameterIndexOffset = typeParameterIndexOffset + ownerClassTypeParametersCount,
|
||||
currentPath = newPath
|
||||
)
|
||||
}
|
||||
|
||||
inline fun <reified T : CirDeclaration> get(node: CirNode<*, *>): T? {
|
||||
return (if (isCommon) node.commonDeclaration() else node.targetDeclarations[targetIndex]) as T?
|
||||
}
|
||||
|
||||
inline fun <reified T : CirDeclaration> get(node: CirNodeWithLiftingUp<*, *>): T? {
|
||||
return when {
|
||||
isCommon -> node.commonDeclaration() as T?
|
||||
node.isLiftedUp -> null
|
||||
else -> node.targetDeclarations[targetIndex] as T?
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun rootContext(rootNode: CirRootNode, targetIndex: Int): MetadataBuildingVisitorContext {
|
||||
val isCommon = rootNode.indexOfCommon == targetIndex
|
||||
val target = (if (isCommon) rootNode.commonDeclaration() else rootNode.targetDeclarations[targetIndex])!!.target
|
||||
|
||||
return MetadataBuildingVisitorContext(
|
||||
targetIndex = targetIndex,
|
||||
target = target,
|
||||
isCommon = isCommon,
|
||||
typeParameterIndexOffset = 0,
|
||||
currentPath = Path.Empty
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ClassConsumer {
|
||||
private val _allClasses = mutableListOf<KmClass>()
|
||||
private val _sealedClasses = mutableListOf<KmClass>()
|
||||
|
||||
val allClasses: Collection<KmClass> get() = _allClasses
|
||||
val sealedClasses: Collection<KmClass> get() = _sealedClasses
|
||||
|
||||
fun consume(clazz: KmClass) {
|
||||
_allClasses += clazz
|
||||
if (Flag.Common.IS_SEALED(clazz.flags)) _sealedClasses += clazz
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
_allClasses.clear()
|
||||
_sealedClasses.clear()
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.descriptors.commonizer.metadata
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNodeWithLiftingUp
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode
|
||||
|
||||
internal interface VisitingContext {
|
||||
val targetIndex: Int
|
||||
val target: CommonizerTarget
|
||||
val isCommon: Boolean
|
||||
val typeParameterIndexOffset: Int
|
||||
val topLevelContext: VisitingContext
|
||||
|
||||
fun childContext(declarationWithTypeParameters: CirHasTypeParameters): VisitingContext {
|
||||
val ownTypeParametersCount = declarationWithTypeParameters.typeParameters.size
|
||||
return if (ownTypeParametersCount == 0) this else ChildVisitingContext(this, ownTypeParametersCount)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newContext(rootNode: CirRootNode, targetIndex: Int): VisitingContext =
|
||||
TopLevelVisitingContext(rootNode, targetIndex)
|
||||
}
|
||||
|
||||
private class TopLevelVisitingContext(
|
||||
rootNode: CirRootNode,
|
||||
override val targetIndex: Int
|
||||
) : VisitingContext {
|
||||
override val isCommon = rootNode.indexOfCommon == targetIndex
|
||||
override val target = get<CirRoot>(rootNode)!!.target
|
||||
override val typeParameterIndexOffset get() = 0
|
||||
override val topLevelContext: VisitingContext get() = this
|
||||
}
|
||||
|
||||
private class ChildVisitingContext(
|
||||
private val parent: VisitingContext,
|
||||
typeParametersCount: Int
|
||||
) : VisitingContext by parent {
|
||||
override val typeParameterIndexOffset = parent.typeParameterIndexOffset + typeParametersCount
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified T : CirDeclaration> VisitingContext.get(node: CirNodeWithLiftingUp<*, *>): T? {
|
||||
return when {
|
||||
isCommon -> node.commonDeclaration() as T?
|
||||
node.isLiftedUp -> null
|
||||
else -> node.targetDeclarations[targetIndex] as T?
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified T : CirDeclaration> VisitingContext.get(node: CirNode<*, *>): T? {
|
||||
return (if (isCommon) node.commonDeclaration() else node.targetDeclarations[targetIndex]) as T?
|
||||
}
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.descriptors.commonizer.metadata
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import kotlinx.metadata.klib.KlibModuleMetadata
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
// TODO: add logging
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
internal object MetadataBuilder {
|
||||
fun build(node: CirRootNode, targetIndex: Int): Pair<CommonizerTarget, Collection<KlibModuleMetadata>> =
|
||||
node.accept(MetadataBuildingVisitor(), VisitingContext.newContext(node, targetIndex)).cast()
|
||||
|
||||
private class MetadataBuildingVisitor : CirNodeVisitor<VisitingContext, Any?> {
|
||||
private val classConsumer = ClassConsumer()
|
||||
|
||||
override fun visitRootNode(node: CirRootNode, context: VisitingContext): Pair<CommonizerTarget, Collection<KlibModuleMetadata>> {
|
||||
val modules: Collection<KlibModuleMetadata> = buildMembers(context, node.modules)
|
||||
return context.target to modules
|
||||
}
|
||||
|
||||
override fun visitModuleNode(node: CirModuleNode, context: VisitingContext): KlibModuleMetadata? {
|
||||
val cirModule = context.get<CirModule>(node) ?: return null
|
||||
|
||||
val fragments: MutableCollection<KmModuleFragment> = mutableListOf()
|
||||
buildMembers(context, node.packages, destination = fragments)
|
||||
addEmptyFragments(fragments)
|
||||
|
||||
return cirModule.buildModule(fragments)
|
||||
}
|
||||
|
||||
override fun visitPackageNode(node: CirPackageNode, context: VisitingContext): KmModuleFragment? {
|
||||
val cirPackage = context.get<CirPackage>(node) ?: return null
|
||||
try {
|
||||
buildMembers(context, node.classes, callback = classConsumer::consumeAll)
|
||||
|
||||
val topLevelTypeAliases = mutableListOf<KmTypeAlias>()
|
||||
node.typeAliases.values.forEach { typeAliasNode ->
|
||||
when (val classifier = typeAliasNode.accept(this, context)) {
|
||||
null -> Unit
|
||||
is KmClass -> classConsumer.consume(classifier)
|
||||
is KmTypeAlias -> topLevelTypeAliases += classifier
|
||||
else -> error("Unexpected classifier: ${classifier::class.java}, $classifier")
|
||||
}
|
||||
}
|
||||
|
||||
linkSealedClassesWithSubclasses(node.fqName, classConsumer)
|
||||
|
||||
val topLevelFunctions: Collection<KmFunction> = buildMembers(context, node.functions)
|
||||
val topLevelProperties: Collection<KmProperty> = buildMembers(context, node.properties)
|
||||
|
||||
return cirPackage.buildModuleFragment(classConsumer.allClasses, topLevelTypeAliases, topLevelFunctions, topLevelProperties)
|
||||
} finally {
|
||||
// Important: clean-up class consumer every time when leaving package
|
||||
classConsumer.reset()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPropertyNode(node: CirPropertyNode, context: VisitingContext): KmProperty? {
|
||||
return context.get<CirProperty>(node)?.buildProperty(context)
|
||||
}
|
||||
|
||||
override fun visitFunctionNode(node: CirFunctionNode, context: VisitingContext): KmFunction? {
|
||||
return context.get<CirFunction>(node)?.buildFunction(context)
|
||||
}
|
||||
|
||||
override fun visitClassNode(node: CirClassNode, context: VisitingContext): KmClass? {
|
||||
val cirClass = context.get<CirClass>(node) ?: return null
|
||||
|
||||
@Suppress("NAME_SHADOWING") val context = if (cirClass.isInner) context else context.topLevelContext
|
||||
val classContext = context.childContext(cirClass)
|
||||
|
||||
val directNestedClasses = buildMembers(context = classContext, node.classes, callback = classConsumer::consumeAll)
|
||||
val nestedConstructors: Collection<KmConstructor> = buildMembers(context = classContext, node.constructors)
|
||||
val nestedFunctions: Collection<KmFunction> = buildMembers(context = classContext, node.functions)
|
||||
val nestedProperties: Collection<KmProperty> = buildMembers(context = classContext, node.properties)
|
||||
|
||||
val className = node.classId.asString()
|
||||
|
||||
return cirClass.buildClass(context, className, directNestedClasses, nestedConstructors, nestedFunctions, nestedProperties)
|
||||
}
|
||||
|
||||
override fun visitClassConstructorNode(node: CirClassConstructorNode, context: VisitingContext): KmConstructor? {
|
||||
return context.get<CirClassConstructor>(node)?.buildClassConstructor(context)
|
||||
}
|
||||
|
||||
override fun visitTypeAliasNode(node: CirTypeAliasNode, context: VisitingContext): Any? {
|
||||
val cirClassifier = context.get<CirClassifier>(node) ?: return null
|
||||
val className = node.classId.asString()
|
||||
|
||||
return when (cirClassifier) {
|
||||
is CirTypeAlias -> cirClassifier.buildTypeAlias(context)
|
||||
is CirClass -> cirClassifier.buildClass(context, className, emptyList(), emptyList(), emptyList(), emptyList())
|
||||
else -> error("Unexpected CIR classifier: ${cirClassifier::class.java}, $cirClassifier")
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified N : CirNode<*, *>, reified M : Any> buildMembers(
|
||||
context: VisitingContext,
|
||||
cirMembersNodes: Map<*, N>,
|
||||
destination: MutableCollection<M> = mutableListOf(),
|
||||
callback: (Collection<M>) -> Unit = {}
|
||||
): Collection<M> {
|
||||
return cirMembersNodes.values.mapNotNullTo(destination) { it.accept(this, context) as M? }.also(callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ClassConsumer {
|
||||
private val _allClasses = mutableListOf<KmClass>()
|
||||
private val _sealedClasses = mutableListOf<KmClass>()
|
||||
|
||||
val allClasses: Collection<KmClass> get() = _allClasses
|
||||
val sealedClasses: Collection<KmClass> get() = _sealedClasses
|
||||
|
||||
fun consume(clazz: KmClass) {
|
||||
_allClasses += clazz
|
||||
if (Flag.Common.IS_SEALED(clazz.flags)) _sealedClasses += clazz
|
||||
}
|
||||
|
||||
fun consumeAll(classes: Collection<KmClass>) = classes.forEach(::consume)
|
||||
|
||||
fun reset() {
|
||||
_allClasses.clear()
|
||||
_sealedClasses.clear()
|
||||
}
|
||||
}
|
||||
+37
-42
@@ -5,36 +5,34 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors.commonizer.stats
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.AggregatedStatsCollector.AggregatedStatsRow
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.RawStatsCollector.CommonDeclarationStatus.*
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
class AggregatedStatsCollector(
|
||||
targets: List<KonanTarget>,
|
||||
private val output: StatsOutput
|
||||
targets: List<KonanTarget>
|
||||
) : StatsCollector {
|
||||
private val aggregatingOutput = AggregatingOutput()
|
||||
private val wrappedCollector = RawStatsCollector(targets, aggregatingOutput)
|
||||
private val wrappedCollector = RawStatsCollector(targets)
|
||||
|
||||
override fun logStats(result: List<DeclarationDescriptor?>) {
|
||||
wrappedCollector.logStats(result)
|
||||
override fun logDeclaration(targetIndex: Int, lazyStatsKey: () -> StatsCollector.StatsKey) {
|
||||
wrappedCollector.logDeclaration(targetIndex, lazyStatsKey)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
output.writeHeader(AggregatedStatsHeader)
|
||||
override fun writeTo(statsOutput: StatsOutput) {
|
||||
val aggregatingOutput = AggregatingOutput()
|
||||
wrappedCollector.writeTo(aggregatingOutput)
|
||||
|
||||
aggregatingOutput.aggregatedStats.keys.sortedBy { it }.forEach { key ->
|
||||
val row = aggregatingOutput.aggregatedStats.getValue(key)
|
||||
output.writeRow(row)
|
||||
statsOutput.use {
|
||||
statsOutput.writeHeader(AggregatedStatsHeader)
|
||||
|
||||
aggregatingOutput.aggregatedStats.keys.sortedBy { it }.forEach { key ->
|
||||
val row = aggregatingOutput.aggregatedStats.getValue(key)
|
||||
statsOutput.writeRow(row)
|
||||
}
|
||||
}
|
||||
|
||||
output.close()
|
||||
wrappedCollector.close()
|
||||
}
|
||||
|
||||
object AggregatedStatsHeader : StatsOutput.StatsHeader {
|
||||
private val headerItems = listOf(
|
||||
override fun toList(): List<String> = listOf(
|
||||
"Declaration Type",
|
||||
"Lifted Up",
|
||||
"Lifted Up, %%",
|
||||
@@ -46,11 +44,9 @@ class AggregatedStatsCollector(
|
||||
"Failed: Other, %%",
|
||||
"Total"
|
||||
)
|
||||
|
||||
override fun toList(): List<String> = headerItems
|
||||
}
|
||||
|
||||
class AggregatedStatsRow(
|
||||
private class AggregatedStatsRow(
|
||||
private val declarationType: DeclarationType
|
||||
) : StatsOutput.StatsRow {
|
||||
var liftedUp: Int = 0
|
||||
@@ -78,33 +74,32 @@ class AggregatedStatsCollector(
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private class AggregatingOutput : StatsOutput {
|
||||
val aggregatedStats = HashMap<DeclarationType, AggregatedStatsRow>()
|
||||
|
||||
@Suppress("MoveVariableDeclarationIntoWhen")
|
||||
private class AggregatingOutput : StatsOutput {
|
||||
val aggregatedStats = HashMap<DeclarationType, AggregatedStatsRow>()
|
||||
override fun writeHeader(header: StatsOutput.StatsHeader) {
|
||||
check(header is RawStatsCollector.RawStatsHeader)
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override fun writeHeader(header: StatsOutput.StatsHeader) {
|
||||
check(header is RawStatsCollector.RawStatsHeader)
|
||||
// do nothing
|
||||
}
|
||||
override fun writeRow(row: StatsOutput.StatsRow) {
|
||||
check(row is RawStatsCollector.RawStatsRow)
|
||||
|
||||
override fun writeRow(row: StatsOutput.StatsRow) {
|
||||
check(row is RawStatsCollector.RawStatsRow)
|
||||
|
||||
val aggregatedStatsRow = aggregatedStats.getOrPut(row.declarationType) { AggregatedStatsRow(row.declarationType) }
|
||||
when (row.common) {
|
||||
LIFTED_UP -> aggregatedStatsRow.liftedUp++
|
||||
EXPECT -> aggregatedStatsRow.successfullyCommonized++
|
||||
MISSING -> {
|
||||
if (row.platform.any { it == RawStatsCollector.PlatformDeclarationStatus.MISSING }) {
|
||||
aggregatedStatsRow.failedBecauseMissing++
|
||||
} else {
|
||||
aggregatedStatsRow.failedOther++
|
||||
val declarationType = row.statsKey.declarationType
|
||||
val aggregatedStatsRow = aggregatedStats.getOrPut(declarationType) { AggregatedStatsRow(declarationType) }
|
||||
when (row.common) {
|
||||
LIFTED_UP -> aggregatedStatsRow.liftedUp++
|
||||
EXPECT -> aggregatedStatsRow.successfullyCommonized++
|
||||
MISSING -> {
|
||||
if (row.platform.any { it == RawStatsCollector.PlatformDeclarationStatus.MISSING }) {
|
||||
aggregatedStatsRow.failedBecauseMissing++
|
||||
} else {
|
||||
aggregatedStatsRow.failedOther++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() = Unit
|
||||
override fun close() = Unit
|
||||
}
|
||||
}
|
||||
|
||||
+1
-29
@@ -5,9 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors.commonizer.stats
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
enum class DeclarationType(val alias: String) {
|
||||
TOP_LEVEL_CONST_VAL("TOP-LEVEL CONST-VAL"),
|
||||
TOP_LEVEL_VAL("TOP-LEVEL VAL"),
|
||||
@@ -23,30 +20,5 @@ enum class DeclarationType(val alias: String) {
|
||||
TYPE_ALIAS("TYPE_ALIAS"),
|
||||
ENUM_ENTRY("ENUM_ENTRY"),
|
||||
ENUM_CLASS("ENUM_CLASS"),
|
||||
MODULE("MODULE"),
|
||||
UNKNOWN("UNKNOWN");
|
||||
|
||||
companion object {
|
||||
val DeclarationDescriptor.declarationType: DeclarationType
|
||||
get() = when (this) {
|
||||
is ClassDescriptor -> {
|
||||
if (isCompanionObject) {
|
||||
COMPANION_OBJECT
|
||||
} else when (kind) {
|
||||
ClassKind.ENUM_CLASS -> ENUM_CLASS
|
||||
ClassKind.ENUM_ENTRY -> ENUM_ENTRY
|
||||
ClassKind.INTERFACE -> if (DescriptorUtils.isTopLevelDeclaration(this)) TOP_LEVEL_INTERFACE else NESTED_INTERFACE
|
||||
else -> if (DescriptorUtils.isTopLevelDeclaration(this)) TOP_LEVEL_CLASS else NESTED_CLASS
|
||||
}
|
||||
}
|
||||
is TypeAliasDescriptor -> TYPE_ALIAS
|
||||
is ClassConstructorDescriptor -> CLASS_CONSTRUCTOR
|
||||
is FunctionDescriptor -> if (DescriptorUtils.isTopLevelDeclaration(this)) TOP_LEVEL_FUN else NESTED_FUN
|
||||
is PropertyDescriptor -> if (DescriptorUtils.isTopLevelDeclaration(this)) {
|
||||
if (isConst) TOP_LEVEL_CONST_VAL else TOP_LEVEL_VAL
|
||||
} else NESTED_VAL
|
||||
is ModuleDescriptor -> MODULE
|
||||
else -> UNKNOWN
|
||||
}
|
||||
}
|
||||
MODULE("MODULE")
|
||||
}
|
||||
|
||||
+94
-94
@@ -5,19 +5,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors.commonizer.stats
|
||||
|
||||
import com.intellij.util.containers.FactoryMap
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.DeclarationType.Companion.declarationType
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.utils.signature
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector.StatsKey
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsOutput.StatsHeader
|
||||
import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsOutput.StatsRow
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
/**
|
||||
* Allows printing commonization statistics to the file system.
|
||||
*
|
||||
* Output format is defined in [RawStatsCollector.output].
|
||||
* Output format is defined in [StatsOutput].
|
||||
*
|
||||
* Header row: "FQ Name, Extension Receiver, Parameter Names, Parameter Types, Declaration Type, common, <platform1>, <platform2> [<platformN>...]"
|
||||
* Header row: "ID, Extension Receiver, Parameter Names, Parameter Types, Declaration Type, common, <platform1>, <platform2> [<platformN>...]"
|
||||
*
|
||||
* Possible values for "Declaration Type":
|
||||
* - MODULE
|
||||
@@ -44,113 +46,109 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
*
|
||||
* Example of output:
|
||||
|
||||
FQ Name|Extension Receiver|Parameter Names|Parameter Types|Declaration Type|common|macos_x64|ios_x64
|
||||
<SystemConfiguration>||||MODULE|E|A|A
|
||||
platform.SystemConfiguration.SCPreferencesContext||||CLASS|E|A|A
|
||||
platform.SystemConfiguration.SCPreferencesContext.Companion||||COMPANION_OBJECT|E|A|A
|
||||
platform.SystemConfiguration.SCNetworkConnectionContext||||CLASS|E|A|A
|
||||
platform.SystemConfiguration.SCNetworkConnectionContext.Companion||||COMPANION_OBJECT|E|A|A
|
||||
platform.SystemConfiguration.SCDynamicStoreRefVar||||TYPE_ALIAS|-|O|O
|
||||
platform.SystemConfiguration.SCVLANInterfaceRef||||TYPE_ALIAS|-|O|O
|
||||
ID|Extension Receiver|Parameter Names|Parameter Types|Declaration Type|common|macos_x64|ios_x64
|
||||
SystemConfiguration||||MODULE|E|A|A
|
||||
platform/SystemConfiguration/SCPreferencesContext||||CLASS|E|A|A
|
||||
platform/SystemConfiguration/SCPreferencesContext.Companion||||COMPANION_OBJECT|E|A|A
|
||||
platform/SystemConfiguration/SCNetworkConnectionContext||||CLASS|E|A|A
|
||||
platform/SystemConfiguration/SCNetworkConnectionContext.Companion||||COMPANION_OBJECT|E|A|A
|
||||
platform/SystemConfiguration/SCDynamicStoreRefVar||||TYPE_ALIAS|-|O|O
|
||||
platform/SystemConfiguration/SCVLANInterfaceRef||||TYPE_ALIAS|-|O|O
|
||||
|
||||
*/
|
||||
class RawStatsCollector(
|
||||
private val targets: List<KonanTarget>,
|
||||
private val output: StatsOutput
|
||||
) : StatsCollector {
|
||||
private var headerWritten = false
|
||||
class RawStatsCollector(private val targets: List<KonanTarget>) : StatsCollector {
|
||||
private inline val dimension get() = targets.size + 1
|
||||
private inline val targetNames get() = targets.map { it.name }
|
||||
|
||||
override fun logStats(result: List<DeclarationDescriptor?>) {
|
||||
if (!headerWritten) {
|
||||
writeHeader()
|
||||
headerWritten = true
|
||||
}
|
||||
private inline val indexOfCommon get() = targets.size
|
||||
private inline val platformDeclarationsCount get() = targets.size
|
||||
|
||||
val firstNotNull = result.firstNonNull()
|
||||
val lastIsNull = result.last() == null
|
||||
private val stats = FactoryMap.create<StatsKey, StatsValue> { StatsValue(dimension) }
|
||||
|
||||
val statsRow = RawStatsRow(
|
||||
dimension = targets.size,
|
||||
fqName = if (firstNotNull is ModuleDescriptor) firstNotNull.name.asString() else firstNotNull.fqNameSafe.asString(),
|
||||
declarationType = firstNotNull.declarationType
|
||||
)
|
||||
override fun logDeclaration(targetIndex: Int, lazyStatsKey: () -> StatsKey) {
|
||||
stats.getValue(lazyStatsKey())[targetIndex] = true
|
||||
}
|
||||
|
||||
// extension receiver
|
||||
if (firstNotNull is PropertyDescriptor || firstNotNull is SimpleFunctionDescriptor) {
|
||||
statsRow.extensionReceiver =
|
||||
(firstNotNull as CallableDescriptor).extensionReceiverParameter?.type?.signature.orEmpty()
|
||||
}
|
||||
|
||||
if (firstNotNull is ConstructorDescriptor || firstNotNull is SimpleFunctionDescriptor) {
|
||||
val functionDescriptor = (firstNotNull as FunctionDescriptor)
|
||||
// parameter names
|
||||
statsRow.parameterNames = functionDescriptor.valueParameters.joinToString { it.name.asString() }
|
||||
// parameter types
|
||||
statsRow.parameterTypes = functionDescriptor.valueParameters.joinToString { it.type.signature }
|
||||
}
|
||||
|
||||
var isLiftedUp = !lastIsNull
|
||||
for (index in 0 until result.size - 1) {
|
||||
statsRow.platform += when {
|
||||
result[index] == null -> PlatformDeclarationStatus.MISSING
|
||||
lastIsNull -> PlatformDeclarationStatus.ORIGINAL
|
||||
else -> {
|
||||
isLiftedUp = false
|
||||
PlatformDeclarationStatus.ACTUAL
|
||||
}
|
||||
override fun writeTo(statsOutput: StatsOutput) {
|
||||
val mergedStats = stats.filterTo(mutableMapOf()) { (statsKey, _) ->
|
||||
when (statsKey.declarationType) {
|
||||
DeclarationType.TOP_LEVEL_CLASS, DeclarationType.TOP_LEVEL_INTERFACE -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
statsRow.common = when {
|
||||
isLiftedUp -> CommonDeclarationStatus.LIFTED_UP
|
||||
lastIsNull -> CommonDeclarationStatus.MISSING
|
||||
else -> CommonDeclarationStatus.EXPECT
|
||||
stats.forEach { (statsKey, statsValue) ->
|
||||
when (statsKey.declarationType) {
|
||||
DeclarationType.TOP_LEVEL_CLASS, DeclarationType.TOP_LEVEL_INTERFACE -> {
|
||||
if (statsValue[indexOfCommon]) {
|
||||
val alternativeKey = statsKey.copy(declarationType = DeclarationType.TYPE_ALIAS)
|
||||
val alternativeValue = mergedStats[alternativeKey]
|
||||
if (alternativeValue != null && !alternativeValue[indexOfCommon]) {
|
||||
alternativeValue[indexOfCommon] = true
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
mergedStats[statsKey] = statsValue
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
output.writeRow(statsRow)
|
||||
}
|
||||
statsOutput.use {
|
||||
statsOutput.writeHeader(RawStatsHeader(targetNames))
|
||||
|
||||
override fun close() {
|
||||
output.close()
|
||||
}
|
||||
mergedStats.forEach { (statsKey, statsValue) ->
|
||||
val commonIsMissing = !statsValue[indexOfCommon]
|
||||
|
||||
private fun writeHeader() {
|
||||
output.writeHeader(RawStatsHeader(targets.map { it.name }))
|
||||
}
|
||||
var isLiftedUp = !commonIsMissing
|
||||
val platform = ArrayList<PlatformDeclarationStatus>(platformDeclarationsCount)
|
||||
|
||||
class RawStatsHeader(
|
||||
private val targetNames: List<String>
|
||||
) : StatsOutput.StatsHeader {
|
||||
override fun toList(): List<String> = mutableListOf<String>().apply {
|
||||
this += "FQ Name"
|
||||
this += "Extension Receiver"
|
||||
this += "Parameter Names"
|
||||
this += "Parameter Types"
|
||||
this += "Declaration Type"
|
||||
this += "common"
|
||||
this += targetNames
|
||||
for (index in 0 until platformDeclarationsCount) {
|
||||
platform += when {
|
||||
!statsValue[index] -> PlatformDeclarationStatus.MISSING
|
||||
commonIsMissing -> PlatformDeclarationStatus.ORIGINAL
|
||||
else -> {
|
||||
isLiftedUp = false
|
||||
PlatformDeclarationStatus.ACTUAL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val common = when {
|
||||
isLiftedUp -> CommonDeclarationStatus.LIFTED_UP
|
||||
commonIsMissing -> CommonDeclarationStatus.MISSING
|
||||
else -> CommonDeclarationStatus.EXPECT
|
||||
}
|
||||
|
||||
statsOutput.writeRow(RawStatsRow(statsKey, common, platform))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RawStatsHeader(private val targetNames: List<String>) : StatsHeader {
|
||||
override fun toList() =
|
||||
listOf("ID", "Extension Receiver", "Parameter Names", "Parameter Types", "Declaration Type", "common") + targetNames
|
||||
}
|
||||
|
||||
class RawStatsRow(
|
||||
dimension: Int,
|
||||
val fqName: String,
|
||||
val declarationType: DeclarationType
|
||||
) : StatsOutput.StatsRow {
|
||||
var extensionReceiver: String = ""
|
||||
var parameterNames: String = ""
|
||||
var parameterTypes: String = ""
|
||||
lateinit var common: CommonDeclarationStatus
|
||||
val platform: MutableList<PlatformDeclarationStatus> = ArrayList(dimension)
|
||||
val statsKey: StatsKey,
|
||||
val common: CommonDeclarationStatus,
|
||||
val platform: List<PlatformDeclarationStatus>
|
||||
) : StatsRow {
|
||||
override fun toList(): List<String> {
|
||||
val result = mutableListOf(
|
||||
statsKey.id,
|
||||
statsKey.extensionReceiver.orEmpty(),
|
||||
statsKey.parameterNames.joinToString(),
|
||||
statsKey.parameterTypes.joinToString(),
|
||||
statsKey.declarationType.alias,
|
||||
common.alias.toString()
|
||||
)
|
||||
|
||||
override fun toList(): List<String> = mutableListOf<String>().apply {
|
||||
this += fqName
|
||||
this += extensionReceiver
|
||||
this += parameterNames
|
||||
this += parameterTypes
|
||||
this += declarationType.alias
|
||||
this += common.alias.toString()
|
||||
platform.forEach { this += it.alias.toString() }
|
||||
platform.mapTo(result) { it.alias.toString() }
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,3 +164,5 @@ class RawStatsCollector(
|
||||
MISSING('-')
|
||||
}
|
||||
}
|
||||
|
||||
private typealias StatsValue = BitSet
|
||||
|
||||
+12
-4
@@ -5,9 +5,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors.commonizer.stats
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import java.io.Closeable
|
||||
interface StatsCollector {
|
||||
data class StatsKey(
|
||||
val id: String,
|
||||
val extensionReceiver: String?,
|
||||
val parameterNames: List<String>,
|
||||
val parameterTypes: List<String>,
|
||||
val declarationType: DeclarationType
|
||||
) {
|
||||
constructor(id: String, declarationType: DeclarationType) : this(id, null, emptyList(), emptyList(), declarationType)
|
||||
}
|
||||
|
||||
interface StatsCollector : Closeable {
|
||||
fun logStats(result: List<DeclarationDescriptor?>)
|
||||
fun logDeclaration(targetIndex: Int, lazyStatsKey: () -> StatsKey)
|
||||
fun writeTo(statsOutput: StatsOutput)
|
||||
}
|
||||
|
||||
@@ -44,6 +44,9 @@ private val OBJC_INTEROP_CALLABLE_ANNOTATIONS = listOf(
|
||||
"ObjCFactory"
|
||||
)
|
||||
|
||||
internal val DEFAULT_CONSTRUCTOR_NAME = Name.identifier("<init>").intern()
|
||||
internal val DEFAULT_SETTER_VALUE_NAME = Name.identifier("value").intern()
|
||||
|
||||
internal fun Name.strip(): String =
|
||||
asString().removeSurrounding("<", ">")
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ private fun StringBuilder.buildTypeSignature(type: KotlinType, exploredTypeParam
|
||||
}
|
||||
append("]")
|
||||
}
|
||||
|
||||
if (type.isMarkedNullable)
|
||||
append("?")
|
||||
} else {
|
||||
// N.B. this is classifier type
|
||||
val abbreviation = (type as? AbbreviatedType)?.abbreviation ?: type
|
||||
@@ -81,10 +84,10 @@ private fun StringBuilder.buildTypeSignature(type: KotlinType, exploredTypeParam
|
||||
}
|
||||
append(">")
|
||||
}
|
||||
}
|
||||
|
||||
if (type.isMarkedNullable)
|
||||
append("?")
|
||||
if (abbreviation.isMarkedNullable)
|
||||
append("?")
|
||||
}
|
||||
}
|
||||
|
||||
// dedicated to hold unique entries of "signature"
|
||||
|
||||
Reference in New Issue
Block a user