diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt index 5f7be36d5df..81e29e33ed3 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.serializeToByteArray import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DeclarationDescriptor @@ -63,7 +64,7 @@ open class MetadataSerializer(private val dependOnOldBuiltIns: Boolean) { val analyzer = AnalyzerWithCompilerReport(messageCollector) analyzer.analyzeAndReport(files) { - DefaultAnalyzerFacade.analyzeFiles(files, moduleName, dependOnOldBuiltIns) { _, content -> + DefaultAnalyzerFacade.analyzeFiles(files, moduleName, dependOnOldBuiltIns, configuration.languageVersionSettings) { _, content -> environment.createPackagePartProvider(content.moduleContentScope) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt index c65c031c7ca..f0280c1720f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/DefaultAnalyzerFacade.kt @@ -43,15 +43,10 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmentProvider /** - * A facade that is used to analyze platform independent modules in multi-platform projects. + * A facade that is used to analyze common (platform-independent) modules in multi-platform projects. * See [TargetPlatform.Default] */ object DefaultAnalyzerFacade : AnalyzerFacade() { - private val languageVersionSettings = LanguageVersionSettingsImpl( - LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, - specificFeatures = mapOf(LanguageFeature.MultiPlatformProjects to LanguageFeature.State.ENABLED) - ) - private class SourceModuleInfo( override val name: Name, override val capabilities: Map, Any?>, @@ -64,12 +59,19 @@ object DefaultAnalyzerFacade : AnalyzerFacade() { } fun analyzeFiles( - files: Collection, moduleName: Name, dependOnBuiltIns: Boolean, + files: Collection, moduleName: Name, dependOnBuiltIns: Boolean, languageVersionSettings: LanguageVersionSettings, capabilities: Map, Any?> = mapOf(MultiTargetPlatform.CAPABILITY to MultiTargetPlatform.Common), packagePartProviderFactory: (ModuleInfo, ModuleContent) -> PackagePartProvider ): AnalysisResult { val moduleInfo = SourceModuleInfo(moduleName, capabilities, dependOnBuiltIns) val project = files.firstOrNull()?.project ?: throw AssertionError("No files to analyze") + + val multiplatformLanguageSettings = object : LanguageVersionSettings by languageVersionSettings { + override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State = + if (feature == LanguageFeature.MultiPlatformProjects) LanguageFeature.State.ENABLED + else languageVersionSettings.getFeatureSupport(feature) + } + @Suppress("NAME_SHADOWING") val resolver = setupResolverForProject( "sources for metadata serializer", @@ -77,7 +79,7 @@ object DefaultAnalyzerFacade : AnalyzerFacade() { { ModuleContent(files, GlobalSearchScope.allScope(project)) }, object : PlatformAnalysisParameters {}, object : LanguageSettingsProvider { - override fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project) = languageVersionSettings + override fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project) = multiplatformLanguageSettings override fun getTargetPlatform(moduleInfo: ModuleInfo) = TargetPlatformVersion.NoVersion }, packagePartProviderFactory = packagePartProviderFactory, @@ -113,7 +115,8 @@ object DefaultAnalyzerFacade : AnalyzerFacade() { val trace = CodeAnalyzerInitializer.getInstance(project).createTrace() val container = createContainerToResolveCommonCode( - moduleContext, trace, declarationProviderFactory, moduleContentScope, targetEnvironment, packagePartProvider + moduleContext, trace, declarationProviderFactory, moduleContentScope, targetEnvironment, packagePartProvider, + languageSettingsProvider.getLanguageVersionSettings(moduleInfo, project) ) val packageFragmentProviders = listOf( @@ -130,7 +133,8 @@ object DefaultAnalyzerFacade : AnalyzerFacade() { declarationProviderFactory: DeclarationProviderFactory, moduleContentScope: GlobalSearchScope, targetEnvironment: TargetEnvironment, - packagePartProvider: PackagePartProvider + packagePartProvider: PackagePartProvider, + languageVersionSettings: LanguageVersionSettings ): StorageComponentContainer = createContainer("ResolveCommonCode", targetPlatform) { configureModule(moduleContext, targetPlatform, TargetPlatformVersion.NoVersion, bindingTrace) diff --git a/compiler/testData/multiplatform/compilerArguments/common.kt b/compiler/testData/multiplatform/compilerArguments/common.kt new file mode 100644 index 00000000000..2a1dde5f48c --- /dev/null +++ b/compiler/testData/multiplatform/compilerArguments/common.kt @@ -0,0 +1,9 @@ +// ADDITIONAL_COMPILER_ARGUMENTS: -Xcoroutines=enable + +fun f(g: suspend () -> Unit): Any = g + +suspend fun h() = f { } + +header suspend fun k() + +header fun l(g: suspend () -> Unit): Any diff --git a/compiler/testData/multiplatform/compilerArguments/output.txt b/compiler/testData/multiplatform/compilerArguments/output.txt new file mode 100644 index 00000000000..4c0afff7be9 --- /dev/null +++ b/compiler/testData/multiplatform/compilerArguments/output.txt @@ -0,0 +1,3 @@ +-- Common -- +Exit code: OK +Output: diff --git a/compiler/tests-common/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt b/compiler/tests-common/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt index fbc31856855..849cf2dee1d 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt +++ b/compiler/tests-common/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt @@ -291,7 +291,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() { val platform = moduleDescriptor.getMultiTargetPlatform() if (platform == MultiTargetPlatform.Common) { return DefaultAnalyzerFacade.analyzeFiles( - files, moduleDescriptor.name, true, + files, moduleDescriptor.name, true, languageVersionSettings, mapOf( MultiTargetPlatform.CAPABILITY to MultiTargetPlatform.Common, MODULE_FILES to files diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt index 93bc83c0bed..8094f858cfd 100644 --- a/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.js.K2JSCompiler import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler +import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase import org.jetbrains.kotlin.test.util.trimTrailingWhitespacesAndAddNewlineAtEOF @@ -68,9 +69,9 @@ abstract class AbstractMultiPlatformIntegrationTest : KtUsefulTestCase() { KotlinTestUtils.assertEqualsToFile(File(root, "output.txt"), result.replace('\\', '/')) } - private fun CLICompiler<*>.compileBothWays(commonSource: File, platformSource: File, vararg additionalArguments: String): String { - val platformFirst = compile(listOf(platformSource, commonSource), *additionalArguments) - val commonFirst = compile(listOf(commonSource, platformSource), *additionalArguments) + private fun CLICompiler<*>.compileBothWays(commonSource: File, platformSource: File, vararg mainArguments: String): String { + val platformFirst = compile(listOf(platformSource, commonSource), *mainArguments) + val commonFirst = compile(listOf(commonSource, platformSource), *mainArguments) if (platformFirst != commonFirst) { assertEquals( "Compilation results are different when compiling [platform-specific, common] compared to when compiling [common, platform-specific]", @@ -81,13 +82,17 @@ abstract class AbstractMultiPlatformIntegrationTest : KtUsefulTestCase() { return platformFirst } - private fun CLICompiler<*>.compile(sources: List, vararg additionalArguments: String): String = buildString { + private fun CLICompiler<*>.compile(sources: List, vararg mainArguments: String): String = buildString { val (output, exitCode) = AbstractCliTest.executeCompilerGrabOutput( this@compile, - sources.map(File::getAbsolutePath) + listOf("-Xmulti-platform") + additionalArguments + sources.map(File::getAbsolutePath) + listOf("-Xmulti-platform") + mainArguments + loadExtraArguments(sources) ) appendln("Exit code: $exitCode") appendln("Output:") appendln(output) }.trimTrailingWhitespacesAndAddNewlineAtEOF().trimEnd('\r', '\n') + + private fun loadExtraArguments(sources: List): List = sources.flatMap { source -> + InTextDirectivesUtils.findListWithPrefixes(source.readText(), "// ADDITIONAL_COMPILER_ARGUMENTS:") + } } diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java index 869b8a24218..af95063b9ef 100644 --- a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java @@ -42,6 +42,12 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform doTest(fileName); } + @TestMetadata("compilerArguments") + public void testCompilerArguments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/compilerArguments/"); + doTest(fileName); + } + @TestMetadata("createImplClassInPlatformModule") public void testCreateImplClassInPlatformModule() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/multiplatform/createImplClassInPlatformModule/");