From 44b7859356b7d8c7b239e4258e06b233771a6f2c Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 17 Jan 2023 21:57:35 +0100 Subject: [PATCH] [FIR] Implement FIR metadata serialization Add FirMetadataSerializer Add CLI metadata tests on FIR --- compiler/cli/build.gradle.kts | 1 + .../FirKotlinToJvmBytecodeCompiler.kt | 29 +-- .../cli/jvm/compiler/cliCompilerUtils.kt | 70 ++++-- .../cli/metadata/FirMetadataSerializer.kt | 221 ++++++++++++++++++ .../kotlin/cli/metadata/K2MetadataCompiler.kt | 14 +- .../metadata/anonymousObjectTypeWithFir.args | 5 + ...fir.out => anonymousObjectTypeWithFir.out} | 3 +- compiler/testData/cli/metadata/fir.kt | 3 - .../inheritorOfExpectSealedClassWithFir.args | 8 + .../inheritorOfExpectSealedClassWithFir.out | 2 + .../{fir.args => kotlinPackageWithFir.args} | 6 +- .../cli/metadata/kotlinPackageWithFir.out | 5 + .../cli/metadata/moduleNameWithFir.args | 7 + .../cli/metadata/moduleNameWithFir.out | 2 + .../optionalExpectationUsageWithFir.args | 7 + .../optionalExpectationUsageWithFir.out | 2 + .../kotlin/cli/CliTestGenerated.java | 32 ++- 17 files changed, 361 insertions(+), 56 deletions(-) create mode 100644 compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt create mode 100644 compiler/testData/cli/metadata/anonymousObjectTypeWithFir.args rename compiler/testData/cli/metadata/{fir.out => anonymousObjectTypeWithFir.out} (56%) delete mode 100644 compiler/testData/cli/metadata/fir.kt create mode 100644 compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.args create mode 100644 compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.out rename compiler/testData/cli/metadata/{fir.args => kotlinPackageWithFir.args} (50%) create mode 100644 compiler/testData/cli/metadata/kotlinPackageWithFir.out create mode 100644 compiler/testData/cli/metadata/moduleNameWithFir.args create mode 100644 compiler/testData/cli/metadata/moduleNameWithFir.out create mode 100644 compiler/testData/cli/metadata/optionalExpectationUsageWithFir.args create mode 100644 compiler/testData/cli/metadata/optionalExpectationUsageWithFir.out diff --git a/compiler/cli/build.gradle.kts b/compiler/cli/build.gradle.kts index cacbb5fb9d6..3139a97f8cd 100644 --- a/compiler/cli/build.gradle.kts +++ b/compiler/cli/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { api(project(":compiler:fir:checkers:checkers.jvm")) api(project(":compiler:fir:checkers:checkers.js")) api(project(":compiler:fir:checkers:checkers.native")) + api(project(":compiler:fir:fir-serialization")) api(project(":kotlin-util-klib")) api(project(":kotlin-util-io")) 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 5b4501341ee..9f690144f06 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 @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.CodegenFactory @@ -47,7 +46,6 @@ import org.jetbrains.kotlin.fir.types.isString import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler import org.jetbrains.kotlin.ir.symbols.* -import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.Module import org.jetbrains.kotlin.modules.TargetId @@ -196,7 +194,13 @@ object FirKotlinToJvmBytecodeCompiler { var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() - val providerAndScopeForIncrementalCompilation = createComponentsForIncrementalCompilation(sourceScope) + val providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( + projectEnvironment, + incrementalComponents, + moduleConfiguration, + targetIds, + sourceScope + ) providerAndScopeForIncrementalCompilation?.precompiledBinariesFileScope?.let { librariesScope -= it @@ -302,25 +306,6 @@ object FirKotlinToJvmBytecodeCompiler { return resolveAndCheckFir(session, session.buildFirFromKtFiles(ktFiles), diagnosticsReporter) } - private fun CompilationContext.createComponentsForIncrementalCompilation( - sourceScope: AbstractProjectFileSearchScope - ): IncrementalCompilationContext? { - if (targetIds == null || incrementalComponents == null) return null - val directoryWithIncrementalPartsFromPreviousCompilation = - moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY] - ?: return null - val incrementalCompilationScope = directoryWithIncrementalPartsFromPreviousCompilation.walk() - .filter { it.extension == "class" } - .let { projectEnvironment.getSearchScopeByIoFiles(it.asIterable()) } - .takeIf { !it.isEmpty } - ?: return null - val packagePartProvider = IncrementalPackagePartProvider( - projectEnvironment.getPackagePartProvider(sourceScope), - targetIds.map(incrementalComponents::getIncrementalCache) - ) - return IncrementalCompilationContext(emptyList(), packagePartProvider, incrementalCompilationScope) - } - private fun CompilationContext.runBackend( ktFiles: List, fir2IrResult: Fir2IrResult, diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt index 7ac6c9dd41b..acad6dfd540 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/cliCompilerUtils.kt @@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileSystem +import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices import org.jetbrains.kotlin.backend.common.output.OutputFileCollection import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys @@ -30,15 +31,20 @@ import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.fir.BinaryModuleData import org.jetbrains.kotlin.fir.DependencyListForCliModule import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider +import org.jetbrains.kotlin.fir.session.FirCommonSessionFactory import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory +import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope import org.jetbrains.kotlin.javac.JavacWrapper +import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.modules.JavaRootPath import org.jetbrains.kotlin.modules.Module import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.psi.KtFile @@ -196,6 +202,29 @@ fun ModuleBuilder.configureFromArgs(args: K2JVMCompilerArguments) { } } +fun createContextForIncrementalCompilation( + projectEnvironment: AbstractProjectEnvironment, + incrementalComponents: IncrementalCompilationComponents?, + moduleConfiguration: CompilerConfiguration, + targetIds: List?, + sourceScope: AbstractProjectFileSearchScope, +): IncrementalCompilationContext? { + if (targetIds == null || incrementalComponents == null) return null + val directoryWithIncrementalPartsFromPreviousCompilation = + moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY] + ?: return null + val incrementalCompilationScope = directoryWithIncrementalPartsFromPreviousCompilation.walk() + .filter { it.extension == "class" } + .let { projectEnvironment.getSearchScopeByIoFiles(it.asIterable()) } + .takeIf { !it.isEmpty } + ?: return null + val packagePartProvider = IncrementalPackagePartProvider( + projectEnvironment.getPackagePartProvider(sourceScope), + targetIds.map(incrementalComponents::getIncrementalCache) + ) + return IncrementalCompilationContext(emptyList(), packagePartProvider, incrementalCompilationScope) +} + fun createFirLibraryListAndSession( moduleName: String, configuration: CompilerConfiguration, @@ -203,12 +232,13 @@ fun createFirLibraryListAndSession( scope: AbstractProjectFileSearchScope, librariesScope: AbstractProjectFileSearchScope, friendPaths: List, - sessionProvider: FirProjectSessionProvider + sessionProvider: FirProjectSessionProvider, + isJvm: Boolean = true ): DependencyListForCliModule { val binaryModuleData = BinaryModuleData.initialize( Name.identifier(moduleName), - JvmPlatforms.unspecifiedJvmPlatform, - JvmPlatformAnalyzerServices + if (isJvm) JvmPlatforms.unspecifiedJvmPlatform else CommonPlatforms.defaultCommonPlatform, + if (isJvm) JvmPlatformAnalyzerServices else CommonPlatformAnalyzerServices ) val libraryList = DependencyListForCliModule.build(binaryModuleData) { dependencies(configuration.jvmClasspathRoots.map { it.toPath() }) @@ -216,16 +246,30 @@ fun createFirLibraryListAndSession( friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList()) friendDependencies(friendPaths) } - FirJvmSessionFactory.createLibrarySession( - Name.identifier(moduleName), - sessionProvider, - libraryList.moduleDataProvider, - projectEnvironment, - scope, - projectEnvironment.getPackagePartProvider(librariesScope), - configuration.languageVersionSettings, - registerExtraComponents = {}, - ) + if (isJvm) { + FirJvmSessionFactory.createLibrarySession( + Name.identifier(moduleName), + sessionProvider, + libraryList.moduleDataProvider, + projectEnvironment, + scope, + projectEnvironment.getPackagePartProvider(librariesScope), + configuration.languageVersionSettings, + registerExtraComponents = {}, + ) + } else { + FirCommonSessionFactory.createLibrarySession( + Name.identifier(moduleName), + sessionProvider, + libraryList.moduleDataProvider, + projectEnvironment, + scope, + projectEnvironment.getPackagePartProvider(librariesScope), + configuration.languageVersionSettings, + registerExtraComponents = {}, + ) + } return libraryList } + diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt new file mode 100644 index 00000000000..dd5986e8c81 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/FirMetadataSerializer.kt @@ -0,0 +1,221 @@ +/* + * 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.cli.metadata + +import com.intellij.openapi.Disposable +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.openapi.vfs.VirtualFileManager +import org.jetbrains.kotlin.KtSourceFile +import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager +import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter +import org.jetbrains.kotlin.cli.jvm.compiler.* +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.collectSources +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.createContextForIncrementalCompilation +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory +import org.jetbrains.kotlin.fir.FirModuleDataImpl +import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers +import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar +import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider +import org.jetbrains.kotlin.fir.moduleData +import org.jetbrains.kotlin.fir.packageFqName +import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput +import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles +import org.jetbrains.kotlin.fir.pipeline.buildFirViaLightTree +import org.jetbrains.kotlin.fir.pipeline.resolveAndCheckFir +import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile +import org.jetbrains.kotlin.fir.session.FirCommonSessionFactory +import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope +import org.jetbrains.kotlin.library.KotlinAbiVersion +import org.jetbrains.kotlin.library.KotlinLibraryVersioning +import org.jetbrains.kotlin.library.SerializedMetadata +import org.jetbrains.kotlin.library.impl.BuiltInsPlatform +import org.jetbrains.kotlin.library.impl.buildKotlinLibrary +import org.jetbrains.kotlin.library.metadata.KlibMetadataHeaderFlags +import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf +import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion +import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.CommonPlatforms +import org.jetbrains.kotlin.psi.KtFile +import java.io.File + +internal class FirMetadataSerializer(private val metadataVersion: BuiltInsBinaryVersion) { + fun serialize(environment: KotlinCoreEnvironment, rootDisposable: Disposable) { + val performanceManager = environment.configuration.getNotNull(CLIConfigurationKeys.PERF_MANAGER) + + performanceManager.notifyAnalysisStarted() + val compilerResult = runFirCompiler(environment, performanceManager, rootDisposable) ?: return + performanceManager.notifyAnalysisFinished() + + performanceManager.notifyGenerationStarted() + performSerialization(compilerResult, environment.configuration, checkNotNull(environment.destDir)) + performanceManager.notifyGenerationFinished() + } + + private fun runFirCompiler( + environment: KotlinCoreEnvironment, + performanceManager: CommonCompilerPerformanceManager, + rootDisposable: Disposable + ): ModuleCompilerAnalyzedOutput? { + val configuration = environment.configuration + val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) + val moduleName = Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>") + val isLightTree = configuration.getBoolean(CommonConfigurationKeys.USE_LIGHT_TREE) + + val sessionProvider = FirProjectSessionProvider() + + val projectEnvironment: VfsBasedProjectEnvironment + var librariesScope: AbstractProjectFileSearchScope + val sourceScope: AbstractProjectFileSearchScope + val librariesHelperScope: AbstractProjectFileSearchScope + var psiFiles: List? = null + var ltFiles: List? = null + val providerAndScopeForIncrementalCompilation: IncrementalCompilationContext? + + if (isLightTree) { + projectEnvironment = environment.toAbstractProjectEnvironment() as VfsBasedProjectEnvironment + librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() + librariesHelperScope = projectEnvironment.getSearchScopeForProjectLibraries() + ltFiles = collectSources(configuration, projectEnvironment, messageCollector).let { it.first + it.second }.toList() + sourceScope = projectEnvironment.getSearchScopeBySourceFiles(ltFiles) + providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( + configuration, + projectEnvironment, + sourceScope, + previousStepsSymbolProviders = emptyList(), + incrementalExcludesScope = null + )?.also { (_, _, precompiledBinariesFileScope) -> + precompiledBinariesFileScope?.let { librariesScope -= it } + } + } else { + projectEnvironment = VfsBasedProjectEnvironment( + environment.project, + VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) + ) { environment.createPackagePartProvider(it) } + librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() + librariesHelperScope = librariesScope + psiFiles = environment.getSourceFiles() + sourceScope = projectEnvironment.getSearchScopeByPsiFiles(psiFiles) + projectEnvironment.getSearchScopeForProjectJavaSources() + providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation( + projectEnvironment, + configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS), + configuration, + configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId), + sourceScope + ) + providerAndScopeForIncrementalCompilation?.precompiledBinariesFileScope?.let { + librariesScope -= it + } + } + + val libraryList = createFirLibraryListAndSession( + moduleName.asString(), configuration, projectEnvironment, + scope = librariesHelperScope, librariesScope = librariesScope, friendPaths = emptyList(), sessionProvider = sessionProvider, + isJvm = false + ) + + val commonModuleData = FirModuleDataImpl( + moduleName, + libraryList.regularDependencies, + listOf(), + libraryList.friendsDependencies, + CommonPlatforms.defaultCommonPlatform, + CommonPlatformAnalyzerServices + ) + val project = projectEnvironment.project + val session = FirCommonSessionFactory.createModuleBasedSession( + commonModuleData, + sessionProvider, + sourceScope, + projectEnvironment, + incrementalCompilationContext = providerAndScopeForIncrementalCompilation, + FirExtensionRegistrar.getInstances(project), + configuration.languageVersionSettings, + lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER), + enumWhenTracker = configuration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER), + needRegisterJavaElementFinder = true, + registerExtraComponents = {}, + init = { + if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)) { + registerExtendedCommonCheckers() + } + } + ) + + val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter() + val firFiles = if (isLightTree) + session.buildFirViaLightTree(ltFiles!!, diagnosticsReporter, performanceManager::addSourcesStats) + else + session.buildFirFromKtFiles(psiFiles!!) + + val result = resolveAndCheckFir(session, firFiles, diagnosticsReporter) + + return if (diagnosticsReporter.hasErrors) { + val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) + FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames) + null + } else { + result + } + } + + private fun performSerialization(firOutput: ModuleCompilerAnalyzedOutput, configuration: CompilerConfiguration, destDir: File) { + val fragments = mutableMapOf>() + + for (firFile in firOutput.fir) { + val packageFragment = serializeSingleFirFile(firFile, firOutput.session, firOutput.scopeSession, metadataVersion) + fragments.getOrPut(firFile.packageFqName.asString()) { mutableListOf() }.add(packageFragment.toByteArray()) + } + + val header = KlibMetadataProtoBuf.Header.newBuilder() + header.moduleName = firOutput.session.moduleData.name.asString() + + if (configuration.languageVersionSettings.isPreRelease()) { + header.flags = KlibMetadataHeaderFlags.PRE_RELEASE + } + + val fragmentNames = mutableListOf() + val fragmentParts = mutableListOf>() + + for ((fqName, fragment) in fragments.entries.sortedBy { it.key }) { + fragmentNames += fqName + fragmentParts += fragment + header.addPackageFragmentName(fqName) + } + + val module = header.build().toByteArray() + + val serializedMetadata = SerializedMetadata(module, fragmentParts, fragmentNames) + + val versions = KotlinLibraryVersioning( + abiVersion = KotlinAbiVersion.CURRENT, + libraryVersion = null, + compilerVersion = KotlinCompilerVersion.getVersion(), + metadataVersion = KlibMetadataVersion.INSTANCE.toString(), + irVersion = null + ) + + buildKotlinLibrary( + emptyList(), + serializedMetadata, + null, + versions, + destDir.absolutePath, + configuration[CommonConfigurationKeys.MODULE_NAME]!!, + nopack = true, + perFile = false, + manifestProperties = null, + dataFlowGraph = null, + builtInsPlatform = BuiltInsPlatform.COMMON + ) + } +} + diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataCompiler.kt index d899a0c171b..8c34517d866 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataCompiler.kt @@ -58,10 +58,6 @@ class K2MetadataCompiler : CLICompiler() { paths: KotlinPaths? ): ExitCode { val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR)) { - collector.report(ERROR, "Compilation to metadata is not supported with language version 2.0 right now") - return ExitCode.COMPILATION_ERROR - } val performanceManager = configuration.getNotNull(CLIConfigurationKeys.PERF_MANAGER) val pluginLoadResult = loadPlugins(paths, arguments, configuration) @@ -118,10 +114,14 @@ class K2MetadataCompiler : CLICompiler() { try { val metadataVersion = configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? BuiltInsBinaryVersion ?: BuiltInsBinaryVersion.INSTANCE - if (arguments.expectActualLinker) { - K2MetadataKlibSerializer(metadataVersion).serialize(environment) + if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR)) { + FirMetadataSerializer(metadataVersion).serialize(environment, rootDisposable) } else { - MetadataSerializer(metadataVersion, true).serialize(environment) + if (arguments.expectActualLinker) { + K2MetadataKlibSerializer(metadataVersion).serialize(environment) + } else { + MetadataSerializer(metadataVersion, true).serialize(environment) + } } } catch (e: CompilationException) { collector.report(EXCEPTION, OutputMessageUtil.renderException(e), MessageUtil.psiElementToMessageLocation(e.element)) diff --git a/compiler/testData/cli/metadata/anonymousObjectTypeWithFir.args b/compiler/testData/cli/metadata/anonymousObjectTypeWithFir.args new file mode 100644 index 00000000000..b78831a17a8 --- /dev/null +++ b/compiler/testData/cli/metadata/anonymousObjectTypeWithFir.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/anonymousObjectType.kt +-d +$TEMP_DIR$ +-language-version +2.0 diff --git a/compiler/testData/cli/metadata/fir.out b/compiler/testData/cli/metadata/anonymousObjectTypeWithFir.out similarity index 56% rename from compiler/testData/cli/metadata/fir.out rename to compiler/testData/cli/metadata/anonymousObjectTypeWithFir.out index 4cb9b6a0e99..86ca0241885 100644 --- a/compiler/testData/cli/metadata/fir.out +++ b/compiler/testData/cli/metadata/anonymousObjectTypeWithFir.out @@ -1,3 +1,2 @@ warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features -error: compilation to metadata is not supported with language version 2.0 right now -COMPILATION_ERROR +OK diff --git a/compiler/testData/cli/metadata/fir.kt b/compiler/testData/cli/metadata/fir.kt deleted file mode 100644 index 369872f2b25..00000000000 --- a/compiler/testData/cli/metadata/fir.kt +++ /dev/null @@ -1,3 +0,0 @@ -package test - -expect class Some diff --git a/compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.args b/compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.args new file mode 100644 index 00000000000..27f1123c813 --- /dev/null +++ b/compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.args @@ -0,0 +1,8 @@ +$TESTDATA_DIR$/inheritorOfExpectSealedClass/common-1.kt +$TESTDATA_DIR$/inheritorOfExpectSealedClass/common-2.kt +$TESTDATA_DIR$/inheritorOfExpectSealedClass/common-3.kt +-d +$TEMP_DIR$ +-Xcommon-sources=$TESTDATA_DIR$/inheritorOfExpectSealedClass/common-1.kt,$TESTDATA_DIR$/inheritorOfExpectSealedClass/common-2.kt +-language-version +2.0 \ No newline at end of file diff --git a/compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.out b/compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.out new file mode 100644 index 00000000000..86ca0241885 --- /dev/null +++ b/compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.out @@ -0,0 +1,2 @@ +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/testData/cli/metadata/fir.args b/compiler/testData/cli/metadata/kotlinPackageWithFir.args similarity index 50% rename from compiler/testData/cli/metadata/fir.args rename to compiler/testData/cli/metadata/kotlinPackageWithFir.args index 4be050d48ab..4c498378196 100644 --- a/compiler/testData/cli/metadata/fir.args +++ b/compiler/testData/cli/metadata/kotlinPackageWithFir.args @@ -1,5 +1,5 @@ -$TESTDATA_DIR$/fir.kt --language-version -2.0 +$TESTDATA_DIR$/../kotlinPackage.kt -d $TEMP_DIR$ +-language-version +2.0 diff --git a/compiler/testData/cli/metadata/kotlinPackageWithFir.out b/compiler/testData/cli/metadata/kotlinPackageWithFir.out new file mode 100644 index 00000000000..889c70030e5 --- /dev/null +++ b/compiler/testData/cli/metadata/kotlinPackageWithFir.out @@ -0,0 +1,5 @@ +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +compiler/testData/cli/kotlinPackage.kt:1:1: error: only the Kotlin standard library is allowed to use the 'kotlin' package +package kotlin.mylibrary +^ +COMPILATION_ERROR diff --git a/compiler/testData/cli/metadata/moduleNameWithFir.args b/compiler/testData/cli/metadata/moduleNameWithFir.args new file mode 100644 index 00000000000..601c5d995a3 --- /dev/null +++ b/compiler/testData/cli/metadata/moduleNameWithFir.args @@ -0,0 +1,7 @@ +$TESTDATA_DIR$/moduleName.kt +-d +$TEMP_DIR$ +-module-name +foo +-language-version +2.0 diff --git a/compiler/testData/cli/metadata/moduleNameWithFir.out b/compiler/testData/cli/metadata/moduleNameWithFir.out new file mode 100644 index 00000000000..86ca0241885 --- /dev/null +++ b/compiler/testData/cli/metadata/moduleNameWithFir.out @@ -0,0 +1,2 @@ +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/testData/cli/metadata/optionalExpectationUsageWithFir.args b/compiler/testData/cli/metadata/optionalExpectationUsageWithFir.args new file mode 100644 index 00000000000..29081c401ae --- /dev/null +++ b/compiler/testData/cli/metadata/optionalExpectationUsageWithFir.args @@ -0,0 +1,7 @@ +$TESTDATA_DIR$/optionalExpectationUsage.kt +-d +$TEMP_DIR$ +-cp +$TESTDATA_DIR$/../../../../dist/common/kotlin-stdlib-common.jar +-language-version +2.0 diff --git a/compiler/testData/cli/metadata/optionalExpectationUsageWithFir.out b/compiler/testData/cli/metadata/optionalExpectationUsageWithFir.out new file mode 100644 index 00000000000..86ca0241885 --- /dev/null +++ b/compiler/testData/cli/metadata/optionalExpectationUsageWithFir.out @@ -0,0 +1,2 @@ +warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java index 2632ff6fa42..34c3d575e46 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -477,9 +477,9 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/firMultiplatformCompilationWithError.args"); } - @TestMetadata("firMultiplatformCompilationWithLightTreeWithoutErrors.args") - public void testFirMultiplatformCompilationWithLightTreeWithoutErrors() throws Exception { - runTest("compiler/testData/cli/jvm/firMultiplatformCompilationWithLightTreeWithoutErrors.args"); + @TestMetadata("firMultiplatformCompilationWithPsiWithoutErrors.args") + public void testFirMultiplatformCompilationWithPsiWithoutErrors() throws Exception { + runTest("compiler/testData/cli/jvm/firMultiplatformCompilationWithPsiWithoutErrors.args"); } @TestMetadata("firMultiplatformCompilationWithoutErrors.args") @@ -1481,9 +1481,9 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/metadata/anonymousObjectType.args"); } - @TestMetadata("fir.args") - public void testFir() throws Exception { - runTest("compiler/testData/cli/metadata/fir.args"); + @TestMetadata("anonymousObjectTypeWithFir.args") + public void testAnonymousObjectTypeWithFir() throws Exception { + runTest("compiler/testData/cli/metadata/anonymousObjectTypeWithFir.args"); } @TestMetadata("inheritorOfExpectSealedClass.args") @@ -1491,19 +1491,39 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/metadata/inheritorOfExpectSealedClass.args"); } + @TestMetadata("inheritorOfExpectSealedClassWithFir.args") + public void testInheritorOfExpectSealedClassWithFir() throws Exception { + runTest("compiler/testData/cli/metadata/inheritorOfExpectSealedClassWithFir.args"); + } + @TestMetadata("kotlinPackage.args") public void testKotlinPackage() throws Exception { runTest("compiler/testData/cli/metadata/kotlinPackage.args"); } + @TestMetadata("kotlinPackageWithFir.args") + public void testKotlinPackageWithFir() throws Exception { + runTest("compiler/testData/cli/metadata/kotlinPackageWithFir.args"); + } + @TestMetadata("moduleName.args") public void testModuleName() throws Exception { runTest("compiler/testData/cli/metadata/moduleName.args"); } + @TestMetadata("moduleNameWithFir.args") + public void testModuleNameWithFir() throws Exception { + runTest("compiler/testData/cli/metadata/moduleNameWithFir.args"); + } + @TestMetadata("optionalExpectationUsage.args") public void testOptionalExpectationUsage() throws Exception { runTest("compiler/testData/cli/metadata/optionalExpectationUsage.args"); } + + @TestMetadata("optionalExpectationUsageWithFir.args") + public void testOptionalExpectationUsageWithFir() throws Exception { + runTest("compiler/testData/cli/metadata/optionalExpectationUsageWithFir.args"); + } } }