[K/N] A proper FrontendPhase
Rewrite frontend compiler phase using the new machinery. As a side effect, some lateinit context properties are not lazy anymore.
This commit is contained in:
committed by
Space Team
parent
4bae6d794c
commit
182662f7ed
+7
-7
@@ -62,13 +62,13 @@ internal class NativeMapping : DefaultMapping() {
|
||||
val loweredInlineClassConstructors = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrConstructor, IrSimpleFunction>()
|
||||
}
|
||||
|
||||
internal class Context(config: KonanConfig) : KonanBackendContext(config), ConfigChecks {
|
||||
lateinit var frontendServices: FrontendServices
|
||||
lateinit var environment: KotlinCoreEnvironment
|
||||
lateinit var bindingContext: BindingContext
|
||||
|
||||
lateinit var moduleDescriptor: ModuleDescriptor
|
||||
|
||||
internal class Context(
|
||||
config: KonanConfig,
|
||||
val environment: KotlinCoreEnvironment,
|
||||
val frontendServices: FrontendServices,
|
||||
var bindingContext: BindingContext,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
) : KonanBackendContext(config), ConfigChecks {
|
||||
/**
|
||||
* Valid from [createSymbolTablePhase] until [destroySymbolTablePhase].
|
||||
*/
|
||||
|
||||
+2
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FrontendContext
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportLazy
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportLazyImpl
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportProblemCollector
|
||||
@@ -45,7 +46,7 @@ internal fun StorageComponentContainer.initContainer(config: KonanConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ComponentProvider.postprocessComponents(context: Context, files: Collection<KtFile>) {
|
||||
internal fun ComponentProvider.postprocessComponents(context: FrontendContext, files: Collection<KtFile>) {
|
||||
context.frontendServices = this.get<FrontendServices>()
|
||||
|
||||
context.config.configuration.get(KonanConfigKeys.EMIT_LAZY_OBJC_HEADER_FILE)?.let {
|
||||
|
||||
+3
-2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FrontendContext
|
||||
import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
@@ -30,7 +31,7 @@ internal object TopDownAnalyzerFacadeForKonan {
|
||||
|
||||
private val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
|
||||
|
||||
fun analyzeFiles(files: Collection<KtFile>, context: Context): AnalysisResult {
|
||||
fun analyzeFiles(files: Collection<KtFile>, context: FrontendContext): AnalysisResult {
|
||||
val config = context.config
|
||||
val moduleName = Name.special("<${config.moduleId}>")
|
||||
|
||||
@@ -69,7 +70,7 @@ internal object TopDownAnalyzerFacadeForKonan {
|
||||
files: Collection<KtFile>,
|
||||
trace: BindingTrace,
|
||||
moduleContext: ModuleContext,
|
||||
context: Context,
|
||||
context: FrontendContext,
|
||||
projectContext: ProjectContext,
|
||||
additionalPackages: List<PackageFragmentProvider> = emptyList()
|
||||
): AnalysisResult {
|
||||
|
||||
+17
-40
@@ -6,13 +6,12 @@
|
||||
package org.jetbrains.kotlin.backend.konan.driver
|
||||
|
||||
import kotlinx.cinterop.usingJvmCInteropCallbacks
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FrontendContextImpl
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FrontendPhase
|
||||
import org.jetbrains.kotlin.backend.konan.driver.phases.FrontendPhaseOutput
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.konan.util.usingNativeMemoryAllocator
|
||||
|
||||
/**
|
||||
@@ -33,13 +32,22 @@ internal class StaticCompilerDriver : CompilerDriver() {
|
||||
targets.list()
|
||||
}
|
||||
|
||||
val context = Context(konanConfig)
|
||||
context.environment = environment
|
||||
context.phaseConfig.konanPhasesConfig(konanConfig) // TODO: Wrong place to call it
|
||||
|
||||
if (konanConfig.infoArgsOnly) return
|
||||
|
||||
if (!context.frontendPhase()) return
|
||||
val frontendContext = FrontendContextImpl(konanConfig)
|
||||
val frontendOutput = FrontendPhase.phaseBody(frontendContext, environment)
|
||||
if (frontendOutput is FrontendPhaseOutput.ShouldNotGenerateCode) {
|
||||
return
|
||||
}
|
||||
require(frontendOutput is FrontendPhaseOutput.Full)
|
||||
val context = Context(
|
||||
konanConfig,
|
||||
environment,
|
||||
frontendOutput.frontendServices,
|
||||
frontendOutput.bindingContext,
|
||||
frontendOutput.moduleDescriptor,
|
||||
)
|
||||
context.phaseConfig.konanPhasesConfig(konanConfig) // TODO: Wrong place to call it
|
||||
|
||||
usingNativeMemoryAllocator {
|
||||
usingJvmCInteropCallbacks {
|
||||
@@ -51,35 +59,4 @@ internal class StaticCompilerDriver : CompilerDriver() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if should generate code.
|
||||
private fun Context.frontendPhase(): Boolean {
|
||||
lateinit var analysisResult: AnalysisResult
|
||||
|
||||
do {
|
||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(
|
||||
messageCollector,
|
||||
environment.configuration.languageVersionSettings,
|
||||
environment.configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
|
||||
)
|
||||
|
||||
// Build AST and binding info.
|
||||
analyzerWithCompilerReport.analyzeAndReport(environment.getSourceFiles()) {
|
||||
TopDownAnalyzerFacadeForKonan.analyzeFiles(environment.getSourceFiles(), this)
|
||||
}
|
||||
if (analyzerWithCompilerReport.hasErrors()) {
|
||||
throw KonanCompilationException()
|
||||
}
|
||||
analysisResult = analyzerWithCompilerReport.analysisResult
|
||||
if (analysisResult is AnalysisResult.RetryWithAdditionalRoots) {
|
||||
environment.addKotlinSourceRoots(analysisResult.additionalKotlinRoots)
|
||||
}
|
||||
} while(analysisResult is AnalysisResult.RetryWithAdditionalRoots)
|
||||
|
||||
moduleDescriptor = analysisResult.moduleDescriptor
|
||||
bindingContext = analysisResult.bindingContext
|
||||
|
||||
return analysisResult.shouldGenerateCode
|
||||
}
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.driver.phases
|
||||
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.backend.konan.FrontendServices
|
||||
import org.jetbrains.kotlin.backend.konan.KonanCompilationException
|
||||
import org.jetbrains.kotlin.backend.konan.KonanConfig
|
||||
import org.jetbrains.kotlin.backend.konan.TopDownAnalyzerFacadeForKonan
|
||||
import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext
|
||||
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
|
||||
import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
sealed class FrontendPhaseOutput {
|
||||
object ShouldNotGenerateCode : FrontendPhaseOutput()
|
||||
|
||||
data class Full(
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val bindingContext: BindingContext,
|
||||
val frontendServices: FrontendServices,
|
||||
val environment: KotlinCoreEnvironment,
|
||||
) : FrontendPhaseOutput()
|
||||
}
|
||||
|
||||
internal interface FrontendContext : PhaseContext {
|
||||
var frontendServices: FrontendServices
|
||||
}
|
||||
|
||||
internal class FrontendContextImpl(
|
||||
config: KonanConfig
|
||||
) : BasicPhaseContext(config), FrontendContext {
|
||||
override lateinit var frontendServices: FrontendServices
|
||||
}
|
||||
|
||||
internal val FrontendPhase = createSimpleNamedCompilerPhase(
|
||||
"Frontend", "Compiler frontend",
|
||||
outputIfNotEnabled = { _, _, _, _ -> FrontendPhaseOutput.ShouldNotGenerateCode }
|
||||
) { context: FrontendContext, input: KotlinCoreEnvironment ->
|
||||
lateinit var analysisResult: AnalysisResult
|
||||
|
||||
do {
|
||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(
|
||||
context.messageCollector,
|
||||
input.configuration.languageVersionSettings,
|
||||
input.configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
|
||||
)
|
||||
|
||||
// Build AST and binding info.
|
||||
analyzerWithCompilerReport.analyzeAndReport(input.getSourceFiles()) {
|
||||
TopDownAnalyzerFacadeForKonan.analyzeFiles(input.getSourceFiles(), context)
|
||||
}
|
||||
if (analyzerWithCompilerReport.hasErrors()) {
|
||||
throw KonanCompilationException()
|
||||
}
|
||||
analysisResult = analyzerWithCompilerReport.analysisResult
|
||||
if (analysisResult is AnalysisResult.RetryWithAdditionalRoots) {
|
||||
input.addKotlinSourceRoots(analysisResult.additionalKotlinRoots)
|
||||
}
|
||||
} while (analysisResult is AnalysisResult.RetryWithAdditionalRoots)
|
||||
|
||||
val moduleDescriptor = analysisResult.moduleDescriptor
|
||||
val bindingContext = analysisResult.bindingContext
|
||||
|
||||
if (analysisResult.shouldGenerateCode) {
|
||||
FrontendPhaseOutput.Full(moduleDescriptor, bindingContext, context.frontendServices, input)
|
||||
} else {
|
||||
FrontendPhaseOutput.ShouldNotGenerateCode
|
||||
}
|
||||
}
|
||||
|
||||
internal fun <T : FrontendContext> PhaseEngine<T>.runFrontend(environment: KotlinCoreEnvironment): FrontendPhaseOutput {
|
||||
return this.runPhase(FrontendPhase, environment)
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.driver.phases
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfigurationService
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaserState
|
||||
import org.jetbrains.kotlin.backend.common.phaser.SimpleNamedCompilerPhase
|
||||
|
||||
internal fun <Context : LoggingContext, Input, Output> createSimpleNamedCompilerPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
outputIfNotEnabled: (PhaseConfigurationService, PhaserState<Input>, Context, Input) -> Output,
|
||||
phaseBody: (Context, Input) -> Output
|
||||
): SimpleNamedCompilerPhase<Context, Input, Output> = object : SimpleNamedCompilerPhase<Context, Input, Output>(name, description) {
|
||||
override fun outputIfNotEnabled(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input): Output =
|
||||
outputIfNotEnabled(phaseConfig, phaserState, context, input)
|
||||
|
||||
override fun phaseBody(context: Context, input: Input): Output =
|
||||
phaseBody(context, input)
|
||||
}
|
||||
|
||||
internal fun <Context : LoggingContext, Input> createSimpleNamedCompilerPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
phaseBody: (Context, Input) -> Unit
|
||||
): SimpleNamedCompilerPhase<Context, Input, Unit> = object : SimpleNamedCompilerPhase<Context, Input, Unit>(name, description) {
|
||||
override fun outputIfNotEnabled(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input) {}
|
||||
|
||||
override fun phaseBody(context: Context, input: Input): Unit =
|
||||
phaseBody(context, input)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user