[FIR] Support .jar output with -Xuse-fir flag
To proper support we need to fully implement main function detector, see KT-44557 ^KT-42868 Fixed
This commit is contained in:
committed by
teamcityserver
parent
9a5a3bfdfb
commit
8286927e8c
+53
-11
@@ -22,16 +22,15 @@ 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.config.*
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.fir.DependencyListForCliModule
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
|
||||||
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.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.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.convertToIr
|
import org.jetbrains.kotlin.fir.pipeline.convertToIr
|
||||||
import org.jetbrains.kotlin.fir.pipeline.runCheckers
|
import org.jetbrains.kotlin.fir.pipeline.runCheckers
|
||||||
@@ -41,6 +40,11 @@ import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
|||||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory.createSessionWithDependencies
|
import org.jetbrains.kotlin.fir.session.FirSessionFactory.createSessionWithDependencies
|
||||||
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.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.isArrayType
|
||||||
|
import org.jetbrains.kotlin.fir.types.isString
|
||||||
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
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
|
||||||
@@ -78,7 +82,7 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
"ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir"
|
"ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir"
|
||||||
)
|
)
|
||||||
|
|
||||||
val outputs = newLinkedHashMapWithExpectedSize<Module, GenerationState>(chunk.size)
|
val outputs = newLinkedHashMapWithExpectedSize<Module, 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
|
||||||
@@ -102,17 +106,21 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
outputs[module] = generationState
|
outputs[module] = generationState
|
||||||
}
|
}
|
||||||
|
|
||||||
val mainClassFqName: FqName? =
|
val mainClassFqName: FqName? = runIf(chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) {
|
||||||
if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null)
|
val firResult = outputs.values.single().first
|
||||||
TODO(".jar output is not yet supported for -Xuse-fir: KT-42868")
|
findMainClass(firResult)
|
||||||
else null
|
}
|
||||||
|
|
||||||
return writeOutputs(
|
return writeOutputs(
|
||||||
(projectEnvironment as? PsiBasedProjectEnvironment)?.project, projectConfiguration, chunk, outputs, mainClassFqName
|
(projectEnvironment as? PsiBasedProjectEnvironment)?.project,
|
||||||
|
projectConfiguration,
|
||||||
|
chunk,
|
||||||
|
outputs.mapValues { (_, value) -> value.second },
|
||||||
|
mainClassFqName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun CompilationContext.compileModule(): GenerationState? {
|
private fun CompilationContext.compileModule(): Pair<FirResult, GenerationState>? {
|
||||||
performanceManager?.notifyAnalysisStarted()
|
performanceManager?.notifyAnalysisStarted()
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
@@ -141,7 +149,7 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
performanceManager?.notifyGenerationFinished()
|
performanceManager?.notifyGenerationFinished()
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
return generationState
|
return firResult to generationState
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FirResult(
|
private class FirResult(
|
||||||
@@ -335,4 +343,38 @@ object FirKotlinToJvmBytecodeCompiler {
|
|||||||
val incrementalComponents: IncrementalCompilationComponents?,
|
val incrementalComponents: IncrementalCompilationComponents?,
|
||||||
val extendedAnalysisMode: Boolean
|
val extendedAnalysisMode: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun findMainClass(firResult: FirResult): FqName? {
|
||||||
|
// TODO: replace with proper main function detector, KT-44557
|
||||||
|
val compatibleClasses = mutableListOf<FqName>()
|
||||||
|
val visitor = object : FirVisitorVoid() {
|
||||||
|
lateinit var file: FirFile
|
||||||
|
|
||||||
|
override fun visitElement(element: FirElement) {}
|
||||||
|
|
||||||
|
override fun visitFile(file: FirFile) {
|
||||||
|
this.file = file
|
||||||
|
file.acceptChildren(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {
|
||||||
|
if (simpleFunction.name.asString() != "main") return
|
||||||
|
if (simpleFunction.typeParameters.isNotEmpty()) return
|
||||||
|
when (simpleFunction.valueParameters.size) {
|
||||||
|
0 -> {}
|
||||||
|
1 -> {
|
||||||
|
val parameterType = simpleFunction.valueParameters.single().returnTypeRef.coneType
|
||||||
|
if (!parameterType.isArrayType || parameterType.arrayElementType()?.isString != true) return
|
||||||
|
}
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
|
||||||
|
compatibleClasses += FqName.fromSegments(
|
||||||
|
file.packageFqName.pathSegments().map { it.asString() } + "${file.name.removeSuffix(".kt").capitalize()}Kt"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
firResult.fir.forEach { it.accept(visitor) }
|
||||||
|
return compatibleClasses.singleOrNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user