[FIR & FIR2IR] Prepare test and CLI infrastructure to support MPP
- Move out getAnalyzerServices from FirFrontendFacade to TestSetupUtils - Simplify DependencyListForCliModule. Now it takes BinaryModuleData as input - FirOutArtifact contains several FirOutputArtifactPart - Simplify FirFrontendFacade
This commit is contained in:
committed by
Space Team
parent
3029e47609
commit
5d273ce839
+1
-1
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
import org.jetbrains.kotlin.test.getAnalyzerServices
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.analysis.project.structure.*
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
import org.jetbrains.kotlin.test.getAnalyzerServices
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
interface KtModuleWithModifiableDependencies {
|
interface KtModuleWithModifiableDependencies {
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreApplicationEnvironment
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
import org.jetbrains.kotlin.test.getAnalyzerServices
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
|
|
||||||
abstract class AnalysisApiEnvironmentManager : TestService {
|
abstract class AnalysisApiEnvironmentManager : TestService {
|
||||||
|
|||||||
+54
-5
@@ -9,11 +9,13 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.createFirResolveSessionForNoCaching
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.createFirResolveSessionForNoCaching
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.FirLowLevelCompilerBasedTestConfigurator
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformer
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformer
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.AbstractCompilerBasedTest
|
import org.jetbrains.kotlin.analysis.test.framework.AbstractCompilerBasedTest
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.base.registerAnalysisApiBaseTestServices
|
import org.jetbrains.kotlin.analysis.test.framework.base.registerAnalysisApiBaseTestServices
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleByCompilerConfiguration
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleByCompilerConfiguration
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||||
@@ -23,15 +25,13 @@ import org.jetbrains.kotlin.test.builders.testConfiguration
|
|||||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifactImpl
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.FirOutputPartForDependsOnModule
|
||||||
import org.jetbrains.kotlin.test.model.DependencyKind
|
import org.jetbrains.kotlin.test.model.DependencyKind
|
||||||
import org.jetbrains.kotlin.test.model.FrontendFacade
|
import org.jetbrains.kotlin.test.model.FrontendFacade
|
||||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
|
||||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
|
||||||
import org.jetbrains.kotlin.test.services.isKtFile
|
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.FirLowLevelCompilerBasedTestConfigurator
|
|
||||||
|
|
||||||
abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
||||||
@OptIn(TestInfrastructureInternals::class)
|
@OptIn(TestInfrastructureInternals::class)
|
||||||
@@ -58,11 +58,55 @@ abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
|||||||
inner class LowLevelFirFrontendFacade(
|
inner class LowLevelFirFrontendFacade(
|
||||||
testServices: TestServices
|
testServices: TestServices
|
||||||
) : FrontendFacade<FirOutputArtifact>(testServices, FrontendKinds.FIR) {
|
) : FrontendFacade<FirOutputArtifact>(testServices, FrontendKinds.FIR) {
|
||||||
|
private val testModulesByName by lazy { testServices.moduleStructure.modules.associateBy { it.name } }
|
||||||
|
|
||||||
override val directiveContainers: List<DirectivesContainer>
|
override val directiveContainers: List<DirectivesContainer>
|
||||||
get() = listOf(FirDiagnosticsDirectives)
|
get() = listOf(FirDiagnosticsDirectives)
|
||||||
|
|
||||||
|
override fun shouldRunAnalysis(module: TestModule): Boolean {
|
||||||
|
if (!super.shouldRunAnalysis(module)) return false
|
||||||
|
|
||||||
|
return if (module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) {
|
||||||
|
testServices.moduleStructure
|
||||||
|
.modules.none { testModule -> testModule.dependsOnDependencies.any { testModulesByName[it.moduleName] == module } }
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun analyze(module: TestModule): FirOutputArtifact {
|
override fun analyze(module: TestModule): FirOutputArtifact {
|
||||||
|
val isMppSupported = module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||||
|
|
||||||
|
val sortedModules = if (isMppSupported) sortDependsOnTopologically(module) else listOf(module)
|
||||||
|
|
||||||
|
val firOutputPartForDependsOnModules = mutableListOf<FirOutputPartForDependsOnModule>()
|
||||||
|
for (testModule in sortedModules) {
|
||||||
|
firOutputPartForDependsOnModules.add(analyzeDependsOnModule(testModule))
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirOutputArtifactImpl(firOutputPartForDependsOnModules)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sortDependsOnTopologically(module: TestModule): List<TestModule> {
|
||||||
|
val sortedModules = mutableListOf<TestModule>()
|
||||||
|
val visitedModules = mutableSetOf<TestModule>()
|
||||||
|
val modulesQueue = ArrayDeque<TestModule>()
|
||||||
|
modulesQueue.add(module)
|
||||||
|
|
||||||
|
while (modulesQueue.isNotEmpty()) {
|
||||||
|
val currentModule = modulesQueue.removeFirst()
|
||||||
|
if (!visitedModules.add(currentModule)) continue
|
||||||
|
sortedModules.add(currentModule)
|
||||||
|
|
||||||
|
for (dependency in currentModule.dependsOnDependencies) {
|
||||||
|
modulesQueue.add(testServices.dependencyProvider.getTestModule(dependency.moduleName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortedModules.reversed()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun analyzeDependsOnModule(module: TestModule): FirOutputPartForDependsOnModule {
|
||||||
val moduleInfoProvider = testServices.ktModuleProvider
|
val moduleInfoProvider = testServices.ktModuleProvider
|
||||||
val ktModule = moduleInfoProvider.getModule(module.name) as KtSourceModuleByCompilerConfiguration
|
val ktModule = moduleInfoProvider.getModule(module.name) as KtSourceModuleByCompilerConfiguration
|
||||||
|
|
||||||
@@ -81,7 +125,12 @@ abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
|||||||
} else DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS
|
} else DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS
|
||||||
|
|
||||||
val analyzerFacade = LowLevelFirAnalyzerFacade(firResolveSession, allFirFiles.toMap(), diagnosticCheckerFilter)
|
val analyzerFacade = LowLevelFirAnalyzerFacade(firResolveSession, allFirFiles.toMap(), diagnosticCheckerFilter)
|
||||||
return LowLevelFirOutputArtifact(firResolveSession.useSiteFirSession, analyzerFacade)
|
return FirOutputPartForDependsOnModule(
|
||||||
|
module,
|
||||||
|
firResolveSession.useSiteFirSession,
|
||||||
|
analyzerFacade,
|
||||||
|
analyzerFacade.allFirFiles
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -18,10 +18,12 @@ import org.jetbrains.kotlin.test.services.assertions
|
|||||||
|
|
||||||
internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
internal class LLDiagnosticParameterChecker(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val diagnostics = info.firAnalyzerFacade.runCheckers().values.flatten()
|
for (part in info.partsForDependsOnModules) {
|
||||||
|
val diagnostics = part.firAnalyzerFacade.runCheckers().values.flatten()
|
||||||
|
|
||||||
for (diagnostic in diagnostics) {
|
for (diagnostic in diagnostics) {
|
||||||
checkDiagnosticIsSuitableForFirIde(diagnostic as KtPsiDiagnostic)
|
checkDiagnosticIsSuitableForFirIde(diagnostic as KtPsiDiagnostic)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
@@ -36,7 +37,7 @@ class LowLevelFirAnalyzerFacade(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun runResolution(): List<FirFile> = shouldNotBeCalled()
|
override fun runResolution(): List<FirFile> = shouldNotBeCalled()
|
||||||
override fun convertToIr(fir2IrExtensions: Fir2IrExtensions): Fir2IrResult = shouldNotBeCalled()
|
override fun convertToIr(fir2IrExtensions: Fir2IrExtensions, dependentComponents: List<Fir2IrComponents>): Fir2IrResult = shouldNotBeCalled()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldNotBeCalled(): Nothing = error("Should not be called for LL test")
|
private fun shouldNotBeCalled(): Nothing = error("Should not be called for LL test")
|
||||||
|
|||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.analysis.low.level.api.fir.compiler.based
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
|
||||||
import org.jetbrains.kotlin.test.model.TestFile
|
|
||||||
|
|
||||||
class LowLevelFirOutputArtifact(
|
|
||||||
override val session: FirSession,
|
|
||||||
override val firAnalyzerFacade: LowLevelFirAnalyzerFacade,
|
|
||||||
) : FirOutputArtifact() {
|
|
||||||
override val allFirFiles: Map<TestFile, FirFile>
|
|
||||||
get() = firAnalyzerFacade.allFirFiles
|
|
||||||
}
|
|
||||||
@@ -43,9 +43,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirModuleDataImpl
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter
|
import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter
|
||||||
@@ -55,7 +53,6 @@ import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
|||||||
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
|
||||||
import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles
|
import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles
|
||||||
import org.jetbrains.kotlin.fir.pipeline.runCheckers
|
import org.jetbrains.kotlin.fir.pipeline.runCheckers
|
||||||
import org.jetbrains.kotlin.fir.pipeline.runResolution
|
import org.jetbrains.kotlin.fir.pipeline.runResolution
|
||||||
@@ -509,7 +506,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
|
|
||||||
val mainModule = MainModule.SourceFiles(environmentForJS.getSourceFiles())
|
val mainModule = MainModule.SourceFiles(environmentForJS.getSourceFiles())
|
||||||
|
|
||||||
val dependencyList = DependencyListForCliModule.build(mainModuleName, JsPlatforms.defaultJsPlatform, JsPlatformAnalyzerServices) {
|
val binaryModuleData = BinaryModuleData.initialize(mainModuleName, JsPlatforms.defaultJsPlatform, JsPlatformAnalyzerServices)
|
||||||
|
val dependencyList = DependencyListForCliModule.build(binaryModuleData) {
|
||||||
dependencies(libraries.map { Paths.get(it).toAbsolutePath() })
|
dependencies(libraries.map { Paths.get(it).toAbsolutePath() })
|
||||||
friendDependencies(friendLibraries.map { Paths.get(it).toAbsolutePath() })
|
friendDependencies(friendLibraries.map { Paths.get(it).toAbsolutePath() })
|
||||||
// TODO: !!! dependencies module data?
|
// TODO: !!! dependencies module data?
|
||||||
@@ -533,8 +531,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
dependencyList.regularDependencies,
|
dependencyList.regularDependencies,
|
||||||
dependencyList.dependsOnDependencies,
|
dependencyList.dependsOnDependencies,
|
||||||
dependencyList.friendsDependencies,
|
dependencyList.friendsDependencies,
|
||||||
dependencyList.platform,
|
JsPlatforms.defaultJsPlatform,
|
||||||
dependencyList.analyzerServices
|
JsPlatformAnalyzerServices
|
||||||
)
|
)
|
||||||
|
|
||||||
val session = FirJsSessionFactory.createJsModuleBasedSession(
|
val session = FirJsSessionFactory.createJsModuleBasedSession(
|
||||||
@@ -598,7 +596,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO: replace with appropriate (probably empty) implementation
|
Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO: replace with appropriate (probably empty) implementation
|
||||||
IrGenerationExtension.getInstances(environmentForJS.project),
|
IrGenerationExtension.getInstances(environmentForJS.project),
|
||||||
generateSignatures = false,
|
generateSignatures = false,
|
||||||
kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance // TODO: consider passing externally
|
kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance, // TODO: consider passing externally
|
||||||
|
dependentComponents = emptyList()
|
||||||
).also {
|
).also {
|
||||||
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
|
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
|
||||||
}
|
}
|
||||||
|
|||||||
+129
-94
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
|
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||||
@@ -26,24 +25,21 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
|||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
|
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
import org.jetbrains.kotlin.fir.backend.jvm.*
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
|
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.pipeline.*
|
import org.jetbrains.kotlin.fir.pipeline.*
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper
|
import org.jetbrains.kotlin.fir.session.*
|
||||||
import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext
|
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
||||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||||
@@ -52,18 +48,16 @@ import org.jetbrains.kotlin.fir.types.isArrayType
|
|||||||
import org.jetbrains.kotlin.fir.types.isString
|
import org.jetbrains.kotlin.fir.types.isString
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
|
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.IncrementalPackagePartProvider
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||||
import org.jetbrains.kotlin.modules.Module
|
import org.jetbrains.kotlin.modules.Module
|
||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
@@ -102,15 +96,8 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
)
|
)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (projectConfiguration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) {
|
|
||||||
messageCollector.report(
|
|
||||||
CompilerMessageSeverity.ERROR,
|
|
||||||
"K2 compiler does not support multi-platform projects yet, so please remove -Xuse-k2 flag"
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val outputs = ArrayList<Pair<ModuleCompilerAnalyzedOutput, GenerationState>>(chunk.size)
|
val outputs = ArrayList<Pair<FirResult, GenerationState>>(chunk.size)
|
||||||
val targetIds = projectConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
|
val targetIds = projectConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
|
||||||
val incrementalComponents = projectConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
|
val incrementalComponents = projectConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
|
||||||
val isMultiModuleChunk = chunk.size > 1
|
val isMultiModuleChunk = chunk.size > 1
|
||||||
@@ -140,14 +127,14 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val mainClassFqName: FqName? = runIf(chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
val mainClassFqName: FqName? = runIf(chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
||||||
findMainClass(outputs.single().first.fir)
|
findMainClass(outputs.single().first.platformOutput.fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeOutputsIfNeeded(
|
return writeOutputsIfNeeded(
|
||||||
project,
|
project,
|
||||||
projectConfiguration,
|
projectConfiguration,
|
||||||
chunk,
|
chunk,
|
||||||
outputs.map(Pair<ModuleCompilerAnalyzedOutput, GenerationState>::second),
|
outputs.map(Pair<FirResult, GenerationState>::second),
|
||||||
mainClassFqName
|
mainClassFqName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -160,7 +147,7 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
?.mapTo(destination) { it::class.qualifiedName }
|
?.mapTo(destination) { it::class.qualifiedName }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompilationContext.compileModule(): Pair<ModuleCompilerAnalyzedOutput, GenerationState>? {
|
private fun CompilationContext.compileModule(): Pair<FirResult, GenerationState>? {
|
||||||
performanceManager?.notifyAnalysisStarted()
|
performanceManager?.notifyAnalysisStarted()
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
@@ -181,8 +168,11 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
performanceManager?.notifyIRTranslationStarted()
|
performanceManager?.notifyIRTranslationStarted()
|
||||||
|
|
||||||
val fir2IrExtensions = JvmFir2IrExtensions(moduleConfiguration, JvmIrDeserializerImpl(), JvmIrMangler)
|
val fir2IrExtensions = JvmFir2IrExtensions(moduleConfiguration, JvmIrDeserializerImpl(), JvmIrMangler)
|
||||||
val linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
|
val fir2IrResult = firResult.convertToIrAndActualize(
|
||||||
val fir2IrResult = firResult.convertToIr(fir2IrExtensions, irGenerationExtensions, linkViaSignatures)
|
fir2IrExtensions,
|
||||||
|
irGenerationExtensions,
|
||||||
|
linkViaSignatures = moduleConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
|
||||||
|
)
|
||||||
|
|
||||||
performanceManager?.notifyIRTranslationFinished()
|
performanceManager?.notifyIRTranslationFinished()
|
||||||
|
|
||||||
@@ -190,7 +180,7 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
allSources,
|
allSources,
|
||||||
fir2IrResult,
|
fir2IrResult,
|
||||||
fir2IrExtensions,
|
fir2IrExtensions,
|
||||||
firResult.session,
|
firResult.platformOutput.session,
|
||||||
diagnosticsReporter
|
diagnosticsReporter
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -203,14 +193,12 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
return firResult to generationState
|
return firResult to generationState
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>, diagnosticsReporter: BaseDiagnosticsCollector): ModuleCompilerAnalyzedOutput? {
|
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>, diagnosticsReporter: BaseDiagnosticsCollector): FirResult? {
|
||||||
@Suppress("NAME_SHADOWING")
|
|
||||||
var ktFiles = ktFiles
|
|
||||||
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
|
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
|
||||||
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
|
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceScope = (projectEnvironment as VfsBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) +
|
val sourceScope = (projectEnvironment as VfsBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) +
|
||||||
projectEnvironment.getSearchScopeForProjectJavaSources()
|
projectEnvironment.getSearchScopeForProjectJavaSources()
|
||||||
|
|
||||||
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
|
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
|
||||||
@@ -223,85 +211,132 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
|
|
||||||
val languageVersionSettings = moduleConfiguration.languageVersionSettings
|
val languageVersionSettings = moduleConfiguration.languageVersionSettings
|
||||||
|
|
||||||
val commonKtFiles = ktFiles.filter { it.isCommonSource == true }
|
val isMppEnabled = languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||||
|
|
||||||
val sessionProvider = FirProjectSessionProvider()
|
val sessionProvider = FirProjectSessionProvider()
|
||||||
|
|
||||||
fun createSession(
|
val moduleName = module.getModuleName()
|
||||||
name: String,
|
val libraryList = createLibraryListAndSession(moduleName, sessionProvider, librariesScope, languageVersionSettings)
|
||||||
platform: TargetPlatform,
|
|
||||||
analyzerServices: PlatformDependentAnalyzerServices,
|
|
||||||
sourceScope: AbstractProjectFileSearchScope,
|
|
||||||
needRegisterJavaElementFinder: Boolean,
|
|
||||||
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}
|
|
||||||
): FirSession {
|
|
||||||
return FirSessionFactoryHelper.createSessionWithDependencies(
|
|
||||||
Name.identifier(name),
|
|
||||||
platform,
|
|
||||||
analyzerServices,
|
|
||||||
externalSessionProvider = sessionProvider,
|
|
||||||
projectEnvironment,
|
|
||||||
languageVersionSettings,
|
|
||||||
sourceScope,
|
|
||||||
librariesScope,
|
|
||||||
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
|
||||||
enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
|
|
||||||
providerAndScopeForIncrementalCompilation,
|
|
||||||
firExtensionRegistrars,
|
|
||||||
needRegisterJavaElementFinder,
|
|
||||||
dependenciesConfigurator = {
|
|
||||||
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
|
|
||||||
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
|
|
||||||
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
|
||||||
dependenciesConfigurator()
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
if (extendedAnalysisMode) {
|
|
||||||
registerExtendedCommonCheckers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val commonSession = runIf(
|
val commonModuleData = runIf(isMppEnabled) {
|
||||||
languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) && commonKtFiles.isNotEmpty()
|
FirModuleDataImpl(
|
||||||
) {
|
Name.identifier("${module.getModuleName()}-common"),
|
||||||
val commonSourcesScope = projectEnvironment.getSearchScopeByPsiFiles(commonKtFiles)
|
libraryList.regularDependencies,
|
||||||
sourceScope -= commonSourcesScope
|
listOf(),
|
||||||
ktFiles = ktFiles.filterNot { it.isCommonSource == true }
|
libraryList.friendsDependencies,
|
||||||
createSession(
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
"${module.getModuleName()}-common",
|
JvmPlatformAnalyzerServices
|
||||||
CommonPlatforms.defaultCommonPlatform,
|
|
||||||
CommonPlatformAnalyzerServices,
|
|
||||||
commonSourcesScope,
|
|
||||||
needRegisterJavaElementFinder = false
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val platformModuleData = FirModuleDataImpl(
|
||||||
val session = createSession(
|
Name.identifier(module.getModuleName()),
|
||||||
module.getModuleName(),
|
libraryList.regularDependencies,
|
||||||
|
listOfNotNull(commonModuleData),
|
||||||
|
libraryList.friendsDependencies,
|
||||||
JvmPlatforms.unspecifiedJvmPlatform,
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
JvmPlatformAnalyzerServices,
|
JvmPlatformAnalyzerServices
|
||||||
sourceScope,
|
)
|
||||||
needRegisterJavaElementFinder = true
|
|
||||||
) {
|
val lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER)
|
||||||
if (commonSession != null) {
|
val enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER)
|
||||||
sourceDependsOnDependencies(listOf(commonSession.moduleData))
|
val sessionConfigurator: FirSessionConfigurator.() -> Unit = {
|
||||||
|
if (extendedAnalysisMode) {
|
||||||
|
registerExtendedCommonCheckers()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val commonKtFiles = mutableListOf<KtFile>()
|
||||||
|
val platformKtFiles = mutableListOf<KtFile>()
|
||||||
|
val commonSourcesScope: AbstractProjectFileSearchScope?
|
||||||
|
val platformSourcesScope: AbstractProjectFileSearchScope
|
||||||
|
if (isMppEnabled) {
|
||||||
|
for (ktFile in ktFiles) {
|
||||||
|
(if (ktFile.isCommonSource == true) commonKtFiles else platformKtFiles).add(ktFile)
|
||||||
|
}
|
||||||
|
commonSourcesScope = projectEnvironment.getSearchScopeByPsiFiles(commonKtFiles)
|
||||||
|
platformSourcesScope = sourceScope - commonSourcesScope
|
||||||
|
} else {
|
||||||
|
platformKtFiles.addAll(ktFiles)
|
||||||
|
commonSourcesScope = null
|
||||||
|
platformSourcesScope = sourceScope
|
||||||
|
}
|
||||||
|
|
||||||
|
val commonSession = runIf(isMppEnabled) {
|
||||||
|
FirJvmSessionFactory.createModuleBasedSession(
|
||||||
|
commonModuleData!!,
|
||||||
|
sessionProvider,
|
||||||
|
commonSourcesScope!!,
|
||||||
|
projectEnvironment,
|
||||||
|
providerAndScopeForIncrementalCompilation,
|
||||||
|
firExtensionRegistrars,
|
||||||
|
languageVersionSettings,
|
||||||
|
lookupTracker,
|
||||||
|
enumWhenTracker,
|
||||||
|
needRegisterJavaElementFinder = true,
|
||||||
|
registerExtraComponents = {},
|
||||||
|
sessionConfigurator
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val platformSession = FirJvmSessionFactory.createModuleBasedSession(
|
||||||
|
platformModuleData,
|
||||||
|
sessionProvider,
|
||||||
|
platformSourcesScope,
|
||||||
|
projectEnvironment,
|
||||||
|
providerAndScopeForIncrementalCompilation,
|
||||||
|
firExtensionRegistrars,
|
||||||
|
languageVersionSettings,
|
||||||
|
lookupTracker,
|
||||||
|
enumWhenTracker,
|
||||||
|
needRegisterJavaElementFinder = true,
|
||||||
|
registerExtraComponents = {},
|
||||||
|
sessionConfigurator,
|
||||||
|
)
|
||||||
|
|
||||||
|
val commonOutput = commonSession?.let { buildResolveAndCheckFir(it, commonKtFiles, diagnosticsReporter) }
|
||||||
|
val platformOutput = buildResolveAndCheckFir(platformSession, platformKtFiles, diagnosticsReporter)
|
||||||
|
|
||||||
|
return if (syntaxErrors || diagnosticsReporter.hasErrors) null else FirResult(platformOutput, commonOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CompilationContext.createLibraryListAndSession(
|
||||||
|
moduleName: String,
|
||||||
|
sessionProvider: FirProjectSessionProvider,
|
||||||
|
librariesScope: AbstractProjectFileSearchScope,
|
||||||
|
languageVersionSettings: LanguageVersionSettings
|
||||||
|
): DependencyListForCliModule {
|
||||||
|
val binaryModuleData = BinaryModuleData.initialize(
|
||||||
|
Name.identifier(moduleName),
|
||||||
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
|
JvmPlatformAnalyzerServices
|
||||||
|
)
|
||||||
|
val libraryList = DependencyListForCliModule.build(binaryModuleData) {
|
||||||
|
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
|
||||||
|
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
|
||||||
|
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||||
friendDependencies(module.getFriendPaths())
|
friendDependencies(module.getFriendPaths())
|
||||||
}
|
}
|
||||||
|
FirJvmSessionFactory.createLibrarySession(
|
||||||
|
Name.identifier(moduleName),
|
||||||
|
sessionProvider,
|
||||||
|
libraryList.moduleDataProvider,
|
||||||
|
projectEnvironment,
|
||||||
|
librariesScope,
|
||||||
|
projectEnvironment.getPackagePartProvider(librariesScope),
|
||||||
|
languageVersionSettings,
|
||||||
|
registerExtraComponents = {},
|
||||||
|
)
|
||||||
|
return libraryList
|
||||||
|
}
|
||||||
|
|
||||||
val commonRawFir = commonSession?.buildFirFromKtFiles(commonKtFiles)
|
private fun buildResolveAndCheckFir(
|
||||||
|
session: FirSession,
|
||||||
|
ktFiles: List<KtFile>,
|
||||||
|
diagnosticsReporter: BaseDiagnosticsCollector
|
||||||
|
): ModuleCompilerAnalyzedOutput {
|
||||||
val rawFir = session.buildFirFromKtFiles(ktFiles)
|
val rawFir = session.buildFirFromKtFiles(ktFiles)
|
||||||
|
|
||||||
commonSession?.apply {
|
|
||||||
val (commonScopeSession, commonFir) = runResolution(commonRawFir!!)
|
|
||||||
runCheckers(commonScopeSession, commonFir, diagnosticsReporter)
|
|
||||||
}
|
|
||||||
|
|
||||||
val (scopeSession, fir) = session.runResolution(rawFir)
|
val (scopeSession, fir) = session.runResolution(rawFir)
|
||||||
session.runCheckers(scopeSession, fir, diagnosticsReporter)
|
session.runCheckers(scopeSession, fir, diagnosticsReporter)
|
||||||
|
return ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
|
||||||
return if (syntaxErrors || diagnosticsReporter.hasErrors) null else ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompilationContext.createComponentsForIncrementalCompilation(
|
private fun CompilationContext.createComponentsForIncrementalCompilation(
|
||||||
|
|||||||
+149
-129
@@ -19,7 +19,6 @@ import com.intellij.psi.search.GlobalSearchScope
|
|||||||
import com.intellij.util.io.URLUtil
|
import com.intellij.util.io.URLUtil
|
||||||
import org.jetbrains.kotlin.KtSourceFile
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.KtVirtualFileSourceFile
|
import org.jetbrains.kotlin.KtVirtualFileSourceFile
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl
|
import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl
|
||||||
@@ -44,7 +43,9 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
|||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
|
import org.jetbrains.kotlin.fir.BinaryModuleData
|
||||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
||||||
|
import org.jetbrains.kotlin.fir.FirModuleDataImpl
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
||||||
@@ -52,10 +53,10 @@ import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
|
|||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
|
||||||
import org.jetbrains.kotlin.fir.pipeline.*
|
import org.jetbrains.kotlin.fir.pipeline.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper
|
import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory
|
||||||
|
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
||||||
import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext
|
import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
||||||
@@ -71,16 +72,14 @@ import org.jetbrains.kotlin.modules.TargetId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
|
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.LinkedHashSet
|
import kotlin.reflect.KFunction2
|
||||||
|
|
||||||
private const val kotlinFileExtensionWithDot = ".${KotlinFileType.EXTENSION}"
|
private const val kotlinFileExtensionWithDot = ".${KotlinFileType.EXTENSION}"
|
||||||
private const val javaFileExtensionWithDot = ".${JavaFileType.DEFAULT_EXTENSION}"
|
private const val javaFileExtensionWithDot = ".${JavaFileType.DEFAULT_EXTENSION}"
|
||||||
@@ -105,14 +104,6 @@ fun compileModulesUsingFrontendIrAndLightTree(
|
|||||||
"ATTENTION!\n This build uses experimental K2 compiler: \n -Xuse-k2"
|
"ATTENTION!\n This build uses experimental K2 compiler: \n -Xuse-k2"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (compilerConfiguration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) {
|
|
||||||
messageCollector.report(
|
|
||||||
CompilerMessageSeverity.ERROR,
|
|
||||||
"K2 compiler does not support multi-platform projects yet, so please remove -Xuse-k2 flag"
|
|
||||||
)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val outputs = mutableListOf<GenerationState>()
|
val outputs = mutableListOf<GenerationState>()
|
||||||
var mainClassFqName: FqName? = null
|
var mainClassFqName: FqName? = null
|
||||||
|
|
||||||
@@ -148,7 +139,7 @@ fun compileModulesUsingFrontendIrAndLightTree(
|
|||||||
|
|
||||||
// TODO: consider what to do if many modules has main classes
|
// TODO: consider what to do if many modules has main classes
|
||||||
if (mainClassFqName == null && moduleConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
if (mainClassFqName == null && moduleConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
||||||
mainClassFqName = findMainClass(analysisResults.fir)
|
mainClassFqName = findMainClass(analysisResults.platformOutput.fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diagnosticsReporter.hasErrors) {
|
if (diagnosticsReporter.hasErrors) {
|
||||||
@@ -225,7 +216,7 @@ fun collectSources(
|
|||||||
|
|
||||||
fun convertAnalyzedFirToIr(
|
fun convertAnalyzedFirToIr(
|
||||||
input: ModuleCompilerInput,
|
input: ModuleCompilerInput,
|
||||||
analysisResults: ModuleCompilerAnalyzedOutput,
|
analysisResults: FirResult,
|
||||||
environment: ModuleCompilerEnvironment
|
environment: ModuleCompilerEnvironment
|
||||||
): ModuleCompilerIrBackendInput {
|
): ModuleCompilerIrBackendInput {
|
||||||
val extensions = JvmFir2IrExtensions(input.configuration, JvmIrDeserializerImpl(), JvmIrMangler)
|
val extensions = JvmFir2IrExtensions(input.configuration, JvmIrDeserializerImpl(), JvmIrMangler)
|
||||||
@@ -237,7 +228,7 @@ fun convertAnalyzedFirToIr(
|
|||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
val linkViaSignatures = input.configuration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
|
val linkViaSignatures = input.configuration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
|
||||||
val (irModuleFragment, components, pluginContext) =
|
val (irModuleFragment, components, pluginContext) =
|
||||||
analysisResults.convertToIr(extensions, irGenerationExtensions, linkViaSignatures)
|
analysisResults.convertToIrAndActualize(extensions, irGenerationExtensions, linkViaSignatures)
|
||||||
|
|
||||||
return ModuleCompilerIrBackendInput(
|
return ModuleCompilerIrBackendInput(
|
||||||
input.targetId,
|
input.targetId,
|
||||||
@@ -246,7 +237,7 @@ fun convertAnalyzedFirToIr(
|
|||||||
irModuleFragment,
|
irModuleFragment,
|
||||||
components.symbolTable,
|
components.symbolTable,
|
||||||
components,
|
components,
|
||||||
analysisResults.session,
|
analysisResults.platformOutput.session,
|
||||||
pluginContext
|
pluginContext
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -310,73 +301,158 @@ fun compileModuleToAnalyzedFir(
|
|||||||
incrementalExcludesScope: AbstractProjectFileSearchScope?,
|
incrementalExcludesScope: AbstractProjectFileSearchScope?,
|
||||||
diagnosticsReporter: DiagnosticReporter,
|
diagnosticsReporter: DiagnosticReporter,
|
||||||
performanceManager: CommonCompilerPerformanceManager?
|
performanceManager: CommonCompilerPerformanceManager?
|
||||||
): ModuleCompilerAnalyzedOutput {
|
): FirResult {
|
||||||
var sourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.platformSources)
|
val languageVersionSettings = input.configuration.languageVersionSettings
|
||||||
val sessionProvider = FirProjectSessionProvider()
|
val projectEnvironment = environment.projectEnvironment
|
||||||
val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
val moduleConfiguration = input.configuration
|
||||||
|
val isMppEnabled = languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||||
|
val sourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.platformSources)
|
||||||
|
|
||||||
val commonSession = runIf(
|
val commonSourcesScope: AbstractProjectFileSearchScope?
|
||||||
input.commonSources.isNotEmpty() && input.configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
val platformSourcesScope: AbstractProjectFileSearchScope
|
||||||
) {
|
if (isMppEnabled) {
|
||||||
val commonSourcesScope = environment.projectEnvironment.getSearchScopeBySourceFiles(input.commonSources)
|
commonSourcesScope = projectEnvironment.getSearchScopeBySourceFiles(input.commonSources)
|
||||||
sourcesScope -= commonSourcesScope
|
platformSourcesScope = sourcesScope - commonSourcesScope
|
||||||
createSession(
|
} else {
|
||||||
"${input.targetId.name}-common",
|
commonSourcesScope = null
|
||||||
input.commonPlatform,
|
platformSourcesScope = sourcesScope
|
||||||
input.configuration,
|
}
|
||||||
environment.projectEnvironment,
|
|
||||||
commonSourcesScope,
|
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
|
||||||
CommonPlatformAnalyzerServices,
|
val commonProviderAndScopeForIncrementalCompilation = runIf(isMppEnabled) {
|
||||||
sessionProvider,
|
createContextForIncrementalCompilation(
|
||||||
|
moduleConfiguration,
|
||||||
|
projectEnvironment,
|
||||||
|
commonSourcesScope!!,
|
||||||
previousStepsSymbolProviders,
|
previousStepsSymbolProviders,
|
||||||
incrementalExcludesScope,
|
incrementalExcludesScope
|
||||||
extendedAnalysisMode,
|
)?.also { (_, _, precompiledBinariesFileScope) ->
|
||||||
needRegisterJavaElementFinder = false
|
precompiledBinariesFileScope?.let { librariesScope -= it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val platformProviderAndScopeForIncrementalCompilation = createContextForIncrementalCompilation(
|
||||||
|
moduleConfiguration,
|
||||||
|
projectEnvironment,
|
||||||
|
platformSourcesScope,
|
||||||
|
previousStepsSymbolProviders,
|
||||||
|
incrementalExcludesScope
|
||||||
|
)?.also { (_, _, precompiledBinariesFileScope) ->
|
||||||
|
precompiledBinariesFileScope?.let { librariesScope -= it }
|
||||||
|
}
|
||||||
|
|
||||||
|
val sessionProvider = FirProjectSessionProvider()
|
||||||
|
val moduleName = input.targetId.name
|
||||||
|
|
||||||
|
val libraryList = createLibraryListAndSession(moduleName, input.configuration, projectEnvironment, librariesScope, sessionProvider)
|
||||||
|
|
||||||
|
val commonModuleData = runIf(isMppEnabled) {
|
||||||
|
FirModuleDataImpl(
|
||||||
|
Name.identifier("${moduleName}-common"),
|
||||||
|
libraryList.regularDependencies,
|
||||||
|
listOf(),
|
||||||
|
libraryList.friendsDependencies,
|
||||||
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
|
JvmPlatformAnalyzerServices
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val platformModuleData = FirModuleDataImpl(
|
||||||
|
Name.identifier(moduleName),
|
||||||
|
libraryList.regularDependencies,
|
||||||
|
listOfNotNull(commonModuleData),
|
||||||
|
libraryList.friendsDependencies,
|
||||||
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
|
JvmPlatformAnalyzerServices
|
||||||
|
)
|
||||||
|
|
||||||
val session = createSession(
|
val extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) }
|
||||||
input.targetId.name,
|
?: emptyList()
|
||||||
input.platform,
|
val lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER)
|
||||||
input.configuration,
|
val enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER)
|
||||||
environment.projectEnvironment,
|
val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
||||||
sourcesScope,
|
val sessionConfigurator: FirSessionConfigurator.() -> Unit = {
|
||||||
JvmPlatformAnalyzerServices,
|
if (extendedAnalysisMode) {
|
||||||
sessionProvider,
|
registerExtendedCommonCheckers()
|
||||||
previousStepsSymbolProviders,
|
|
||||||
incrementalExcludesScope,
|
|
||||||
extendedAnalysisMode,
|
|
||||||
needRegisterJavaElementFinder = true
|
|
||||||
) {
|
|
||||||
if (commonSession != null) {
|
|
||||||
sourceDependsOnDependencies(listOf(commonSession.moduleData))
|
|
||||||
}
|
}
|
||||||
friendDependencies(input.configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
|
||||||
sourceFriendsDependencies(input.friendFirModules)
|
|
||||||
}
|
}
|
||||||
|
val javaSourcesScope = projectEnvironment.getSearchScopeForProjectJavaSources()
|
||||||
|
|
||||||
|
val commonSession = runIf(isMppEnabled) {
|
||||||
|
FirJvmSessionFactory.createModuleBasedSession(
|
||||||
|
commonModuleData!!,
|
||||||
|
sessionProvider,
|
||||||
|
javaSourcesScope,
|
||||||
|
projectEnvironment,
|
||||||
|
commonProviderAndScopeForIncrementalCompilation,
|
||||||
|
extensionRegistrars,
|
||||||
|
languageVersionSettings,
|
||||||
|
lookupTracker,
|
||||||
|
enumWhenTracker,
|
||||||
|
needRegisterJavaElementFinder = true,
|
||||||
|
registerExtraComponents = {},
|
||||||
|
sessionConfigurator,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val platformSession = FirJvmSessionFactory.createModuleBasedSession(
|
||||||
|
platformModuleData,
|
||||||
|
sessionProvider,
|
||||||
|
javaSourcesScope,
|
||||||
|
projectEnvironment,
|
||||||
|
platformProviderAndScopeForIncrementalCompilation,
|
||||||
|
extensionRegistrars,
|
||||||
|
languageVersionSettings,
|
||||||
|
lookupTracker,
|
||||||
|
enumWhenTracker,
|
||||||
|
needRegisterJavaElementFinder = true,
|
||||||
|
registerExtraComponents = {},
|
||||||
|
sessionConfigurator
|
||||||
|
)
|
||||||
|
|
||||||
val countFilesAndLines = if (performanceManager == null) null else performanceManager::addSourcesStats
|
val countFilesAndLines = if (performanceManager == null) null else performanceManager::addSourcesStats
|
||||||
|
val commonOutput = commonSession?.let { buildResolveAndCheckFir(it, input.commonSources, diagnosticsReporter, countFilesAndLines) }
|
||||||
|
val platformOutput = buildResolveAndCheckFir(platformSession, input.platformSources, diagnosticsReporter, countFilesAndLines)
|
||||||
|
|
||||||
// raw fir
|
return FirResult(platformOutput, commonOutput)
|
||||||
val commonRawFir = commonSession?.buildFirViaLightTree(
|
}
|
||||||
input.commonSources,
|
|
||||||
diagnosticsReporter,
|
fun createLibraryListAndSession(
|
||||||
countFilesAndLines
|
moduleName: String,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
projectEnvironment: AbstractProjectEnvironment,
|
||||||
|
librariesScope: AbstractProjectFileSearchScope,
|
||||||
|
sessionProvider: FirProjectSessionProvider
|
||||||
|
): DependencyListForCliModule {
|
||||||
|
val binaryModuleData = BinaryModuleData.initialize(
|
||||||
|
Name.identifier(moduleName),
|
||||||
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
|
JvmPlatformAnalyzerServices
|
||||||
)
|
)
|
||||||
val rawFir =
|
val libraryList = DependencyListForCliModule.build(binaryModuleData) {
|
||||||
session.buildFirViaLightTree(input.platformSources, diagnosticsReporter, countFilesAndLines)
|
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
|
||||||
|
dependencies(configuration.jvmModularRoots.map { it.toPath() })
|
||||||
// resolution
|
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||||
commonSession?.apply {
|
|
||||||
val (commonScopeSession, commonFir) = runResolution(commonRawFir!!)
|
|
||||||
// TODO: find out what to do with commonFir
|
|
||||||
runCheckers(commonScopeSession, commonFir, environment.diagnosticsReporter)
|
|
||||||
}
|
}
|
||||||
|
FirJvmSessionFactory.createLibrarySession(
|
||||||
|
Name.identifier(moduleName),
|
||||||
|
sessionProvider,
|
||||||
|
libraryList.moduleDataProvider,
|
||||||
|
projectEnvironment,
|
||||||
|
projectEnvironment.getSearchScopeForProjectLibraries(),
|
||||||
|
projectEnvironment.getPackagePartProvider(librariesScope),
|
||||||
|
configuration.languageVersionSettings,
|
||||||
|
registerExtraComponents = {},
|
||||||
|
)
|
||||||
|
return libraryList
|
||||||
|
}
|
||||||
|
|
||||||
val (scopeSession, fir) = session.runResolution(rawFir)
|
private fun buildResolveAndCheckFir(
|
||||||
// checkers
|
session: FirSession,
|
||||||
session.runCheckers(scopeSession, fir, environment.diagnosticsReporter)
|
ktFiles: Collection<KtSourceFile>,
|
||||||
|
diagnosticsReporter: DiagnosticReporter,
|
||||||
|
countFilesAndLines: KFunction2<Int, Int, Unit>?
|
||||||
|
): ModuleCompilerAnalyzedOutput {
|
||||||
|
val firFiles = session.buildFirViaLightTree(ktFiles, diagnosticsReporter, countFilesAndLines)
|
||||||
|
val (scopeSession, fir) = session.runResolution(firFiles)
|
||||||
|
session.runCheckers(scopeSession, fir, diagnosticsReporter)
|
||||||
return ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
|
return ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,63 +489,7 @@ fun writeOutputs(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createSession(
|
fun createContextForIncrementalCompilation(
|
||||||
name: String,
|
|
||||||
platform: TargetPlatform,
|
|
||||||
moduleConfiguration: CompilerConfiguration,
|
|
||||||
projectEnvironment: AbstractProjectEnvironment,
|
|
||||||
sourceScope: AbstractProjectFileSearchScope,
|
|
||||||
analyzerServices: PlatformDependentAnalyzerServices,
|
|
||||||
sessionProvider: FirProjectSessionProvider?,
|
|
||||||
previousStepsSymbolProviders: List<FirSymbolProvider>,
|
|
||||||
incrementalExcludesScope: AbstractProjectFileSearchScope?,
|
|
||||||
extendedAnalysisMode: Boolean,
|
|
||||||
needRegisterJavaElementFinder: Boolean,
|
|
||||||
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
|
|
||||||
): FirSession {
|
|
||||||
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
|
|
||||||
|
|
||||||
val providerAndScopeForIncrementalCompilation =
|
|
||||||
createContextForIncrementalCompilation(
|
|
||||||
moduleConfiguration,
|
|
||||||
projectEnvironment,
|
|
||||||
sourceScope,
|
|
||||||
previousStepsSymbolProviders,
|
|
||||||
incrementalExcludesScope
|
|
||||||
)
|
|
||||||
?.also { (_, _, precompiledBinariesFileScope) ->
|
|
||||||
precompiledBinariesFileScope?.let { librariesScope -= it }
|
|
||||||
}
|
|
||||||
|
|
||||||
return FirSessionFactoryHelper.createSessionWithDependencies(
|
|
||||||
Name.identifier(name),
|
|
||||||
platform,
|
|
||||||
analyzerServices,
|
|
||||||
externalSessionProvider = sessionProvider,
|
|
||||||
projectEnvironment,
|
|
||||||
moduleConfiguration.languageVersionSettings,
|
|
||||||
projectEnvironment.getSearchScopeForProjectJavaSources(),
|
|
||||||
librariesScope,
|
|
||||||
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
|
||||||
enumWhenTracker = moduleConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
|
|
||||||
providerAndScopeForIncrementalCompilation,
|
|
||||||
extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) }
|
|
||||||
?: emptyList(),
|
|
||||||
needRegisterJavaElementFinder = needRegisterJavaElementFinder,
|
|
||||||
dependenciesConfigurator = {
|
|
||||||
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
|
|
||||||
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
|
|
||||||
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
|
||||||
dependenciesConfigurator()
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
if (extendedAnalysisMode) {
|
|
||||||
registerExtendedCommonCheckers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createContextForIncrementalCompilation(
|
|
||||||
compilerConfiguration: CompilerConfiguration,
|
compilerConfiguration: CompilerConfiguration,
|
||||||
projectEnvironment: AbstractProjectEnvironment,
|
projectEnvironment: AbstractProjectEnvironment,
|
||||||
sourceScope: AbstractProjectFileSearchScope,
|
sourceScope: AbstractProjectFileSearchScope,
|
||||||
|
|||||||
+22
-77
@@ -9,117 +9,66 @@ import org.jetbrains.kotlin.fir.deserialization.LibraryPathFilter
|
|||||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.deserialization.MultipleModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.MultipleModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
class DependencyListForCliModule(
|
class DependencyListForCliModule(
|
||||||
val platform: TargetPlatform,
|
|
||||||
val analyzerServices: PlatformDependentAnalyzerServices,
|
|
||||||
val regularDependencies: List<FirModuleData>,
|
val regularDependencies: List<FirModuleData>,
|
||||||
val dependsOnDependencies: List<FirModuleData>,
|
val dependsOnDependencies: List<FirModuleData>,
|
||||||
val friendsDependencies: List<FirModuleData>,
|
val friendsDependencies: List<FirModuleData>,
|
||||||
val moduleDataProvider: ModuleDataProvider,
|
val moduleDataProvider: ModuleDataProvider,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
fun createDependencyModuleData(
|
inline fun build(binaryModuleData: BinaryModuleData, init: Builder.() -> Unit = {}): DependencyListForCliModule {
|
||||||
name: Name,
|
return Builder(binaryModuleData).apply(init).build()
|
||||||
platform: TargetPlatform,
|
|
||||||
analyzerServices: PlatformDependentAnalyzerServices
|
|
||||||
): FirModuleData {
|
|
||||||
return FirModuleDataImpl(
|
|
||||||
name,
|
|
||||||
dependencies = emptyList(),
|
|
||||||
dependsOnDependencies = emptyList(),
|
|
||||||
friendDependencies = emptyList(),
|
|
||||||
platform,
|
|
||||||
analyzerServices,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun build(
|
|
||||||
mainModuleName: Name,
|
|
||||||
platform: TargetPlatform,
|
|
||||||
analyzerServices: PlatformDependentAnalyzerServices,
|
|
||||||
init: Builder.() -> Unit = {}
|
|
||||||
): DependencyListForCliModule {
|
|
||||||
return Builder(mainModuleName, platform, analyzerServices).apply(init).build()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Builder(val mainModuleName: Name, val platform: TargetPlatform, val analyzerServices: PlatformDependentAnalyzerServices) {
|
class Builder(val binaryModuleData: BinaryModuleData) {
|
||||||
private fun createData(name: String): FirModuleData = createDependencyModuleData(Name.special(name), platform, analyzerServices)
|
|
||||||
|
|
||||||
private val binaryRegularDependenciesModuleData: FirModuleData = createData("<regular dependencies of $mainModuleName>")
|
|
||||||
private val binaryDependsOnModuleData: FirModuleData = createData("<dependsOn dependencies of $mainModuleName")
|
|
||||||
private val binaryFriendsModuleData: FirModuleData = createData("<friends dependencies of $mainModuleName")
|
|
||||||
|
|
||||||
private val allRegularDependencies = mutableListOf<FirModuleData>()
|
private val allRegularDependencies = mutableListOf<FirModuleData>()
|
||||||
private val allFriendsDependencies = mutableListOf<FirModuleData>()
|
private val allFriendsDependencies = mutableListOf<FirModuleData>()
|
||||||
private val allDependsOnDependencies = mutableListOf<FirModuleData>()
|
private val allDependsOnDependencies = mutableListOf<FirModuleData>()
|
||||||
|
|
||||||
private val filtersMap: Map<FirModuleData, MutableSet<Path>> =
|
private val filtersMap: Map<FirModuleData, MutableSet<Path>> =
|
||||||
listOf(
|
listOf(
|
||||||
binaryDependsOnModuleData,
|
binaryModuleData.dependsOn,
|
||||||
binaryFriendsModuleData,
|
binaryModuleData.friends,
|
||||||
binaryRegularDependenciesModuleData
|
binaryModuleData.regular
|
||||||
).map { it to mutableSetOf<Path>() }.toMap()
|
).associateWith { mutableSetOf() }
|
||||||
|
|
||||||
fun dependency(vararg path: Path) {
|
fun dependency(vararg path: Path) {
|
||||||
filtersMap.getValue(binaryRegularDependenciesModuleData) += path
|
filtersMap.getValue(binaryModuleData.regular) += path
|
||||||
}
|
|
||||||
|
|
||||||
fun friendDependency(vararg path: Path) {
|
|
||||||
filtersMap.getValue(binaryFriendsModuleData) += path
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dependsOnDependency(vararg path: Path) {
|
|
||||||
filtersMap.getValue(binaryDependsOnModuleData) += path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dependency(vararg path: String) {
|
fun dependency(vararg path: String) {
|
||||||
path.mapTo(filtersMap.getValue(binaryRegularDependenciesModuleData)) { Paths.get(it) }
|
path.mapTo(filtersMap.getValue(binaryModuleData.regular)) { Paths.get(it) }
|
||||||
}
|
|
||||||
|
|
||||||
fun friendDependency(vararg path: String) {
|
|
||||||
path.mapTo(filtersMap.getValue(binaryFriendsModuleData)) { Paths.get(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun dependsOnDependency(vararg path: String) {
|
|
||||||
path.mapTo(filtersMap.getValue(binaryDependsOnModuleData)) { Paths.get(it) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("dependenciesString")
|
@JvmName("dependenciesString")
|
||||||
fun dependencies(paths: Collection<String>) {
|
fun dependencies(paths: Collection<String>) {
|
||||||
paths.mapTo(filtersMap.getValue(binaryRegularDependenciesModuleData)) { Paths.get(it) }
|
paths.mapTo(filtersMap.getValue(binaryModuleData.regular)) { Paths.get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("friendDependenciesString")
|
@JvmName("friendDependenciesString")
|
||||||
fun friendDependencies(paths: Collection<String>) {
|
fun friendDependencies(paths: Collection<String>) {
|
||||||
paths.mapTo(filtersMap.getValue(binaryFriendsModuleData)) { Paths.get(it) }
|
paths.mapTo(filtersMap.getValue(binaryModuleData.friends)) { Paths.get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("dependsOnDependenciesString")
|
@JvmName("dependsOnDependenciesString")
|
||||||
fun dependsOnDependencies(paths: Collection<String>) {
|
fun dependsOnDependencies(paths: Collection<String>) {
|
||||||
paths.mapTo(filtersMap.getValue(binaryDependsOnModuleData)) { Paths.get(it) }
|
paths.mapTo(filtersMap.getValue(binaryModuleData.dependsOn)) { Paths.get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dependencies(paths: Collection<Path>) {
|
fun dependencies(paths: Collection<Path>) {
|
||||||
filtersMap.getValue(binaryRegularDependenciesModuleData) += paths
|
filtersMap.getValue(binaryModuleData.regular) += paths
|
||||||
}
|
}
|
||||||
|
|
||||||
fun friendDependencies(paths: Collection<Path>) {
|
fun friendDependencies(paths: Collection<Path>) {
|
||||||
filtersMap.getValue(binaryFriendsModuleData) += paths
|
filtersMap.getValue(binaryModuleData.friends) += paths
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dependsOnDependencies(paths: Collection<Path>) {
|
fun dependsOnDependencies(paths: Collection<Path>) {
|
||||||
filtersMap.getValue(binaryDependsOnModuleData) += paths
|
filtersMap.getValue(binaryModuleData.dependsOn) += paths
|
||||||
}
|
|
||||||
|
|
||||||
fun sourceDependencies(modules: Collection<FirModuleData>) {
|
|
||||||
allRegularDependencies += modules
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sourceFriendsDependencies(modules: Collection<FirModuleData>) {
|
fun sourceFriendsDependencies(modules: Collection<FirModuleData>) {
|
||||||
@@ -136,29 +85,25 @@ class DependencyListForCliModule(
|
|||||||
.mapValues { LibraryPathFilter.LibraryList(it.value) }
|
.mapValues { LibraryPathFilter.LibraryList(it.value) }
|
||||||
.toMutableMap()
|
.toMutableMap()
|
||||||
|
|
||||||
allRegularDependencies += binaryRegularDependenciesModuleData
|
allRegularDependencies += binaryModuleData.regular
|
||||||
if (pathFiltersMap.isEmpty()) {
|
if (pathFiltersMap.isEmpty()) {
|
||||||
return DependencyListForCliModule(
|
return DependencyListForCliModule(
|
||||||
platform,
|
|
||||||
analyzerServices,
|
|
||||||
allRegularDependencies,
|
allRegularDependencies,
|
||||||
dependsOnDependencies = allDependsOnDependencies,
|
dependsOnDependencies = allDependsOnDependencies,
|
||||||
friendsDependencies = allFriendsDependencies,
|
friendsDependencies = allFriendsDependencies,
|
||||||
SingleModuleDataProvider(binaryRegularDependenciesModuleData)
|
SingleModuleDataProvider(binaryModuleData.regular)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (binaryFriendsModuleData in pathFiltersMap) {
|
if (binaryModuleData.friends in pathFiltersMap) {
|
||||||
allFriendsDependencies += binaryFriendsModuleData
|
allFriendsDependencies += binaryModuleData.friends
|
||||||
}
|
}
|
||||||
if (binaryDependsOnModuleData in pathFiltersMap) {
|
if (binaryModuleData.dependsOn in pathFiltersMap) {
|
||||||
allDependsOnDependencies += binaryDependsOnModuleData
|
allDependsOnDependencies += binaryModuleData.dependsOn
|
||||||
}
|
}
|
||||||
|
|
||||||
val moduleDataProvider = MultipleModuleDataProvider(pathFiltersMap)
|
val moduleDataProvider = MultipleModuleDataProvider(pathFiltersMap)
|
||||||
pathFiltersMap.putIfAbsent(binaryRegularDependenciesModuleData, LibraryPathFilter.TakeAll)
|
pathFiltersMap.putIfAbsent(binaryModuleData.regular, LibraryPathFilter.TakeAll)
|
||||||
return DependencyListForCliModule(
|
return DependencyListForCliModule(
|
||||||
platform,
|
|
||||||
analyzerServices,
|
|
||||||
allRegularDependencies,
|
allRegularDependencies,
|
||||||
allDependsOnDependencies,
|
allDependsOnDependencies,
|
||||||
allFriendsDependencies,
|
allFriendsDependencies,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
|||||||
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
|
||||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||||
@@ -17,34 +18,65 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler
|
|||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
|
||||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
|
||||||
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
|
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
|
|
||||||
|
data class FirResult(
|
||||||
|
val platformOutput: ModuleCompilerAnalyzedOutput,
|
||||||
|
val commonOutput: ModuleCompilerAnalyzedOutput?
|
||||||
|
)
|
||||||
|
|
||||||
data class ModuleCompilerAnalyzedOutput(
|
data class ModuleCompilerAnalyzedOutput(
|
||||||
val session: FirSession,
|
val session: FirSession,
|
||||||
val scopeSession: ScopeSession,
|
val scopeSession: ScopeSession,
|
||||||
val fir: List<FirFile>
|
val fir: List<FirFile>
|
||||||
)
|
)
|
||||||
|
|
||||||
fun ModuleCompilerAnalyzedOutput.convertToIr(
|
fun FirResult.convertToIrAndActualize(
|
||||||
fir2IrExtensions: Fir2IrExtensions,
|
fir2IrExtensions: Fir2IrExtensions,
|
||||||
irGeneratorExtensions: Collection<IrGenerationExtension>,
|
irGeneratorExtensions: Collection<IrGenerationExtension>,
|
||||||
linkViaSignatures: Boolean
|
linkViaSignatures: Boolean,
|
||||||
): Fir2IrResult {
|
): Fir2IrResult {
|
||||||
val commonFirFiles = session.moduleData.dependsOnDependencies
|
val result: Fir2IrResult
|
||||||
.map { it.session }
|
|
||||||
.filter { it.kind == FirSession.Kind.Source }
|
|
||||||
.flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() }
|
|
||||||
|
|
||||||
|
if (commonOutput != null) {
|
||||||
|
val commonIrOutput = commonOutput.convertToIr(
|
||||||
|
fir2IrExtensions,
|
||||||
|
irGeneratorExtensions,
|
||||||
|
linkViaSignatures = true,
|
||||||
|
dependentComponents = emptyList()
|
||||||
|
)
|
||||||
|
result = platformOutput.convertToIr(
|
||||||
|
fir2IrExtensions,
|
||||||
|
irGeneratorExtensions,
|
||||||
|
linkViaSignatures = true,
|
||||||
|
dependentComponents = listOf(commonIrOutput.components)
|
||||||
|
)
|
||||||
|
// TODO: implement IR actualization
|
||||||
|
} else {
|
||||||
|
result = platformOutput.convertToIr(
|
||||||
|
fir2IrExtensions,
|
||||||
|
irGeneratorExtensions,
|
||||||
|
linkViaSignatures = linkViaSignatures,
|
||||||
|
dependentComponents = emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ModuleCompilerAnalyzedOutput.convertToIr(
|
||||||
|
fir2IrExtensions: Fir2IrExtensions,
|
||||||
|
irGeneratorExtensions: Collection<IrGenerationExtension>,
|
||||||
|
linkViaSignatures: Boolean,
|
||||||
|
dependentComponents: List<Fir2IrComponents>
|
||||||
|
): Fir2IrResult {
|
||||||
if (linkViaSignatures) {
|
if (linkViaSignatures) {
|
||||||
val signaturer = JvmIdSignatureDescriptor(mangler = JvmDescriptorMangler(mainDetector = null))
|
val signaturer = JvmIdSignatureDescriptor(mangler = JvmDescriptorMangler(mainDetector = null))
|
||||||
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
|
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
|
||||||
session, scopeSession, fir + commonFirFiles,
|
session, scopeSession, fir,
|
||||||
session.languageVersionSettings, signaturer, fir2IrExtensions,
|
session.languageVersionSettings, signaturer, fir2IrExtensions,
|
||||||
FirJvmKotlinMangler(session),
|
FirJvmKotlinMangler(session),
|
||||||
JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
|
JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
|
||||||
@@ -55,7 +87,7 @@ fun ModuleCompilerAnalyzedOutput.convertToIr(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return Fir2IrConverter.createModuleFragmentWithoutSignatures(
|
return Fir2IrConverter.createModuleFragmentWithoutSignatures(
|
||||||
session, scopeSession, fir + commonFirFiles,
|
session, scopeSession, fir,
|
||||||
session.languageVersionSettings, fir2IrExtensions,
|
session.languageVersionSettings, fir2IrExtensions,
|
||||||
FirJvmKotlinMangler(session),
|
FirJvmKotlinMangler(session),
|
||||||
JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
|
JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
|
||||||
|
|||||||
+2
-7
@@ -6,17 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.fir.session
|
package org.jetbrains.kotlin.fir.session
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
|
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerJsCheckers
|
|
||||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirSwitchableExtensionDeclarationsSymbolProvider
|
import org.jetbrains.kotlin.fir.extensions.FirSwitchableExtensionDeclarationsSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.java.FirCliSession
|
import org.jetbrains.kotlin.fir.java.FirCliSession
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
@@ -25,7 +21,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProv
|
|||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirLibrarySessionProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirLibrarySessionProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
|
|
||||||
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
|
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -54,12 +49,12 @@ abstract class FirAbstractSessionFactory {
|
|||||||
val kotlinScopeProvider = createKotlinScopeProvider.invoke()
|
val kotlinScopeProvider = createKotlinScopeProvider.invoke()
|
||||||
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
||||||
|
|
||||||
val builtinsModuleData = DependencyListForCliModule.createDependencyModuleData(
|
val builtinsModuleData = BinaryModuleData.createDependencyModuleData(
|
||||||
Name.special("<builtins of ${mainModuleName.asString()}"),
|
Name.special("<builtins of ${mainModuleName.asString()}"),
|
||||||
moduleDataProvider.platform,
|
moduleDataProvider.platform,
|
||||||
moduleDataProvider.analyzerServices,
|
moduleDataProvider.analyzerServices,
|
||||||
)
|
)
|
||||||
builtinsModuleData.bindSession(this@session)
|
builtinsModuleData.bindSession(this)
|
||||||
|
|
||||||
val providers = createProviders(this, builtinsModuleData, kotlinScopeProvider)
|
val providers = createProviders(this, builtinsModuleData, kotlinScopeProvider)
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.*
|
|||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
@@ -29,7 +30,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
|
|||||||
fun createLibrarySession(
|
fun createLibrarySession(
|
||||||
mainModuleName: Name,
|
mainModuleName: Name,
|
||||||
sessionProvider: FirProjectSessionProvider,
|
sessionProvider: FirProjectSessionProvider,
|
||||||
dependencyList: DependencyListForCliModule,
|
moduleDataProvider: ModuleDataProvider,
|
||||||
projectEnvironment: AbstractProjectEnvironment,
|
projectEnvironment: AbstractProjectEnvironment,
|
||||||
scope: AbstractProjectFileSearchScope,
|
scope: AbstractProjectFileSearchScope,
|
||||||
packagePartProvider: PackagePartProvider,
|
packagePartProvider: PackagePartProvider,
|
||||||
@@ -39,7 +40,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
|
|||||||
return createLibrarySession(
|
return createLibrarySession(
|
||||||
mainModuleName,
|
mainModuleName,
|
||||||
sessionProvider,
|
sessionProvider,
|
||||||
dependencyList.moduleDataProvider,
|
moduleDataProvider,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
registerExtraComponents = {
|
registerExtraComponents = {
|
||||||
it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver())
|
it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver())
|
||||||
@@ -50,15 +51,20 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
|
|||||||
listOf(
|
listOf(
|
||||||
JvmClassFileBasedSymbolProvider(
|
JvmClassFileBasedSymbolProvider(
|
||||||
session,
|
session,
|
||||||
dependencyList.moduleDataProvider,
|
moduleDataProvider,
|
||||||
kotlinScopeProvider,
|
kotlinScopeProvider,
|
||||||
packagePartProvider,
|
packagePartProvider,
|
||||||
projectEnvironment.getKotlinClassFinder(scope),
|
projectEnvironment.getKotlinClassFinder(scope),
|
||||||
projectEnvironment.getFirJavaFacade(session, dependencyList.moduleDataProvider.allModuleData.last(), scope)
|
projectEnvironment.getFirJavaFacade(session, moduleDataProvider.allModuleData.last(), scope)
|
||||||
),
|
),
|
||||||
FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
|
FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
|
||||||
FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
|
FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
|
||||||
OptionalAnnotationClassesProvider(session, dependencyList.moduleDataProvider, kotlinScopeProvider, packagePartProvider)
|
OptionalAnnotationClassesProvider(
|
||||||
|
session,
|
||||||
|
moduleDataProvider,
|
||||||
|
kotlinScopeProvider,
|
||||||
|
packagePartProvider
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
|
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
|
||||||
@@ -24,11 +25,10 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
|
|||||||
mainModuleName: Name,
|
mainModuleName: Name,
|
||||||
resolvedLibraries: List<KotlinResolvedLibrary>,
|
resolvedLibraries: List<KotlinResolvedLibrary>,
|
||||||
sessionProvider: FirProjectSessionProvider,
|
sessionProvider: FirProjectSessionProvider,
|
||||||
dependencyListForCliModule: DependencyListForCliModule,
|
moduleDataProvider: ModuleDataProvider,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
registerExtraComponents: ((FirSession) -> Unit) = {},
|
registerExtraComponents: ((FirSession) -> Unit) = {},
|
||||||
): FirSession {
|
): FirSession {
|
||||||
val moduleDataProvider = dependencyListForCliModule.moduleDataProvider
|
|
||||||
return createLibrarySession(
|
return createLibrarySession(
|
||||||
mainModuleName,
|
mainModuleName,
|
||||||
sessionProvider,
|
sessionProvider,
|
||||||
|
|||||||
+5
-4
@@ -38,13 +38,14 @@ object FirSessionFactoryHelper {
|
|||||||
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
|
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
|
||||||
noinline sessionConfigurator: FirSessionConfigurator.() -> Unit = {},
|
noinline sessionConfigurator: FirSessionConfigurator.() -> Unit = {},
|
||||||
): FirSession {
|
): FirSession {
|
||||||
val dependencyList = DependencyListForCliModule.build(moduleName, platform, analyzerServices, dependenciesConfigurator)
|
val binaryModuleData = BinaryModuleData.initialize(moduleName, platform, analyzerServices)
|
||||||
|
val dependencyList = DependencyListForCliModule.build(binaryModuleData, init = dependenciesConfigurator)
|
||||||
val sessionProvider = externalSessionProvider ?: FirProjectSessionProvider()
|
val sessionProvider = externalSessionProvider ?: FirProjectSessionProvider()
|
||||||
val packagePartProvider = projectEnvironment.getPackagePartProvider(librariesScope)
|
val packagePartProvider = projectEnvironment.getPackagePartProvider(librariesScope)
|
||||||
FirJvmSessionFactory.createLibrarySession(
|
FirJvmSessionFactory.createLibrarySession(
|
||||||
moduleName,
|
moduleName,
|
||||||
sessionProvider,
|
sessionProvider,
|
||||||
dependencyList,
|
dependencyList.moduleDataProvider,
|
||||||
projectEnvironment,
|
projectEnvironment,
|
||||||
librariesScope,
|
librariesScope,
|
||||||
packagePartProvider,
|
packagePartProvider,
|
||||||
@@ -57,8 +58,8 @@ object FirSessionFactoryHelper {
|
|||||||
dependencyList.regularDependencies,
|
dependencyList.regularDependencies,
|
||||||
dependencyList.dependsOnDependencies,
|
dependencyList.dependsOnDependencies,
|
||||||
dependencyList.friendsDependencies,
|
dependencyList.friendsDependencies,
|
||||||
dependencyList.platform,
|
platform,
|
||||||
dependencyList.analyzerServices
|
analyzerServices
|
||||||
)
|
)
|
||||||
return FirJvmSessionFactory.createModuleBasedSession(
|
return FirJvmSessionFactory.createModuleBasedSession(
|
||||||
mainModuleData,
|
mainModuleData,
|
||||||
|
|||||||
+10
-20
@@ -48,7 +48,9 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter
|
|||||||
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
|
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.moduleData
|
import org.jetbrains.kotlin.fir.moduleData
|
||||||
|
import org.jetbrains.kotlin.fir.pipeline.FirResult
|
||||||
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
|
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
|
||||||
|
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
||||||
@@ -203,7 +205,7 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
|
|
||||||
var incrementalExcludesScope: AbstractProjectFileSearchScope? = null
|
var incrementalExcludesScope: AbstractProjectFileSearchScope? = null
|
||||||
|
|
||||||
fun firIncrementalCycle(): ModuleCompilerAnalyzedOutput? {
|
fun firIncrementalCycle(): FirResult? {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
val compilerInput = ModuleCompilerInput(
|
val compilerInput = ModuleCompilerInput(
|
||||||
@@ -229,7 +231,7 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
|
|
||||||
// TODO: consider what to do if many compilations find a main class
|
// TODO: consider what to do if many compilations find a main class
|
||||||
if (mainClassFqName == null && configuration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
if (mainClassFqName == null && configuration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
||||||
mainClassFqName = findMainClass(analysisResults.fir)
|
mainClassFqName = findMainClass(analysisResults.platformOutput.fir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: switch the whole IC to KtSourceFile instead of FIle
|
// TODO: switch the whole IC to KtSourceFile instead of FIle
|
||||||
@@ -273,19 +275,7 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
val extensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler)
|
val extensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler)
|
||||||
val irGenerationExtensions =
|
val irGenerationExtensions =
|
||||||
(projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) }.orEmpty()
|
(projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) }.orEmpty()
|
||||||
val allCommonFirFiles = cycleResult.session.moduleData.dependsOnDependencies
|
val platformIrOutput = cycleResult.convertToIrAndActualize(extensions, irGenerationExtensions, linkViaSignatures = false)
|
||||||
.map { it.session }
|
|
||||||
.filter { it.kind == FirSession.Kind.Source }
|
|
||||||
.flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() }
|
|
||||||
|
|
||||||
val (irModuleFragment, components, pluginContext) = Fir2IrConverter.createModuleFragmentWithoutSignatures(
|
|
||||||
cycleResult.session, cycleResult.scopeSession, cycleResult.fir + allCommonFirFiles,
|
|
||||||
cycleResult.session.languageVersionSettings, extensions,
|
|
||||||
FirJvmKotlinMangler(cycleResult.session), JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
|
|
||||||
Fir2IrJvmSpecialAnnotationSymbolProvider(),
|
|
||||||
irGenerationExtensions,
|
|
||||||
kotlinBuiltIns = DefaultBuiltIns.Instance // TODO: consider passing externally
|
|
||||||
)
|
|
||||||
|
|
||||||
performanceManager?.notifyIRTranslationFinished()
|
performanceManager?.notifyIRTranslationFinished()
|
||||||
|
|
||||||
@@ -293,11 +283,11 @@ class IncrementalFirJvmCompilerRunner(
|
|||||||
targetId,
|
targetId,
|
||||||
configuration,
|
configuration,
|
||||||
extensions,
|
extensions,
|
||||||
irModuleFragment,
|
platformIrOutput.irModuleFragment,
|
||||||
components.symbolTable,
|
platformIrOutput.components.symbolTable,
|
||||||
components,
|
platformIrOutput.components,
|
||||||
cycleResult.session,
|
cycleResult.platformOutput.session,
|
||||||
pluginContext
|
platformIrOutput.pluginContext
|
||||||
)
|
)
|
||||||
|
|
||||||
val codegenOutput = generateCodeFromIr(irInput, compilerEnvironment, performanceManager)
|
val codegenOutput = generateCodeFromIr(irInput, compilerEnvironment, performanceManager)
|
||||||
|
|||||||
+86
-80
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.backend.FirMetadataSource
|
|||||||
import org.jetbrains.kotlin.fir.backend.jvm.makeLocalFirMetadataSerializerForMetadataSource
|
import org.jetbrains.kotlin.fir.backend.jvm.makeLocalFirMetadataSerializerForMetadataSource
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
|
import org.jetbrains.kotlin.fir.pipeline.FirResult
|
||||||
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
|
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
|
||||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
@@ -26,7 +27,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal fun collectNewDirtySources(
|
internal fun collectNewDirtySources(
|
||||||
analysisResults: ModuleCompilerAnalyzedOutput,
|
analysisResults: FirResult,
|
||||||
targetId: TargetId,
|
targetId: TargetId,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
caches: IncrementalJvmCachesManager,
|
caches: IncrementalJvmCachesManager,
|
||||||
@@ -35,96 +36,101 @@ internal fun collectNewDirtySources(
|
|||||||
): LinkedHashSet<File> {
|
): LinkedHashSet<File> {
|
||||||
val changesCollector = ChangesCollector()
|
val changesCollector = ChangesCollector()
|
||||||
val globalSerializationBindings = JvmSerializationBindings()
|
val globalSerializationBindings = JvmSerializationBindings()
|
||||||
analysisResults.fir.forEach {
|
|
||||||
it.accept(object : FirVisitor<Unit, MutableList<MetadataSerializer>>() {
|
|
||||||
|
|
||||||
inline fun withMetadataSerializer(
|
fun visitFirFiles(analyzedOutput: ModuleCompilerAnalyzedOutput) {
|
||||||
metadata: FirMetadataSource,
|
analyzedOutput.fir.forEach {
|
||||||
data: MutableList<MetadataSerializer>,
|
it.accept(object : FirVisitor<Unit, MutableList<MetadataSerializer>>() {
|
||||||
body: (MetadataSerializer) -> Unit
|
inline fun withMetadataSerializer(
|
||||||
) {
|
metadata: FirMetadataSource,
|
||||||
val serializer = makeLocalFirMetadataSerializerForMetadataSource(
|
data: MutableList<MetadataSerializer>,
|
||||||
metadata,
|
body: (MetadataSerializer) -> Unit
|
||||||
analysisResults.session,
|
) {
|
||||||
analysisResults.scopeSession,
|
val serializer = makeLocalFirMetadataSerializerForMetadataSource(
|
||||||
globalSerializationBindings,
|
metadata,
|
||||||
data.lastOrNull(),
|
analyzedOutput.session,
|
||||||
targetId,
|
analyzedOutput.scopeSession,
|
||||||
configuration
|
globalSerializationBindings,
|
||||||
)
|
data.lastOrNull(),
|
||||||
data.push(serializer)
|
targetId,
|
||||||
body(serializer)
|
configuration
|
||||||
data.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitElement(element: FirElement, data: MutableList<MetadataSerializer>) {
|
|
||||||
element.acceptChildren(this, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitRegularClass(regularClass: FirRegularClass, data: MutableList<MetadataSerializer>) {
|
|
||||||
visitClass(regularClass, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: MutableList<MetadataSerializer>) {
|
|
||||||
visitClass(anonymousObject, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFile(file: FirFile, data: MutableList<MetadataSerializer>) {
|
|
||||||
val metadata = FirMetadataSource.File(listOf(file))
|
|
||||||
withMetadataSerializer(metadata, data) {
|
|
||||||
file.acceptChildren(this, data)
|
|
||||||
// TODO: compare package fragments?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableList<MetadataSerializer>) {
|
|
||||||
data.firstOrNull()?.let { serializer ->
|
|
||||||
super.visitFunction(simpleFunction, data)
|
|
||||||
serializer.bindMethodMetadata(
|
|
||||||
FirMetadataSource.Function(simpleFunction),
|
|
||||||
Method(simpleFunction.name.asString(), simpleFunction.computeJvmDescriptor())
|
|
||||||
)
|
)
|
||||||
|
data.push(serializer)
|
||||||
|
body(serializer)
|
||||||
|
data.pop()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitConstructor(constructor: FirConstructor, data: MutableList<MetadataSerializer>) {
|
override fun visitElement(element: FirElement, data: MutableList<MetadataSerializer>) {
|
||||||
super.visitConstructor(constructor, data)
|
element.acceptChildren(this, data)
|
||||||
data.first().bindMethodMetadata(
|
}
|
||||||
FirMetadataSource.Function(constructor),
|
|
||||||
Method(SpecialNames.INIT.asString(), constructor.computeJvmDescriptor(""))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitProperty(property: FirProperty, data: MutableList<MetadataSerializer>) {
|
override fun visitRegularClass(regularClass: FirRegularClass, data: MutableList<MetadataSerializer>) {
|
||||||
property.acceptChildren(this, data)
|
visitClass(regularClass, 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<MetadataSerializer>) {
|
override fun visitAnonymousObject(anonymousObject: FirAnonymousObject, data: MutableList<MetadataSerializer>) {
|
||||||
val metadata = FirMetadataSource.Class(klass)
|
visitClass(anonymousObject, data)
|
||||||
withMetadataSerializer(metadata, data) { serializer ->
|
}
|
||||||
klass.acceptChildren(this, data)
|
|
||||||
serializer.serialize(metadata)?.let { (classProto, nameTable) ->
|
override fun visitFile(file: FirFile, data: MutableList<MetadataSerializer>) {
|
||||||
caches.platformCache.saveFrontendClassToCache(
|
val metadata = FirMetadataSource.File(listOf(file))
|
||||||
klass.classId,
|
withMetadataSerializer(metadata, data) {
|
||||||
classProto as ProtoBuf.Class,
|
file.acceptChildren(this, data)
|
||||||
nameTable,
|
// TODO: compare package fragments?
|
||||||
null, // TODO: !!
|
}
|
||||||
changesCollector
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableList<MetadataSerializer>) {
|
||||||
|
data.firstOrNull()?.let { serializer ->
|
||||||
|
super.visitFunction(simpleFunction, data)
|
||||||
|
serializer.bindMethodMetadata(
|
||||||
|
FirMetadataSource.Function(simpleFunction),
|
||||||
|
Method(simpleFunction.name.asString(), simpleFunction.computeJvmDescriptor())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, mutableListOf())
|
override fun visitConstructor(constructor: FirConstructor, data: MutableList<MetadataSerializer>) {
|
||||||
|
super.visitConstructor(constructor, data)
|
||||||
|
data.first().bindMethodMetadata(
|
||||||
|
FirMetadataSource.Function(constructor),
|
||||||
|
Method(SpecialNames.INIT.asString(), constructor.computeJvmDescriptor(""))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitProperty(property: FirProperty, data: MutableList<MetadataSerializer>) {
|
||||||
|
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<MetadataSerializer>) {
|
||||||
|
val metadata = FirMetadataSource.Class(klass)
|
||||||
|
withMetadataSerializer(metadata, data) { serializer ->
|
||||||
|
klass.acceptChildren(this, data)
|
||||||
|
serializer.serialize(metadata)?.let { (classProto, nameTable) ->
|
||||||
|
caches.platformCache.saveFrontendClassToCache(
|
||||||
|
klass.classId,
|
||||||
|
classProto as ProtoBuf.Class,
|
||||||
|
nameTable,
|
||||||
|
null, // TODO: !!
|
||||||
|
changesCollector
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, mutableListOf())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analysisResults.commonOutput?.let { visitFirFiles(it) }
|
||||||
|
visitFirFiles(analysisResults.platformOutput)
|
||||||
|
|
||||||
val (dirtyLookupSymbols, dirtyClassFqNames, forceRecompile) = changesCollector.getDirtyData(listOf(caches.platformCache), reporter)
|
val (dirtyLookupSymbols, dirtyClassFqNames, forceRecompile) = changesCollector.getDirtyData(listOf(caches.platformCache), reporter)
|
||||||
|
|
||||||
val forceToRecompileFiles = mapClassesFqNamesToFiles(listOf(caches.platformCache), forceRecompile, reporter)
|
val forceToRecompileFiles = mapClassesFqNamesToFiles(listOf(caches.platformCache), forceRecompile, reporter)
|
||||||
|
|||||||
+2
-2
@@ -3,9 +3,9 @@
|
|||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
fun <T> lazy(initializer: () -> T): Lazy<T> = <!UNRESOLVED_REFERENCE!>TODO<!>()
|
fun <T> lazy(initializer: () -> T): Lazy<T> = TODO()
|
||||||
interface Lazy<out T> {
|
interface Lazy<out T> {
|
||||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = <!UNRESOLVED_REFERENCE!>TODO<!>()
|
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
expect class OuterClass {
|
expect class OuterClass {
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ interface J
|
|||||||
|
|
||||||
expect class Foo : I, C, J
|
expect class Foo : I, C, J
|
||||||
|
|
||||||
<!SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>expect class Bar : C()<!>
|
<!SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR!>expect class Bar : C()<!>
|
||||||
|
|
||||||
// MODULE: m2-jvm()()(m1-common)
|
// MODULE: m2-jvm()()(m1-common)
|
||||||
// FILE: jvm.kt
|
// FILE: jvm.kt
|
||||||
|
|||||||
@@ -5,6 +5,16 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test
|
package org.jetbrains.kotlin.test
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
|
import org.jetbrains.kotlin.platform.isCommon
|
||||||
|
import org.jetbrains.kotlin.platform.isJs
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
|
import org.jetbrains.kotlin.platform.konan.isNative
|
||||||
|
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||||
|
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,3 +32,13 @@ private fun computeHomeDirectory(): String {
|
|||||||
val userDir = System.getProperty("user.dir")
|
val userDir = System.getProperty("user.dir")
|
||||||
return File(userDir ?: ".").canonicalPath
|
return File(userDir ?: ".").canonicalPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
|
||||||
|
return when {
|
||||||
|
isJvm() -> JvmPlatformAnalyzerServices
|
||||||
|
isJs() -> JsPlatformAnalyzerServices
|
||||||
|
isNative() -> NativePlatformAnalyzerServices
|
||||||
|
isCommon() -> CommonPlatformAnalyzerServices
|
||||||
|
else -> error("Unknown target platform: $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -41,7 +41,7 @@ class JvmBackendDiagnosticsHandler(testServices: TestServices) : JvmBinaryArtifa
|
|||||||
private fun getKtFiles(module: TestModule): Map<TestFile, KtFile> {
|
private fun getKtFiles(module: TestModule): Map<TestFile, KtFile> {
|
||||||
return when (module.frontendKind) {
|
return when (module.frontendKind) {
|
||||||
FrontendKinds.ClassicFrontend -> testServices.dependencyProvider.getArtifact(module, FrontendKinds.ClassicFrontend).ktFiles
|
FrontendKinds.ClassicFrontend -> testServices.dependencyProvider.getArtifact(module, FrontendKinds.ClassicFrontend).ktFiles
|
||||||
FrontendKinds.FIR -> testServices.dependencyProvider.getArtifact(module, FrontendKinds.FIR).firFiles.entries
|
FrontendKinds.FIR -> testServices.dependencyProvider.getArtifact(module, FrontendKinds.FIR).mainFirFiles.entries
|
||||||
.associate { it.key to (it.value.psi as KtFile) }
|
.associate { it.key to (it.value.psi as KtFile) }
|
||||||
else -> testServices.assertions.fail { "Unknown frontend kind ${module.frontendKind}" }
|
else -> testServices.assertions.fail { "Unknown frontend kind ${module.frontendKind}" }
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-16
@@ -22,25 +22,29 @@ class NoFirCompilationErrorsHandler(testServices: TestServices) : FirAnalysisHan
|
|||||||
get() = listOf(CodegenTestDirectives)
|
get() = listOf(CodegenTestDirectives)
|
||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
var hasError = false
|
for (part in info.partsForDependsOnModules) {
|
||||||
val ignoreErrors = IGNORE_FIR_DIAGNOSTICS in module.directives
|
var hasError = false
|
||||||
for ((firFile, diagnostics) in info.firAnalyzerFacade.runCheckers()) {
|
|
||||||
for (diagnostic in diagnostics) {
|
val ignoreErrors = IGNORE_FIR_DIAGNOSTICS in part.module.directives
|
||||||
if (diagnostic.severity == Severity.ERROR) {
|
for ((firFile, diagnostics) in part.firAnalyzerFacade.runCheckers()) {
|
||||||
hasError = true
|
for (diagnostic in diagnostics) {
|
||||||
if (!ignoreErrors) {
|
if (diagnostic.severity == Severity.ERROR) {
|
||||||
val diagnosticText = RootDiagnosticRendererFactory(diagnostic).render(diagnostic)
|
hasError = true
|
||||||
val range = diagnostic.textRanges.first()
|
if (!ignoreErrors) {
|
||||||
val locationText = firFile.source?.psi?.containingFile?.let { psiFile ->
|
val diagnosticText = RootDiagnosticRendererFactory(diagnostic).render(diagnostic)
|
||||||
PsiDiagnosticUtils.atLocation(psiFile, range)
|
val range = diagnostic.textRanges.first()
|
||||||
} ?: "${firFile.name}:$range"
|
val locationText = firFile.source?.psi?.containingFile?.let { psiFile ->
|
||||||
throw IllegalStateException("${diagnostic.factory.name}: $diagnosticText at $locationText")
|
PsiDiagnosticUtils.atLocation(psiFile, range)
|
||||||
|
} ?: "${firFile.name}:$range"
|
||||||
|
throw IllegalStateException("${diagnostic.factory.name}: $diagnosticText at $locationText")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!hasError && ignoreErrors) {
|
if (!hasError && ignoreErrors) {
|
||||||
assertions.fail { "Test contains $IGNORE_FIR_DIAGNOSTICS directive but no errors was reported. Please remove directive" }
|
assertions.fail { "Test contains $IGNORE_FIR_DIAGNOSTICS directive but no errors was reported. Please remove directive" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.backend.js.KotlinFileSerializedData
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.test.model.BackendKinds
|
import org.jetbrains.kotlin.test.model.BackendKinds
|
||||||
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
||||||
|
|
||||||
@@ -43,6 +42,7 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
|
|||||||
data class JvmIrBackendInput(
|
data class JvmIrBackendInput(
|
||||||
val state: GenerationState,
|
val state: GenerationState,
|
||||||
val codegenFactory: JvmIrCodegenFactory,
|
val codegenFactory: JvmIrCodegenFactory,
|
||||||
|
val dependentInputs: List<JvmIrCodegenFactory.JvmIrBackendInput>,
|
||||||
val backendInput: JvmIrCodegenFactory.JvmIrBackendInput,
|
val backendInput: JvmIrCodegenFactory.JvmIrBackendInput,
|
||||||
val sourceFiles: List<KtSourceFile>
|
val sourceFiles: List<KtSourceFile>
|
||||||
) : IrBackendInput() {
|
) : IrBackendInput() {
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ class JvmIrBackendFacade(
|
|||||||
}
|
}
|
||||||
val state = inputArtifact.state
|
val state = inputArtifact.state
|
||||||
try {
|
try {
|
||||||
inputArtifact.codegenFactory.generateModule(state, inputArtifact.backendInput)
|
inputArtifact.codegenFactory.generateModule(state, inputArtifact.backendInput.last())
|
||||||
} catch (e: BackendException) {
|
} catch (e: BackendException) {
|
||||||
if (CodegenTestDirectives.IGNORE_ERRORS in module.directives) {
|
if (CodegenTestDirectives.IGNORE_ERRORS in module.directives) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
+4
-3
@@ -64,13 +64,14 @@ class ClassicFrontend2IrConverter(
|
|||||||
.diagnosticReporter(DiagnosticReporterFactory.createReporter())
|
.diagnosticReporter(DiagnosticReporterFactory.createReporter())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val convertionResult =
|
val conversionResult =
|
||||||
codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationStateAndFiles(state, psiFiles.values))
|
codegenFactory.convertToIr(CodegenFactory.IrConversionInput.fromGenerationStateAndFiles(state, psiFiles.values))
|
||||||
return IrBackendInput.JvmIrBackendInput(
|
return IrBackendInput.JvmIrBackendInput(
|
||||||
state,
|
state,
|
||||||
codegenFactory,
|
codegenFactory,
|
||||||
convertionResult,
|
dependentInputs = emptyList(),
|
||||||
emptyList()
|
conversionResult,
|
||||||
|
sourceFiles = emptyList()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -69,7 +69,7 @@ class Fir2IrJsResultsConverter(
|
|||||||
val fir2IrExtensions = Fir2IrExtensions.Default
|
val fir2IrExtensions = Fir2IrExtensions.Default
|
||||||
val firFiles = inputArtifact.allFirFiles.values
|
val firFiles = inputArtifact.allFirFiles.values
|
||||||
val (irModuleFragment, components, pluginContext) =
|
val (irModuleFragment, components, pluginContext) =
|
||||||
inputArtifact.firAnalyzerFacade.convertToJsIr(firFiles, fir2IrExtensions, module, configuration, testServices)
|
inputArtifact.partsForDependsOnModules.last().firAnalyzerFacade.convertToJsIr(firFiles, fir2IrExtensions, module, configuration, testServices)
|
||||||
|
|
||||||
val sourceFiles = firFiles.mapNotNull { it.sourceFile }
|
val sourceFiles = firFiles.mapNotNull { it.sourceFile }
|
||||||
val firFilesBySourceFile = firFiles.associateBy { it.sourceFile }
|
val firFilesBySourceFile = firFiles.associateBy { it.sourceFile }
|
||||||
@@ -81,7 +81,7 @@ class Fir2IrJsResultsConverter(
|
|||||||
?: GenerationState.LANGUAGE_TO_METADATA_VERSION.getValue(module.languageVersionSettings.languageVersion)
|
?: GenerationState.LANGUAGE_TO_METADATA_VERSION.getValue(module.languageVersionSettings.languageVersion)
|
||||||
|
|
||||||
// At this point, checkers will already have been run by a previous test step. `runCheckers` returns the cached diagnostics map.
|
// At this point, checkers will already have been run by a previous test step. `runCheckers` returns the cached diagnostics map.
|
||||||
val diagnosticsMap = inputArtifact.firAnalyzerFacade.runCheckers()
|
val diagnosticsMap = inputArtifact.partsForDependsOnModules.last().firAnalyzerFacade.runCheckers()
|
||||||
val hasErrors = diagnosticsMap.any { entry -> entry.value.any { it.severity == Severity.ERROR } }
|
val hasErrors = diagnosticsMap.any { entry -> entry.value.any { it.severity == Severity.ERROR } }
|
||||||
|
|
||||||
return IrBackendInput.JsIrBackendInput(
|
return IrBackendInput.JsIrBackendInput(
|
||||||
|
|||||||
+42
-23
@@ -12,7 +12,9 @@ import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
|
import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
|
||||||
@@ -40,22 +42,18 @@ class Fir2IrResultsConverter(
|
|||||||
module: TestModule,
|
module: TestModule,
|
||||||
inputArtifact: FirOutputArtifact
|
inputArtifact: FirOutputArtifact
|
||||||
): IrBackendInput {
|
): IrBackendInput {
|
||||||
|
val isMppSupported = module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||||
|
|
||||||
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||||
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
|
||||||
val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler)
|
val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler)
|
||||||
val (irModuleFragment, components, pluginContext) = inputArtifact.firAnalyzerFacade.convertToIr(fir2IrExtensions)
|
|
||||||
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
|
|
||||||
|
|
||||||
val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG)
|
|
||||||
val codegenFactory = JvmIrCodegenFactory(configuration, phaseConfig)
|
|
||||||
|
|
||||||
// TODO: handle fir from light tree
|
|
||||||
val ktFiles = inputArtifact.firFiles.values.mapNotNull { it.psi as KtFile? }
|
|
||||||
val sourceFiles = inputArtifact.firFiles.values.mapNotNull { it.sourceFile }
|
|
||||||
|
|
||||||
// Create and initialize the module and its dependencies
|
// Create and initialize the module and its dependencies
|
||||||
val project = compilerConfigurationProvider.getProject(module)
|
val project = compilerConfigurationProvider.getProject(module)
|
||||||
|
// TODO: handle fir from light tree
|
||||||
|
val ktFiles = inputArtifact.mainFirFiles.mapNotNull { it.value.psi as KtFile? }
|
||||||
|
val sourceFiles = inputArtifact.mainFirFiles.mapNotNull { it.value.sourceFile }
|
||||||
val container = TopDownAnalyzerFacadeForJVM.createContainer(
|
val container = TopDownAnalyzerFacadeForJVM.createContainer(
|
||||||
project, ktFiles, NoScopeRecordCliBindingTrace(), configuration,
|
project, ktFiles, NoScopeRecordCliBindingTrace(), configuration,
|
||||||
compilerConfigurationProvider.getPackagePartProviderFactory(module),
|
compilerConfigurationProvider.getPackagePartProviderFactory(module),
|
||||||
@@ -63,28 +61,49 @@ class Fir2IrResultsConverter(
|
|||||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles), emptyList()
|
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles), emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
val generationState = GenerationState.Builder(
|
val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG)
|
||||||
project, ClassBuilderFactories.TEST,
|
|
||||||
container.get(), dummyBindingContext, configuration
|
|
||||||
).isIrBackend(
|
|
||||||
true
|
|
||||||
).jvmBackendClassResolver(
|
|
||||||
FirJvmBackendClassResolver(components)
|
|
||||||
).build()
|
|
||||||
|
|
||||||
return IrBackendInput.JvmIrBackendInput(
|
val componentsMap = mutableMapOf<String, Fir2IrComponents>()
|
||||||
generationState,
|
val dependentIrParts = mutableListOf<JvmIrCodegenFactory.JvmIrBackendInput>()
|
||||||
codegenFactory,
|
lateinit var mainIrPart: JvmIrCodegenFactory.JvmIrBackendInput
|
||||||
JvmIrCodegenFactory.JvmIrBackendInput(
|
|
||||||
|
for ((index, firOutputPart) in inputArtifact.partsForDependsOnModules.withIndex()) {
|
||||||
|
val (irModuleFragment, components, pluginContext) = firOutputPart.firAnalyzerFacade.convertToIr(fir2IrExtensions)
|
||||||
|
componentsMap[firOutputPart.module.name] = components
|
||||||
|
|
||||||
|
val irPart = JvmIrCodegenFactory.JvmIrBackendInput(
|
||||||
irModuleFragment,
|
irModuleFragment,
|
||||||
components.symbolTable,
|
components.symbolTable,
|
||||||
phaseConfig,
|
phaseConfig,
|
||||||
components.irProviders,
|
components.irProviders,
|
||||||
fir2IrExtensions,
|
fir2IrExtensions,
|
||||||
FirJvmBackendExtension(inputArtifact.session, components),
|
FirJvmBackendExtension(firOutputPart.session, components),
|
||||||
pluginContext,
|
pluginContext,
|
||||||
notifyCodegenStart = {},
|
notifyCodegenStart = {},
|
||||||
),
|
)
|
||||||
|
|
||||||
|
if (index < inputArtifact.partsForDependsOnModules.size - 1) {
|
||||||
|
dependentIrParts.add(irPart)
|
||||||
|
} else {
|
||||||
|
mainIrPart = irPart
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val codegenFactory = JvmIrCodegenFactory(configuration, phaseConfig)
|
||||||
|
val generationState = GenerationState.Builder(
|
||||||
|
project, ClassBuilderFactories.TEST,
|
||||||
|
container.get(), NoScopeRecordCliBindingTrace().bindingContext, configuration
|
||||||
|
).isIrBackend(
|
||||||
|
true
|
||||||
|
).jvmBackendClassResolver(
|
||||||
|
FirJvmBackendClassResolver(componentsMap[module.name]!!)
|
||||||
|
).build()
|
||||||
|
|
||||||
|
return IrBackendInput.JvmIrBackendInput(
|
||||||
|
generationState,
|
||||||
|
codegenFactory,
|
||||||
|
dependentIrParts,
|
||||||
|
mainIrPart,
|
||||||
sourceFiles
|
sourceFiles
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+231
-158
@@ -5,11 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.frontend.fir
|
package org.jetbrains.kotlin.test.frontend.fir
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.StandardFileSystems
|
import com.intellij.openapi.vfs.StandardFileSystems
|
||||||
import com.intellij.openapi.vfs.VirtualFileManager
|
import com.intellij.openapi.vfs.VirtualFileManager
|
||||||
import com.intellij.psi.PsiElementFinder
|
import com.intellij.psi.PsiElementFinder
|
||||||
import com.intellij.psi.search.ProjectScope
|
import com.intellij.psi.search.ProjectScope
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope
|
import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope
|
||||||
@@ -19,17 +19,16 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
|||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory
|
import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory
|
||||||
import org.jetbrains.kotlin.fir.session.FirNativeSessionFactory
|
import org.jetbrains.kotlin.fir.session.FirNativeSessionFactory
|
||||||
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
|
||||||
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
||||||
import org.jetbrains.kotlin.ir.backend.js.resolverLogger
|
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.isCommon
|
import org.jetbrains.kotlin.platform.isCommon
|
||||||
@@ -37,25 +36,22 @@ import org.jetbrains.kotlin.platform.isJs
|
|||||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
import org.jetbrains.kotlin.platform.konan.isNative
|
import org.jetbrains.kotlin.platform.konan.isNative
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||||
import org.jetbrains.kotlin.test.model.DependencyRelation
|
import org.jetbrains.kotlin.test.getAnalyzerServices
|
||||||
import org.jetbrains.kotlin.test.model.FrontendFacade
|
import org.jetbrains.kotlin.test.model.FrontendFacade
|
||||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.*
|
import org.jetbrains.kotlin.test.services.*
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
open class FirFrontendFacade(
|
open class FirFrontendFacade(
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
private val additionalSessionConfiguration: SessionConfiguration?
|
private val additionalSessionConfiguration: SessionConfiguration?
|
||||||
) : FrontendFacade<FirOutputArtifact>(testServices, FrontendKinds.FIR) {
|
) : FrontendFacade<FirOutputArtifact>(testServices, FrontendKinds.FIR) {
|
||||||
|
private val testModulesByName by lazy { testServices.moduleStructure.modules.associateBy { it.name } }
|
||||||
|
|
||||||
// Separate constructor is needed for creating callable references to it
|
// Separate constructor is needed for creating callable references to it
|
||||||
constructor(testServices: TestServices) : this(testServices, additionalSessionConfiguration = null)
|
constructor(testServices: TestServices) : this(testServices, additionalSessionConfiguration = null)
|
||||||
|
|
||||||
@@ -67,53 +63,150 @@ open class FirFrontendFacade(
|
|||||||
override val directiveContainers: List<DirectivesContainer>
|
override val directiveContainers: List<DirectivesContainer>
|
||||||
get() = listOf(FirDiagnosticsDirectives)
|
get() = listOf(FirDiagnosticsDirectives)
|
||||||
|
|
||||||
|
override fun shouldRunAnalysis(module: TestModule): Boolean {
|
||||||
|
if (!super.shouldRunAnalysis(module)) return false
|
||||||
|
|
||||||
|
return if (module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) {
|
||||||
|
testServices.moduleStructure
|
||||||
|
.modules.none { testModule -> testModule.dependsOnDependencies.any { testModulesByName[it.moduleName] == module } }
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun registerExtraComponents(session: FirSession) {}
|
open fun registerExtraComponents(session: FirSession) {}
|
||||||
|
|
||||||
override fun analyze(module: TestModule): FirOutputArtifact {
|
override fun analyze(module: TestModule): FirOutputArtifact {
|
||||||
val moduleInfoProvider = testServices.firModuleInfoProvider
|
val isMppSupported = module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)
|
||||||
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
|
||||||
// TODO: add configurable parser
|
|
||||||
|
|
||||||
val project = compilerConfigurationProvider.getProject(module)
|
val sortedModules = if (isMppSupported) sortDependsOnTopologically(module) else listOf(module)
|
||||||
|
|
||||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
val (moduleDataMap, moduleDataProvider) = initializeModuleData(sortedModules)
|
||||||
|
|
||||||
val lightTreeEnabled = FirDiagnosticsDirectives.USE_LIGHT_TREE in module.directives
|
val projectEnvironment = createLibrarySession(
|
||||||
val (ktFiles, lightTreeFiles) = if (lightTreeEnabled) {
|
module,
|
||||||
emptyList<KtFile>() to testServices.sourceFileProvider.getLightTreeFilesForSourceFiles(module.files).values
|
testServices.compilerConfigurationProvider.getProject(module),
|
||||||
} else {
|
Name.special("<${module.name}>"),
|
||||||
testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project).values to emptyList()
|
testServices.firModuleInfoProvider.firSessionProvider,
|
||||||
|
moduleDataProvider,
|
||||||
|
testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||||
|
)
|
||||||
|
|
||||||
|
val targetPlatform = module.targetPlatform
|
||||||
|
val firOutputPartForDependsOnModules = mutableListOf<FirOutputPartForDependsOnModule>()
|
||||||
|
for (testModule in sortedModules) {
|
||||||
|
firOutputPartForDependsOnModules.add(
|
||||||
|
analyze(
|
||||||
|
testModule,
|
||||||
|
moduleDataMap[testModule]!!,
|
||||||
|
targetPlatform,
|
||||||
|
projectEnvironment,
|
||||||
|
isMppSupported = isMppSupported
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FirOutputArtifactImpl(firOutputPartForDependsOnModules)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sortDependsOnTopologically(module: TestModule): List<TestModule> {
|
||||||
|
val sortedModules = mutableListOf<TestModule>()
|
||||||
|
val visitedModules = mutableSetOf<TestModule>()
|
||||||
|
val modulesQueue = ArrayDeque<TestModule>()
|
||||||
|
modulesQueue.add(module)
|
||||||
|
|
||||||
|
while (modulesQueue.isNotEmpty()) {
|
||||||
|
val currentModule = modulesQueue.removeFirst()
|
||||||
|
if (!visitedModules.add(currentModule)) continue
|
||||||
|
sortedModules.add(currentModule)
|
||||||
|
|
||||||
|
for (dependency in currentModule.dependsOnDependencies) {
|
||||||
|
modulesQueue.add(testServices.dependencyProvider.getTestModule(dependency.moduleName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortedModules.reversed()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeModuleData(modules: List<TestModule>): Pair<Map<TestModule, FirModuleData>, ModuleDataProvider> {
|
||||||
|
val mainModule = modules.last()
|
||||||
|
|
||||||
|
val targetPlatform = mainModule.targetPlatform
|
||||||
|
val analyzerServices = targetPlatform.getAnalyzerServices()
|
||||||
|
|
||||||
// the special name is required for `KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns`
|
// the special name is required for `KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns`
|
||||||
// it doesn't seem convincingly legitimate, probably should be refactored
|
// it doesn't seem convincingly legitimate, probably should be refactored
|
||||||
val moduleName = Name.special("<${module.name}>")
|
val moduleName = Name.special("<${mainModule.name}>")
|
||||||
|
val binaryModuleData = BinaryModuleData.initialize(moduleName, targetPlatform, analyzerServices)
|
||||||
|
|
||||||
|
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||||
|
val configuration = compilerConfigurationProvider.getCompilerConfiguration(mainModule)
|
||||||
|
|
||||||
|
val libraryList = initializeLibraryList(mainModule, binaryModuleData, targetPlatform, configuration)
|
||||||
|
|
||||||
|
val moduleInfoProvider = testServices.firModuleInfoProvider
|
||||||
|
val moduleDataMap = mutableMapOf<TestModule, FirModuleData>()
|
||||||
|
|
||||||
|
for (module in modules) {
|
||||||
|
val regularModules = libraryList.regularDependencies + moduleInfoProvider.getRegularDependentSourceModules(module)
|
||||||
|
val friendModules = libraryList.friendsDependencies + moduleInfoProvider.getDependentFriendSourceModules(module)
|
||||||
|
val dependsOnModules = libraryList.dependsOnDependencies + moduleInfoProvider.getDependentDependsOnSourceModules(module)
|
||||||
|
|
||||||
|
val moduleData = FirModuleDataImpl(
|
||||||
|
Name.special("<${module.name}>"),
|
||||||
|
regularModules,
|
||||||
|
dependsOnModules,
|
||||||
|
friendModules,
|
||||||
|
module.targetPlatform,
|
||||||
|
module.targetPlatform.getAnalyzerServices()
|
||||||
|
)
|
||||||
|
|
||||||
|
moduleInfoProvider.registerModuleData(module, moduleData)
|
||||||
|
|
||||||
|
moduleDataMap[module] = moduleData
|
||||||
|
}
|
||||||
|
|
||||||
|
return moduleDataMap to libraryList.moduleDataProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeLibraryList(
|
||||||
|
mainModule: TestModule,
|
||||||
|
binaryModuleData: BinaryModuleData,
|
||||||
|
targetPlatform: TargetPlatform,
|
||||||
|
configuration: CompilerConfiguration,
|
||||||
|
): DependencyListForCliModule {
|
||||||
|
return DependencyListForCliModule.build(binaryModuleData) {
|
||||||
|
when {
|
||||||
|
targetPlatform.isCommon() || targetPlatform.isJvm() || targetPlatform.isNative() -> {
|
||||||
|
dependencies(configuration.jvmModularRoots.map { it.toPath() })
|
||||||
|
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
|
||||||
|
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||||
|
}
|
||||||
|
targetPlatform.isJs() -> {
|
||||||
|
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(mainModule, testServices)
|
||||||
|
dependencies(runtimeKlibsPaths.map { Paths.get(it).toAbsolutePath() })
|
||||||
|
dependencies(transitiveLibraries.map { it.toPath().toAbsolutePath() })
|
||||||
|
friendDependencies(friendLibraries.map { it.toPath().toAbsolutePath() })
|
||||||
|
}
|
||||||
|
else -> error("Unsupported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createLibrarySession(
|
||||||
|
module: TestModule,
|
||||||
|
project: Project,
|
||||||
|
moduleName: Name,
|
||||||
|
sessionProvider: FirProjectSessionProvider,
|
||||||
|
moduleDataProvider: ModuleDataProvider,
|
||||||
|
configuration: CompilerConfiguration
|
||||||
|
): AbstractProjectEnvironment? {
|
||||||
|
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||||
|
val projectEnvironment: AbstractProjectEnvironment?
|
||||||
val languageVersionSettings = module.languageVersionSettings
|
val languageVersionSettings = module.languageVersionSettings
|
||||||
val analyzerServices = module.targetPlatform.getAnalyzerServices()
|
|
||||||
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
|
||||||
val extensionRegistrars = FirExtensionRegistrar.getInstances(project)
|
|
||||||
|
|
||||||
val sessionConfigurator: FirSessionConfigurator.() -> Unit = {
|
|
||||||
if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
|
|
||||||
registerExtendedCommonCheckers()
|
|
||||||
}
|
|
||||||
additionalSessionConfiguration?.invoke(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
val isCommonOrJvm = module.targetPlatform.isJvm() || module.targetPlatform.isCommon()
|
|
||||||
|
|
||||||
val dependencyList = buildDependencyList(module, moduleName, moduleInfoProvider, analyzerServices) {
|
|
||||||
if (isCommonOrJvm || module.targetPlatform.isNative()) {
|
|
||||||
configureJvmDependencies(configuration)
|
|
||||||
} else {
|
|
||||||
configureJsDependencies(module, testServices)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val projectEnvironment: VfsBasedProjectEnvironment?
|
|
||||||
|
|
||||||
when {
|
when {
|
||||||
isCommonOrJvm -> {
|
// TODO: use common session for common target platform when it's implemented
|
||||||
|
module.targetPlatform.isCommon() || module.targetPlatform.isJvm() -> {
|
||||||
val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
|
val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
|
||||||
projectEnvironment = VfsBasedProjectEnvironment(
|
projectEnvironment = VfsBasedProjectEnvironment(
|
||||||
project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
|
project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
|
||||||
@@ -123,8 +216,8 @@ open class FirFrontendFacade(
|
|||||||
|
|
||||||
FirJvmSessionFactory.createLibrarySession(
|
FirJvmSessionFactory.createLibrarySession(
|
||||||
moduleName,
|
moduleName,
|
||||||
moduleInfoProvider.firSessionProvider,
|
sessionProvider,
|
||||||
dependencyList,
|
moduleDataProvider,
|
||||||
projectEnvironment,
|
projectEnvironment,
|
||||||
projectFileSearchScope,
|
projectFileSearchScope,
|
||||||
packagePartProvider,
|
packagePartProvider,
|
||||||
@@ -136,8 +229,8 @@ open class FirFrontendFacade(
|
|||||||
projectEnvironment = null
|
projectEnvironment = null
|
||||||
TestFirJsSessionFactory.createLibrarySession(
|
TestFirJsSessionFactory.createLibrarySession(
|
||||||
moduleName,
|
moduleName,
|
||||||
moduleInfoProvider.firSessionProvider,
|
sessionProvider,
|
||||||
dependencyList,
|
moduleDataProvider,
|
||||||
module,
|
module,
|
||||||
testServices,
|
testServices,
|
||||||
configuration,
|
configuration,
|
||||||
@@ -150,29 +243,97 @@ open class FirFrontendFacade(
|
|||||||
FirNativeSessionFactory.createLibrarySession(
|
FirNativeSessionFactory.createLibrarySession(
|
||||||
moduleName,
|
moduleName,
|
||||||
listOf(),
|
listOf(),
|
||||||
moduleInfoProvider.firSessionProvider,
|
sessionProvider,
|
||||||
dependencyList,
|
moduleDataProvider,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
registerExtraComponents = ::registerExtraComponents,
|
registerExtraComponents = ::registerExtraComponents,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> error("Unsupported")
|
else -> error("Unsupported")
|
||||||
}
|
}
|
||||||
|
return projectEnvironment
|
||||||
|
}
|
||||||
|
|
||||||
val mainModuleData = FirModuleDataImpl(
|
private fun analyze(
|
||||||
moduleName,
|
module: TestModule,
|
||||||
dependencyList.regularDependencies,
|
moduleData: FirModuleData,
|
||||||
dependencyList.dependsOnDependencies,
|
targetPlatform: TargetPlatform,
|
||||||
dependencyList.friendsDependencies,
|
projectEnvironment: AbstractProjectEnvironment?,
|
||||||
dependencyList.platform,
|
isMppSupported: Boolean,
|
||||||
dependencyList.analyzerServices
|
): FirOutputPartForDependsOnModule {
|
||||||
|
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||||
|
val moduleInfoProvider = testServices.firModuleInfoProvider
|
||||||
|
val sessionProvider = moduleInfoProvider.firSessionProvider
|
||||||
|
|
||||||
|
val project = compilerConfigurationProvider.getProject(module)
|
||||||
|
|
||||||
|
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||||
|
|
||||||
|
val lightTreeEnabled = FirDiagnosticsDirectives.USE_LIGHT_TREE in module.directives
|
||||||
|
val (ktFiles, lightTreeFiles) = if (lightTreeEnabled) {
|
||||||
|
emptyList<KtFile>() to testServices.sourceFileProvider.getLightTreeFilesForSourceFiles(module.files).values
|
||||||
|
} else {
|
||||||
|
testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project).values to emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val extensionRegistrars = FirExtensionRegistrar.getInstances(project)
|
||||||
|
val sessionConfigurator: FirSessionConfigurator.() -> Unit = {
|
||||||
|
if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
|
||||||
|
registerExtendedCommonCheckers()
|
||||||
|
}
|
||||||
|
additionalSessionConfiguration?.invoke(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
val moduleBasedSession = createModuleBasedSession(
|
||||||
|
module,
|
||||||
|
moduleData,
|
||||||
|
targetPlatform,
|
||||||
|
sessionProvider,
|
||||||
|
projectEnvironment,
|
||||||
|
extensionRegistrars,
|
||||||
|
sessionConfigurator,
|
||||||
|
project,
|
||||||
|
ktFiles
|
||||||
)
|
)
|
||||||
|
|
||||||
val session = when {
|
val enablePluginPhases = FirDiagnosticsDirectives.ENABLE_PLUGIN_PHASES in module.directives
|
||||||
isCommonOrJvm -> {
|
val firAnalyzerFacade = FirAnalyzerFacade(
|
||||||
|
moduleBasedSession,
|
||||||
|
module.languageVersionSettings,
|
||||||
|
ktFiles,
|
||||||
|
lightTreeFiles,
|
||||||
|
IrGenerationExtension.getInstances(project),
|
||||||
|
lightTreeEnabled,
|
||||||
|
enablePluginPhases,
|
||||||
|
generateSignatures = module.targetBackend == TargetBackend.JVM_IR_SERIALIZE || isMppSupported,
|
||||||
|
)
|
||||||
|
val firFiles = firAnalyzerFacade.runResolution()
|
||||||
|
val filesMap = firFiles.mapNotNull { firFile ->
|
||||||
|
val testFile = module.files.firstOrNull { it.name == firFile.name } ?: return@mapNotNull null
|
||||||
|
testFile to firFile
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
return FirOutputPartForDependsOnModule(module, moduleBasedSession, firAnalyzerFacade, filesMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createModuleBasedSession(
|
||||||
|
module: TestModule,
|
||||||
|
moduleData: FirModuleData,
|
||||||
|
targetPlatform: TargetPlatform,
|
||||||
|
sessionProvider: FirProjectSessionProvider,
|
||||||
|
projectEnvironment: AbstractProjectEnvironment?,
|
||||||
|
extensionRegistrars: List<FirExtensionRegistrar>,
|
||||||
|
sessionConfigurator: FirSessionConfigurator.() -> Unit,
|
||||||
|
project: Project,
|
||||||
|
ktFiles: Collection<KtFile>
|
||||||
|
): FirSession {
|
||||||
|
val languageVersionSettings = module.languageVersionSettings
|
||||||
|
return when {
|
||||||
|
// TODO: use common session for common target platform when it's implemented
|
||||||
|
targetPlatform.isCommon() || targetPlatform.isJvm() -> {
|
||||||
FirJvmSessionFactory.createModuleBasedSession(
|
FirJvmSessionFactory.createModuleBasedSession(
|
||||||
mainModuleData,
|
moduleData,
|
||||||
moduleInfoProvider.firSessionProvider,
|
sessionProvider,
|
||||||
PsiBasedProjectFileSearchScope(TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)),
|
PsiBasedProjectFileSearchScope(TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)),
|
||||||
projectEnvironment!!,
|
projectEnvironment!!,
|
||||||
incrementalCompilationContext = null,
|
incrementalCompilationContext = null,
|
||||||
@@ -185,10 +346,10 @@ open class FirFrontendFacade(
|
|||||||
sessionConfigurator,
|
sessionConfigurator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
module.targetPlatform.isJs() -> {
|
targetPlatform.isJs() -> {
|
||||||
TestFirJsSessionFactory.createModuleBasedSession(
|
TestFirJsSessionFactory.createModuleBasedSession(
|
||||||
mainModuleData,
|
moduleData,
|
||||||
moduleInfoProvider.firSessionProvider,
|
sessionProvider,
|
||||||
extensionRegistrars,
|
extensionRegistrars,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
null,
|
null,
|
||||||
@@ -196,10 +357,10 @@ open class FirFrontendFacade(
|
|||||||
sessionConfigurator,
|
sessionConfigurator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
module.targetPlatform.isNative() -> {
|
targetPlatform.isNative() -> {
|
||||||
FirNativeSessionFactory.createModuleBasedSession(
|
FirNativeSessionFactory.createModuleBasedSession(
|
||||||
mainModuleData,
|
moduleData,
|
||||||
moduleInfoProvider.firSessionProvider,
|
sessionProvider,
|
||||||
extensionRegistrars,
|
extensionRegistrars,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
registerExtraComponents = ::registerExtraComponents,
|
registerExtraComponents = ::registerExtraComponents,
|
||||||
@@ -208,93 +369,5 @@ open class FirFrontendFacade(
|
|||||||
}
|
}
|
||||||
else -> error("Unsupported")
|
else -> error("Unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleInfoProvider.registerModuleData(module, session.moduleData)
|
|
||||||
|
|
||||||
val enablePluginPhases = FirDiagnosticsDirectives.ENABLE_PLUGIN_PHASES in module.directives
|
|
||||||
val firAnalyzerFacade = FirAnalyzerFacade(
|
|
||||||
session,
|
|
||||||
languageVersionSettings,
|
|
||||||
ktFiles,
|
|
||||||
lightTreeFiles,
|
|
||||||
IrGenerationExtension.getInstances(project),
|
|
||||||
lightTreeEnabled,
|
|
||||||
enablePluginPhases,
|
|
||||||
generateSignatures = module.targetBackend == TargetBackend.JVM_IR_SERIALIZE
|
|
||||||
)
|
|
||||||
val firFiles = firAnalyzerFacade.runResolution()
|
|
||||||
val filesMap = firFiles.mapNotNull { firFile ->
|
|
||||||
val testFile = module.files.firstOrNull { it.name == firFile.name } ?: return@mapNotNull null
|
|
||||||
testFile to firFile
|
|
||||||
}.toMap()
|
|
||||||
|
|
||||||
return FirOutputArtifactImpl(session, filesMap, firAnalyzerFacade)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun DependencyListForCliModule.Builder.configureJvmDependencies(
|
|
||||||
configuration: CompilerConfiguration,
|
|
||||||
) {
|
|
||||||
dependencies(configuration.jvmModularRoots.map { it.toPath() })
|
|
||||||
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
|
|
||||||
|
|
||||||
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun DependencyListForCliModule.Builder.configureJsDependencies(
|
|
||||||
module: TestModule,
|
|
||||||
testServices: TestServices,
|
|
||||||
) {
|
|
||||||
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
|
||||||
|
|
||||||
dependencies(runtimeKlibsPaths.map { Paths.get(it).toAbsolutePath() })
|
|
||||||
dependencies(transitiveLibraries.map { it.toPath().toAbsolutePath() })
|
|
||||||
|
|
||||||
friendDependencies(friendLibraries.map { it.toPath().toAbsolutePath() })
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getJsDependencies(module: TestModule, testServices: TestServices): Triple<List<String>, List<File>, List<File>> {
|
|
||||||
val runtimeKlibsPaths = JsEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
|
|
||||||
val transitiveLibraries = JsEnvironmentConfigurator.getKlibDependencies(module, testServices, DependencyRelation.RegularDependency)
|
|
||||||
val friendLibraries = JsEnvironmentConfigurator.getKlibDependencies(module, testServices, DependencyRelation.FriendDependency)
|
|
||||||
return Triple(runtimeKlibsPaths, transitiveLibraries, friendLibraries)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> {
|
|
||||||
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
|
||||||
return runtimeKlibsPaths + transitiveLibraries.map { it.path } + friendLibraries.map { it.path }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun resolveJsLibraries(
|
|
||||||
module: TestModule,
|
|
||||||
testServices: TestServices,
|
|
||||||
configuration: CompilerConfiguration
|
|
||||||
): List<KotlinResolvedLibrary> {
|
|
||||||
val paths = getAllJsDependenciesPaths(module, testServices)
|
|
||||||
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
|
|
||||||
val logger = configuration.resolverLogger
|
|
||||||
return jsResolveLibraries(paths, repositories, logger).getFullResolvedList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildDependencyList(
|
|
||||||
module: TestModule,
|
|
||||||
moduleName: Name,
|
|
||||||
moduleInfoProvider: FirModuleInfoProvider,
|
|
||||||
analyzerServices: PlatformDependentAnalyzerServices,
|
|
||||||
configureDependencies: DependencyListForCliModule.Builder.() -> Unit,
|
|
||||||
) = DependencyListForCliModule.build(moduleName, module.targetPlatform, analyzerServices) {
|
|
||||||
configureDependencies()
|
|
||||||
sourceDependencies(moduleInfoProvider.getRegularDependentSourceModules(module))
|
|
||||||
sourceFriendsDependencies(moduleInfoProvider.getDependentFriendSourceModules(module))
|
|
||||||
sourceDependsOnDependencies(moduleInfoProvider.getDependentDependsOnSourceModules(module))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
|
|
||||||
return when {
|
|
||||||
isJvm() -> JvmPlatformAnalyzerServices
|
|
||||||
isJs() -> JsPlatformAnalyzerServices
|
|
||||||
isNative() -> NativePlatformAnalyzerServices
|
|
||||||
isCommon() -> CommonPlatformAnalyzerServices
|
|
||||||
else -> error("Unknown target platform: $this")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -20,7 +20,9 @@ class FirModuleInfoProvider(private val testServices: TestServices) : TestServic
|
|||||||
private val firModuleDataByModule: MutableMap<TestModule, FirModuleData> = mutableMapOf()
|
private val firModuleDataByModule: MutableMap<TestModule, FirModuleData> = mutableMapOf()
|
||||||
|
|
||||||
fun registerModuleData(module: TestModule, moduleData: FirModuleData) {
|
fun registerModuleData(module: TestModule, moduleData: FirModuleData) {
|
||||||
if (module in firModuleDataByModule) error("module data for module $module already registered")
|
// Allow reregistering since tests with several targets are possible (JVM, JS)
|
||||||
|
// FirFrontendFacade creates modules for every platform. But if several targets are presented, several common modules will be initialized.
|
||||||
|
// It's not possible to reuse moduleData for the same modules because moduleData depends on the platform.
|
||||||
firModuleDataByModule[module] = moduleData
|
firModuleDataByModule[module] = moduleData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-12
@@ -6,27 +6,28 @@
|
|||||||
package org.jetbrains.kotlin.test.frontend.fir
|
package org.jetbrains.kotlin.test.frontend.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
import org.jetbrains.kotlin.fir.AbstractFirAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.fir.FirAnalyzerFacade
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||||
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
import org.jetbrains.kotlin.test.model.ResultingArtifact
|
||||||
import org.jetbrains.kotlin.test.model.TestFile
|
import org.jetbrains.kotlin.test.model.TestFile
|
||||||
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
|
|
||||||
abstract class FirOutputArtifact : ResultingArtifact.FrontendOutput<FirOutputArtifact>() {
|
// Only MPP contains several parts inside FirOutputArtifact, other projects only contain single part.
|
||||||
abstract val session: FirSession
|
data class FirOutputPartForDependsOnModule(
|
||||||
abstract val firAnalyzerFacade: AbstractFirAnalyzerFacade
|
val module: TestModule,
|
||||||
abstract val allFirFiles: Map<TestFile, FirFile>
|
val session: FirSession,
|
||||||
|
val firAnalyzerFacade: AbstractFirAnalyzerFacade,
|
||||||
|
val firFiles: Map<TestFile, FirFile>
|
||||||
|
)
|
||||||
|
|
||||||
|
abstract class FirOutputArtifact(val partsForDependsOnModules: List<FirOutputPartForDependsOnModule>) : ResultingArtifact.FrontendOutput<FirOutputArtifact>() {
|
||||||
|
val allFirFiles: Map<TestFile, FirFile> = partsForDependsOnModules.fold(emptyMap()) { acc, part -> acc + part.firFiles }
|
||||||
|
|
||||||
override val kind: FrontendKinds.FIR
|
override val kind: FrontendKinds.FIR
|
||||||
get() = FrontendKinds.FIR
|
get() = FrontendKinds.FIR
|
||||||
|
|
||||||
|
val mainFirFiles: Map<TestFile, FirFile> by lazy { allFirFiles.filterKeys { !it.isAdditional } }
|
||||||
val firFiles: Map<TestFile, FirFile> by lazy { allFirFiles.filterKeys { !it.isAdditional } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FirOutputArtifactImpl(
|
class FirOutputArtifactImpl(parts: List<FirOutputPartForDependsOnModule>) : FirOutputArtifact(parts)
|
||||||
override val session: FirSession,
|
|
||||||
override val allFirFiles: Map<TestFile, FirFile>,
|
|
||||||
override val firAnalyzerFacade: FirAnalyzerFacade
|
|
||||||
) : FirOutputArtifact()
|
|
||||||
+33
-6
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.test.frontend.fir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.FirModuleDataImpl
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.session.FirJsSessionFactory
|
import org.jetbrains.kotlin.fir.session.FirJsSessionFactory
|
||||||
@@ -18,15 +18,19 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||||
import org.jetbrains.kotlin.ir.backend.js.resolverLogger
|
import org.jetbrains.kotlin.ir.backend.js.resolverLogger
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.test.model.DependencyRelation
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
object TestFirJsSessionFactory {
|
object TestFirJsSessionFactory {
|
||||||
fun createLibrarySession(
|
fun createLibrarySession(
|
||||||
mainModuleName: Name,
|
mainModuleName: Name,
|
||||||
sessionProvider: FirProjectSessionProvider,
|
sessionProvider: FirProjectSessionProvider,
|
||||||
dependencyListForCliModule: DependencyListForCliModule,
|
moduleDataProvider: ModuleDataProvider,
|
||||||
module: TestModule,
|
module: TestModule,
|
||||||
testServices: TestServices,
|
testServices: TestServices,
|
||||||
configuration: CompilerConfiguration,
|
configuration: CompilerConfiguration,
|
||||||
@@ -42,14 +46,14 @@ object TestFirJsSessionFactory {
|
|||||||
mainModuleName,
|
mainModuleName,
|
||||||
resolvedLibraries,
|
resolvedLibraries,
|
||||||
sessionProvider,
|
sessionProvider,
|
||||||
dependencyListForCliModule.moduleDataProvider,
|
moduleDataProvider,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
registerExtraComponents,
|
registerExtraComponents,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createModuleBasedSession(
|
fun createModuleBasedSession(
|
||||||
mainModuleData: FirModuleDataImpl, sessionProvider: FirProjectSessionProvider, extensionRegistrars: List<FirExtensionRegistrar>,
|
mainModuleData: FirModuleData, sessionProvider: FirProjectSessionProvider, extensionRegistrars: List<FirExtensionRegistrar>,
|
||||||
languageVersionSettings: LanguageVersionSettings, lookupTracker: LookupTracker?,
|
languageVersionSettings: LanguageVersionSettings, lookupTracker: LookupTracker?,
|
||||||
registerExtraComponents: ((FirSession) -> Unit),
|
registerExtraComponents: ((FirSession) -> Unit),
|
||||||
sessionConfigurator: FirSessionConfigurator.() -> Unit,
|
sessionConfigurator: FirSessionConfigurator.() -> Unit,
|
||||||
@@ -63,4 +67,27 @@ object TestFirJsSessionFactory {
|
|||||||
registerExtraComponents,
|
registerExtraComponents,
|
||||||
sessionConfigurator
|
sessionConfigurator
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun resolveJsLibraries(
|
||||||
|
module: TestModule,
|
||||||
|
testServices: TestServices,
|
||||||
|
configuration: CompilerConfiguration
|
||||||
|
): List<KotlinResolvedLibrary> {
|
||||||
|
val paths = getAllJsDependenciesPaths(module, testServices)
|
||||||
|
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
|
||||||
|
val logger = configuration.resolverLogger
|
||||||
|
return jsResolveLibraries(paths, repositories, logger).getFullResolvedList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> {
|
||||||
|
val (runtimeKlibsPaths, transitiveLibraries, friendLibraries) = getJsDependencies(module, testServices)
|
||||||
|
return runtimeKlibsPaths + transitiveLibraries.map { it.path } + friendLibraries.map { it.path }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getJsDependencies(module: TestModule, testServices: TestServices): Triple<List<String>, List<File>, List<File>> {
|
||||||
|
val runtimeKlibsPaths = JsEnvironmentConfigurator.getRuntimePathsForModule(module, testServices)
|
||||||
|
val transitiveLibraries = JsEnvironmentConfigurator.getKlibDependencies(module, testServices, DependencyRelation.RegularDependency)
|
||||||
|
val friendLibraries = JsEnvironmentConfigurator.getKlibDependencies(module, testServices, DependencyRelation.FriendDependency)
|
||||||
|
return Triple(runtimeKlibsPaths, transitiveLibraries, friendLibraries)
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.test.services.TestServices
|
|||||||
|
|
||||||
class FirCfgConsistencyHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
class FirCfgConsistencyHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
info.firFiles.values.forEach { it.accept(FirCfgConsistencyChecker(assertions)) }
|
info.mainFirFiles.values.forEach { it.accept(FirCfgConsistencyChecker(assertions)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ class FirCfgDumpHandler(testServices: TestServices) : FirAnalysisHandler(testSer
|
|||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
if (alreadyDumped || FirDiagnosticsDirectives.DUMP_CFG !in module.directives) return
|
if (alreadyDumped || FirDiagnosticsDirectives.DUMP_CFG !in module.directives) return
|
||||||
val file = info.firFiles.values.first()
|
val file = info.mainFirFiles.values.first()
|
||||||
val renderLevels = RENDERER_CFG_LEVELS in module.directives
|
val renderLevels = RENDERER_CFG_LEVELS in module.directives
|
||||||
file.accept(FirControlFlowGraphRenderVisitor(builder, renderLevels))
|
file.accept(FirControlFlowGraphRenderVisitor(builder, renderLevels))
|
||||||
alreadyDumped = true
|
alreadyDumped = true
|
||||||
|
|||||||
+34
-30
@@ -61,39 +61,43 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
listOf(service(::DiagnosticsService))
|
listOf(service(::DiagnosticsService))
|
||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val diagnosticsPerFile = info.firAnalyzerFacade.runCheckers()
|
for (part in info.partsForDependsOnModules) {
|
||||||
val lightTreeComparingModeEnabled = FirDiagnosticsDirectives.COMPARE_WITH_LIGHT_TREE in module.directives
|
val diagnosticsPerFile = part.firAnalyzerFacade.runCheckers()
|
||||||
val lightTreeEnabled = FirDiagnosticsDirectives.USE_LIGHT_TREE in module.directives
|
val currentModule = part.module
|
||||||
|
|
||||||
for (file in module.files) {
|
val lightTreeComparingModeEnabled = FirDiagnosticsDirectives.COMPARE_WITH_LIGHT_TREE in currentModule.directives
|
||||||
val firFile = info.firFiles[file] ?: continue
|
val lightTreeEnabled = FirDiagnosticsDirectives.USE_LIGHT_TREE in currentModule.directives
|
||||||
var diagnostics = diagnosticsPerFile[firFile] ?: continue
|
|
||||||
if (AdditionalFilesDirectives.CHECK_TYPE in module.directives) {
|
for (file in currentModule.files) {
|
||||||
diagnostics = diagnostics.filter { it.factory.name != FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.name }
|
val firFile = info.mainFirFiles[file] ?: continue
|
||||||
}
|
var diagnostics = diagnosticsPerFile[firFile] ?: continue
|
||||||
if (LanguageSettingsDirectives.API_VERSION in module.directives) {
|
if (AdditionalFilesDirectives.CHECK_TYPE in currentModule.directives) {
|
||||||
diagnostics = diagnostics.filter { it.factory.name != FirErrors.NEWER_VERSION_IN_SINCE_KOTLIN.name }
|
diagnostics = diagnostics.filter { it.factory.name != FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.name }
|
||||||
}
|
}
|
||||||
val diagnosticsMetadataInfos = diagnostics.flatMap { diagnostic ->
|
if (LanguageSettingsDirectives.API_VERSION in currentModule.directives) {
|
||||||
if (!diagnosticsService.shouldRenderDiagnostic(
|
diagnostics = diagnostics.filter { it.factory.name != FirErrors.NEWER_VERSION_IN_SINCE_KOTLIN.name }
|
||||||
module,
|
}
|
||||||
diagnostic.factory.name,
|
val diagnosticsMetadataInfos = diagnostics.flatMap { diagnostic ->
|
||||||
diagnostic.severity
|
if (!diagnosticsService.shouldRenderDiagnostic(
|
||||||
|
currentModule,
|
||||||
|
diagnostic.factory.name,
|
||||||
|
diagnostic.severity
|
||||||
|
)
|
||||||
|
) return@flatMap emptyList()
|
||||||
|
// SYNTAX errors will be reported later
|
||||||
|
if (diagnostic.factory == FirSyntaxErrors.SYNTAX) return@flatMap emptyList()
|
||||||
|
if (!diagnostic.isValid) return@flatMap emptyList()
|
||||||
|
diagnostic.toMetaInfos(
|
||||||
|
file,
|
||||||
|
globalMetadataInfoHandler,
|
||||||
|
lightTreeEnabled,
|
||||||
|
lightTreeComparingModeEnabled
|
||||||
)
|
)
|
||||||
) return@flatMap emptyList()
|
}
|
||||||
// SYNTAX errors will be reported later
|
globalMetadataInfoHandler.addMetadataInfosForFile(file, diagnosticsMetadataInfos)
|
||||||
if (diagnostic.factory == FirSyntaxErrors.SYNTAX) return@flatMap emptyList()
|
collectSyntaxDiagnostics(file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||||
if (!diagnostic.isValid) return@flatMap emptyList()
|
collectDebugInfoDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||||
diagnostic.toMetaInfos(
|
|
||||||
file,
|
|
||||||
globalMetadataInfoHandler,
|
|
||||||
lightTreeEnabled,
|
|
||||||
lightTreeComparingModeEnabled
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
globalMetadataInfoHandler.addMetadataInfosForFile(file, diagnosticsMetadataInfos)
|
|
||||||
collectSyntaxDiagnostics(file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
|
||||||
collectDebugInfoDiagnostics(module, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-16
@@ -32,25 +32,28 @@ class FirDumpHandler(
|
|||||||
get() = listOf(FirDiagnosticsDirectives)
|
get() = listOf(FirDiagnosticsDirectives)
|
||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
if (FirDiagnosticsDirectives.FIR_DUMP !in module.directives) return
|
for (part in info.partsForDependsOnModules) {
|
||||||
val builderForModule = dumper.builderForModule(module)
|
val currentModule = part.module
|
||||||
val firFiles = info.firFiles
|
if (FirDiagnosticsDirectives.FIR_DUMP !in currentModule.directives) return
|
||||||
|
val builderForModule = dumper.builderForModule(currentModule)
|
||||||
|
val firFiles = info.mainFirFiles
|
||||||
|
|
||||||
val allFiles = buildList {
|
val allFiles = buildList {
|
||||||
addAll(firFiles.values)
|
addAll(firFiles.values)
|
||||||
addAll(info.session.createFilesWithGeneratedDeclarations())
|
addAll(part.session.createFilesWithGeneratedDeclarations())
|
||||||
}
|
}
|
||||||
info.session.lazyDeclarationResolver.startResolvingPhase(FirResolvePhase.BODY_RESOLVE)
|
part.session.lazyDeclarationResolver.startResolvingPhase(FirResolvePhase.BODY_RESOLVE)
|
||||||
|
|
||||||
val renderer = FirRenderer(
|
val renderer = FirRenderer(
|
||||||
builder = builderForModule,
|
builder = builderForModule,
|
||||||
packageDirectiveRenderer = FirPackageDirectiveRenderer(),
|
packageDirectiveRenderer = FirPackageDirectiveRenderer(),
|
||||||
classMemberRenderer = FirClassMemberRendererWithGeneratedDeclarations(info.session)
|
classMemberRenderer = FirClassMemberRendererWithGeneratedDeclarations(part.session)
|
||||||
)
|
)
|
||||||
allFiles.forEach {
|
allFiles.forEach {
|
||||||
renderer.renderElementAsString(it)
|
renderer.renderElementAsString(it)
|
||||||
|
}
|
||||||
|
part.session.lazyDeclarationResolver.finishResolvingPhase(FirResolvePhase.BODY_RESOLVE)
|
||||||
}
|
}
|
||||||
info.session.lazyDeclarationResolver.finishResolvingPhase(FirResolvePhase.BODY_RESOLVE)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
|
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
|
||||||
|
|||||||
+6
-4
@@ -13,10 +13,12 @@ import org.jetbrains.kotlin.test.services.assertions
|
|||||||
|
|
||||||
class FirResolveContractViolationErrorHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
class FirResolveContractViolationErrorHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val session = info.session
|
for (part in info.partsForDependsOnModules) {
|
||||||
val lazyResolver = session.lazyDeclarationResolver as? FirCompilerLazyDeclarationResolverWithPhaseChecking ?: return
|
val session = part.session
|
||||||
val exceptions = lazyResolver.getContractViolationExceptions().ifEmpty { return }
|
val lazyResolver = session.lazyDeclarationResolver as? FirCompilerLazyDeclarationResolverWithPhaseChecking ?: return
|
||||||
testServices.assertions.failAll(exceptions)
|
val exceptions = lazyResolver.getContractViolationExceptions().ifEmpty { return }
|
||||||
|
testServices.assertions.failAll(exceptions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||||
|
|||||||
+1
-4
@@ -6,16 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.test.frontend.fir.handlers
|
package org.jetbrains.kotlin.test.frontend.fir.handlers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeAmbiguousSuper
|
import org.jetbrains.kotlin.fir.diagnostics.ConeAmbiguousSuper
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirErrorLoop
|
import org.jetbrains.kotlin.fir.expressions.FirErrorLoop
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirLoop
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirLoopJump
|
import org.jetbrains.kotlin.fir.expressions.FirLoopJump
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeFunctionExpectedError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeFunctionExpectedError
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||||
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
|
||||||
@@ -31,7 +28,7 @@ class FirResolvedTypesVerifier(testServices: TestServices) : FirAnalysisHandler(
|
|||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val visitor = Visitor()
|
val visitor = Visitor()
|
||||||
for (firFile in info.firFiles.values) {
|
for (firFile in info.mainFirFiles.values) {
|
||||||
firFile.acceptChildren(visitor, firFile)
|
firFile.acceptChildren(visitor, firFile)
|
||||||
}
|
}
|
||||||
val ignored = IGNORE_LEAKED_INTERNAL_TYPES in module.directives
|
val ignored = IGNORE_LEAKED_INTERNAL_TYPES in module.directives
|
||||||
|
|||||||
+9
-6
@@ -41,12 +41,15 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
|
|||||||
get() = listOf(FirDiagnosticsDirectives)
|
get() = listOf(FirDiagnosticsDirectives)
|
||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val fqNamesWithNames = module.directives[FirDiagnosticsDirectives.SCOPE_DUMP]
|
for (part in info.partsForDependsOnModules) {
|
||||||
if (fqNamesWithNames.isEmpty()) return
|
val currentModule = part.module
|
||||||
val printer = SmartPrinter(dumper.builderForModule(module), indent = " ")
|
val fqNamesWithNames = currentModule.directives[FirDiagnosticsDirectives.SCOPE_DUMP]
|
||||||
for (fqNameWithNames in fqNamesWithNames) {
|
if (fqNamesWithNames.isEmpty()) return
|
||||||
val (fqName, names) = extractFqNameAndMemberNames(fqNameWithNames)
|
val printer = SmartPrinter(dumper.builderForModule(currentModule), indent = " ")
|
||||||
printer.processClass(fqName, names, info.session, info.firAnalyzerFacade.scopeSession, module)
|
for (fqNameWithNames in fqNamesWithNames) {
|
||||||
|
val (fqName, names) = extractFqNameAndMemberNames(fqNameWithNames)
|
||||||
|
printer.processClass(fqName, names, part.session, part.firAnalyzerFacade.scopeSession, currentModule)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class FirAnalyzerFacade(
|
|||||||
val irGeneratorExtensions: Collection<IrGenerationExtension>,
|
val irGeneratorExtensions: Collection<IrGenerationExtension>,
|
||||||
val useLightTree: Boolean = false,
|
val useLightTree: Boolean = false,
|
||||||
val enablePluginPhases: Boolean = false,
|
val enablePluginPhases: Boolean = false,
|
||||||
val generateSignatures: Boolean = false,
|
val generateSignatures: Boolean = false
|
||||||
) : AbstractFirAnalyzerFacade() {
|
) : AbstractFirAnalyzerFacade() {
|
||||||
private var firFiles: List<FirFile>? = null
|
private var firFiles: List<FirFile>? = null
|
||||||
private var _scopeSession: ScopeSession? = null
|
private var _scopeSession: ScopeSession? = null
|
||||||
@@ -108,13 +108,8 @@ class FirAnalyzerFacade(
|
|||||||
val mangler = JvmDescriptorMangler(null)
|
val mangler = JvmDescriptorMangler(null)
|
||||||
val signaturer = JvmIdSignatureDescriptor(mangler)
|
val signaturer = JvmIdSignatureDescriptor(mangler)
|
||||||
|
|
||||||
val commonFirFiles = session.moduleData.dependsOnDependencies
|
|
||||||
.map { it.session }
|
|
||||||
.filter { it.kind == FirSession.Kind.Source }
|
|
||||||
.flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() }
|
|
||||||
|
|
||||||
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
|
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
|
||||||
session, _scopeSession!!, firFiles!! + commonFirFiles,
|
session, _scopeSession!!, firFiles!!,
|
||||||
languageVersionSettings, signaturer,
|
languageVersionSettings, signaturer,
|
||||||
fir2IrExtensions,
|
fir2IrExtensions,
|
||||||
FirJvmKotlinMangler(session), JvmIrMangler, IrFactoryImpl,
|
FirJvmKotlinMangler(session), JvmIrMangler, IrFactoryImpl,
|
||||||
|
|||||||
+1
-1
@@ -80,7 +80,7 @@ abstract class AbstractVisualizerBlackBoxTest {
|
|||||||
TestRunner(firConfiguration).runTest(filePath) { testConfiguration ->
|
TestRunner(firConfiguration).runTest(filePath) { testConfiguration ->
|
||||||
testConfiguration.testServices.moduleStructure.modules.forEach { firModule ->
|
testConfiguration.testServices.moduleStructure.modules.forEach { firModule ->
|
||||||
val firArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(firModule, FrontendKinds.FIR)
|
val firArtifact = testConfiguration.testServices.dependencyProvider.getArtifact(firModule, FrontendKinds.FIR)
|
||||||
val firRenderer = firArtifact.firFiles.values.firstOrNull()?.let { FirVisualizer(it) }
|
val firRenderer = firArtifact.mainFirFiles.values.firstOrNull()?.let { FirVisualizer(it) }
|
||||||
firRenderResult = firRenderer?.render()?.trim() ?: ""
|
firRenderResult = firRenderer?.render()?.trim() ?: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.io.File
|
|||||||
|
|
||||||
internal class FirOutputHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
internal class FirOutputHandler(testServices: TestServices) : FirAnalysisHandler(testServices) {
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val renderer = info.firFiles.values.firstOrNull()?.let { FirVisualizer(it) } ?: return
|
val renderer = info.mainFirFiles.values.firstOrNull()?.let { FirVisualizer(it) } ?: return
|
||||||
val firRenderResult = renderer.render().trim()
|
val firRenderResult = renderer.render().trim()
|
||||||
|
|
||||||
val replaceFrom = module.directives[VisualizerDirectives.TEST_FILE_PATH].first()
|
val replaceFrom = module.directives[VisualizerDirectives.TEST_FILE_PATH].first()
|
||||||
|
|||||||
+6
-4
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
|||||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
||||||
|
import org.jetbrains.kotlin.fir.BinaryModuleData
|
||||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
||||||
import org.jetbrains.kotlin.fir.FirModuleDataImpl
|
import org.jetbrains.kotlin.fir.FirModuleDataImpl
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
@@ -45,7 +46,8 @@ internal fun PhaseContext.firFrontend(
|
|||||||
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
|
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
|
||||||
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
|
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
|
||||||
}
|
}
|
||||||
val dependencyList = DependencyListForCliModule.build(mainModuleName, CommonPlatforms.defaultCommonPlatform, NativePlatformAnalyzerServices) {
|
val binaryModuleData = BinaryModuleData.initialize(mainModuleName, CommonPlatforms.defaultCommonPlatform, NativePlatformAnalyzerServices)
|
||||||
|
val dependencyList = DependencyListForCliModule.build(binaryModuleData) {
|
||||||
dependencies(config.resolvedLibraries.getFullList().map { it.libraryFile.absolutePath })
|
dependencies(config.resolvedLibraries.getFullList().map { it.libraryFile.absolutePath })
|
||||||
friendDependencies(config.friendModuleFiles.map { it.absolutePath })
|
friendDependencies(config.friendModuleFiles.map { it.absolutePath })
|
||||||
// TODO: !!! dependencies module data?
|
// TODO: !!! dependencies module data?
|
||||||
@@ -55,7 +57,7 @@ internal fun PhaseContext.firFrontend(
|
|||||||
mainModuleName,
|
mainModuleName,
|
||||||
resolvedLibraries,
|
resolvedLibraries,
|
||||||
sessionProvider,
|
sessionProvider,
|
||||||
dependencyList,
|
dependencyList.moduleDataProvider,
|
||||||
configuration.languageVersionSettings,
|
configuration.languageVersionSettings,
|
||||||
registerExtraComponents = {},
|
registerExtraComponents = {},
|
||||||
)
|
)
|
||||||
@@ -64,8 +66,8 @@ internal fun PhaseContext.firFrontend(
|
|||||||
dependencyList.regularDependencies,
|
dependencyList.regularDependencies,
|
||||||
dependencyList.dependsOnDependencies,
|
dependencyList.dependsOnDependencies,
|
||||||
dependencyList.friendsDependencies,
|
dependencyList.friendsDependencies,
|
||||||
dependencyList.platform,
|
CommonPlatforms.defaultCommonPlatform,
|
||||||
dependencyList.analyzerServices
|
NativePlatformAnalyzerServices
|
||||||
)
|
)
|
||||||
val session = FirNativeSessionFactory.createModuleBasedSession(
|
val session = FirNativeSessionFactory.createModuleBasedSession(
|
||||||
mainModuleData,
|
mainModuleData,
|
||||||
|
|||||||
+40
-18
@@ -13,11 +13,8 @@ import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
|
|||||||
import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector
|
import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.*
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.*
|
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.*
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.toAbstractProjectEnvironment
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||||
@@ -29,10 +26,11 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
|||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
|
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.java.FirProjectSessionProvider
|
||||||
import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles
|
import org.jetbrains.kotlin.fir.pipeline.*
|
||||||
import org.jetbrains.kotlin.fir.pipeline.runCheckers
|
|
||||||
import org.jetbrains.kotlin.fir.pipeline.runResolution
|
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||||
import org.jetbrains.kotlin.modules.TargetId
|
import org.jetbrains.kotlin.modules.TargetId
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
@@ -52,6 +50,8 @@ import kotlin.script.experimental.jvm.JvmDependencyFromClassLoader
|
|||||||
import kotlin.script.experimental.jvm.compilationCache
|
import kotlin.script.experimental.jvm.compilationCache
|
||||||
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
|
||||||
import kotlin.script.experimental.jvm.jvm
|
import kotlin.script.experimental.jvm.jvm
|
||||||
|
import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class ScriptJvmCompilerIsolated(val hostConfiguration: ScriptingHostConfiguration) : ScriptCompilerProxy {
|
class ScriptJvmCompilerIsolated(val hostConfiguration: ScriptingHostConfiguration) : ScriptCompilerProxy {
|
||||||
|
|
||||||
@@ -349,20 +349,42 @@ private fun doCompileWithK2(
|
|||||||
val sessionProvider = FirProjectSessionProvider()
|
val sessionProvider = FirProjectSessionProvider()
|
||||||
val extendedAnalysisMode = kotlinCompilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
val extendedAnalysisMode = kotlinCompilerConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
|
||||||
|
|
||||||
val session = createSession(
|
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
|
||||||
targetId.name,
|
val providerAndScopeForIncrementalCompilation = createContextForIncrementalCompilation(
|
||||||
JvmPlatforms.unspecifiedJvmPlatform,
|
compilerInput.configuration,
|
||||||
kotlinCompilerConfiguration,
|
|
||||||
projectEnvironment,
|
projectEnvironment,
|
||||||
sourcesScope,
|
sourcesScope,
|
||||||
JvmPlatformAnalyzerServices,
|
emptyList(),
|
||||||
|
null
|
||||||
|
)?.also { (_, _, precompiledBinariesFileScope) ->
|
||||||
|
precompiledBinariesFileScope?.let { librariesScope -= it }
|
||||||
|
}
|
||||||
|
val libraryList = createLibraryListAndSession(targetId.name, kotlinCompilerConfiguration, projectEnvironment, librariesScope, sessionProvider)
|
||||||
|
val moduleData = FirModuleDataImpl(
|
||||||
|
Name.identifier(targetId.name),
|
||||||
|
libraryList.regularDependencies,
|
||||||
|
listOf(),
|
||||||
|
libraryList.friendsDependencies,
|
||||||
|
JvmPlatforms.unspecifiedJvmPlatform,
|
||||||
|
JvmPlatformAnalyzerServices
|
||||||
|
)
|
||||||
|
val session = FirJvmSessionFactory.createModuleBasedSession(
|
||||||
|
moduleData,
|
||||||
sessionProvider,
|
sessionProvider,
|
||||||
previousStepsSymbolProviders = emptyList(),
|
sourcesScope,
|
||||||
incrementalExcludesScope = null,
|
projectEnvironment,
|
||||||
extendedAnalysisMode = extendedAnalysisMode,
|
providerAndScopeForIncrementalCompilation,
|
||||||
needRegisterJavaElementFinder = true
|
extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) }
|
||||||
|
?: emptyList(),
|
||||||
|
kotlinCompilerConfiguration.languageVersionSettings,
|
||||||
|
lookupTracker = kotlinCompilerConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
|
||||||
|
enumWhenTracker = kotlinCompilerConfiguration.get(CommonConfigurationKeys.ENUM_WHEN_TRACKER),
|
||||||
|
needRegisterJavaElementFinder = true,
|
||||||
|
registerExtraComponents = {},
|
||||||
) {
|
) {
|
||||||
friendDependencies(kotlinCompilerConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
if (extendedAnalysisMode) {
|
||||||
|
registerExtendedCommonCheckers()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
session.scriptDefinitionProviderService?.run {
|
session.scriptDefinitionProviderService?.run {
|
||||||
@@ -376,7 +398,7 @@ private fun doCompileWithK2(
|
|||||||
// checkers
|
// checkers
|
||||||
session.runCheckers(scopeSession, fir, diagnosticsReporter)
|
session.runCheckers(scopeSession, fir, diagnosticsReporter)
|
||||||
|
|
||||||
val analysisResults = ModuleCompilerAnalyzedOutput(session, scopeSession, fir)
|
val analysisResults = FirResult(ModuleCompilerAnalyzedOutput(session, scopeSession, fir), null)
|
||||||
|
|
||||||
if (diagnosticsReporter.hasErrors) {
|
if (diagnosticsReporter.hasErrors) {
|
||||||
diagnosticsReporter.reportToMessageCollector(messageCollector, renderDiagnosticName)
|
diagnosticsReporter.reportToMessageCollector(messageCollector, renderDiagnosticName)
|
||||||
|
|||||||
Reference in New Issue
Block a user