From 343201497127336faea2754a45ba17f8962bc3b1 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 22 Jun 2017 11:32:48 +0200 Subject: [PATCH] Add 'generateModule' method to CodegenFactory --- .../kotlin/codegen/CodegenFactory.kt | 66 +++++++++++++++++++ .../kotlin/codegen/KotlinCodegenFacade.java | 57 +--------------- .../kotlin/backend/jvm/JvmBackendFacade.kt | 21 +++--- .../kotlin/backend/jvm/JvmIrCodegenFactory.kt | 11 ++++ 4 files changed, 92 insertions(+), 63 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt index e3c2c24be4e..423276f6843 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CodegenFactory.kt @@ -16,19 +16,85 @@ package org.jetbrains.kotlin.codegen +import com.google.common.collect.Sets +import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile interface CodegenFactory { + fun generateModule(state: GenerationState, files: Collection, errorHandler: CompilationErrorHandler) fun createPackageCodegen(state: GenerationState, files: Collection, fqName: FqName, registry: PackagePartRegistry): PackageCodegen fun createMultifileClassCodegen(state: GenerationState, files: Collection, fqName: FqName, registry: PackagePartRegistry): MultifileClassCodegen + + companion object { + fun doCheckCancelled(state: GenerationState) { + if (state.classBuilderMode.generateBodies) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + } + } + } } object DefaultCodegenFactory : CodegenFactory { + override fun generateModule(state: GenerationState, files: Collection, errorHandler: CompilationErrorHandler) { + val filesInPackages = MultiMap() + val filesInMultifileClasses = MultiMap() + + for (file in files) { + if (file == null) throw IllegalArgumentException("A null file given for compilation") + + val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file) + + if (fileClassInfo.withJvmMultifileClass) { + filesInMultifileClasses.putValue(fileClassInfo.facadeClassFqName, file) + } + else { + filesInPackages.putValue(file.packageFqName, file) + } + } + + val obsoleteMultifileClasses = HashSet(state.obsoleteMultifileClasses) + for (multifileClassFqName in filesInMultifileClasses.keySet() + obsoleteMultifileClasses) { + CodegenFactory.doCheckCancelled(state) + generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler) + } + + val packagesWithObsoleteParts = HashSet(state.packagesWithObsoleteParts) + for (packageFqName in packagesWithObsoleteParts + filesInPackages.keySet()) { + CodegenFactory.doCheckCancelled(state) + generatePackage(state, packageFqName, filesInPackages.get(packageFqName), errorHandler) + } + } + override fun createPackageCodegen(state: GenerationState, files: Collection, fqName: FqName, registry: PackagePartRegistry) = PackageCodegenImpl(state, files, fqName, registry) override fun createMultifileClassCodegen(state: GenerationState, files: Collection, fqName: FqName, registry: PackagePartRegistry) = MultifileClassCodegenImpl(state, files, fqName, registry) + + private fun generateMultifileClass( + state: GenerationState, + multifileClassFqName: FqName, + files: Collection, + handler: CompilationErrorHandler + ) { + val codegen = state.factory.forMultifileClass(multifileClassFqName, files) + codegen.generate(handler) + } + + fun generatePackage( + state: GenerationState, + packageFqName: FqName, + jetFiles: Collection, + errorHandler: CompilationErrorHandler + ) { + // We do not really generate package class, but use old package fqName to identify package in module-info. + //FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName); + val codegen = state.factory.forPackage(packageFqName, jetFiles) + codegen.generate(errorHandler) + } + } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java index 9551b278655..41313e88d63 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java @@ -16,19 +16,13 @@ package org.jetbrains.kotlin.codegen; -import com.intellij.util.containers.MultiMap; -import kotlin.collections.SetsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.codegen.state.GenerationState; -import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo; -import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.psi.KtFile; import java.util.Collection; -import java.util.HashSet; -import java.util.Set; public class KotlinCodegenFacade { @@ -50,64 +44,19 @@ public class KotlinCodegenFacade { @NotNull GenerationState state, @NotNull CompilationErrorHandler errorHandler ) { - MultiMap filesInPackages = new MultiMap<>(); - MultiMap filesInMultifileClasses = new MultiMap<>(); + state.getCodegenFactory().generateModule(state, files, errorHandler); - for (KtFile file : files) { - if (file == null) throw new IllegalArgumentException("A null file given for compilation"); - - JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file); - - if (fileClassInfo.getWithJvmMultifileClass()) { - filesInMultifileClasses.putValue(fileClassInfo.getFacadeClassFqName(), file); - } - else { - filesInPackages.putValue(file.getPackageFqName(), file); - } - } - - Set obsoleteMultifileClasses = new HashSet<>(state.getObsoleteMultifileClasses()); - for (FqName multifileClassFqName : SetsKt.plus(filesInMultifileClasses.keySet(), obsoleteMultifileClasses)) { - doCheckCancelled(state); - generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler); - } - - Set packagesWithObsoleteParts = new HashSet<>(state.getPackagesWithObsoleteParts()); - for (FqName packageFqName : SetsKt.plus(packagesWithObsoleteParts, filesInPackages.keySet())) { - doCheckCancelled(state); - generatePackage(state, packageFqName, filesInPackages.get(packageFqName), errorHandler); - } - - doCheckCancelled(state); + CodegenFactory.Companion.doCheckCancelled(state); state.getFactory().done(); } - private static void doCheckCancelled(GenerationState state) { - if (state.getClassBuilderMode().generateBodies) { - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); - } - } - public static void generatePackage( @NotNull GenerationState state, @NotNull FqName packageFqName, @NotNull Collection jetFiles, @NotNull CompilationErrorHandler errorHandler ) { - // We do not really generate package class, but use old package fqName to identify package in module-info. - //FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName); - PackageCodegen codegen = state.getFactory().forPackage(packageFqName, jetFiles); - codegen.generate(errorHandler); - } - - private static void generateMultifileClass( - @NotNull GenerationState state, - @NotNull FqName multifileClassFqName, - @NotNull Collection files, - @NotNull CompilationErrorHandler handler - ) { - MultifileClassCodegen codegen = state.getFactory().forMultifileClass(multifileClassFqName, files); - codegen.generate(handler); + DefaultCodegenFactory.INSTANCE.generatePackage(state, packageFqName, jetFiles, errorHandler); } private KotlinCodegenFacade() {} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt index 1796238ce35..39a6d82c1ed 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt @@ -18,25 +18,28 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.codegen.CompilationErrorHandler import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator -import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator +import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext object JvmBackendFacade { - fun compileCorrectFiles(state: GenerationState, errorHandler: CompilationErrorHandler) { - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - state.beforeCompile() - ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - doGenerateFiles(state.files, state, errorHandler) - } fun doGenerateFiles(files: Collection, state: GenerationState, errorHandler: CompilationErrorHandler) { - // TODO multifile classes support - val psi2ir = Psi2IrTranslator() val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext) val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files) + + doGenerateFilesInternal(state, errorHandler, irModuleFragment, psi2irContext) + } + + internal fun doGenerateFilesInternal( + state: GenerationState, + errorHandler: CompilationErrorHandler, + irModuleFragment: IrModuleFragment, + psi2irContext: GeneratorContext + ) { val jvmBackendContext = JvmBackendContext( state, psi2irContext.sourceManager, psi2irContext.irBuiltIns, irModuleFragment, psi2irContext.symbolTable ) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 671036f6886..93c51558690 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -23,8 +23,19 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator object JvmIrCodegenFactory : CodegenFactory { + + override fun generateModule(state: GenerationState, files: Collection, errorHandler: CompilationErrorHandler) { + assert(!files.any { it == null }) + + val psi2ir = Psi2IrTranslator() + val psi2irContext = psi2ir.createGeneratorContext(state.module, state.bindingContext) + val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files as Collection) + JvmBackendFacade.doGenerateFilesInternal(state, errorHandler, irModuleFragment, psi2irContext) + } + override fun createPackageCodegen(state: GenerationState, files: Collection, fqName: FqName, registry: PackagePartRegistry): PackageCodegen { val impl = PackageCodegenImpl(state, files, fqName, registry)