[LL API] Run fir2ir separately for files in different modules
Each module may have its own compiler configuration. ^KTIJ-27061 Fixed
This commit is contained in:
+169
-50
@@ -17,10 +17,14 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getModule
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedId
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedId
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedValueAnalyzer
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedValueAnalyzer
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CompilationPeerCollector
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CompilationPeerCollector
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.codeFragment
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
@@ -31,17 +35,17 @@ import org.jetbrains.kotlin.codegen.CodegenFactory
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticMarker
|
import org.jetbrains.kotlin.diagnostics.DiagnosticMarker
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.Severity
|
import org.jetbrains.kotlin.diagnostics.Severity
|
||||||
import org.jetbrains.kotlin.fir.backend.*
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.*
|
import org.jetbrains.kotlin.fir.backend.jvm.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.pipeline.applyIrGenerationExtensions
|
import org.jetbrains.kotlin.fir.pipeline.applyIrGenerationExtensions
|
||||||
import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir
|
import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
@@ -65,8 +69,11 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
|
import org.jetbrains.kotlin.ir.symbols.IrSymbolInternals
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
|
import org.jetbrains.kotlin.ir.util.DelicateSymbolTableApi
|
||||||
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
import org.jetbrains.kotlin.ir.util.classId
|
import org.jetbrains.kotlin.ir.util.classId
|
||||||
|
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
|
||||||
|
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
@@ -95,12 +102,6 @@ internal class KtFirCompilerFacility(
|
|||||||
is KtCompilerTarget.Jvm -> target.classBuilderFactory
|
is KtCompilerTarget.Jvm -> target.classBuilderFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
val effectiveConfiguration = configuration
|
|
||||||
.copy()
|
|
||||||
.apply {
|
|
||||||
put(CommonConfigurationKeys.USE_FIR, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
val mainFirFile = getFullyResolvedFirFile(file)
|
val mainFirFile = getFullyResolvedFirFile(file)
|
||||||
|
|
||||||
val frontendDiagnostics = file.collectDiagnosticsForFile(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
|
val frontendDiagnostics = file.collectDiagnosticsForFile(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
|
||||||
@@ -129,61 +130,67 @@ internal class KtFirCompilerFacility(
|
|||||||
add(file)
|
add(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
val firFilesToCompile = filesToCompile.map(::getFullyResolvedFirFile)
|
// Files in the code fragment context module are compiled together with the code fragment itself.
|
||||||
|
val targetModule = mainFirFile.llFirModuleData.ktModule
|
||||||
|
val (targetFiles, dependencyFiles) = filesToCompile.partition { firResolveSession.getModule(it) == targetModule }
|
||||||
|
require(targetFiles.isNotEmpty())
|
||||||
|
|
||||||
val generateClassFilter = SingleFileGenerateClassFilter(file, compilationPeerData.inlinedClasses)
|
val jvmIrDeserializer = JvmIrDeserializerImpl()
|
||||||
|
val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter()
|
||||||
|
|
||||||
val jvmGeneratorExtensions = JvmFir2IrExtensions(effectiveConfiguration, JvmIrDeserializerImpl(), JvmIrMangler)
|
val dependencyFir2IrResults = dependencyFiles
|
||||||
val fir2IrExtensions = CompilerFacilityFir2IrExtensions(jvmGeneratorExtensions, codeFragmentMappings?.injectedValueProvider)
|
.map(::getFullyResolvedFirFile)
|
||||||
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
|
.groupBy { it.llFirSession }
|
||||||
|
.map { (dependencySession, dependencyFiles) ->
|
||||||
|
val dependencyConfiguration = configuration
|
||||||
|
.copy()
|
||||||
|
.apply {
|
||||||
|
put(CommonConfigurationKeys.USE_FIR, true)
|
||||||
|
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, dependencySession.languageVersionSettings)
|
||||||
|
}
|
||||||
|
|
||||||
val fir2IrConfiguration = Fir2IrConfiguration(
|
val dependencyFir2IrExtensions = JvmFir2IrExtensions(dependencyConfiguration, jvmIrDeserializer, JvmIrMangler)
|
||||||
effectiveConfiguration.languageVersionSettings,
|
runFir2Ir(dependencySession, dependencyFiles, dependencyFir2IrExtensions, diagnosticReporter, dependencyConfiguration)
|
||||||
diagnosticsReporter,
|
}
|
||||||
linkViaSignatures = false,
|
|
||||||
evaluatedConstTracker = effectiveConfiguration[CommonConfigurationKeys.EVALUATED_CONST_TRACKER] ?: EvaluatedConstTracker.create(),
|
val targetConfiguration = configuration
|
||||||
inlineConstTracker = effectiveConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
|
.copy()
|
||||||
expectActualTracker = effectiveConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
|
.apply {
|
||||||
allowNonCachedDeclarations = true,
|
put(CommonConfigurationKeys.USE_FIR, true)
|
||||||
useIrFakeOverrideBuilder = effectiveConfiguration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
|
}
|
||||||
|
|
||||||
|
val jvmGeneratorExtensions = JvmFir2IrExtensions(targetConfiguration, jvmIrDeserializer, JvmIrMangler)
|
||||||
|
val targetFir2IrExtensions = CompilerFacilityFir2IrExtensions(
|
||||||
|
jvmGeneratorExtensions,
|
||||||
|
dependencyFir2IrResults,
|
||||||
|
codeFragmentMappings?.injectedValueProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
val fir2IrResult = Fir2IrConverter.createIrModuleFragment(
|
val targetSession = mainFirFile.llFirSession
|
||||||
rootModuleSession,
|
val targetFirFiles = targetFiles.map(::getFullyResolvedFirFile)
|
||||||
firResolveSession.getScopeSessionFor(rootModuleSession),
|
val targetFir2IrResult = runFir2Ir(targetSession, targetFirFiles, targetFir2IrExtensions, diagnosticReporter, targetConfiguration)
|
||||||
firFilesToCompile,
|
|
||||||
fir2IrExtensions,
|
|
||||||
fir2IrConfiguration,
|
|
||||||
JvmIrMangler,
|
|
||||||
IrFactoryImpl,
|
|
||||||
FirJvmVisibilityConverter,
|
|
||||||
Fir2IrJvmSpecialAnnotationSymbolProvider(),
|
|
||||||
DefaultBuiltIns.Instance,
|
|
||||||
Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(false), FirJvmKotlinMangler()),
|
|
||||||
initializedIrBuiltIns = null,
|
|
||||||
::JvmIrTypeSystemContext,
|
|
||||||
)
|
|
||||||
|
|
||||||
patchCodeFragmentIr(fir2IrResult)
|
patchCodeFragmentIr(targetFir2IrResult)
|
||||||
|
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
|
|
||||||
val irGeneratorExtensions = IrGenerationExtension.getInstances(project)
|
val irGeneratorExtensions = IrGenerationExtension.getInstances(project)
|
||||||
fir2IrResult.components.applyIrGenerationExtensions(fir2IrResult.irModuleFragment, irGeneratorExtensions)
|
targetFir2IrResult.components.applyIrGenerationExtensions(targetFir2IrResult.irModuleFragment, irGeneratorExtensions)
|
||||||
|
|
||||||
val bindingContext = NoScopeRecordCliBindingTrace().bindingContext
|
val bindingContext = NoScopeRecordCliBindingTrace().bindingContext
|
||||||
val codegenFactory = createJvmIrCodegenFactory(effectiveConfiguration, file is KtCodeFragment, fir2IrResult.irModuleFragment)
|
val codegenFactory = createJvmIrCodegenFactory(targetConfiguration, file is KtCodeFragment, targetFir2IrResult.irModuleFragment)
|
||||||
|
val generateClassFilter = SingleFileGenerateClassFilter(file, compilationPeerData.inlinedClasses)
|
||||||
|
|
||||||
val generationState = GenerationState.Builder(
|
val generationState = GenerationState.Builder(
|
||||||
project,
|
project,
|
||||||
classBuilderFactory,
|
classBuilderFactory,
|
||||||
fir2IrResult.irModuleFragment.descriptor,
|
targetFir2IrResult.irModuleFragment.descriptor,
|
||||||
bindingContext,
|
bindingContext,
|
||||||
filesToCompile,
|
targetFiles,
|
||||||
effectiveConfiguration,
|
targetConfiguration,
|
||||||
).generateDeclaredClassFilter(generateClassFilter)
|
).generateDeclaredClassFilter(generateClassFilter)
|
||||||
.codegenFactory(codegenFactory)
|
.codegenFactory(codegenFactory)
|
||||||
.diagnosticReporter(diagnosticsReporter)
|
.diagnosticReporter(diagnosticReporter)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -193,12 +200,12 @@ internal class KtFirCompilerFacility(
|
|||||||
|
|
||||||
codegenFactory.generateModuleInFrontendIRMode(
|
codegenFactory.generateModuleInFrontendIRMode(
|
||||||
generationState,
|
generationState,
|
||||||
fir2IrResult.irModuleFragment,
|
targetFir2IrResult.irModuleFragment,
|
||||||
fir2IrResult.components.symbolTable,
|
targetFir2IrResult.components.symbolTable,
|
||||||
fir2IrResult.components.irProviders,
|
targetFir2IrResult.components.irProviders,
|
||||||
CompilerFacilityJvmGeneratorExtensions(jvmGeneratorExtensions),
|
CompilerFacilityJvmGeneratorExtensions(jvmGeneratorExtensions),
|
||||||
FirJvmBackendExtension(fir2IrResult.components, null),
|
FirJvmBackendExtension(targetFir2IrResult.components, null),
|
||||||
fir2IrResult.pluginContext
|
targetFir2IrResult.pluginContext
|
||||||
)
|
)
|
||||||
|
|
||||||
CodegenFactory.doCheckCancelled(generationState)
|
CodegenFactory.doCheckCancelled(generationState)
|
||||||
@@ -222,12 +229,48 @@ internal class KtFirCompilerFacility(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return KtCompilationResult.Success(outputFiles, capturedValues)
|
return KtCompilationResult.Success(outputFiles, capturedValues)
|
||||||
} finally {
|
} finally {
|
||||||
generationState.destroy()
|
generationState.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun runFir2Ir(
|
||||||
|
session: LLFirSession,
|
||||||
|
firFiles: List<FirFile>,
|
||||||
|
fir2IrExtensions: Fir2IrExtensions,
|
||||||
|
diagnosticReporter: DiagnosticReporter,
|
||||||
|
effectiveConfiguration: CompilerConfiguration,
|
||||||
|
): Fir2IrResult {
|
||||||
|
val fir2IrConfiguration = Fir2IrConfiguration(
|
||||||
|
session.languageVersionSettings,
|
||||||
|
diagnosticReporter,
|
||||||
|
linkViaSignatures = false,
|
||||||
|
evaluatedConstTracker = effectiveConfiguration[CommonConfigurationKeys.EVALUATED_CONST_TRACKER] ?: EvaluatedConstTracker.create(),
|
||||||
|
inlineConstTracker = effectiveConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
|
||||||
|
expectActualTracker = effectiveConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
|
||||||
|
allowNonCachedDeclarations = true,
|
||||||
|
useIrFakeOverrideBuilder = effectiveConfiguration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
|
||||||
|
)
|
||||||
|
|
||||||
|
return Fir2IrConverter.createIrModuleFragment(
|
||||||
|
session,
|
||||||
|
session.getScopeSession(),
|
||||||
|
firFiles,
|
||||||
|
fir2IrExtensions,
|
||||||
|
fir2IrConfiguration,
|
||||||
|
JvmIrMangler,
|
||||||
|
IrFactoryImpl,
|
||||||
|
FirJvmVisibilityConverter,
|
||||||
|
Fir2IrJvmSpecialAnnotationSymbolProvider(),
|
||||||
|
DefaultBuiltIns.Instance,
|
||||||
|
Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(false), FirJvmKotlinMangler()),
|
||||||
|
initializedIrBuiltIns = null,
|
||||||
|
::JvmIrTypeSystemContext,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun patchCodeFragmentIr(fir2IrResult: Fir2IrResult) {
|
private fun patchCodeFragmentIr(fir2IrResult: Fir2IrResult) {
|
||||||
fun isCodeFragmentFile(irFile: IrFile): Boolean {
|
fun isCodeFragmentFile(irFile: IrFile): Boolean {
|
||||||
val firFiles = (irFile.metadata as? FirMetadataSource.File)?.files ?: return false
|
val firFiles = (irFile.metadata as? FirMetadataSource.File)?.files ?: return false
|
||||||
@@ -391,11 +434,23 @@ internal class KtFirCompilerFacility(
|
|||||||
|
|
||||||
private class CompilerFacilityFir2IrExtensions(
|
private class CompilerFacilityFir2IrExtensions(
|
||||||
delegate: Fir2IrExtensions,
|
delegate: Fir2IrExtensions,
|
||||||
|
private val dependencyFir2IrResults: List<Fir2IrResult>,
|
||||||
private val injectedValueProvider: InjectedSymbolProvider?
|
private val injectedValueProvider: InjectedSymbolProvider?
|
||||||
) : Fir2IrExtensions by delegate {
|
) : Fir2IrExtensions by delegate {
|
||||||
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue? {
|
override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue? {
|
||||||
return injectedValueProvider?.invoke(calleeReference, conversionScope)
|
return injectedValueProvider?.invoke(calleeReference, conversionScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateSymbolTableApi::class)
|
||||||
|
override fun registerDeclarations(symbolTable: SymbolTable) {
|
||||||
|
val visitor = DeclarationRegistrarVisitor(symbolTable)
|
||||||
|
|
||||||
|
for (dependencyFir2IrResult in dependencyFir2IrResults) {
|
||||||
|
for (dependencyFile in dependencyFir2IrResult.irModuleFragment.files) {
|
||||||
|
dependencyFile.acceptVoid(visitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SingleFileGenerateClassFilter(
|
private class SingleFileGenerateClassFilter(
|
||||||
@@ -567,3 +622,67 @@ private class IrDeclarationPatchingVisitor(private val mapping: Map<FirDeclarati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DeclarationRegistrarVisitor(private val consumer: SymbolTable) : IrElementVisitorVoid {
|
||||||
|
override fun visitElement(element: IrElement) {
|
||||||
|
element.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClass(declaration: IrClass) {
|
||||||
|
register(declaration, consumer::declareClassIfNotExists)
|
||||||
|
super.visitClass(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeAlias(declaration: IrTypeAlias) {
|
||||||
|
register(declaration, consumer::declareTypeAliasIfNotExists)
|
||||||
|
super.visitTypeAlias(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitScript(declaration: IrScript) {
|
||||||
|
register(declaration, consumer::declareScript)
|
||||||
|
super.visitScript(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitTypeParameter(declaration: IrTypeParameter) {
|
||||||
|
if (declaration.parent is IrClass) {
|
||||||
|
register(declaration, consumer::declareGlobalTypeParameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
super.visitTypeParameter(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitConstructor(declaration: IrConstructor) {
|
||||||
|
register(declaration, consumer::declareConstructorIfNotExists)
|
||||||
|
super.visitConstructor(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
||||||
|
register(declaration, consumer::declareSimpleFunctionIfNotExists)
|
||||||
|
super.visitSimpleFunction(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(declaration: IrProperty) {
|
||||||
|
register(declaration, consumer::declarePropertyIfNotExists)
|
||||||
|
super.visitProperty(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitField(declaration: IrField) {
|
||||||
|
register(declaration, consumer::declareField)
|
||||||
|
super.visitField(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitEnumEntry(declaration: IrEnumEntry) {
|
||||||
|
register(declaration, consumer::declareEnumEntry)
|
||||||
|
super.visitEnumEntry(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(IrSymbolInternals::class)
|
||||||
|
private inline fun <reified S : IrSymbol, D : IrDeclaration> register(
|
||||||
|
declaration: D,
|
||||||
|
registrar: (IdSignature, () -> S, (S) -> D) -> Unit,
|
||||||
|
) {
|
||||||
|
val symbol = declaration.symbol as S
|
||||||
|
val signature = symbol.signature ?: return
|
||||||
|
registrar(signature, { symbol }, { declaration })
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.analysis.api.fir.test.cases.generated.cases.components.compilerFacility;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory;
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData;
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator;
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind;
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind;
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode;
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode;
|
||||||
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compilerFacility.AbstractMultiModuleCompilerFacilityTest;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class FirIdeNormalAnalysisSourceModuleMultiModuleCompilerFacilityTestGenerated extends AbstractMultiModuleCompilerFacilityTest {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public AnalysisApiTestConfigurator getConfigurator() {
|
||||||
|
return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator(
|
||||||
|
new AnalysisApiTestConfiguratorFactoryData(
|
||||||
|
FrontendKind.Fir,
|
||||||
|
TestModuleKind.Source,
|
||||||
|
AnalysisSessionMode.Normal,
|
||||||
|
AnalysisApiMode.Ide
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInCompilationMultiModule() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("commonUsage.kt")
|
||||||
|
public void testCommonUsage() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("defaultParameterValue.kt")
|
||||||
|
public void testDefaultParameterValue() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("internalUsage.kt")
|
||||||
|
public void testInternalUsage() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
-9
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.analysis.api.components.KtCompilerFacility
|
|||||||
import org.jetbrains.kotlin.analysis.api.components.KtCompilerTarget
|
import org.jetbrains.kotlin.analysis.api.components.KtCompilerTarget
|
||||||
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
|
||||||
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
|
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest
|
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
@@ -36,6 +37,7 @@ import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirective
|
|||||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.assertions
|
import org.jetbrains.kotlin.test.services.assertions
|
||||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||||
@@ -45,7 +47,9 @@ import org.jetbrains.org.objectweb.asm.tree.ClassNode
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
|
|
||||||
abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedSingleModuleTest() {
|
abstract class AbstractMultiModuleCompilerFacilityTest : AbstractCompilerFacilityTest()
|
||||||
|
|
||||||
|
abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedTest() {
|
||||||
private companion object {
|
private companion object {
|
||||||
private val ALLOWED_ERRORS = listOf(
|
private val ALLOWED_ERRORS = listOf(
|
||||||
FirErrors.INVISIBLE_REFERENCE,
|
FirErrors.INVISIBLE_REFERENCE,
|
||||||
@@ -64,7 +68,9 @@ abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedSingleModu
|
|||||||
).map { it.name }
|
).map { it.name }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
|
override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||||
|
val mainModule = moduleStructure.modules.first { it.name == "main" }
|
||||||
|
val ktFiles = testServices.ktModuleProvider.getModuleFiles(mainModule).filterIsInstance<KtFile>()
|
||||||
val ktFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" }
|
val ktFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" }
|
||||||
|
|
||||||
val irCollector = CollectingIrGenerationExtension()
|
val irCollector = CollectingIrGenerationExtension()
|
||||||
@@ -73,22 +79,22 @@ abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedSingleModu
|
|||||||
project.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName)
|
project.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName)
|
||||||
.registerExtension(irCollector, LoadingOrder.LAST, project)
|
.registerExtension(irCollector, LoadingOrder.LAST, project)
|
||||||
|
|
||||||
val ktCodeFragment = createCodeFragment(ktFile, module, testServices)
|
val ktCodeFragment = createCodeFragment(ktFile, mainModule, testServices)
|
||||||
if (ktCodeFragment != null) {
|
if (ktCodeFragment != null) {
|
||||||
for (importNameString in module.directives[Directives.CODE_FRAGMENT_IMPORT]) {
|
for (importNameString in mainModule.directives[Directives.CODE_FRAGMENT_IMPORT]) {
|
||||||
ktCodeFragment.addImport("import $importNameString")
|
ktCodeFragment.addImport("import $importNameString")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val compilerConfiguration = CompilerConfiguration().apply {
|
val compilerConfiguration = CompilerConfiguration().apply {
|
||||||
put(CommonConfigurationKeys.MODULE_NAME, module.name)
|
put(CommonConfigurationKeys.MODULE_NAME, mainModule.name)
|
||||||
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, module.languageVersionSettings)
|
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, mainModule.languageVersionSettings)
|
||||||
put(JVMConfigurationKeys.IR, true)
|
put(JVMConfigurationKeys.IR, true)
|
||||||
|
|
||||||
module.directives[Directives.CODE_FRAGMENT_CLASS_NAME].singleOrNull()
|
mainModule.directives[Directives.CODE_FRAGMENT_CLASS_NAME].singleOrNull()
|
||||||
?.let { put(KtCompilerFacility.CODE_FRAGMENT_CLASS_NAME, it) }
|
?.let { put(KtCompilerFacility.CODE_FRAGMENT_CLASS_NAME, it) }
|
||||||
|
|
||||||
module.directives[Directives.CODE_FRAGMENT_METHOD_NAME].singleOrNull()
|
mainModule.directives[Directives.CODE_FRAGMENT_METHOD_NAME].singleOrNull()
|
||||||
?.let { put(KtCompilerFacility.CODE_FRAGMENT_METHOD_NAME, it) }
|
?.let { put(KtCompilerFacility.CODE_FRAGMENT_METHOD_NAME, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.ir.txt
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
MODULE_FRAGMENT
|
||||||
|
FILE fqName:<root> fileName:main.kt
|
||||||
|
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||||
|
CALL 'public final fun lib (): kotlin.String declared in lib.LibKt' type=kotlin.String origin=null
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// MODULE: lib
|
||||||
|
// TARGET_PLATFORM: Common
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun lib(): String = "foo"
|
||||||
|
|
||||||
|
// MODULE: main()()(lib)
|
||||||
|
// TARGET_PLATFORM: JVM
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
import lib.lib
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
lib()
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public final class MainKt {
|
||||||
|
// source: 'main.kt'
|
||||||
|
public final static method test(): void
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
MODULE_FRAGMENT
|
||||||
|
FILE fqName:<root> fileName:main.kt
|
||||||
|
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||||
|
CALL 'public final fun lib (a: kotlin.Int): kotlin.String declared in lib.LibKt' type=kotlin.String origin=null
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
fun lib(a: Int = 5): String {
|
||||||
|
return "$a"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
import lib.lib
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
lib()
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public final class MainKt {
|
||||||
|
// source: 'main.kt'
|
||||||
|
public final static method test(): void
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
MODULE_FRAGMENT
|
||||||
|
FILE fqName:<root> fileName:main.kt
|
||||||
|
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
|
BLOCK_BODY
|
||||||
|
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||||
|
CALL 'internal final fun lib (): kotlin.String declared in lib.LibKt' type=kotlin.String origin=null
|
||||||
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// MODULE: lib
|
||||||
|
// FILE: lib.kt
|
||||||
|
|
||||||
|
package lib
|
||||||
|
|
||||||
|
internal fun lib(): String = "foo"
|
||||||
|
|
||||||
|
// MODULE: main(lib)
|
||||||
|
// FILE: main.kt
|
||||||
|
|
||||||
|
import lib.lib
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
lib()
|
||||||
|
}
|
||||||
Vendored
+4
@@ -0,0 +1,4 @@
|
|||||||
|
public final class MainKt {
|
||||||
|
// source: 'main.kt'
|
||||||
|
public final static method test(): void
|
||||||
|
}
|
||||||
+5
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.callRes
|
|||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.callResolver.AbstractResolveCandidatesTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.callResolver.AbstractResolveCandidatesTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compileTimeConstantProvider.AbstractCompileTimeConstantEvaluatorTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compileTimeConstantProvider.AbstractCompileTimeConstantEvaluatorTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compilerFacility.AbstractCompilerFacilityTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compilerFacility.AbstractCompilerFacilityTest
|
||||||
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compilerFacility.AbstractMultiModuleCompilerFacilityTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByDelegatedMemberScopeTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByDelegatedMemberScopeTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByMemberScopeTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByMemberScopeTest
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByPsiTest
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByPsiTest
|
||||||
@@ -92,6 +93,10 @@ internal fun AnalysisApiTestGroup.generateAnalysisApiTests() {
|
|||||||
test(AbstractCompilerFacilityTest::class) {
|
test(AbstractCompilerFacilityTest::class) {
|
||||||
model("compilation", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
|
model("compilation", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test(AbstractMultiModuleCompilerFacilityTest::class, filter = testModuleKindIs(TestModuleKind.Source)) {
|
||||||
|
model("compilationMultiModule", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group(filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.ScriptSource)) {
|
group(filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.ScriptSource)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user