diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index 3d30e51d131..f2d8c04a9ae 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -30,12 +30,10 @@ import org.jetbrains.kotlin.fir.extensions.typeAttributeExtensions import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.serialization.constant.* import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl @@ -182,16 +180,7 @@ class FirElementSerializer private constructor( } } - fun FirClass.nestedClassifiers(): List> { - val scope = - defaultType().scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = null) ?: return emptyList() - return buildList { - scope.getClassifierNames().mapNotNullTo(this) { scope.getSingleClassifier(it) } - addAll(providedDeclarationsService.getProvidedNestedClassifiers(classSymbol, scopeSession)) - } - } - - val nestedClassifiers = klass.nestedClassifiers() + val nestedClassifiers = computeNestedClassifiersForClass(classSymbol) for (nestedClassifier in nestedClassifiers) { if (nestedClassifier is FirTypeAliasSymbol) { typeAliasProto(nestedClassifier.fir)?.let { builder.addTypeAlias(it) } @@ -265,6 +254,14 @@ class FirElementSerializer private constructor( return builder } + fun computeNestedClassifiersForClass(classSymbol: FirClassSymbol<*>): List> { + val scope = session.nestedClassifierScope(classSymbol.fir) ?: return emptyList() + return buildList { + scope.getClassifierNames().mapNotNullTo(this) { scope.getSingleClassifier(it) } + addAll(providedDeclarationsService.getProvidedNestedClassifiers(classSymbol, scopeSession)) + } + } + private fun FirClass.memberDeclarations(): List { return collectDeclarations> { memberScope, addDeclarationIfNeeded -> memberScope.processAllFunctions { addDeclarationIfNeeded(it) } diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt index 02dd663868c..d5dabd4614c 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/firKlibSerialization.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.packageFqName import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.serialization.SerializableStringTable @@ -24,8 +25,11 @@ fun serializeSingleFirFile( languageVersionSettings: LanguageVersionSettings, ): ProtoBuf.PackageFragment { val approximator = TypeApproximatorForMetadataSerializer(session) - val packageSerializer = FirElementSerializer.createTopLevel(session, scopeSession, serializerExtension, approximator, - languageVersionSettings) + val packageSerializer = FirElementSerializer.createTopLevel( + session, scopeSession, serializerExtension, + approximator, + languageVersionSettings + ) // TODO: typealiases (see klib serializer) // TODO: split package fragment (see klib serializer) @@ -33,20 +37,28 @@ fun serializeSingleFirFile( val packageProto = packageSerializer.packagePartProto(file.packageFqName, listOf(file), actualizedExpectDeclarations).build() - fun List.makeClassesProtoWithNested(): List> { - return filterIsInstance().filter { it.shouldBeSerialized(actualizedExpectDeclarations) } + val classesProto = mutableListOf>() + + fun List>.makeClassesProtoWithNested() { + val classSymbols = this + .filter { it.fir.shouldBeSerialized(actualizedExpectDeclarations) } .sortedBy { it.classId.asFqNameString() } - .flatMap { - val classSerializer = FirElementSerializer.create( - session, scopeSession, it, serializerExtension, null, - approximator, languageVersionSettings - ) - val index = classSerializer.stringTable.getFqNameIndex(it) - listOf(classSerializer.classProto(it).build() to index) + it.declarations.makeClassesProtoWithNested() - } + for (symbol in classSymbols) { + val klass = symbol.fir + val classSerializer = FirElementSerializer.create( + session, scopeSession, klass, serializerExtension, null, + approximator, languageVersionSettings + ) + val index = classSerializer.stringTable.getFqNameIndex(klass) + + classesProto += classSerializer.classProto(klass).build() to index + classSerializer.computeNestedClassifiersForClass(symbol).filterIsInstance>().makeClassesProtoWithNested() + } } - val classesProto = serializerExtension.processFile(file) { file.declarations.makeClassesProtoWithNested() } + serializerExtension.processFile(file) { + file.declarations.mapNotNull { it.symbol as? FirClassSymbol<*> }.makeClassesProtoWithNested() + } val hasTopLevelDeclarations = file.declarations.any { it is FirMemberDeclaration && it.shouldBeSerialized(actualizedExpectDeclarations) && diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2KotlinxSerializationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2KotlinxSerializationIT.kt index 5eec882e6eb..554c608ea5a 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2KotlinxSerializationIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/K2KotlinxSerializationIT.kt @@ -63,4 +63,12 @@ class K2KotlinxSerializationIT : KGPBaseTest() { build(":compileProductionExecutableKotlinJs") } } + + @DisplayName("Compile test sourceset with kotlinx.serialization to JS. KT-57781") + @GradleTest + fun `test kotlinx serialization compile test source set to JS`() { + project("kotlinxSerializationK2WithJs", gradleVersion) { + build(":compileTestKotlinJs") + } + } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinxSerializationK2WithJs/src/test/kotlin/SimpleTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinxSerializationK2WithJs/src/test/kotlin/SimpleTest.kt new file mode 100644 index 00000000000..5e8acc69776 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlinxSerializationK2WithJs/src/test/kotlin/SimpleTest.kt @@ -0,0 +1,5 @@ +class SimpleTest { + fun test() { + ErrorResponse.serializer() + } +}