[FIR] Handle expect declarations in JVM backend

1. Do not generate bytecode for expect declarations

2. Serialize @OptionalExpectation annotations into .kotlin_module file

^KT-62931: Fixed
This commit is contained in:
vladislav.grechko
2024-02-08 18:01:11 +01:00
committed by Space Team
parent b74501ee93
commit d753a22fc6
24 changed files with 352 additions and 113 deletions
@@ -116,7 +116,6 @@ public class ClassFileFactory implements OutputFileCollection {
public void done() {
if (!isDone) {
isDone = true;
writeModuleMappings();
for (ClassFileFactoryFinalizerExtension extension : finalizers) {
extension.finalizeClassFactory(this);
}
@@ -127,20 +126,8 @@ public class ClassFileFactory implements OutputFileCollection {
generators.clear();
}
private void writeModuleMappings() {
JvmModuleProtoBuf.Module.Builder builder = JvmModuleProtoBuf.Module.newBuilder();
String outputFilePath = getMappingFileName(state.getModuleName());
StringTableImpl stringTable = new StringTableImpl();
ClassFileUtilsKt.addDataFromCompiledModule(builder, packagePartRegistry, stringTable, state);
Pair<ProtoBuf.StringTable, ProtoBuf.QualifiedNameTable> tables = stringTable.buildProto();
builder.setStringTable(tables.getFirst());
builder.setQualifiedNameTable(tables.getSecond());
JvmModuleProtoBuf.Module moduleProto = builder.build();
generators.put(outputFilePath, new OutAndSourceFileList(CollectionsKt.toList(sourceFiles)) {
public void setModuleMapping(JvmModuleProtoBuf.Module moduleProto) {
generators.put(getMappingFileName(state.getModuleName()), new OutAndSourceFileList(CollectionsKt.toList(sourceFiles)) {
@Override
public byte[] asBytes(ClassBuilderFactory factory) {
int flags = 0;
@@ -23,10 +23,12 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.serialization.StringTableImpl
interface CodegenFactory {
fun convertToIr(input: IrConversionInput): BackendInput
@@ -126,7 +128,20 @@ object DefaultCodegenFactory : CodegenFactory {
}
override fun invokeCodegen(input: CodegenFactory.CodegenInput) {
// Do nothing
generateModuleMetadata(input)
}
private fun generateModuleMetadata(result: CodegenFactory.CodegenInput) {
val builder = JvmModuleProtoBuf.Module.newBuilder()
val stringTable = StringTableImpl()
builder.addDataFromCompiledModule(stringTable, result.state)
val (stringTableProto, qualifiedNameTableProto) = stringTable.buildProto()
builder.setStringTable(stringTableProto)
builder.setQualifiedNameTable(qualifiedNameTableProto)
result.state.factory.setModuleMapping(builder.build())
}
private fun generateMultifileClass(state: GenerationState, multifileClassFqName: FqName, files: Collection<KtFile>) {
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.name.FqName
class PackagePartRegistry {
val parts = mutableMapOf<FqName, PackageParts>()
// Drop after old BE removal
val optionalAnnotations = mutableListOf<ClassDescriptor>()
fun addPart(packageFqName: FqName, partInternalName: String, facadeInternalName: String?) {
@@ -37,9 +37,8 @@ fun List<OutputFile>.filterClassFiles(): List<OutputFile> {
return filter { it.relativePath.endsWith(".class") }
}
fun JvmModuleProtoBuf.Module.Builder.addDataFromCompiledModule(
registry: PackagePartRegistry, stringTable: StringTableImpl, state: GenerationState
) {
fun JvmModuleProtoBuf.Module.Builder.addDataFromCompiledModule(stringTable: StringTableImpl, state: GenerationState) {
val registry = state.factory.packagePartRegistry
for (part in registry.parts.values.addCompiledPartsAndSort(state)) {
part.addTo(this)
}
@@ -74,7 +73,7 @@ class JvmOptionalAnnotationSerializerExtension(
override fun shouldUseTypeTable(): Boolean = true
}
private fun Iterable<PackageParts>.addCompiledPartsAndSort(state: GenerationState): List<PackageParts> =
fun Iterable<PackageParts>.addCompiledPartsAndSort(state: GenerationState): List<PackageParts> =
addCompiledParts(state).sortedBy { it.packageFqName }
private fun Iterable<PackageParts>.addCompiledParts(state: GenerationState): List<PackageParts> {
@@ -94,7 +93,7 @@ private fun Iterable<PackageParts>.addCompiledParts(state: GenerationState): Lis
}
}
private fun GenerationState.loadCompiledModule(): ModuleMapping? {
fun GenerationState.loadCompiledModule(): ModuleMapping? {
val moduleMappingData = incrementalCacheForThisTarget?.getModuleMappingData() ?: return null
return ModuleMapping.loadModuleMapping(moduleMappingData, "<incremental>", deserializationConfiguration) { version ->
throw IllegalStateException("Version of the generated module cannot be incompatible: $version")