From fc1f2e9c725c9f1d88410b1b12465722ab77f388 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 4 Oct 2021 13:59:41 +0300 Subject: [PATCH] [FIR2IR] Run IrGenerationExtensions after fir2ir stage --- .../FirKotlinToJvmBytecodeCompiler.kt | 9 +- .../kotlin/fir/analysis/FirAnalyzerFacade.kt | 5 +- .../kotlin/fir/pipeline/convertToIr.kt | 11 ++- .../kotlin/fir/backend/Fir2IrConverter.kt | 86 +++++++++++++++++-- .../test/frontend/fir/FirFrontendFacade.kt | 3 +- .../kotlin/codegen/GenerationUtils.kt | 9 +- 6 files changed, 110 insertions(+), 13 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt index 81d62afcde0..7a458e04599 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys @@ -100,7 +101,8 @@ object FirKotlinToJvmBytecodeCompiler { performanceManager, targetIds, incrementalComponents, - extendedAnalysisMode + extendedAnalysisMode, + (projectEnvironment as? PsiBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) } ?: emptyList() ) val generationState = context.compileModule() ?: return false outputs[module] = generationState @@ -134,7 +136,7 @@ object FirKotlinToJvmBytecodeCompiler { performanceManager?.notifyIRTranslationStarted() val extensions = JvmGeneratorExtensionsImpl(moduleConfiguration) - val fir2IrResult = firResult.session.convertToIr(firResult.scopeSession, firResult.fir, extensions) + val fir2IrResult = firResult.session.convertToIr(firResult.scopeSession, firResult.fir, extensions, irGenerationExtensions) performanceManager?.notifyIRTranslationFinished() @@ -341,7 +343,8 @@ object FirKotlinToJvmBytecodeCompiler { val performanceManager: CommonCompilerPerformanceManager?, val targetIds: List?, val incrementalComponents: IncrementalCompilationComponents?, - val extendedAnalysisMode: Boolean + val extendedAnalysisMode: Boolean, + val irGenerationExtensions: Collection ) private fun findMainClass(firResult: FirResult): FqName? { diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/analysis/FirAnalyzerFacade.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/analysis/FirAnalyzerFacade.kt index 7e57fe53482..0d3c3bc38b1 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/analysis/FirAnalyzerFacade.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/analysis/FirAnalyzerFacade.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.analysis +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.fir.FirSession @@ -45,6 +46,7 @@ class FirAnalyzerFacade( val languageVersionSettings: LanguageVersionSettings, val ktFiles: Collection = emptyList(), // may be empty if light tree mode enabled val originalFiles: Collection = emptyList(), // may be empty if light tree mode disabled + val irGeneratorExtensions: Collection, val useLightTree: Boolean = false, val enablePluginPhases: Boolean = false, ) : AbstractFirAnalyzerFacade() { @@ -113,7 +115,8 @@ class FirAnalyzerFacade( languageVersionSettings, signaturer, extensions, FirJvmKotlinMangler(session), IrFactoryImpl, FirJvmVisibilityConverter, - Fir2IrJvmSpecialAnnotationSymbolProvider() + Fir2IrJvmSpecialAnnotationSymbolProvider(), + irGeneratorExtensions ) } } diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt index 16cdd1cb14a..1460b82465e 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/pipeline/convertToIr.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.pipeline +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.Fir2IrConverter @@ -22,7 +23,12 @@ import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions -fun FirSession.convertToIr(scopeSession: ScopeSession, firFiles: List, extensions: GeneratorExtensions): Fir2IrResult { +fun FirSession.convertToIr( + scopeSession: ScopeSession, + firFiles: List, + extensions: GeneratorExtensions, + irGeneratorExtensions: Collection +): Fir2IrResult { val signaturer = JvmIdSignatureDescriptor(JvmDescriptorMangler(null)) val commonFirFiles = moduleData.dependsOnDependencies @@ -35,6 +41,7 @@ fun FirSession.convertToIr(scopeSession: ScopeSession, firFiles: List, languageVersionSettings, signaturer, extensions, FirJvmKotlinMangler(this), IrFactoryImpl, FirJvmVisibilityConverter, - Fir2IrJvmSpecialAnnotationSymbolProvider() + Fir2IrJvmSpecialAnnotationSymbolProvider(), + irGeneratorExtensions ) } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 279e69c1ee1..e3db6a03674 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -5,11 +5,17 @@ package org.jetbrains.kotlin.fir.backend +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl +import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.evaluate.evaluateConstants import org.jetbrains.kotlin.fir.backend.generators.* +import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic @@ -19,6 +25,7 @@ import org.jetbrains.kotlin.fir.extensions.declarationGenerators import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.generatedMembers import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers +import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.packageFqName import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.resolve.ScopeSession @@ -28,15 +35,17 @@ import org.jetbrains.kotlin.ir.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl -import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator -import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator -import org.jetbrains.kotlin.ir.util.IdSignatureComposer -import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.linkage.IrDeserializer +import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions import org.jetbrains.kotlin.psi2ir.generators.generateTypicalIrProviderList +import org.jetbrains.kotlin.resolve.BindingContext class Fir2IrConverter( private val moduleDescriptor: FirModuleDescriptor, @@ -308,7 +317,8 @@ class Fir2IrConverter( mangler: FirMangler, irFactory: IrFactory, visibilityConverter: Fir2IrVisibilityConverter, - specialSymbolProvider: Fir2IrSpecialSymbolProvider? + specialSymbolProvider: Fir2IrSpecialSymbolProvider?, + irGenerationExtensions: Collection ): Fir2IrResult { val moduleDescriptor = FirModuleDescriptor(session) val symbolTable = SymbolTable(signaturer, irFactory) @@ -375,7 +385,73 @@ class Fir2IrConverter( evaluateConstants(irModuleFragment) + if (irGenerationExtensions.isNotEmpty()) { + val pluginContext = Fir2IrPluginContext( + languageVersionSettings, + BuiltinSymbolsBase(irBuiltIns, symbolTable), + session.moduleData.platform, + irBuiltIns, + symbolTable + ) + for (extension in irGenerationExtensions) { + extension.generate(irModuleFragment, pluginContext) + } + } + return Fir2IrResult(irModuleFragment, symbolTable, components) } } + + private class Fir2IrPluginContext( + override val languageVersionSettings: LanguageVersionSettings, + override val symbols: BuiltinSymbolsBase, + override val platform: TargetPlatform?, + override val irBuiltIns: IrBuiltIns, + @property:ObsoleteDescriptorBasedAPI + override val symbolTable: SymbolTable + ) : IrPluginContext { + @ObsoleteDescriptorBasedAPI + override val moduleDescriptor: ModuleDescriptor + get() = error("Should not be called") + + @ObsoleteDescriptorBasedAPI + override val bindingContext: BindingContext + get() = error("Should not be called") + + @ObsoleteDescriptorBasedAPI + override val typeTranslator: TypeTranslator + get() = error("Should not be called") + + override fun createDiagnosticReporter(pluginId: String): IrMessageLogger { + error("Should not be called") + } + + override fun referenceClass(fqName: FqName): IrClassSymbol? { + error("Should not be called") + } + + override fun referenceTypeAlias(fqName: FqName): IrTypeAliasSymbol? { + error("Should not be called") + } + + override fun referenceConstructors(classFqn: FqName): Collection { + error("Should not be called") + } + + override fun referenceFunctions(fqName: FqName): Collection { + error("Should not be called") + } + + override fun referenceProperties(fqName: FqName): Collection { + error("Should not be called") + } + + override fun referenceTopLevel( + signature: IdSignature, + kind: IrDeserializer.TopLevelSymbolKind, + moduleDescriptor: ModuleDescriptor + ): IrSymbol? { + error("Should not be called") + } + } } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt index 936c9061363..61a84535fba 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt @@ -11,13 +11,13 @@ import com.intellij.psi.PsiElementFinder import com.intellij.psi.search.ProjectScope import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices import org.jetbrains.kotlin.asJava.finder.JavaElementFinder +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers import org.jetbrains.kotlin.fir.moduleData @@ -116,6 +116,7 @@ class FirFrontendFacade( languageVersionSettings, ktFiles, originalFiles, + IrGenerationExtension.getInstances(project), lightTreeEnabled, enablePluginPhases ) diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt index 789bff20155..103bd39d172 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.TestsCompiletimeError import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.asJava.finder.JavaElementFinder +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys @@ -105,7 +106,13 @@ object GenerationUtils { val session = createSessionForTests(project, scope, librariesScope, "main", getPackagePartProvider = packagePartProvider) // TODO: add running checkers and check that it's safe to compile - val firAnalyzerFacade = FirAnalyzerFacade(session, configuration.languageVersionSettings, files) + val firAnalyzerFacade = FirAnalyzerFacade( + session, + configuration.languageVersionSettings, + files, + emptyList(), + IrGenerationExtension.getInstances(project) + ) val extensions = JvmGeneratorExtensionsImpl(configuration) val (moduleFragment, symbolTable, components) = firAnalyzerFacade.convertToIr(extensions) val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext