[klib] Add an option to write out header klibs
The header klib is supposed to only contain the public abi of the module similar to jvm-abi-gen. It is intended to be used as a dependency for other klib compilations instead of the full klib for compilation avoidance. ^KT-60807
This commit is contained in:
+13
-4
@@ -74,6 +74,7 @@ class FirElementSerializer private constructor(
|
||||
private val serializeTypeTableToFunction: Boolean,
|
||||
private val typeApproximator: AbstractTypeApproximator,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val produceHeaderKlib: Boolean,
|
||||
) {
|
||||
private val contractSerializer = FirContractSerializer()
|
||||
private val providedDeclarationsService = session.providedDeclarationsForMetadataService
|
||||
@@ -89,7 +90,8 @@ class FirElementSerializer private constructor(
|
||||
|
||||
fun addDeclaration(declaration: FirDeclaration, onUnsupportedDeclaration: (FirDeclaration) -> Unit) {
|
||||
if (declaration is FirMemberDeclaration) {
|
||||
if (!declaration.shouldBeSerialized(actualizedExpectDeclarations)) return
|
||||
if (!declaration.isNotExpectOrShouldBeSerialized(actualizedExpectDeclarations)) return
|
||||
if (!declaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)) return
|
||||
when (declaration) {
|
||||
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
||||
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
||||
@@ -178,6 +180,7 @@ class FirElementSerializer private constructor(
|
||||
*/
|
||||
if (regularClass != null && regularClass.classKind != ClassKind.ENUM_ENTRY) {
|
||||
for (constructor in regularClass.constructors()) {
|
||||
if (!constructor.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)) continue
|
||||
builder.addConstructor(constructorProto(constructor))
|
||||
}
|
||||
|
||||
@@ -203,6 +206,7 @@ class FirElementSerializer private constructor(
|
||||
|
||||
for (declaration in callableMembers) {
|
||||
if (declaration !is FirEnumEntry && declaration.isStatic) continue // ??? Miss values() & valueOf()
|
||||
if (!declaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)) continue
|
||||
when (declaration) {
|
||||
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
|
||||
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
|
||||
@@ -1042,7 +1046,7 @@ class FirElementSerializer private constructor(
|
||||
FirElementSerializer(
|
||||
session, scopeSession, declaration, Interner(typeParameters), extension,
|
||||
typeTable, versionRequirementTable, serializeTypeTableToFunction = false,
|
||||
typeApproximator, languageVersionSettings
|
||||
typeApproximator, languageVersionSettings, produceHeaderKlib
|
||||
)
|
||||
|
||||
val stringTable: FirElementAwareStringTable
|
||||
@@ -1148,6 +1152,7 @@ class FirElementSerializer private constructor(
|
||||
extension: FirSerializerExtension,
|
||||
typeApproximator: AbstractTypeApproximator,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
produceHeaderKlib: Boolean = false,
|
||||
): FirElementSerializer =
|
||||
FirElementSerializer(
|
||||
session, scopeSession, null,
|
||||
@@ -1155,6 +1160,7 @@ class FirElementSerializer private constructor(
|
||||
serializeTypeTableToFunction = false,
|
||||
typeApproximator,
|
||||
languageVersionSettings,
|
||||
produceHeaderKlib,
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@@ -1171,6 +1177,7 @@ class FirElementSerializer private constructor(
|
||||
versionRequirementTable = null, serializeTypeTableToFunction = true,
|
||||
typeApproximator,
|
||||
languageVersionSettings,
|
||||
produceHeaderKlib = false,
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@@ -1182,16 +1189,17 @@ class FirElementSerializer private constructor(
|
||||
parentSerializer: FirElementSerializer?,
|
||||
typeApproximator: AbstractTypeApproximator,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
produceHeaderKlib: Boolean = false,
|
||||
): FirElementSerializer {
|
||||
val parentClassId = klass.symbol.classId.outerClassId
|
||||
val parent = if (parentClassId != null && !parentClassId.isLocal) {
|
||||
val parentClass = session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)!!.fir as FirRegularClass
|
||||
parentSerializer ?: create(
|
||||
session, scopeSession, parentClass, extension, null, typeApproximator,
|
||||
languageVersionSettings,
|
||||
languageVersionSettings, produceHeaderKlib
|
||||
)
|
||||
} else {
|
||||
createTopLevel(session, scopeSession, extension, typeApproximator, languageVersionSettings)
|
||||
createTopLevel(session, scopeSession, extension, typeApproximator, languageVersionSettings, produceHeaderKlib)
|
||||
}
|
||||
|
||||
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
|
||||
@@ -1212,6 +1220,7 @@ class FirElementSerializer private constructor(
|
||||
serializeTypeTableToFunction = false,
|
||||
typeApproximator,
|
||||
languageVersionSettings,
|
||||
produceHeaderKlib,
|
||||
)
|
||||
for (typeParameter in klass.typeParameters) {
|
||||
if (typeParameter !is FirTypeParameter) continue
|
||||
|
||||
+10
-4
@@ -22,12 +22,14 @@ fun serializeSingleFirFile(
|
||||
actualizedExpectDeclarations: Set<FirDeclaration>?,
|
||||
serializerExtension: FirKLibSerializerExtension,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
produceHeaderKlib: Boolean = false,
|
||||
): ProtoBuf.PackageFragment {
|
||||
val approximator = TypeApproximatorForMetadataSerializer(session)
|
||||
val packageSerializer = FirElementSerializer.createTopLevel(
|
||||
session, scopeSession, serializerExtension,
|
||||
approximator,
|
||||
languageVersionSettings
|
||||
languageVersionSettings,
|
||||
produceHeaderKlib
|
||||
)
|
||||
|
||||
// TODO: typealiases (see klib serializer)
|
||||
@@ -40,13 +42,16 @@ fun serializeSingleFirFile(
|
||||
|
||||
fun List<FirClassSymbol<*>>.makeClassesProtoWithNested() {
|
||||
val classSymbols = this
|
||||
.filter { it.fir.shouldBeSerialized(actualizedExpectDeclarations) }
|
||||
.filter {
|
||||
it.fir.isNotExpectOrShouldBeSerialized(actualizedExpectDeclarations) &&
|
||||
it.fir.isNotPrivateOrShouldBeSerialized(produceHeaderKlib)
|
||||
}
|
||||
.sortedBy { it.classId.asFqNameString() }
|
||||
for (symbol in classSymbols) {
|
||||
val klass = symbol.fir
|
||||
val classSerializer = FirElementSerializer.create(
|
||||
session, scopeSession, klass, serializerExtension, null,
|
||||
approximator, languageVersionSettings
|
||||
approximator, languageVersionSettings, produceHeaderKlib
|
||||
)
|
||||
val index = classSerializer.stringTable.getFqNameIndex(klass)
|
||||
|
||||
@@ -60,7 +65,8 @@ fun serializeSingleFirFile(
|
||||
}
|
||||
|
||||
val hasTopLevelDeclarations = file.declarations.any {
|
||||
it is FirMemberDeclaration && it.shouldBeSerialized(actualizedExpectDeclarations) &&
|
||||
it is FirMemberDeclaration && it.isNotExpectOrShouldBeSerialized(actualizedExpectDeclarations) &&
|
||||
it.isNotPrivateOrShouldBeSerialized(produceHeaderKlib) &&
|
||||
(it is FirProperty || it is FirSimpleFunction || it is FirTypeAlias)
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
@@ -47,6 +48,10 @@ fun ConeKotlinType.suspendFunctionTypeToFunctionTypeWithContinuation(session: Fi
|
||||
)
|
||||
}
|
||||
|
||||
fun FirMemberDeclaration.shouldBeSerialized(actualizedExpectDeclaration: Set<FirDeclaration>?): Boolean {
|
||||
fun FirMemberDeclaration.isNotExpectOrShouldBeSerialized(actualizedExpectDeclaration: Set<FirDeclaration>?): Boolean {
|
||||
return !isExpect || actualizedExpectDeclaration == null || this !in actualizedExpectDeclaration
|
||||
}
|
||||
|
||||
fun FirMemberDeclaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib: Boolean): Boolean {
|
||||
return !produceHeaderKlib || visibility.isPublicAPI
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user