Add 'generateModule' method to CodegenFactory
This commit is contained in:
@@ -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<KtFile?>, errorHandler: CompilationErrorHandler)
|
||||
fun createPackageCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry): PackageCodegen
|
||||
fun createMultifileClassCodegen(state: GenerationState, files: Collection<KtFile>, 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<KtFile?>, errorHandler: CompilationErrorHandler) {
|
||||
val filesInPackages = MultiMap<FqName, KtFile>()
|
||||
val filesInMultifileClasses = MultiMap<FqName, KtFile>()
|
||||
|
||||
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<KtFile>, fqName: FqName, registry: PackagePartRegistry) =
|
||||
PackageCodegenImpl(state, files, fqName, registry)
|
||||
|
||||
override fun createMultifileClassCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry) =
|
||||
MultifileClassCodegenImpl(state, files, fqName, registry)
|
||||
|
||||
private fun generateMultifileClass(
|
||||
state: GenerationState,
|
||||
multifileClassFqName: FqName,
|
||||
files: Collection<KtFile>,
|
||||
handler: CompilationErrorHandler
|
||||
) {
|
||||
val codegen = state.factory.forMultifileClass(multifileClassFqName, files)
|
||||
codegen.generate(handler)
|
||||
}
|
||||
|
||||
fun generatePackage(
|
||||
state: GenerationState,
|
||||
packageFqName: FqName,
|
||||
jetFiles: Collection<KtFile>,
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<FqName, KtFile> filesInPackages = new MultiMap<>();
|
||||
MultiMap<FqName, KtFile> 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<FqName> obsoleteMultifileClasses = new HashSet<>(state.getObsoleteMultifileClasses());
|
||||
for (FqName multifileClassFqName : SetsKt.plus(filesInMultifileClasses.keySet(), obsoleteMultifileClasses)) {
|
||||
doCheckCancelled(state);
|
||||
generateMultifileClass(state, multifileClassFqName, filesInMultifileClasses.get(multifileClassFqName), errorHandler);
|
||||
}
|
||||
|
||||
Set<FqName> 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<KtFile> 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<KtFile> files,
|
||||
@NotNull CompilationErrorHandler handler
|
||||
) {
|
||||
MultifileClassCodegen codegen = state.getFactory().forMultifileClass(multifileClassFqName, files);
|
||||
codegen.generate(handler);
|
||||
DefaultCodegenFactory.INSTANCE.generatePackage(state, packageFqName, jetFiles, errorHandler);
|
||||
}
|
||||
|
||||
private KotlinCodegenFacade() {}
|
||||
|
||||
@@ -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<KtFile>, 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
|
||||
)
|
||||
|
||||
@@ -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<KtFile?>, 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<KtFile>)
|
||||
JvmBackendFacade.doGenerateFilesInternal(state, errorHandler, irModuleFragment, psi2irContext)
|
||||
}
|
||||
|
||||
override fun createPackageCodegen(state: GenerationState, files: Collection<KtFile>, fqName: FqName, registry: PackagePartRegistry): PackageCodegen {
|
||||
val impl = PackageCodegenImpl(state, files, fqName, registry)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user