diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt index 858846c2e8a..9ffa6e63ba2 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirCompilerFacility.kt @@ -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.LLFirResolveSession 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.compile.CodeFragmentCapturedId 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.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.backend.common.extensions.IrGenerationExtension 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.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticMarker +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.jvm.* 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.signatureComposerForJvmFir2Ir 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.IrSymbolInternals 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.StubGeneratorExtensions +import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -95,12 +102,6 @@ internal class KtFirCompilerFacility( is KtCompilerTarget.Jvm -> target.classBuilderFactory } - val effectiveConfiguration = configuration - .copy() - .apply { - put(CommonConfigurationKeys.USE_FIR, true) - } - val mainFirFile = getFullyResolvedFirFile(file) val frontendDiagnostics = file.collectDiagnosticsForFile(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS) @@ -129,61 +130,67 @@ internal class KtFirCompilerFacility( 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 fir2IrExtensions = CompilerFacilityFir2IrExtensions(jvmGeneratorExtensions, codeFragmentMappings?.injectedValueProvider) - val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() + val dependencyFir2IrResults = dependencyFiles + .map(::getFullyResolvedFirFile) + .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( - effectiveConfiguration.languageVersionSettings, - diagnosticsReporter, - 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), + val dependencyFir2IrExtensions = JvmFir2IrExtensions(dependencyConfiguration, jvmIrDeserializer, JvmIrMangler) + runFir2Ir(dependencySession, dependencyFiles, dependencyFir2IrExtensions, diagnosticReporter, dependencyConfiguration) + } + + val targetConfiguration = configuration + .copy() + .apply { + put(CommonConfigurationKeys.USE_FIR, true) + } + + val jvmGeneratorExtensions = JvmFir2IrExtensions(targetConfiguration, jvmIrDeserializer, JvmIrMangler) + val targetFir2IrExtensions = CompilerFacilityFir2IrExtensions( + jvmGeneratorExtensions, + dependencyFir2IrResults, + codeFragmentMappings?.injectedValueProvider ) - val fir2IrResult = Fir2IrConverter.createIrModuleFragment( - rootModuleSession, - firResolveSession.getScopeSessionFor(rootModuleSession), - firFilesToCompile, - fir2IrExtensions, - fir2IrConfiguration, - JvmIrMangler, - IrFactoryImpl, - FirJvmVisibilityConverter, - Fir2IrJvmSpecialAnnotationSymbolProvider(), - DefaultBuiltIns.Instance, - Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(false), FirJvmKotlinMangler()), - initializedIrBuiltIns = null, - ::JvmIrTypeSystemContext, - ) + val targetSession = mainFirFile.llFirSession + val targetFirFiles = targetFiles.map(::getFullyResolvedFirFile) + val targetFir2IrResult = runFir2Ir(targetSession, targetFirFiles, targetFir2IrExtensions, diagnosticReporter, targetConfiguration) - patchCodeFragmentIr(fir2IrResult) + patchCodeFragmentIr(targetFir2IrResult) ProgressManager.checkCanceled() val irGeneratorExtensions = IrGenerationExtension.getInstances(project) - fir2IrResult.components.applyIrGenerationExtensions(fir2IrResult.irModuleFragment, irGeneratorExtensions) + targetFir2IrResult.components.applyIrGenerationExtensions(targetFir2IrResult.irModuleFragment, irGeneratorExtensions) 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( project, classBuilderFactory, - fir2IrResult.irModuleFragment.descriptor, + targetFir2IrResult.irModuleFragment.descriptor, bindingContext, - filesToCompile, - effectiveConfiguration, + targetFiles, + targetConfiguration, ).generateDeclaredClassFilter(generateClassFilter) .codegenFactory(codegenFactory) - .diagnosticReporter(diagnosticsReporter) + .diagnosticReporter(diagnosticReporter) .build() try { @@ -193,12 +200,12 @@ internal class KtFirCompilerFacility( codegenFactory.generateModuleInFrontendIRMode( generationState, - fir2IrResult.irModuleFragment, - fir2IrResult.components.symbolTable, - fir2IrResult.components.irProviders, + targetFir2IrResult.irModuleFragment, + targetFir2IrResult.components.symbolTable, + targetFir2IrResult.components.irProviders, CompilerFacilityJvmGeneratorExtensions(jvmGeneratorExtensions), - FirJvmBackendExtension(fir2IrResult.components, null), - fir2IrResult.pluginContext + FirJvmBackendExtension(targetFir2IrResult.components, null), + targetFir2IrResult.pluginContext ) CodegenFactory.doCheckCancelled(generationState) @@ -222,12 +229,48 @@ internal class KtFirCompilerFacility( } } } + return KtCompilationResult.Success(outputFiles, capturedValues) } finally { generationState.destroy() } } + private fun runFir2Ir( + session: LLFirSession, + firFiles: List, + 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) { fun isCodeFragmentFile(irFile: IrFile): Boolean { val firFiles = (irFile.metadata as? FirMetadataSource.File)?.files ?: return false @@ -391,11 +434,23 @@ internal class KtFirCompilerFacility( private class CompilerFacilityFir2IrExtensions( delegate: Fir2IrExtensions, + private val dependencyFir2IrResults: List, private val injectedValueProvider: InjectedSymbolProvider? ) : Fir2IrExtensions by delegate { override fun findInjectedValue(calleeReference: FirReference, conversionScope: Fir2IrConversionScope): InjectedValue? { 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( @@ -567,3 +622,67 @@ private class IrDeclarationPatchingVisitor(private val mapping: Map register( + declaration: D, + registrar: (IdSignature, () -> S, (S) -> D) -> Unit, + ) { + val symbol = declaration.symbol as S + val signature = symbol.signature ?: return + registrar(signature, { symbol }, { declaration }) + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleMultiModuleCompilerFacilityTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleMultiModuleCompilerFacilityTestGenerated.java new file mode 100644 index 00000000000..a442519a3c6 --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisSourceModuleMultiModuleCompilerFacilityTestGenerated.java @@ -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"); + } +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt index 0d04f037015..cec5eac30e8 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/compilerFacility/AbstractCompilerFacilityTest.kt @@ -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.diagnostics.KtDiagnostic 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.backend.common.extensions.IrGenerationExtension 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.model.TestModule 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.assertions import org.jetbrains.org.objectweb.asm.ClassReader @@ -45,7 +47,9 @@ import org.jetbrains.org.objectweb.asm.tree.ClassNode import java.io.File import kotlin.test.assertFalse -abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedSingleModuleTest() { +abstract class AbstractMultiModuleCompilerFacilityTest : AbstractCompilerFacilityTest() + +abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedTest() { private companion object { private val ALLOWED_ERRORS = listOf( FirErrors.INVISIBLE_REFERENCE, @@ -64,7 +68,9 @@ abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedSingleModu ).map { it.name } } - override fun doTestByFileStructure(ktFiles: List, 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() val ktFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" } val irCollector = CollectingIrGenerationExtension() @@ -73,22 +79,22 @@ abstract class AbstractCompilerFacilityTest : AbstractAnalysisApiBasedSingleModu project.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName) .registerExtension(irCollector, LoadingOrder.LAST, project) - val ktCodeFragment = createCodeFragment(ktFile, module, testServices) + val ktCodeFragment = createCodeFragment(ktFile, mainModule, testServices) 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") } } val compilerConfiguration = CompilerConfiguration().apply { - put(CommonConfigurationKeys.MODULE_NAME, module.name) - put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, module.languageVersionSettings) + put(CommonConfigurationKeys.MODULE_NAME, mainModule.name) + put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, mainModule.languageVersionSettings) 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) } - module.directives[Directives.CODE_FRAGMENT_METHOD_NAME].singleOrNull() + mainModule.directives[Directives.CODE_FRAGMENT_METHOD_NAME].singleOrNull() ?.let { put(KtCompilerFacility.CODE_FRAGMENT_METHOD_NAME, it) } } diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.ir.txt new file mode 100644 index 00000000000..90c049035ab --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.ir.txt @@ -0,0 +1,6 @@ +MODULE_FRAGMENT + FILE fqName: 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 diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.kt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.kt new file mode 100644 index 00000000000..2ec964c2f74 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.kt @@ -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() +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.txt new file mode 100644 index 00000000000..f5177f71d64 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/commonUsage.txt @@ -0,0 +1,4 @@ +public final class MainKt { + // source: 'main.kt' + public final static method test(): void +} diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.ir.txt new file mode 100644 index 00000000000..193803b8ade --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.ir.txt @@ -0,0 +1,6 @@ +MODULE_FRAGMENT + FILE fqName: 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 diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.kt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.kt new file mode 100644 index 00000000000..7368ab4c9ca --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.kt @@ -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() +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.txt new file mode 100644 index 00000000000..f5177f71d64 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/defaultParameterValue.txt @@ -0,0 +1,4 @@ +public final class MainKt { + // source: 'main.kt' + public final static method test(): void +} diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.ir.txt new file mode 100644 index 00000000000..f738e537330 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.ir.txt @@ -0,0 +1,6 @@ +MODULE_FRAGMENT + FILE fqName: 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 diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.kt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.kt new file mode 100644 index 00000000000..c275fd02e2b --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.kt @@ -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() +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.txt new file mode 100644 index 00000000000..f5177f71d64 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiModule/internalUsage.txt @@ -0,0 +1,4 @@ +public final class MainKt { + // source: 'main.kt' + public final static method test(): void +} diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt index b6042c7bb4e..a7dece8c952 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt @@ -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.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.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.AbstractContainingDeclarationProviderByMemberScopeTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.containingDeclarationProvider.AbstractContainingDeclarationProviderByPsiTest @@ -92,6 +93,10 @@ internal fun AnalysisApiTestGroup.generateAnalysisApiTests() { test(AbstractCompilerFacilityTest::class) { 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)) {