diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index aeb26304a77..19e6e59b947 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.cli.jvm -import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.Disposable import org.jetbrains.kotlin.backend.jvm.jvmPhases import org.jetbrains.kotlin.cli.common.* @@ -46,7 +45,6 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompil import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil -import org.jetbrains.kotlin.modules.JavaRootPath import org.jetbrains.kotlin.utils.KotlinPaths import java.io.File @@ -119,40 +117,9 @@ class K2JVMCompiler : CLICompiler() { messageCollector.report(LOGGING, "Configuring the compilation environment") try { - val destination = arguments.destination?.let { File(it) } val buildFile = arguments.buildFile?.let { File(it) } - val moduleChunk = if (buildFile != null) { - fun strongWarning(message: String) { - messageCollector.report(STRONG_WARNING, message) - } - if (destination != null) { - strongWarning("The '-d' option with a directory destination is ignored because '-Xbuild-file' is specified") - } - if (arguments.javaSourceRoots != null) { - strongWarning("The '-Xjava-source-roots' option is ignored because '-Xbuild-file' is specified") - } - if (arguments.javaPackagePrefix != null) { - strongWarning("The '-Xjava-package-prefix' option is ignored because '-Xbuild-file' is specified") - } - configuration.configureContentRootsFromClassPath(arguments) - val sanitizedCollector = FilteringMessageCollector(messageCollector, VERBOSE::contains) - configuration.put(JVMConfigurationKeys.MODULE_XML_FILE, buildFile) - CompileEnvironmentUtil.loadModuleChunk(buildFile, sanitizedCollector) - } else { - if (destination != null) { - if (destination.path.endsWith(".jar")) { - configuration.put(JVMConfigurationKeys.OUTPUT_JAR, destination) - } else { - configuration.put(JVMConfigurationKeys.OUTPUT_DIRECTORY, destination) - } - } - - val module = ModuleBuilder(moduleName, destination?.path ?: ".", "java-production") - module.configureFromArgs(arguments) - - ModuleChunk(listOf(module)) - } + val moduleChunk = configuration.configureModuleChunk(arguments, buildFile) val chunk = moduleChunk.modules configuration.configureSourceRoots(chunk, buildFile) @@ -195,30 +162,6 @@ class K2JVMCompiler : CLICompiler() { } } - private fun ModuleBuilder.configureFromArgs(args: K2JVMCompilerArguments) { - args.friendPaths?.forEach { addFriendDir(it) } - args.classpath?.split(File.pathSeparator)?.forEach { addClasspathEntry(it) } - args.javaSourceRoots?.forEach { - addJavaSourceRoot(JavaRootPath(it, args.javaPackagePrefix)) - } - - val commonSources = args.commonSources?.toSet().orEmpty() - for (arg in args.freeArgs) { - if (arg.endsWith(JavaFileType.DOT_DEFAULT_EXTENSION)) { - addJavaSourceRoot(JavaRootPath(arg, args.javaPackagePrefix)) - } else { - addSourceFiles(arg) - if (arg in commonSources) { - addCommonSourceFiles(arg) - } - - if (File(arg).isDirectory) { - addJavaSourceRoot(JavaRootPath(arg, args.javaPackagePrefix)) - } - } - } - } - override fun MutableList.addPlatformOptions(arguments: K2JVMCompilerArguments) { if (arguments.scriptTemplates?.isNotEmpty() == true) { add("plugin:kotlin.scripting:script-templates=${arguments.scriptTemplates!!.joinToString(",")}") @@ -302,5 +245,50 @@ class K2JVMCompiler : CLICompiler() { } } +fun CompilerConfiguration.configureModuleChunk( + arguments: K2JVMCompilerArguments, + buildFile: File? +): ModuleChunk { + val destination = arguments.destination?.let { File(it) } + + return if (buildFile != null) { + val messageCollector = getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) + + fun strongWarning(message: String) { + messageCollector.report(STRONG_WARNING, message) + } + + if (destination != null) { + strongWarning("The '-d' option with a directory destination is ignored because '-Xbuild-file' is specified") + } + if (arguments.javaSourceRoots != null) { + strongWarning("The '-Xjava-source-roots' option is ignored because '-Xbuild-file' is specified") + } + if (arguments.javaPackagePrefix != null) { + strongWarning("The '-Xjava-package-prefix' option is ignored because '-Xbuild-file' is specified") + } + configureContentRootsFromClassPath(arguments) + val sanitizedCollector = FilteringMessageCollector(messageCollector, VERBOSE::contains) + put(JVMConfigurationKeys.MODULE_XML_FILE, buildFile) + CompileEnvironmentUtil.loadModuleChunk(buildFile, sanitizedCollector) + } else { + if (destination != null) { + if (destination.path.endsWith(".jar")) { + put(JVMConfigurationKeys.OUTPUT_JAR, destination) + } else { + put(JVMConfigurationKeys.OUTPUT_DIRECTORY, destination) + } + } + + val module = ModuleBuilder( + this[CommonConfigurationKeys.MODULE_NAME] ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME, + destination?.path ?: ".", "java-production" + ) + module.configureFromArgs(arguments) + + ModuleChunk(listOf(module)) + } +} + fun main(args: Array) = K2JVMCompiler.main(args) 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 418f1b51afc..52771376811 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 @@ -186,7 +186,7 @@ object FirKotlinToJvmBytecodeCompiler { val providerAndScopeForIncrementalCompilation = createComponentsForIncrementalCompilation(sourceScope) - providerAndScopeForIncrementalCompilation?.scope?.let { + providerAndScopeForIncrementalCompilation?.precompiledBinariesFileScope?.let { librariesScope -= it } @@ -274,7 +274,7 @@ object FirKotlinToJvmBytecodeCompiler { private fun CompilationContext.createComponentsForIncrementalCompilation( sourceScope: AbstractProjectFileSearchScope - ): FirSessionFactory.ProviderAndScopeForIncrementalCompilation? { + ): FirSessionFactory.IncrementalCompilationContext? { if (targetIds == null || incrementalComponents == null) return null val directoryWithIncrementalPartsFromPreviousCompilation = moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY] @@ -288,7 +288,7 @@ object FirKotlinToJvmBytecodeCompiler { projectEnvironment.getPackagePartProvider(sourceScope), targetIds.map(incrementalComponents::getIncrementalCache) ) - return FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope) + return FirSessionFactory.IncrementalCompilationContext(emptyList(), packagePartProvider, incrementalCompilationScope) } private fun CompilationContext.runBackend( @@ -368,7 +368,7 @@ object FirKotlinToJvmBytecodeCompiler { ) } -internal fun findMainClass(fir: List): FqName? { +fun findMainClass(fir: List): FqName? { // TODO: replace with proper main function detector, KT-44557 val compatibleClasses = mutableListOf() val visitor = object : FirVisitorVoid() { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 713bf82a1b7..6cf153de2a1 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -382,7 +382,7 @@ object KotlinToJVMBytecodeCompiler { } } -internal fun CompilerConfiguration.configureSourceRoots(chunk: List, buildFile: File? = null) { +fun CompilerConfiguration.configureSourceRoots(chunk: List, buildFile: File? = null) { for (module in chunk) { val commonSources = getBuildFilePaths(buildFile, module.getCommonSourceFiles()).toSet() diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt index 56f0717aabb..f034767bb34 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt @@ -77,6 +77,17 @@ open class VfsBasedProjectEnvironment( } ?: GlobalSearchScope.EMPTY_SCOPE ) + override fun getSearchScopeByDirectories(directories: Iterable): AbstractProjectFileSearchScope = + PsiBasedProjectFileSearchScope( + directories + .mapNotNull { localFileSystem.findFileByPath(it.absolutePath) } + .toSet() + .takeIf { it.isNotEmpty() } + ?.let { + KotlinToJVMBytecodeCompiler.DirectoriesScope(project, it) + } ?: GlobalSearchScope.EMPTY_SCOPE + ) + fun getSearchScopeByPsiFiles(files: Iterable, allowOutOfProjectRoots: Boolean= false): AbstractProjectFileSearchScope = PsiBasedProjectFileSearchScope( files.map { it.virtualFile }.let { 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 1940abd7d91..7e68326792f 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 @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler +import com.intellij.ide.highlighter.JavaFileType import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile @@ -12,9 +13,11 @@ import com.intellij.openapi.vfs.VirtualFileSystem import org.jetbrains.kotlin.backend.common.output.OutputFileCollection import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil +import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder import org.jetbrains.kotlin.cli.common.output.writeAll import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationStateEventCallback @@ -22,6 +25,7 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.javac.JavacWrapper +import org.jetbrains.kotlin.modules.JavaRootPath import org.jetbrains.kotlin.modules.Module import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.name.FqName @@ -148,3 +152,28 @@ fun writeOutputs( return true } + +fun ModuleBuilder.configureFromArgs(args: K2JVMCompilerArguments) { + args.friendPaths?.forEach { addFriendDir(it) } + args.classpath?.split(File.pathSeparator)?.forEach { addClasspathEntry(it) } + args.javaSourceRoots?.forEach { + addJavaSourceRoot(JavaRootPath(it, args.javaPackagePrefix)) + } + + val commonSources = args.commonSources?.toSet().orEmpty() + for (arg in args.freeArgs) { + if (arg.endsWith(JavaFileType.DOT_DEFAULT_EXTENSION)) { + addJavaSourceRoot(JavaRootPath(arg, args.javaPackagePrefix)) + } else { + addSourceFiles(arg) + if (arg in commonSources) { + addCommonSourceFiles(arg) + } + + if (File(arg).isDirectory) { + addJavaSourceRoot(JavaRootPath(arg, args.javaPackagePrefix)) + } + } + } +} + diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt index fe90289f421..e68fcd458f9 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt @@ -45,15 +45,18 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension 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.pipeline.buildFirViaLightTree import org.jetbrains.kotlin.fir.pipeline.convertToIr import org.jetbrains.kotlin.fir.pipeline.runCheckers import org.jetbrains.kotlin.fir.pipeline.runResolution +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.session.FirSessionFactory 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.MetadataFinderFactory import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory @@ -88,7 +91,7 @@ fun compileModulesUsingFrontendIrAndLightTree( "ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir" ) - val outputs = mutableMapOf() + val outputs = mutableListOf() var mainClassFqName: FqName? = null for (module in chunk) { @@ -108,41 +111,120 @@ fun compileModulesUsingFrontendIrAndLightTree( val diagnosticsReporter = DiagnosticReporterFactory.createReporter() - val (moduleMainClassName, generationState) = compileModule( - ModuleCompilerInput( - TargetId(module), - CommonPlatforms.defaultCommonPlatform, commonSources, - JvmPlatforms.unspecifiedJvmPlatform, platformSources, - moduleConfiguration - ), - ModuleCompilerEnvironment(projectEnvironment, diagnosticsReporter) + val compilerInput = ModuleCompilerInput( + TargetId(module), + CommonPlatforms.defaultCommonPlatform, commonSources, + JvmPlatforms.unspecifiedJvmPlatform, platformSources, + moduleConfiguration ) + val compilerEnvironment = ModuleCompilerEnvironment(projectEnvironment, diagnosticsReporter) + val analysisResults = compileModuleToAnalyzedFir( + compilerInput, + compilerEnvironment, + emptyList(), + null, + ) + // TODO: consider what to do if many modules has main classes + if (mainClassFqName == null && moduleConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { + mainClassFqName = findMainClass(analysisResults.fir) + } + + val irInput = convertAnalyzedFirToIr(compilerInput, analysisResults, compilerEnvironment) + val codegenOutput = generateCodeFromIr(irInput, compilerEnvironment) + FirDiagnosticsCompilerResultsReporter.reportToMessageCollector( diagnosticsReporter, messageCollector, moduleConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) ) - outputs[module] = generationState - - // TODO: consider what to do if many modules contain main class - if (mainClassFqName == null) { - mainClassFqName = moduleMainClassName - } + outputs.add(codegenOutput.generationState) } return writeOutputs( - (projectEnvironment as? VfsBasedProjectEnvironment)?.project, + projectEnvironment, compilerConfiguration, - chunk, outputs, mainClassFqName ) } -fun compileModule( +fun convertAnalyzedFirToIr( input: ModuleCompilerInput, + analysisResults: ModuleCompilerAnalyzedOutput, + environment: ModuleCompilerEnvironment +): ModuleCompilerIrBackendInput { + val extensions = JvmGeneratorExtensionsImpl(input.configuration) + + // fir2ir + val irGenerationExtensions = + (environment.projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) } + val (irModuleFragment, symbolTable, components) = + analysisResults.session.convertToIr( + analysisResults.scopeSession, analysisResults.fir, extensions, irGenerationExtensions ?: emptyList() + ) + + return ModuleCompilerIrBackendInput( + input.targetId, + input.configuration, + extensions, + irModuleFragment, + symbolTable, + components, + analysisResults.session + ) +} + +fun generateCodeFromIr( + input: ModuleCompilerIrBackendInput, environment: ModuleCompilerEnvironment ): ModuleCompilerOutput { + // IR + val codegenFactory = JvmIrCodegenFactory( + input.configuration, + input.configuration.get(CLIConfigurationKeys.PHASE_CONFIG), + jvmGeneratorExtensions = input.extensions + ) + val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext + + val generationState = GenerationState.Builder( + (environment.projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES, + input.irModuleFragment.descriptor, dummyBindingContext, emptyList()/* !! */, + input.configuration + ).codegenFactory( + codegenFactory + ).targetId( + input.targetId + ).moduleName( + input.targetId.name + ).outDirectory( + input.configuration[JVMConfigurationKeys.OUTPUT_DIRECTORY] + ).onIndependentPartCompilationEnd( + createOutputFilesFlushingCallbackIfPossible(input.configuration) + ).isIrBackend( + true + ).jvmBackendClassResolver( + FirJvmBackendClassResolver(input.components) + ).diagnosticReporter( + environment.diagnosticsReporter + ).build() + + generationState.beforeCompile() + codegenFactory.generateModuleInFrontendIRMode( + generationState, input.irModuleFragment, input.symbolTable, input.extensions, + FirJvmBackendExtension(input.firSession, input.components) + ) + CodegenFactory.doCheckCancelled(generationState) + generationState.factory.done() + + return ModuleCompilerOutput(generationState) +} + +fun compileModuleToAnalyzedFir( + input: ModuleCompilerInput, + environment: ModuleCompilerEnvironment, + previousStepsSymbolProviders: List, + incrementalExcludesScope: AbstractProjectFileSearchScope?, +): ModuleCompilerAnalyzedOutput { var sourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.platformSources) //!! val sessionProvider = FirProjectSessionProvider() val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS) @@ -160,6 +242,8 @@ fun compileModule( commonSourcesScope, CommonPlatformAnalyzerServices, sessionProvider, + previousStepsSymbolProviders, + incrementalExcludesScope, extendedAnalysisMode, needRegisterJavaElementFinder = false ) @@ -173,6 +257,8 @@ fun compileModule( sourcesScope, JvmPlatformAnalyzerServices, sessionProvider, + previousStepsSymbolProviders, + incrementalExcludesScope, extendedAnalysisMode, needRegisterJavaElementFinder = true ) { @@ -180,6 +266,7 @@ fun compileModule( sourceDependsOnDependencies(listOf(commonSession.moduleData)) } friendDependencies(input.configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList()) + sourceFriendsDependencies(input.friendFirModules) } // raw fir @@ -197,56 +284,43 @@ fun compileModule( // checkers session.runCheckers(scopeSession, fir, environment.diagnosticsReporter) - val mainClassFqName: FqName? = runIf(input.configuration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { - findMainClass(fir) + return ModuleCompilerAnalyzedOutput(session, scopeSession, fir) +} + +fun writeOutputs( + projectEnvironment: AbstractProjectEnvironment, + configuration: CompilerConfiguration, + outputs: Collection, + mainClassFqName: FqName? +): Boolean { + try { + for (state in outputs) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + writeOutput(state.configuration, state.factory, mainClassFqName) + } + } finally { + outputs.forEach(GenerationState::destroy) } - val extensions = JvmGeneratorExtensionsImpl(input.configuration) + if (configuration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)) { + val singleState = outputs.singleOrNull() + if (singleState != null) { + return JavacWrapper.getInstance((projectEnvironment as VfsBasedProjectEnvironment).project).use { + it.compile(singleState.outDirectory) + } + } else { + configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report( + CompilerMessageSeverity.WARNING, + "A chunk contains multiple modules (${outputs.joinToString { it.moduleName }}). " + + "-Xuse-javac option couldn't be used to compile java files" + ) + } + } - // fir2ir - val irGenerationExtensions = (environment.projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) } - val (irModuleFragment, symbolTable, components) = session.convertToIr(scopeSession, fir, extensions, irGenerationExtensions ?: emptyList()) - - // IR - val codegenFactory = JvmIrCodegenFactory( - input.configuration, - input.configuration.get(CLIConfigurationKeys.PHASE_CONFIG), - jvmGeneratorExtensions = extensions - ) - val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext - - val generationState = GenerationState.Builder( - (environment.projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES, - irModuleFragment.descriptor, dummyBindingContext, emptyList()/* !! */, - input.configuration - ).codegenFactory( - codegenFactory - ).targetId( - input.targetId - ).moduleName( - input.targetId.name - ).outDirectory( - input.configuration[JVMConfigurationKeys.OUTPUT_DIRECTORY] - ).onIndependentPartCompilationEnd( - createOutputFilesFlushingCallbackIfPossible(input.configuration) - ).isIrBackend( - true - ).jvmBackendClassResolver( - FirJvmBackendClassResolver(components) - ).diagnosticReporter( - environment.diagnosticsReporter - ).build() - - generationState.beforeCompile() - codegenFactory.generateModuleInFrontendIRMode( - generationState, irModuleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components) - ) - CodegenFactory.doCheckCancelled(generationState) - generationState.factory.done() - - return ModuleCompilerOutput(mainClassFqName, generationState) + return true } + fun createSession( name: String, platform: TargetPlatform, @@ -255,6 +329,8 @@ fun createSession( sourceScope: AbstractProjectFileSearchScope, analyzerServices: PlatformDependentAnalyzerServices, sessionProvider: FirProjectSessionProvider?, + previousStepsSymbolProviders: List, + incrementalExcludesScope: AbstractProjectFileSearchScope?, extendedAnalysisMode: Boolean, needRegisterJavaElementFinder: Boolean, dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}, @@ -262,9 +338,16 @@ fun createSession( var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() val providerAndScopeForIncrementalCompilation = - createComponentsForIncrementalCompilation(moduleConfiguration, projectEnvironment, sourceScope)?.also { - librariesScope -= it.scope - } + createContextForIncrementalCompilation( + moduleConfiguration, + projectEnvironment, + sourceScope, + previousStepsSymbolProviders, + incrementalExcludesScope + ) + ?.also { (_, _, precompiledBinariesFileScope) -> + precompiledBinariesFileScope?.let { librariesScope -= it } + } return FirSessionFactory.createSessionWithDependencies( Name.identifier(name), @@ -293,27 +376,31 @@ fun createSession( } } -private fun createComponentsForIncrementalCompilation( +private fun createContextForIncrementalCompilation( compilerConfiguration: CompilerConfiguration, projectEnvironment: AbstractProjectEnvironment, - sourceScope: AbstractProjectFileSearchScope -): FirSessionFactory.ProviderAndScopeForIncrementalCompilation? { + sourceScope: AbstractProjectFileSearchScope, + previousStepsSymbolProviders: List, + incrementalExcludesScope: AbstractProjectFileSearchScope?, +): FirSessionFactory.IncrementalCompilationContext? { val targetIds = compilerConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId) val incrementalComponents = compilerConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) if (targetIds == null || incrementalComponents == null) return null - val directoryWithIncrementalPartsFromPreviousCompilation = - compilerConfiguration[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) + val incrementalCompilationScope = + compilerConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY]?.let { dir -> + projectEnvironment.getSearchScopeByDirectories(setOf(dir)).let { + if (incrementalExcludesScope?.isEmpty != false) it + else it - incrementalExcludesScope + } + } + + return if (incrementalCompilationScope == null && previousStepsSymbolProviders.isEmpty()) null + else FirSessionFactory.IncrementalCompilationContext( + previousStepsSymbolProviders, IncrementalPackagePartProvider( + projectEnvironment.getPackagePartProvider(sourceScope), + targetIds.map(incrementalComponents::getIncrementalCache) + ), incrementalCompilationScope ) - return FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope) } private class ProjectEnvironmentWithCoreEnvironmentEmulation( @@ -417,13 +504,17 @@ fun createProjectEnvironment( } } -private fun contentRootToVirtualFile(root: JvmContentRoot, locaFileSystem: VirtualFileSystem, jarFileSystem: VirtualFileSystem, messageCollector: MessageCollector): VirtualFile? = +private fun contentRootToVirtualFile( + root: JvmContentRootBase, locaFileSystem: VirtualFileSystem, jarFileSystem: VirtualFileSystem, messageCollector: MessageCollector +): VirtualFile? = when (root) { // TODO: find out why non-existent location is not reported for JARs, add comment or fix is JvmClasspathRoot -> - if (root.file.isFile) jarFileSystem.findJarRoot(root.file) else locaFileSystem.findExistingRoot(root, "Classpath entry", messageCollector) + if (root.file.isFile) jarFileSystem.findJarRoot(root.file) + else locaFileSystem.findExistingRoot(root, "Classpath entry", messageCollector) is JvmModulePathRoot -> - if (root.file.isFile) jarFileSystem.findJarRoot(root.file) else locaFileSystem.findExistingRoot(root, "Java module root", messageCollector) + if (root.file.isFile) jarFileSystem.findJarRoot(root.file) + else locaFileSystem.findExistingRoot(root, "Java module root", messageCollector) is JavaSourceRoot -> locaFileSystem.findExistingRoot(root, "Java source root", messageCollector) else -> @@ -433,7 +524,9 @@ private fun contentRootToVirtualFile(root: JvmContentRoot, locaFileSystem: Virtu private fun VirtualFileSystem.findJarRoot(file: File): VirtualFile? = findFileByPath("$file${URLUtil.JAR_SEPARATOR}") -private fun VirtualFileSystem.findExistingRoot(root: JvmContentRoot, rootDescription: String, messageCollector: MessageCollector): VirtualFile? { +private fun VirtualFileSystem.findExistingRoot( + root: JvmContentRoot, rootDescription: String, messageCollector: MessageCollector +): VirtualFile? { return findFileByPath(root.file.absolutePath).also { if (it == null) { messageCollector.report( diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt index 4507f980e06..493556159ad 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt @@ -5,10 +5,18 @@ package org.jetbrains.kotlin.cli.jvm.compiler.pipeline +import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.backend.Fir2IrComponents +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.platform.TargetPlatform @@ -22,7 +30,8 @@ data class ModuleCompilerInput( val commonSources: Collection, val platform: TargetPlatform, val platformSources: Collection, - val configuration: CompilerConfiguration + val configuration: CompilerConfiguration, + val friendFirModules: Collection = emptyList() ) data class ModuleCompilerEnvironment( @@ -31,9 +40,23 @@ data class ModuleCompilerEnvironment( ) data class ModuleCompilerOutput( - val mainClassName: FqName?, val generationState: GenerationState ) // --- +data class ModuleCompilerAnalyzedOutput( + val session: FirSession, + val scopeSession: ScopeSession, + val fir: List +) + +data class ModuleCompilerIrBackendInput( + val targetId: TargetId, + val configuration: CompilerConfiguration, + val extensions: JvmGeneratorExtensionsImpl, + val irModuleFragment: IrModuleFragment, + val symbolTable: SymbolTable, + val components: Fir2IrComponents, + val firSession: FirSession +) \ No newline at end of file diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt index 86d3aeaf973..b35060f5864 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirSessionFactory.kt @@ -68,9 +68,13 @@ object FirSessionFactory { } } - data class ProviderAndScopeForIncrementalCompilation( - val packagePartProvider: PackagePartProvider, - val scope: AbstractProjectFileSearchScope + data class IncrementalCompilationContext( + // assuming that providers here do not intersect with the one being built from precompiled binaries + // (maybe easiest way to achieve is to delete libraries + // TODO: consider passing something more abstract instead of precompiler component, in order to avoid file ops here + val previousFirSessionsSymbolProviders: Collection, + val precomiledBinariesPackagePartProvider: PackagePartProvider?, + val precompiledBinariesFileScope: AbstractProjectFileSearchScope? ) inline fun createSessionWithDependencies( @@ -83,7 +87,7 @@ object FirSessionFactory { sourceScope: AbstractProjectFileSearchScope, librariesScope: AbstractProjectFileSearchScope, lookupTracker: LookupTracker?, - providerAndScopeForIncrementalCompilation: ProviderAndScopeForIncrementalCompilation?, + incrementalCompilationContext: IncrementalCompilationContext?, extensionRegistrars: List, needRegisterJavaElementFinder: Boolean, dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}, @@ -114,7 +118,7 @@ object FirSessionFactory { sessionProvider, sourceScope, projectEnvironment, - providerAndScopeForIncrementalCompilation, + incrementalCompilationContext, extensionRegistrars, languageVersionSettings = languageVersionSettings, lookupTracker = lookupTracker, @@ -128,7 +132,7 @@ object FirSessionFactory { sessionProvider: FirProjectSessionProvider, scope: AbstractProjectFileSearchScope, projectEnvironment: AbstractProjectEnvironment, - providerAndScopeForIncrementalCompilation: ProviderAndScopeForIncrementalCompilation?, + incrementalCompilationContext: IncrementalCompilationContext?, extensionRegistrars: List, languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, lookupTracker: LookupTracker? = null, @@ -151,17 +155,19 @@ object FirSessionFactory { val firProvider = FirProviderImpl(this, kotlinScopeProvider) register(FirProvider::class, firProvider) - val symbolProviderForBinariesFromIncrementalCompilation = providerAndScopeForIncrementalCompilation?.let { - JvmClassFileBasedSymbolProvider( - this@session, - SingleModuleDataProvider(moduleData), - kotlinScopeProvider, - it.packagePartProvider, - projectEnvironment.getKotlinClassFinder(it.scope), - projectEnvironment.getFirJavaFacade(this, moduleData, it.scope), - defaultDeserializationOrigin = FirDeclarationOrigin.Precompiled - ) - } + val symbolProviderForBinariesFromIncrementalCompilation = + incrementalCompilationContext?.let { (_, precomiledBinariesPackagePartProvider, precompiledBinariesFileScope) -> + if (precomiledBinariesPackagePartProvider == null || precompiledBinariesFileScope == null) null + else JvmClassFileBasedSymbolProvider( + this@session, + SingleModuleDataProvider(moduleData), + kotlinScopeProvider, + precomiledBinariesPackagePartProvider, + projectEnvironment.getKotlinClassFinder(precompiledBinariesFileScope), + projectEnvironment.getFirJavaFacade(this, moduleData, precompiledBinariesFileScope), + defaultDeserializationOrigin = FirDeclarationOrigin.Precompiled + ) + } FirSessionConfigurator(this).apply { registerCommonCheckers() @@ -180,6 +186,7 @@ object FirSessionFactory { this, listOfNotNull( firProvider.symbolProvider, + *(incrementalCompilationContext?.previousFirSessionsSymbolProviders?.toTypedArray() ?: emptyArray()), symbolProviderForBinariesFromIncrementalCompilation, generatedSymbolsProvider, JavaSymbolProvider(this, projectEnvironment.getFirJavaFacade(this, moduleData, scope)), diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/environment/AbstractProjectEnvironment.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/environment/AbstractProjectEnvironment.kt index 3b071f61b07..cfdea448187 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/environment/AbstractProjectEnvironment.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/environment/AbstractProjectEnvironment.kt @@ -49,6 +49,8 @@ interface AbstractProjectEnvironment { fun getSearchScopeByIoFiles(files: Iterable, allowOutOfProjectRoots: Boolean = false): AbstractProjectFileSearchScope + fun getSearchScopeByDirectories(directories: Iterable): AbstractProjectFileSearchScope + fun getSearchScopeForProjectLibraries(): AbstractProjectFileSearchScope fun getSearchScopeForProjectJavaSources(): AbstractProjectFileSearchScope diff --git a/compiler/incremental-compilation-impl/build.gradle.kts b/compiler/incremental-compilation-impl/build.gradle.kts index e82c47cc155..df6eba52bf2 100644 --- a/compiler/incremental-compilation-impl/build.gradle.kts +++ b/compiler/incremental-compilation-impl/build.gradle.kts @@ -13,6 +13,9 @@ dependencies { api(project(":compiler:frontend.java")) api(project(":compiler:cli")) api(project(":compiler:cli-js")) + api(project(":compiler:fir:entrypoint")) + api(project(":compiler:ir.serialization.jvm")) + api(project(":compiler:backend.jvm.entrypoint")) api(project(":kotlin-build-common")) api(project(":daemon-common")) implementation(commonDependency("com.google.code.gson:gson")) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt index 050851d5ff5..e94019990fb 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/DirtyFilesContainer.kt @@ -16,8 +16,8 @@ class DirtyFilesContainer( ) { private val myDirtyFiles = HashSet() - fun toMutableList(): MutableList = - ArrayList(myDirtyFiles) + fun toMutableLinkedSet(): LinkedHashSet = + LinkedHashSet(myDirtyFiles) fun add(files: Iterable, reason: String?) { val existingKotlinFiles = files.filter { it.isKotlinFile(sourceFilesExtensions) } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index 61d1dd4c30f..1d9d515e3b6 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -54,7 +54,7 @@ abstract class IncrementalCompilerRunner< ) { protected val cacheDirectory = File(workingDir, cacheDirName) - private val dirtySourcesSinceLastTimeFile = File(workingDir, DIRTY_SOURCES_FILE_NAME) + protected val dirtySourcesSinceLastTimeFile = File(workingDir, DIRTY_SOURCES_FILE_NAME) protected val lastBuildInfoFile = File(workingDir, LAST_BUILD_INFO_FILE_NAME) private val abiSnapshotFile = File(workingDir, ABI_SNAPSHOT_FILE_NAME) protected open val kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS @@ -297,14 +297,16 @@ abstract class IncrementalCompilerRunner< } protected abstract fun runCompiler( - sourcesToCompile: Set, + sourcesToCompile: List, args: Args, caches: CacheManager, services: Services, - messageCollector: MessageCollector - ): ExitCode + messageCollector: MessageCollector, + allSources: List, + isIncremental: Boolean + ): Pair> - private fun compileIncrementally( + protected open fun compileIncrementally( args: Args, caches: CacheManager, allKotlinSources: List, @@ -322,11 +324,11 @@ abstract class IncrementalCompilerRunner< val dirtySources = when (compilationMode) { is CompilationMode.Incremental -> { - compilationMode.dirtyFiles.toMutableList() + compilationMode.dirtyFiles.toMutableLinkedSet() } is CompilationMode.Rebuild -> { reporter.addAttribute(compilationMode.reason) - allKotlinSources.toMutableList() + LinkedHashSet(allKotlinSources) } } @@ -362,10 +364,18 @@ abstract class IncrementalCompilerRunner< val bufferingMessageCollector = BufferingMessageCollector() val messageCollectorAdapter = MessageCollectorToOutputItemsCollectorAdapter(bufferingMessageCollector, outputItemsCollector) - exitCode = reporter.measure(BuildTime.COMPILATION_ROUND) { - runCompiler(sourcesToCompile.toSet(), args, caches, services, messageCollectorAdapter) + val compiledSources = reporter.measure(BuildTime.COMPILATION_ROUND) { + runCompiler( + sourcesToCompile, args, caches, services, messageCollectorAdapter, + allKotlinSources, compilationMode is CompilationMode.Incremental + ) + }.let { (ec, compiled) -> + exitCode = ec + compiled } + dirtySources.addAll(compiledSources) + val generatedFiles = outputItemsCollector.outputs.map(SimpleOutputItem::toGeneratedFile) if (compilationMode is CompilationMode.Incremental) { // todo: feels dirty, can this be refactored? @@ -378,7 +388,7 @@ abstract class IncrementalCompilerRunner< } } - reporter.reportCompileIteration(compilationMode is CompilationMode.Incremental, sourcesToCompile, exitCode) + reporter.reportCompileIteration(compilationMode is CompilationMode.Incremental, compiledSources, exitCode) bufferingMessageCollector.flush(originalMessageCollector) if (exitCode != ExitCode.OK) break diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt new file mode 100644 index 00000000000..0cf44cef1b8 --- /dev/null +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalFirJvmCompilerRunner.kt @@ -0,0 +1,356 @@ +/* + * Copyright 2010-2021 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.incremental + +import com.intellij.ide.highlighter.JavaFileType +import com.intellij.openapi.util.Disposer +import com.intellij.psi.PsiJavaModule +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension +import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl +import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor +import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS +import org.jetbrains.kotlin.build.report.BuildReporter +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.ExitCode +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.computeKotlinPaths +import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot +import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots +import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback +import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector +import org.jetbrains.kotlin.cli.common.messages.IrMessageCollector +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder +import org.jetbrains.kotlin.cli.common.setupCommonArguments +import org.jetbrains.kotlin.cli.jvm.* +import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles +import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment +import org.jetbrains.kotlin.cli.jvm.compiler.findMainClass +import org.jetbrains.kotlin.cli.jvm.compiler.forAllFiles +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.* +import org.jetbrains.kotlin.cli.jvm.config.ClassicFrontendSpecificJvmConfigurationKeys +import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot +import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot +import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot +import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.backend.Fir2IrConverter +import org.jetbrains.kotlin.fir.backend.jvm.Fir2IrJvmSpecialAnnotationSymbolProvider +import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler +import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter +import org.jetbrains.kotlin.fir.languageVersionSettings +import org.jetbrains.kotlin.fir.moduleData +import org.jetbrains.kotlin.fir.resolve.providers.firProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker +import org.jetbrains.kotlin.incremental.components.InlineConstTracker +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory +import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler +import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl +import org.jetbrains.kotlin.ir.util.IrMessageLogger +import org.jetbrains.kotlin.load.java.JavaClassesTracker +import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents +import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion +import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.platform.CommonPlatforms +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.progress.CompilationCanceledException +import java.io.File + +class IncrementalFirJvmCompilerRunner( + workingDir: File, + reporter: BuildReporter, + buildHistoryFile: File, + outputFiles: Collection, + modulesApiHistory: ModulesApiHistory, + kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS, + classpathChanges: ClasspathChanges +) : IncrementalJvmCompilerRunner( + workingDir, + reporter, + false, + buildHistoryFile, + outputFiles, + modulesApiHistory, + kotlinSourceFilesExtensions, + classpathChanges +) { + + override fun runCompiler( + sourcesToCompile: List, + args: K2JVMCompilerArguments, + caches: IncrementalJvmCachesManager, + services: Services, + messageCollector: MessageCollector, + allSources: List, + isIncremental: Boolean + ): Pair> { +// val isIncremental = true // TODO + val collector = GroupingMessageCollector(messageCollector, args.allWarningsAsErrors) + // from K2JVMCompiler (~) + val moduleName = args.moduleName ?: JvmProtoBufUtil.DEFAULT_MODULE_NAME + val targetId = TargetId(moduleName, "java-production") // TODO: get rid of magic constant + + val dirtySources = linkedSetOf().apply { addAll(sourcesToCompile) } + + // TODO: probably shoudl be passed along with sourcesToCompile + // TODO: file path normalization + val commonSources = args.commonSources?.mapTo(mutableSetOf(), ::File).orEmpty() + + val exitCode = ExitCode.OK + val allCompiledSources = LinkedHashSet() + val rootDisposable = Disposer.newDisposable() + + try { + // - configuration + val configuration = CompilerConfiguration().apply { + + put(CLIConfigurationKeys.ORIGINAL_MESSAGE_COLLECTOR_KEY, messageCollector) + put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, collector) + put(IrMessageLogger.IR_MESSAGE_LOGGER, IrMessageCollector(collector)) + + setupCommonArguments(args) { JvmMetadataVersion(*it) } + + if (IncrementalCompilation.isEnabledForJvm()) { + putIfNotNull(CommonConfigurationKeys.LOOKUP_TRACKER, services[LookupTracker::class.java]) + + putIfNotNull(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, services[ExpectActualTracker::class.java]) + + putIfNotNull(CommonConfigurationKeys.INLINE_CONST_TRACKER, services[InlineConstTracker::class.java]) + + putIfNotNull( + JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, + services[IncrementalCompilationComponents::class.java] + ) + + putIfNotNull(ClassicFrontendSpecificJvmConfigurationKeys.JAVA_CLASSES_TRACKER, services[JavaClassesTracker::class.java]) + } + + setupJvmSpecificArguments(args) + } + + val paths = computeKotlinPaths(collector, args) + if (collector.hasErrors()) return ExitCode.COMPILATION_ERROR to emptyList() + + // -- plugins + val pluginClasspaths: Iterable = args.pluginClasspaths?.asIterable() ?: emptyList() + val pluginOptions = args.pluginOptions?.toMutableList() ?: ArrayList() + // TODO: add scripting support when ready in FIR + val pluginLoadResult = PluginCliParser.loadPluginsSafe(pluginClasspaths, pluginOptions, configuration) + if (pluginLoadResult != ExitCode.OK) return pluginLoadResult to emptyList() + // -- /plugins + + with(configuration) { + configureJavaModulesContentRoots(args) + configureStandardLibs(paths, args) + configureAdvancedJvmOptions(args) + configureKlibPaths(args) + + val destination = File(args.destination ?: ".") + if (destination.path.endsWith(".jar")) { + put(JVMConfigurationKeys.OUTPUT_JAR, destination) + } else { + put(JVMConfigurationKeys.OUTPUT_DIRECTORY, destination) + } + addAll(JVMConfigurationKeys.MODULES, listOf(ModuleBuilder(targetId.name, destination.path, targetId.type))) + + configureBaseRoots(args) + configureSourceRootsFromSources(allSources, commonSources, args.javaPackagePrefix) + } + // - /configuration + + setIdeaIoUseFallback() + + // -AbstractProjectEnvironment- + val projectEnvironment = + createProjectEnvironment(configuration, rootDisposable, EnvironmentConfigFiles.JVM_CONFIG_FILES, messageCollector) + + // -sources + val allPlatformSourceFiles = linkedSetOf() // TODO: get from caller + val allCommonSourceFiles = linkedSetOf() + + configuration.kotlinSourceRoots.forAllFiles(configuration, projectEnvironment.project) { virtualFile, isCommon -> + val file = File(virtualFile.canonicalPath ?: virtualFile.path) + if (!file.isFile) error("TODO: better error: file not found $virtualFile") + if (isCommon) allCommonSourceFiles.add(file) + else allPlatformSourceFiles.add(file) + } + + val diagnosticsReporter = DiagnosticReporterFactory.createReporter() + val compilerEnvironment = ModuleCompilerEnvironment(projectEnvironment, diagnosticsReporter) + + // !! main class - maybe from cache? + var mainClassFqName: FqName? = null + + var incrementalExcludesScope: AbstractProjectFileSearchScope? = null + + fun firIncrementalCycle(): ModuleCompilerAnalyzedOutput? { + while (true) { + + val compilerInput = ModuleCompilerInput( + targetId, + CommonPlatforms.defaultCommonPlatform, dirtySources.filter { it in allCommonSourceFiles }, + JvmPlatforms.unspecifiedJvmPlatform, dirtySources.filter { it in allPlatformSourceFiles }, + configuration + ) + + val analysisResults = + compileModuleToAnalyzedFir( + compilerInput, + compilerEnvironment, + emptyList(), + incrementalExcludesScope, + ) + + // TODO: consider what to do if many compilations find a main class + if (mainClassFqName == null && configuration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { + mainClassFqName = findMainClass(analysisResults.fir) + } + + allCompiledSources.addAll(dirtySources) + + if (diagnosticsReporter.hasErrors) { + FirDiagnosticsCompilerResultsReporter.reportToMessageCollector( + diagnosticsReporter, + collector, + configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) + ) + return null + } + + val newDirtySources = + collectNewDirtySources(analysisResults, targetId, configuration, caches, allCompiledSources, reporter) + + if (!isIncremental || newDirtySources.isEmpty()) return analysisResults + + caches.platformCache.markDirty(newDirtySources) + val newDirtyFilesOutputsScope = + projectEnvironment.getSearchScopeByIoFiles(caches.inputsCache.getOutputForSourceFiles(newDirtySources)) + incrementalExcludesScope = incrementalExcludesScope.let { + when { + newDirtyFilesOutputsScope.isEmpty -> it + it == null || it.isEmpty -> newDirtyFilesOutputsScope + else -> it + newDirtyFilesOutputsScope + } + } + caches.inputsCache.removeOutputForSourceFiles(newDirtySources) + dirtySources.addAll(newDirtySources) + projectEnvironment.localFileSystem.refresh(false) + } + } + + val cycleResult = firIncrementalCycle() ?: return ExitCode.COMPILATION_ERROR to allCompiledSources + + val extensions = JvmGeneratorExtensionsImpl(configuration) + val irGenerationExtensions = + (projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) }.orEmpty() + val mangler = JvmDescriptorMangler(null) + val signaturer = JvmIdSignatureDescriptor(JvmDescriptorMangler(null)) + val allCommonFirFiles = cycleResult.session.moduleData.dependsOnDependencies + .map { it.session } + .filter { it.kind == FirSession.Kind.Source } + .flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() } + + val (irModuleFragment, symbolTable, components) = Fir2IrConverter.createModuleFragment( + cycleResult.session, cycleResult.scopeSession, cycleResult.fir + allCommonFirFiles, + cycleResult.session.languageVersionSettings, mangler, signaturer, + extensions, FirJvmKotlinMangler(cycleResult.session), IrFactoryImpl, + FirJvmVisibilityConverter, + Fir2IrJvmSpecialAnnotationSymbolProvider(), + irGenerationExtensions + ) + + val irInput = ModuleCompilerIrBackendInput( + targetId, + configuration, + extensions, + irModuleFragment, + symbolTable, + components, + cycleResult.session + ) + + val codegenOutput = generateCodeFromIr(irInput, compilerEnvironment) + + FirDiagnosticsCompilerResultsReporter.reportToMessageCollector( + diagnosticsReporter, + collector, + configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) + ) + + writeOutputs( + projectEnvironment, + configuration, + listOf(codegenOutput.generationState), + mainClassFqName + ) + } catch (e: CompilationCanceledException) { + collector.report(CompilerMessageSeverity.INFO, "Compilation was canceled", null) + return ExitCode.OK to allCompiledSources + } catch (e: RuntimeException) { + val cause = e.cause + if (cause is CompilationCanceledException) { + collector.report(CompilerMessageSeverity.INFO, "Compilation was canceled", null) + return ExitCode.OK to allCompiledSources + } else { + throw e + } + } finally { + collector.flush() + Disposer.dispose(rootDisposable) + } + return exitCode to allCompiledSources + } +} + + +fun CompilerConfiguration.configureBaseRoots(args: K2JVMCompilerArguments) { + + var isJava9Module = false + args.javaSourceRoots?.forEach { + val file = File(it) + val packagePrefix = args.javaPackagePrefix + addJavaSourceRoot(file, packagePrefix) + if (!isJava9Module && packagePrefix == null && (file.name == PsiJavaModule.MODULE_INFO_FILE || + (file.isDirectory && file.listFiles()?.any { it.name == PsiJavaModule.MODULE_INFO_FILE } == true)) + ) { + isJava9Module = true + } + } + + args.classpath?.split(File.pathSeparator)?.forEach { classpathRoot -> + add( + CLIConfigurationKeys.CONTENT_ROOTS, + if (isJava9Module) JvmModulePathRoot(File(classpathRoot)) else JvmClasspathRoot(File(classpathRoot)) + ) + } + + // TODO: modularJdkRoot (now seems only processed from the build file +} + +fun CompilerConfiguration.configureSourceRootsFromSources( + allSources: Collection, commonSources: Set, javaPackagePrefix: String? +) { + for (sourceFile in allSources) { + if (sourceFile.name.endsWith(JavaFileType.DOT_DEFAULT_EXTENSION)) { + addJavaSourceRoot(sourceFile, javaPackagePrefix) + } else { + addKotlinSourceRoot(sourceFile.path, isCommon = sourceFile in commonSources) + + if (sourceFile.isDirectory) { + addJavaSourceRoot(sourceFile, javaPackagePrefix) + } + } + } +} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt index 20716e86443..6c28c348c6b 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt @@ -192,18 +192,20 @@ class IncrementalJsCompilerRunner( } override fun runCompiler( - sourcesToCompile: Set, + sourcesToCompile: List, args: K2JSCompilerArguments, caches: IncrementalJsCachesManager, services: Services, - messageCollector: MessageCollector - ): ExitCode { + messageCollector: MessageCollector, + allSources: List, + isIncremental: Boolean + ): Pair> { val freeArgsBackup = args.freeArgs val compiler = K2JSCompiler() return try { args.freeArgs += sourcesToCompile.map { it.absolutePath } - compiler.exec(messageCollector, services, args) + compiler.exec(messageCollector, services, args) to sourcesToCompile } finally { args.freeArgs = freeArgsBackup reportPerformanceData(compiler.defaultPerformanceManager) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index 01e2c251c62..4d41601f14a 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -86,17 +86,24 @@ fun makeIncrementally( val buildReporter = BuildReporter(icReporter = reporter, buildMetricsReporter = DoNothingBuildMetricsReporter) withIC(args) { - val compiler = IncrementalJvmCompilerRunner( - cachesDir, - buildReporter, - // Use precise setting in case of non-Gradle build - usePreciseJavaTracking = !args.useFir, // TODO: add fir-based java classes tracker when available and set this to true - outputFiles = emptyList(), - buildHistoryFile = buildHistoryFile, - modulesApiHistory = EmptyModulesApiHistory, - kotlinSourceFilesExtensions = kotlinExtensions, - classpathChanges = ClasspathSnapshotDisabled - ) + val compiler = + if (args.useFir) + IncrementalFirJvmCompilerRunner( + cachesDir, buildReporter, buildHistoryFile, emptyList(), EmptyModulesApiHistory, kotlinExtensions, ClasspathSnapshotDisabled + ) + else + IncrementalJvmCompilerRunner( + cachesDir, + buildReporter, + // Use precise setting in case of non-Gradle build + usePreciseJavaTracking = !args.useFir, // TODO: add fir-based java classes tracker when available and set this to true + outputFiles = emptyList(), + buildHistoryFile = buildHistoryFile, + modulesApiHistory = EmptyModulesApiHistory, + kotlinSourceFilesExtensions = kotlinExtensions, + classpathChanges = ClasspathSnapshotDisabled + ) + //TODO set properly compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null) } } @@ -116,7 +123,7 @@ inline fun withIC(args: CommonCompilerArguments, enabled: Boolean = true, fn } } -class IncrementalJvmCompilerRunner( +open class IncrementalJvmCompilerRunner( workingDir: File, reporter: BuildReporter, private val usePreciseJavaTracking: Boolean, @@ -453,12 +460,14 @@ class IncrementalJvmCompilerRunner( } override fun runCompiler( - sourcesToCompile: Set, + sourcesToCompile: List, args: K2JVMCompilerArguments, caches: IncrementalJvmCachesManager, services: Services, - messageCollector: MessageCollector - ): ExitCode { + messageCollector: MessageCollector, + allSources: List, + isIncremental: Boolean + ): Pair> { val compiler = K2JVMCompiler() val freeArgsBackup = args.freeArgs.toList() args.freeArgs += sourcesToCompile.map { it.absolutePath } @@ -466,7 +475,7 @@ class IncrementalJvmCompilerRunner( val exitCode = compiler.exec(messageCollector, services, args) args.freeArgs = freeArgsBackup reportPerformanceData(compiler.defaultPerformanceManager) - return exitCode + return exitCode to sourcesToCompile } override fun performWorkAfterSuccessfulCompilation(caches: IncrementalJvmCachesManager) { diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt index e97cbd85af7..68f1900e755 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt @@ -47,6 +47,10 @@ class InputsCache( } } + fun getOutputForSourceFiles(sources: Iterable): List = sources.flatMap { + sourceToOutputMap[it] + } + // generatedFiles can contain multiple entries with the same source file // for example Kapt3 IC will generate a .java stub and .class stub for each source file fun registerOutputForSourceFiles(generatedFiles: List) { diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt new file mode 100644 index 00000000000..2aca6329be3 --- /dev/null +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/incrementalFirCacheUtils.kt @@ -0,0 +1,146 @@ +/* + * Copyright 2010-2022 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.incremental + +import org.jetbrains.kotlin.backend.common.pop +import org.jetbrains.kotlin.backend.common.push +import org.jetbrains.kotlin.backend.jvm.metadata.MetadataSerializer +import org.jetbrains.kotlin.build.report.ICReporter +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.ModuleCompilerAnalyzedOutput +import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.backend.FirMetadataSource +import org.jetbrains.kotlin.fir.backend.jvm.makeLocalFirMetadataSerializerForMetadataSource +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.classId +import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor +import org.jetbrains.kotlin.fir.visitors.FirVisitor +import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.name.SpecialNames +import org.jetbrains.kotlin.resolve.jvm.JvmClassName +import org.jetbrains.org.objectweb.asm.commons.Method +import java.io.File + +internal fun collectNewDirtySources( + analysisResults: ModuleCompilerAnalyzedOutput, + targetId: TargetId, + configuration: CompilerConfiguration, + caches: IncrementalJvmCachesManager, + alreadyCompiledSources: Set, + reporter: ICReporter +): LinkedHashSet { + val changesCollector = ChangesCollector() + val globalSerializationBindings = JvmSerializationBindings() + analysisResults.fir.forEach { + it.accept(object : FirVisitor>() { + + inline fun withMetadataSerializer( + metadata: FirMetadataSource, + data: MutableList, + body: (MetadataSerializer) -> Unit + ) { + val serializer = makeLocalFirMetadataSerializerForMetadataSource( + metadata, + analysisResults.session, + analysisResults.scopeSession, + globalSerializationBindings, + data.lastOrNull(), + targetId, + configuration + ) + data.push(serializer) + body(serializer) + data.pop() + } + + override fun visitElement(element: FirElement, data: MutableList) { + element.acceptChildren(this, data) + } + + override fun visitRegularClass(regularClass: FirRegularClass, data: MutableList) { + visitClass(regularClass, data) + } + + override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: MutableList) { + visitClass(anonymousObject, data) + } + + override fun visitFile(file: FirFile, data: MutableList) { + val metadata = FirMetadataSource.File(file) + withMetadataSerializer(metadata, data) { + file.acceptChildren(this, data) + // TODO: compare package fragments? + } + } + + override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableList) { + data.firstOrNull()?.let { serializer -> + super.visitFunction(simpleFunction, data) + serializer.bindMethodMetadata( + FirMetadataSource.Function(simpleFunction), + Method(simpleFunction.name.asString(), simpleFunction.computeJvmDescriptor()) + ) + } + } + + override fun visitConstructor(constructor: FirConstructor, data: MutableList) { + super.visitConstructor(constructor, data) + data.first().bindMethodMetadata( + FirMetadataSource.Function(constructor), + Method(SpecialNames.INIT.asString(), constructor.computeJvmDescriptor("")) + ) + } + + override fun visitProperty(property: FirProperty, data: MutableList) { + property.acceptChildren(this, data) +// data.firstOrNull()?.let { +// property.acceptChildren(this, data) +// it.bindPropertyMetadata( +// FirMetadataSource.Property(property), +// Method(property.name.asString(), ""),//property.computeJvmDescriptor()) +// IrDeclarationOrigin.DEFINED +// ) +// } + } + + override fun visitClass(klass: FirClass, data: MutableList) { + val metadata = FirMetadataSource.Class(klass) + withMetadataSerializer(metadata, data) { serializer -> + klass.acceptChildren(this, data) + serializer.serialize(metadata)?.let { (classProto, nameTable) -> + caches.platformCache.collectClassChangesByFeMetadata( + JvmClassName.byClassId(klass.classId), + classProto as ProtoBuf.Class, + nameTable, + changesCollector + ) + } + } + } + }, mutableListOf()) + } + + val (dirtyLookupSymbols, dirtyClassFqNames, forceRecompile) = changesCollector.getDirtyData(listOf(caches.platformCache), reporter) + + val forceToRecompileFiles = mapClassesFqNamesToFiles(listOf(caches.platformCache), forceRecompile, reporter) + + return linkedSetOf().apply { + addAll(mapLookupSymbolsToFiles(caches.lookupCache, dirtyLookupSymbols, reporter, excludes = alreadyCompiledSources)) + addAll( + mapClassesFqNamesToFiles( + listOf(caches.platformCache), + dirtyClassFqNames, + reporter, + excludes = alreadyCompiledSources + ) + ) + if (!alreadyCompiledSources.containsAll(forceToRecompileFiles)) { + addAll(forceToRecompileFiles) + } + } +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt index deb03bd1962..aaedb253515 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt @@ -93,7 +93,7 @@ class FirFrontendFacade( PsiBasedProjectFileSearchScope(sourcesScope), PsiBasedProjectFileSearchScope(librariesScope), lookupTracker = null, - providerAndScopeForIncrementalCompilation = null, + incrementalCompilationContext = null, extensionRegistrars = FirExtensionRegistrar.getInstances(project), needRegisterJavaElementFinder = true, dependenciesConfigurator = { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt index 737b057bea5..6405ccd4a96 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt @@ -97,7 +97,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() { sourceScope = PsiBasedProjectFileSearchScope(scope), librariesScope = PsiBasedProjectFileSearchScope(allProjectScope), lookupTracker = null, - providerAndScopeForIncrementalCompilation = null, + incrementalCompilationContext = null, extensionRegistrars = emptyList(), needRegisterJavaElementFinder = true ) { diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt index 6d334e658fa..274818887f5 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt @@ -41,7 +41,7 @@ fun createSessionForTests( sourceScope, librariesScope, lookupTracker = null, - providerAndScopeForIncrementalCompilation = null, + incrementalCompilationContext = null, extensionRegistrars = emptyList(), needRegisterJavaElementFinder = true, dependenciesConfigurator = { @@ -72,7 +72,7 @@ fun createSessionForTests( PsiBasedProjectFileSearchScope(sourceScope), PsiBasedProjectFileSearchScope(librariesScope), lookupTracker = null, - providerAndScopeForIncrementalCompilation = null, + incrementalCompilationContext = null, extensionRegistrars = emptyList(), needRegisterJavaElementFinder = true, dependenciesConfigurator = {