Metadata: Chunked KlibModuleFragmentWriteStrategy implementation
This commit is contained in:
+73
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
|
||||||
|
class ChunkedKlibModuleFragmentWriteStrategy(
|
||||||
|
private val topLevelClassifierDeclarationsPerFile: Int = 64,
|
||||||
|
private val topLevelCallableDeclarationsPerFile: Int = 128
|
||||||
|
) : KlibModuleFragmentWriteStrategy {
|
||||||
|
override fun processPackageParts(parts: List<KmModuleFragment>): List<KmModuleFragment> {
|
||||||
|
if (parts.isEmpty())
|
||||||
|
return emptyList()
|
||||||
|
|
||||||
|
val fqName = checkNotNull(parts.first().fqName) {
|
||||||
|
"KmModuleFragment should have a not-null fqName!"
|
||||||
|
}
|
||||||
|
|
||||||
|
val classifierFragments = parts.asSequence()
|
||||||
|
.flatMap { it.classes.asSequence() + it.pkg?.typeAliases.orEmpty() }
|
||||||
|
.chunked(topLevelClassifierDeclarationsPerFile) { chunkedClassifiers ->
|
||||||
|
KmModuleFragment().also { fragment ->
|
||||||
|
fragment.fqName = fqName
|
||||||
|
chunkedClassifiers.forEach { classifier ->
|
||||||
|
when (classifier) {
|
||||||
|
is KmClass -> {
|
||||||
|
fragment.classes += classifier
|
||||||
|
fragment.className += classifier.name
|
||||||
|
}
|
||||||
|
is KmTypeAlias -> {
|
||||||
|
val pkg = fragment.pkg ?: KmPackage().also { pkg ->
|
||||||
|
pkg.fqName = fqName
|
||||||
|
fragment.pkg = pkg
|
||||||
|
}
|
||||||
|
pkg.typeAliases += classifier
|
||||||
|
}
|
||||||
|
else -> error("Unexpected classifier type: $classifier")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val callableFragments = parts.asSequence()
|
||||||
|
.flatMap { it.pkg?.let { pkg -> pkg.functions.asSequence() + pkg.properties } ?: emptySequence() }
|
||||||
|
.chunked(topLevelCallableDeclarationsPerFile) { chunkedCallables ->
|
||||||
|
KmModuleFragment().also { fragment ->
|
||||||
|
fragment.fqName = fqName
|
||||||
|
chunkedCallables.forEach { callable ->
|
||||||
|
val pkg = fragment.pkg ?: KmPackage().also { pkg ->
|
||||||
|
pkg.fqName = fqName
|
||||||
|
fragment.pkg = pkg
|
||||||
|
}
|
||||||
|
when (callable) {
|
||||||
|
is KmFunction -> pkg.functions += callable
|
||||||
|
is KmProperty -> pkg.properties += callable
|
||||||
|
else -> error("Unexpected callable type: $callable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val allFragments = (classifierFragments + callableFragments).toList()
|
||||||
|
return if (allFragments.isEmpty()) {
|
||||||
|
// We still need to emit empty packages because they may
|
||||||
|
// represent parts of package declaration (e.g. platform.[]).
|
||||||
|
// Tooling (e.g. `klib contents`) expects this kind of behavior.
|
||||||
|
parts
|
||||||
|
} else allFragments
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user