Reorganize phaser
This commit is contained in:
+4
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -13,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
interface LoggingContext {
|
||||
var inVerbosePhase: Boolean
|
||||
fun log(message: () -> String)
|
||||
}
|
||||
|
||||
@@ -28,4 +30,6 @@ interface CommonBackendContext : BackendContext, LoggingContext {
|
||||
fun getInternalFunctions(name: String): List<FunctionDescriptor>
|
||||
|
||||
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
|
||||
|
||||
val configuration: CompilerConfiguration
|
||||
}
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.common
|
||||
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
interface CompilerPhase<in Context : BackendContext, Data> {
|
||||
val name: String
|
||||
val description: String
|
||||
val prerequisite: Set<CompilerPhase<*, *>>
|
||||
get() = emptySet()
|
||||
|
||||
fun invoke(context: Context, input: Data): Data
|
||||
}
|
||||
|
||||
private typealias AnyPhase = CompilerPhase<*, *>
|
||||
|
||||
class CompilerPhases(private val phaseList: List<AnyPhase>, config: CompilerConfiguration) {
|
||||
|
||||
val phases = phaseList.associate { it.name to it }
|
||||
|
||||
val enabled = computeEnabled(config)
|
||||
val verbose = phaseSetFromConfiguration(config, CommonConfigurationKeys.VERBOSE_PHASES)
|
||||
|
||||
val toDumpStateBefore: Set<AnyPhase>
|
||||
val toDumpStateAfter: Set<AnyPhase>
|
||||
|
||||
val toValidateStateBefore: Set<AnyPhase>
|
||||
val toValidateStateAfter: Set<AnyPhase>
|
||||
|
||||
init {
|
||||
with(CommonConfigurationKeys) {
|
||||
val beforeDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_BEFORE)
|
||||
val afterDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_AFTER)
|
||||
val bothDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE)
|
||||
toDumpStateBefore = beforeDumpSet + bothDumpSet
|
||||
toDumpStateAfter = afterDumpSet + bothDumpSet
|
||||
val beforeValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE_BEFORE)
|
||||
val afterValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE_AFTER)
|
||||
val bothValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE)
|
||||
toValidateStateBefore = beforeValidateSet + bothValidateSet
|
||||
toValidateStateAfter = afterValidateSet + bothValidateSet
|
||||
}
|
||||
}
|
||||
|
||||
fun known(name: String): String {
|
||||
if (phases[name] == null) {
|
||||
error("Unknown phase: $name. Use -Xlist-phases to see the list of phases.")
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
fun list() {
|
||||
phaseList.forEach { phase ->
|
||||
val enabled = if (phase in enabled) "(Enabled)" else ""
|
||||
val verbose = if (phase in verbose) "(Verbose)" else ""
|
||||
|
||||
println(String.format("%1$-30s %2$-50s %3$-10s", "${phase.name}:", phase.description, "$enabled $verbose"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeEnabled(config: CompilerConfiguration) =
|
||||
with(CommonConfigurationKeys) {
|
||||
val disabledPhases = phaseSetFromConfiguration(config, DISABLED_PHASES)
|
||||
phases.values.toSet() - disabledPhases
|
||||
}
|
||||
|
||||
private fun phaseSetFromConfiguration(config: CompilerConfiguration, key: CompilerConfigurationKey<Set<String>>): Set<AnyPhase> {
|
||||
val phaseNames = config.get(key) ?: emptySet()
|
||||
if ("ALL" in phaseNames) return phases.values.toSet()
|
||||
return phaseNames.map { phases[it]!! }.toSet()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface PhaseRunner<Context : BackendContext, Data> {
|
||||
fun runBefore(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
||||
fun runBody(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data
|
||||
fun runAfter(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
||||
}
|
||||
|
||||
abstract class DefaultIrPhaseRunner<Context : CommonBackendContext, Data : IrElement>(private val validator: (data: Data, context: Context) -> Unit = { _, _ -> }) :
|
||||
PhaseRunner<Context, Data> {
|
||||
|
||||
enum class BeforeOrAfter { BEFORE, AFTER }
|
||||
|
||||
abstract val startPhaseMarker: CompilerPhase<Context, Data>
|
||||
abstract val endPhaseMarker: CompilerPhase<Context, Data>
|
||||
|
||||
private var inVerbosePhase = false
|
||||
|
||||
final override fun runBefore(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data) {
|
||||
checkAndRun(phase, phases(context).toDumpStateBefore) { dumpElement(data, phase, context, BeforeOrAfter.BEFORE) }
|
||||
checkAndRun(phase, phases(context).toValidateStateBefore) { validator(data, context) }
|
||||
}
|
||||
|
||||
final override fun runBody(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data {
|
||||
val runner = when {
|
||||
phase === startPhaseMarker -> ::justRun
|
||||
phase === endPhaseMarker -> ::justRun
|
||||
needProfiling(context) -> ::runAndProfile
|
||||
else -> ::justRun
|
||||
}
|
||||
|
||||
inVerbosePhase = phase in phases(context).verbose
|
||||
|
||||
val result = runner(phase, context, source)
|
||||
|
||||
inVerbosePhase = false
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
final override fun runAfter(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data) {
|
||||
checkAndRun(phase, phases(context).toDumpStateAfter) { dumpElement(data, phase, context, BeforeOrAfter.AFTER) }
|
||||
checkAndRun(phase, phases(context).toValidateStateAfter) { validator(data, context) }
|
||||
}
|
||||
|
||||
open fun separator(title: String) = println("\n\n--- $title ----------------------\n")
|
||||
|
||||
protected abstract fun phases(context: Context): CompilerPhases
|
||||
protected abstract fun elementName(input: Data): String
|
||||
protected abstract fun configuration(context: Context): CompilerConfiguration
|
||||
|
||||
private fun needProfiling(context: Context) = configuration(context).getBoolean(CommonConfigurationKeys.PROFILE_PHASES)
|
||||
|
||||
private fun shouldBeDumped(context: Context, input: Data) =
|
||||
elementName(input) !in configuration(context).get(CommonConfigurationKeys.EXCLUDED_ELEMENTS_FROM_DUMPING, emptySet())
|
||||
|
||||
private fun checkAndRun(phase: CompilerPhase<Context, Data>, set: Set<AnyPhase>, block: () -> Unit) {
|
||||
if (phase in set) block()
|
||||
}
|
||||
|
||||
private fun dumpElement(input: Data, phase: CompilerPhase<Context, Data>, context: Context, beforeOrAfter: BeforeOrAfter) {
|
||||
// Exclude nonsensical combinations
|
||||
if (phase === startPhaseMarker && beforeOrAfter == BeforeOrAfter.AFTER) return
|
||||
if (phase === endPhaseMarker && beforeOrAfter == BeforeOrAfter.BEFORE) return
|
||||
|
||||
if (!shouldBeDumped(context, input)) return
|
||||
|
||||
val title = when (phase) {
|
||||
startPhaseMarker -> "IR for ${elementName(input)} at the start of lowering process"
|
||||
endPhaseMarker -> "IR for ${elementName(input)} at the end of lowering process"
|
||||
else -> {
|
||||
val beforeOrAfterStr = beforeOrAfter.name.toLowerCase()
|
||||
"IR for ${elementName(input)} $beforeOrAfterStr ${phase.description}"
|
||||
}
|
||||
}
|
||||
separator(title)
|
||||
println(input.dump())
|
||||
}
|
||||
|
||||
private fun runAndProfile(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data {
|
||||
var result: Data = source
|
||||
val msec = measureTimeMillis { result = phase.invoke(context, source) }
|
||||
println("${phase.description}: $msec msec")
|
||||
return result
|
||||
}
|
||||
|
||||
private fun justRun(phase: CompilerPhase<Context, Data>, context: Context, source: Data) =
|
||||
phase.invoke(context, source)
|
||||
}
|
||||
|
||||
class CompilerPhaseManager<Context : BackendContext, Data>(
|
||||
val context: Context,
|
||||
val phases: CompilerPhases,
|
||||
val data: Data,
|
||||
private val phaseRunner: PhaseRunner<Context, Data>,
|
||||
val parent: CompilerPhaseManager<Context, *>? = null
|
||||
) {
|
||||
val depth: Int = parent?.depth?.inc() ?: 0
|
||||
|
||||
private val previousPhases = mutableSetOf<CompilerPhase<Context, Data>>()
|
||||
|
||||
fun <NewData> createChild(
|
||||
newData: NewData,
|
||||
newPhaseRunner: PhaseRunner<Context, NewData>
|
||||
) = CompilerPhaseManager(
|
||||
context, phases, newData, newPhaseRunner, parent = this
|
||||
)
|
||||
|
||||
fun createChild() = createChild(data, phaseRunner)
|
||||
|
||||
private fun checkPrerequisite(phase: CompilerPhase<*, *>): Boolean =
|
||||
previousPhases.contains(phase) || parent?.checkPrerequisite(phase) == true
|
||||
|
||||
fun phase(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data {
|
||||
|
||||
if (phase !in phases.enabled) return source
|
||||
|
||||
phase.prerequisite.forEach {
|
||||
if (!checkPrerequisite(it))
|
||||
throw Error("$phase requires $it")
|
||||
}
|
||||
|
||||
previousPhases.add(phase)
|
||||
|
||||
phaseRunner.runBefore(phase, depth, context, source)
|
||||
val result = phaseRunner.runBody(phase, context, source)
|
||||
phaseRunner.runAfter(phase, depth, context, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun <Context : BackendContext, Data> makePhase(
|
||||
lowering: (Context, Data) -> Unit,
|
||||
description: String,
|
||||
name: String,
|
||||
prerequisite: Set<CompilerPhase<*, *>> = emptySet()
|
||||
) = object : CompilerPhase<Context, Data> {
|
||||
override val name = name
|
||||
override val description = description
|
||||
override val prerequisite = prerequisite
|
||||
|
||||
override fun invoke(context: Context, input: Data): Data {
|
||||
lowering(context, input)
|
||||
return input
|
||||
}
|
||||
|
||||
override fun toString() = "Compiler Phase @$name"
|
||||
}
|
||||
@@ -17,10 +17,7 @@
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -54,6 +51,8 @@ interface BodyLoweringPass : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) }
|
||||
|
||||
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
|
||||
+7
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -31,6 +32,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val jvmDefaultArgumentStubPhase = makeIrFilePhase(
|
||||
{ context -> DefaultArgumentStubGenerator(context, false) },
|
||||
name = "DefaultArgumentsStubGenerator",
|
||||
description = "Generate synthetic stubs for functions with default parameter values"
|
||||
)
|
||||
|
||||
// TODO: fix expect/actual default parameters
|
||||
|
||||
open class DefaultArgumentStubGenerator(
|
||||
|
||||
+11
-7
@@ -8,12 +8,14 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithWrappedDescriptors
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.SetDeclarationsParentVisitor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -26,10 +28,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
|
||||
import org.jetbrains.kotlin.ir.util.SymbolRenamer
|
||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -38,6 +36,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
|
||||
object SYNTHESIZED_INIT_BLOCK: IrStatementOriginImpl("SYNTHESIZED_INIT_BLOCK")
|
||||
|
||||
fun makeInitializersPhase(origin: IrDeclarationOrigin, clinitNeeded: Boolean)= makeIrFilePhase(
|
||||
{ context -> InitializersLowering(context, origin, clinitNeeded) },
|
||||
name = "Initializers",
|
||||
description = "Handle initializer statements"
|
||||
)
|
||||
|
||||
class InitializersLowering(
|
||||
val context: CommonBackendContext,
|
||||
val declarationOrigin: IrDeclarationOrigin,
|
||||
|
||||
+13
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
@@ -28,6 +28,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import java.util.*
|
||||
|
||||
val innerClassesPhase = makeIrFilePhase(
|
||||
::InnerClassesLowering,
|
||||
name = "InnerClasses",
|
||||
description = "Move inner classes to toplevel"
|
||||
)
|
||||
|
||||
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
InnerClassTransformer(irClass).lowerInnerClass()
|
||||
@@ -169,6 +175,12 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
}
|
||||
}
|
||||
|
||||
val innerClassConstructorCallsPhase = makeIrFilePhase(
|
||||
::InnerClassConstructorCallsLowering,
|
||||
name = "InnerClassConstructorCalls",
|
||||
description = "Handle constructor calls for inner classes"
|
||||
)
|
||||
|
||||
class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass {
|
||||
override fun lower(irBody: IrBody) {
|
||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
|
||||
+8
-2
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
@@ -32,7 +32,13 @@ import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
class KCallableNamePropertyLowering(val context: BackendContext) : FileLoweringPass {
|
||||
val kCallableNamePropertyPhase = makeIrFilePhase(
|
||||
::KCallableNamePropertyLowering,
|
||||
name = "KCallableNameProperty",
|
||||
description = "Replace name references for callables with constants"
|
||||
)
|
||||
|
||||
private class KCallableNamePropertyLowering(val context: BackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(KCallableNamePropertyTransformer(this))
|
||||
}
|
||||
|
||||
+6
-10
@@ -17,8 +17,8 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -34,15 +34,11 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
fun makeLateinitPhase() = object : CompilerPhase<CommonBackendContext, IrFile> {
|
||||
override val name = "Lateinit"
|
||||
override val description = "Insert checks for lateinit field references"
|
||||
|
||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
||||
LateinitLowering(context).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
val jvmLateinitPhase = makeIrFilePhase(
|
||||
::LateinitLowering,
|
||||
name = "Lateinit",
|
||||
description = "Insert checks for lateinit field references"
|
||||
)
|
||||
|
||||
class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
|
||||
+14
-1
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
@@ -33,8 +33,21 @@ import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
import java.util.*
|
||||
|
||||
val jvmLocalDeclarationsPhase = makeIrFilePhase(
|
||||
{ context ->
|
||||
LocalDeclarationsLowering(context, object : LocalNameProvider {
|
||||
override fun localName(declaration: IrDeclarationWithName): String =
|
||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(declaration))
|
||||
}, Visibilities.PUBLIC, true)
|
||||
},
|
||||
name = "JvmLocalDeclarations",
|
||||
description = "Move local declarations to classes",
|
||||
prerequisite = setOf(sharedVariablesPhase)
|
||||
)
|
||||
|
||||
interface LocalNameProvider {
|
||||
fun localName(declaration: IrDeclarationWithName): String =
|
||||
declaration.name.asString()
|
||||
|
||||
+7
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -18,6 +18,12 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
val propertiesPhase = makeIrFilePhase(
|
||||
::PropertiesLowering,
|
||||
name = "Properties",
|
||||
description = "Move fields and accessors for properties to their classes"
|
||||
)
|
||||
|
||||
class PropertiesLowering() : IrElementTransformerVoid(), FileLoweringPass {
|
||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||
|
||||
|
||||
+9
-1
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
@@ -30,6 +32,12 @@ import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import java.util.*
|
||||
|
||||
val sharedVariablesPhase = makeIrFilePhase(
|
||||
::SharedVariablesLowering,
|
||||
name = "SharedVariables",
|
||||
description = "Transform shared variables"
|
||||
)
|
||||
|
||||
object CoroutineIntrinsicLambdaOrigin : IrStatementOriginImpl("Coroutine intrinsic lambda")
|
||||
|
||||
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
||||
|
||||
+7
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -27,6 +28,12 @@ import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
val tailrecPhase = makeIrFilePhase(
|
||||
::TailrecLowering,
|
||||
name = "Tailrec",
|
||||
description = "Handle tailrec calls"
|
||||
)
|
||||
|
||||
/**
|
||||
* This pass lowers tail recursion calls in `tailrec` functions.
|
||||
*
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.common.phaser
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class PhaserState {
|
||||
val alreadyDone = mutableSetOf<AnyNamedPhase>()
|
||||
var depth = 0
|
||||
}
|
||||
|
||||
fun <R> PhaserState.downlevel(nlevels: Int = 1, block: () -> R): R {
|
||||
depth += nlevels
|
||||
val result = block()
|
||||
depth -= nlevels
|
||||
return result
|
||||
}
|
||||
|
||||
interface CompilerPhase<in Context : CommonBackendContext, in Input, out Output> {
|
||||
fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output
|
||||
|
||||
fun getNamedSubphases(startDepth: Int = 0): List<Pair<Int, NamedCompilerPhase<*, *, *>>> = emptyList()
|
||||
}
|
||||
|
||||
fun <Context: CommonBackendContext, Input, Output> CompilerPhase<Context, Input, Output>.invokeToplevel(
|
||||
phaseConfig: PhaseConfig,
|
||||
context: Context,
|
||||
input: Input
|
||||
): Output = invoke(phaseConfig, PhaserState(), context, input)
|
||||
|
||||
interface SameTypeCompilerPhase<in Context: CommonBackendContext, Data> : CompilerPhase<Context, Data, Data>
|
||||
|
||||
interface NamedCompilerPhase<in Context : CommonBackendContext, in Input, out Output> : CompilerPhase<Context, Input, Output> {
|
||||
val name: String
|
||||
val description: String
|
||||
val prerequisite: Set<AnyNamedPhase> get() = emptySet()
|
||||
}
|
||||
|
||||
typealias AnyNamedPhase = NamedCompilerPhase<*, *, *>
|
||||
|
||||
enum class BeforeOrAfter { BEFORE, AFTER }
|
||||
|
||||
interface PhaseDumperVerifier<in Context : CommonBackendContext, Data> {
|
||||
fun dump(phase: AnyNamedPhase, context: Context, data: Data, beforeOrAfter: BeforeOrAfter)
|
||||
fun verify(context: Context, data: Data)
|
||||
}
|
||||
|
||||
abstract class AbstractNamedPhaseWrapper<in Context : CommonBackendContext, Input, Output>(
|
||||
override val name: String,
|
||||
override val description: String,
|
||||
override val prerequisite: Set<AnyNamedPhase>,
|
||||
private val nlevels: Int = 0,
|
||||
private val lower: CompilerPhase<Context, Input, Output>
|
||||
) : NamedCompilerPhase<Context, Input, Output> {
|
||||
abstract val inputDumperVerifier: PhaseDumperVerifier<Context, Input>
|
||||
abstract val outputDumperVerifier: PhaseDumperVerifier<Context, Output>
|
||||
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output {
|
||||
if (this is SameTypeCompilerPhase<*, *> &&
|
||||
this !in phaseConfig.enabled
|
||||
) {
|
||||
return input as Output
|
||||
}
|
||||
|
||||
assert(phaserState.alreadyDone.containsAll(prerequisite))
|
||||
context.inVerbosePhase = this in phaseConfig.verbose
|
||||
|
||||
runBefore(phaseConfig, context, input)
|
||||
val output = runBody(phaseConfig, phaserState, context, input)
|
||||
runAfter(phaseConfig, context, output)
|
||||
|
||||
phaserState.alreadyDone.add(this)
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
private fun runBefore(phaseConfig: PhaseConfig, context: Context, input: Input) {
|
||||
checkAndRun(phaseConfig.toDumpStateBefore) { inputDumperVerifier.dump(this, context, input, BeforeOrAfter.BEFORE) }
|
||||
checkAndRun(phaseConfig.toValidateStateBefore) { inputDumperVerifier.verify(context, input) }
|
||||
}
|
||||
|
||||
private fun runBody(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output {
|
||||
return if (phaseConfig.needProfiling) {
|
||||
runAndProfile(phaseConfig, phaserState, context, input)
|
||||
} else {
|
||||
phaserState.downlevel(nlevels) {
|
||||
lower.invoke(phaseConfig, phaserState, context, input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runAfter(phaseConfig: PhaseConfig, context: Context, output: Output) {
|
||||
checkAndRun(phaseConfig.toDumpStateAfter) { outputDumperVerifier.dump(this, context, output, BeforeOrAfter.AFTER) }
|
||||
checkAndRun(phaseConfig.toValidateStateAfter) { outputDumperVerifier.verify(context, output) }
|
||||
}
|
||||
|
||||
private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, source: Input): Output {
|
||||
var result: Output? = null
|
||||
val msec = measureTimeMillis {
|
||||
result = phaserState.downlevel(nlevels) {
|
||||
lower.invoke(phaseConfig, phaserState, context, source)
|
||||
}
|
||||
}
|
||||
// TODO: use a proper logger
|
||||
println("${"\t".repeat(phaserState.depth)}$description: $msec msec")
|
||||
return result!!
|
||||
}
|
||||
|
||||
private fun checkAndRun(set: Set<AnyNamedPhase>, block: () -> Unit) {
|
||||
if (this in set) block()
|
||||
}
|
||||
|
||||
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, NamedCompilerPhase<*, *, *>>> =
|
||||
listOf(startDepth to this) + lower.getNamedSubphases(startDepth + nlevels)
|
||||
|
||||
override fun toString() = "Compiler Phase @$name"
|
||||
}
|
||||
|
||||
class SameTypeNamedPhaseWrapper<in Context : CommonBackendContext, Data>(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase>,
|
||||
nlevels: Int = 0,
|
||||
lower: CompilerPhase<Context, Data, Data>,
|
||||
val dumperVerifier: PhaseDumperVerifier<Context, Data>
|
||||
) : AbstractNamedPhaseWrapper<Context, Data, Data>(name, description, prerequisite, nlevels, lower), SameTypeCompilerPhase<Context, Data> {
|
||||
override val inputDumperVerifier get() = dumperVerifier
|
||||
override val outputDumperVerifier get() = dumperVerifier
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package org.jetbrains.kotlin.backend.common.phaser
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.name
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
|
||||
abstract class IrPhaseDumperVerifier<in Context : CommonBackendContext, Data : IrElement>(
|
||||
val verifier: (Context, Data) -> Unit
|
||||
) : PhaseDumperVerifier<Context, Data> {
|
||||
abstract fun Data.getElementName(): String
|
||||
|
||||
// TODO: use a proper logger.
|
||||
override fun dump(phase: AnyNamedPhase, context: Context, data: Data, beforeOrAfter: BeforeOrAfter) {
|
||||
fun separator(title: String) = println("\n\n--- $title ----------------------\n")
|
||||
|
||||
if (!shouldBeDumped(context, data)) return
|
||||
|
||||
val beforeOrAfterStr = beforeOrAfter.name.toLowerCase()
|
||||
val title = "IR for ${data.getElementName()} $beforeOrAfterStr ${phase.description}"
|
||||
separator(title)
|
||||
println(data.dump())
|
||||
}
|
||||
|
||||
override fun verify(context: Context, data: Data) = verifier(context, data)
|
||||
|
||||
private fun shouldBeDumped(context: Context, input: Data) =
|
||||
input.getElementName() !in context.configuration.get(CommonConfigurationKeys.EXCLUDED_ELEMENTS_FROM_DUMPING, emptySet())
|
||||
}
|
||||
|
||||
class IrFileDumperVerifier<in Context : CommonBackendContext>(verifier: (Context, IrFile) -> Unit) :
|
||||
IrPhaseDumperVerifier<Context, IrFile>(verifier) {
|
||||
override fun IrFile.getElementName() = name
|
||||
}
|
||||
|
||||
class IrModuleDumperVerifier<in Context : CommonBackendContext>(verifier: (Context, IrModuleFragment) -> Unit) :
|
||||
IrPhaseDumperVerifier<Context, IrModuleFragment>(verifier) {
|
||||
override fun IrModuleFragment.getElementName() = name.asString()
|
||||
}
|
||||
|
||||
class EmptyDumperVerifier<in Context : CommonBackendContext, Data> : PhaseDumperVerifier<Context, Data> {
|
||||
override fun dump(phase: AnyNamedPhase, context: Context, data: Data, beforeOrAfter: BeforeOrAfter) {}
|
||||
override fun verify(context: Context, data: Data) {}
|
||||
}
|
||||
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
package org.jetbrains.kotlin.backend.common.phaser
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
|
||||
// Phase composition.
|
||||
infix fun <Context : CommonBackendContext, Input, Mid, Output> CompilerPhase<Context, Input, Mid>.then(
|
||||
other: CompilerPhase<Context, Mid, Output>
|
||||
) = object : CompilerPhase<Context, Input, Output> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output =
|
||||
this@then.invoke(phaseConfig, phaserState, context, input).let { mid ->
|
||||
other.invoke(phaseConfig, phaserState, context, mid)
|
||||
}
|
||||
|
||||
override fun getNamedSubphases(startDepth: Int) =
|
||||
this@then.getNamedSubphases(startDepth) + other.getNamedSubphases(startDepth)
|
||||
}
|
||||
|
||||
fun <Context : CommonBackendContext> namedIrModulePhase(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
verify: (Context, IrModuleFragment) -> Unit = { _, _ -> },
|
||||
nlevels: Int = 1,
|
||||
lower: CompilerPhase<Context, IrModuleFragment, IrModuleFragment>
|
||||
) = SameTypeNamedPhaseWrapper(name, description, prerequisite, nlevels, lower, IrModuleDumperVerifier(verify))
|
||||
|
||||
fun <Context : CommonBackendContext> namedIrFilePhase(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
verify: (Context, IrFile) -> Unit = { _, _ -> },
|
||||
nlevels: Int = 1,
|
||||
lower: CompilerPhase<Context, IrFile, IrFile>
|
||||
) = SameTypeNamedPhaseWrapper(name, description, prerequisite, nlevels, lower, IrFileDumperVerifier(verify))
|
||||
|
||||
fun <Context : CommonBackendContext> namedUnitPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
nlevels: Int = 1,
|
||||
lower: CompilerPhase<Context, Unit, Unit>
|
||||
) = SameTypeNamedPhaseWrapper(name, description, prerequisite, nlevels, lower, EmptyDumperVerifier())
|
||||
|
||||
fun <Context : CommonBackendContext> namedOpUnitPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase>,
|
||||
op: Context.() -> Unit
|
||||
) = namedUnitPhase(
|
||||
name, description, prerequisite,
|
||||
nlevels = 0,
|
||||
lower = object : SameTypeCompilerPhase<Context, Unit> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Unit) {
|
||||
context.op()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fun <Context : CommonBackendContext> performByIrFile(
|
||||
name: String = "PerformByIrFile",
|
||||
description: String = "Perform phases by IrFile",
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
verify: (Context, IrModuleFragment) -> Unit = { _, _ -> },
|
||||
lower: CompilerPhase<Context, IrFile, IrFile>
|
||||
) = namedIrModulePhase(
|
||||
name, description, prerequisite, verify,
|
||||
nlevels = 1,
|
||||
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
|
||||
override fun invoke(
|
||||
phaseConfig: PhaseConfig,
|
||||
phaserState: PhaserState,
|
||||
context: Context,
|
||||
input: IrModuleFragment
|
||||
): IrModuleFragment {
|
||||
for (irFile in input.files) {
|
||||
lower.invoke(phaseConfig, phaserState, context, irFile)
|
||||
}
|
||||
|
||||
// TODO: no guarantee that module identity is preserved by `lower`
|
||||
return input
|
||||
}
|
||||
|
||||
override fun getNamedSubphases(startDepth: Int) = lower.getNamedSubphases(startDepth)
|
||||
}
|
||||
)
|
||||
|
||||
fun <Context : CommonBackendContext> makeIrFilePhase(
|
||||
lowering: (Context) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
verify: (Context, IrFile) -> Unit = { _, _ -> }
|
||||
) = namedIrFilePhase(
|
||||
name, description, prerequisite, verify,
|
||||
nlevels = 0,
|
||||
lower = object : SameTypeCompilerPhase<Context, IrFile> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrFile): IrFile {
|
||||
lowering(context).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fun <Context : CommonBackendContext> makeIrModulePhase(
|
||||
lowering: (Context) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet(),
|
||||
verify: (Context, IrModuleFragment) -> Unit = { _, _ -> }
|
||||
) = namedIrModulePhase(
|
||||
name, description, prerequisite, verify,
|
||||
nlevels = 0,
|
||||
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
|
||||
override fun invoke(
|
||||
phaseConfig: PhaseConfig,
|
||||
phaserState: PhaserState,
|
||||
context: Context,
|
||||
input: IrModuleFragment
|
||||
): IrModuleFragment {
|
||||
lowering(context).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fun <Context : CommonBackendContext, Input> unitPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase>,
|
||||
op: Context.() -> Unit
|
||||
) =
|
||||
object : AbstractNamedPhaseWrapper<Context, Input, Unit>(
|
||||
name, description, prerequisite,
|
||||
nlevels = 0,
|
||||
lower = object : CompilerPhase<Context, Input, Unit> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input) {
|
||||
context.op()
|
||||
}
|
||||
}
|
||||
) {
|
||||
override val inputDumperVerifier = EmptyDumperVerifier<Context, Input>()
|
||||
override val outputDumperVerifier = EmptyDumperVerifier<Context, Unit>()
|
||||
}
|
||||
|
||||
fun <Context : CommonBackendContext, Input> unitSink() = object : CompilerPhase<Context, Input, Unit> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input) {}
|
||||
}
|
||||
|
||||
// Intermediate phases to change the object of transformations
|
||||
fun <Context : CommonBackendContext, OldData, NewData> takeFromContext(op: (Context) -> NewData) =
|
||||
object : CompilerPhase<Context, OldData, NewData> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: OldData) = op(context)
|
||||
}
|
||||
|
||||
fun <Context : CommonBackendContext, OldData, NewData> transform(op: (OldData) -> NewData) =
|
||||
object : CompilerPhase<Context, OldData, NewData> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: OldData) = op(input)
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package org.jetbrains.kotlin.backend.common.phaser
|
||||
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
|
||||
class PhaseConfig(private val compoundPhase: CompilerPhase<*, *, *>, config: CompilerConfiguration) {
|
||||
|
||||
val phases = compoundPhase.getNamedSubphases().map { (_, phase) -> phase }.associate { it.name to it }
|
||||
private val enabledMut = computeEnabled(config).toMutableSet()
|
||||
|
||||
val enabled: Set<AnyNamedPhase> get() = enabledMut
|
||||
|
||||
val verbose = phaseSetFromConfiguration(config, CommonConfigurationKeys.VERBOSE_PHASES)
|
||||
val toDumpStateBefore: Set<AnyNamedPhase>
|
||||
|
||||
val toDumpStateAfter: Set<AnyNamedPhase>
|
||||
val toValidateStateBefore: Set<AnyNamedPhase>
|
||||
|
||||
val toValidateStateAfter: Set<AnyNamedPhase>
|
||||
|
||||
init {
|
||||
with(CommonConfigurationKeys) {
|
||||
val beforeDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_BEFORE)
|
||||
val afterDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_AFTER)
|
||||
val bothDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE)
|
||||
toDumpStateBefore = beforeDumpSet + bothDumpSet
|
||||
toDumpStateAfter = afterDumpSet + bothDumpSet
|
||||
val beforeValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE_BEFORE)
|
||||
val afterValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE_AFTER)
|
||||
val bothValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE)
|
||||
toValidateStateBefore = beforeValidateSet + bothValidateSet
|
||||
toValidateStateAfter = afterValidateSet + bothValidateSet
|
||||
}
|
||||
}
|
||||
|
||||
val needProfiling = config.getBoolean(CommonConfigurationKeys.PROFILE_PHASES)
|
||||
|
||||
fun known(name: String): String {
|
||||
if (phases[name] == null) {
|
||||
error("Unknown phase: $name. Use -Xlist-phases to see the list of phases.")
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
fun list() {
|
||||
compoundPhase.getNamedSubphases().forEach { (depth, phase) ->
|
||||
val enabled = if (phase in enabled) "(Enabled)" else ""
|
||||
val verbose = if (phase in verbose) "(Verbose)" else ""
|
||||
|
||||
println(String.format("%1$-50s %2$-50s %3$-10s", "${"\t".repeat(depth)}${phase.name}:", phase.description, "$enabled $verbose"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeEnabled(config: CompilerConfiguration) =
|
||||
with(CommonConfigurationKeys) {
|
||||
val disabledPhases = phaseSetFromConfiguration(config, DISABLED_PHASES)
|
||||
phases.values.toSet() - disabledPhases
|
||||
}
|
||||
|
||||
private fun phaseSetFromConfiguration(config: CompilerConfiguration, key: CompilerConfigurationKey<Set<String>>): Set<AnyNamedPhase> {
|
||||
val phaseNames = config.get(key) ?: emptySet()
|
||||
if ("ALL" in phaseNames) return phases.values.toSet()
|
||||
return phaseNames.map { phases[it]!! }.toSet()
|
||||
}
|
||||
|
||||
fun enable(phase: AnyNamedPhase) {
|
||||
enabledMut.add(phase)
|
||||
}
|
||||
|
||||
fun disable(phase: AnyNamedPhase) {
|
||||
enabledMut.remove(phase)
|
||||
}
|
||||
fun switch(phase: AnyNamedPhase, onOff: Boolean) {
|
||||
if (onOff) {
|
||||
enable(phase)
|
||||
} else {
|
||||
disable(phase)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhases
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
@@ -47,13 +47,14 @@ class JsIrBackendContext(
|
||||
override val irBuiltIns: IrBuiltIns,
|
||||
val symbolTable: SymbolTable,
|
||||
irModuleFragment: IrModuleFragment,
|
||||
val configuration: CompilerConfiguration,
|
||||
override val configuration: CompilerConfiguration,
|
||||
val dependencies: List<IrModuleFragment>
|
||||
) : CommonBackendContext {
|
||||
|
||||
override val builtIns = module.builtIns
|
||||
|
||||
val phases = CompilerPhases(jsPhases, configuration)
|
||||
val phaseConfig = PhaseConfig(jsPhases, configuration)
|
||||
override var inVerbosePhase: Boolean = false
|
||||
|
||||
val internalPackageFragmentDescriptor = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
|
||||
val implicitDeclarationFile by lazy {
|
||||
@@ -283,7 +284,7 @@ class JsIrBackendContext(
|
||||
|
||||
override fun log(message: () -> String) {
|
||||
/*TODO*/
|
||||
print(message())
|
||||
if (inVerbosePhase) print(message())
|
||||
}
|
||||
|
||||
override fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean) {
|
||||
|
||||
+181
-162
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering
|
||||
@@ -21,65 +22,90 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
|
||||
private fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) }
|
||||
|
||||
private fun DeclarationContainerLoweringPass.runOnFilesPostfix(files: Iterable<IrFile>) = files.forEach { runOnFilePostfix(it) }
|
||||
|
||||
private fun ClassLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { runOnFilePostfix(it) }
|
||||
|
||||
|
||||
object IrModuleStartPhase : CompilerPhase<BackendContext, IrModuleFragment> {
|
||||
override val name = "IrModuleFragment"
|
||||
override val description = "State at start of IrModuleFragment lowering"
|
||||
override val prerequisite = emptySet()
|
||||
override fun invoke(context: BackendContext, input: IrModuleFragment) = input
|
||||
private fun validationCallback(context: JsIrBackendContext, module: IrModuleFragment) {
|
||||
val validatorConfig = IrValidatorConfig(
|
||||
abortOnError = true,
|
||||
ensureAllNodesAreDifferent = true,
|
||||
checkTypes = false,
|
||||
checkDescriptors = false
|
||||
)
|
||||
module.accept(IrValidator(context, validatorConfig), null)
|
||||
module.accept(CheckDeclarationParentsVisitor, null)
|
||||
}
|
||||
|
||||
private fun makeJsPhase(
|
||||
lowering: (JsIrBackendContext, IrModuleFragment) -> Unit,
|
||||
private fun makeJsModulePhase(
|
||||
lowering: (JsIrBackendContext) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = makeIrModulePhase<JsIrBackendContext>(lowering, name, description, prerequisite, verify = ::validationCallback)
|
||||
|
||||
private fun makeCustomJsModulePhase(
|
||||
op: (JsIrBackendContext, IrModuleFragment) -> Unit,
|
||||
description: String,
|
||||
name: String,
|
||||
prerequisite: Set<CompilerPhase<JsIrBackendContext, IrModuleFragment>> = emptySet()
|
||||
) = makePhase(lowering, description, name, prerequisite)
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = namedIrModulePhase(
|
||||
name,
|
||||
description,
|
||||
prerequisite,
|
||||
verify = ::validationCallback,
|
||||
nlevels = 0,
|
||||
lower = object : SameTypeCompilerPhase<JsIrBackendContext, IrModuleFragment> {
|
||||
override fun invoke(
|
||||
phaseConfig: PhaseConfig,
|
||||
phaserState: PhaserState,
|
||||
context: JsIrBackendContext,
|
||||
input: IrModuleFragment
|
||||
): IrModuleFragment {
|
||||
op(context, input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
private val MoveBodilessDeclarationsToSeparatePlacePhase = makeJsPhase(
|
||||
{ _, module -> MoveBodilessDeclarationsToSeparatePlace().lower(module) },
|
||||
private val moveBodilessDeclarationsToSeparatePlacePhase = makeJsModulePhase(
|
||||
::MoveBodilessDeclarationsToSeparatePlace,
|
||||
name = "MoveBodilessDeclarationsToSeparatePlace",
|
||||
description = "Move `external` and `built-in` declarations into separate place to make the following lowerings do not care about them"
|
||||
)
|
||||
|
||||
private val ExpectDeclarationsRemovingPhase = makeJsPhase(
|
||||
{ context, module -> ExpectDeclarationsRemoving(context).lower(module) },
|
||||
private val expectDeclarationsRemovingPhase = makeJsModulePhase(
|
||||
::ExpectDeclarationsRemoving,
|
||||
name = "ExpectDeclarationsRemoving",
|
||||
description = "Remove expect declaration from module fragment"
|
||||
)
|
||||
|
||||
private val CoroutineIntrinsicLoweringPhase = makeJsPhase(
|
||||
{ context, module -> CoroutineIntrinsicLowering(context).lower(module) },
|
||||
private val coroutineIntrinsicLoweringPhase = makeJsModulePhase(
|
||||
::CoroutineIntrinsicLowering,
|
||||
name = "CoroutineIntrinsicLowering",
|
||||
description = "Replace common coroutine intrinsics with platform specific ones"
|
||||
)
|
||||
|
||||
private val ArrayInlineConstructorLoweringPhase = makeJsPhase(
|
||||
{ context, module -> ArrayInlineConstructorLowering(context).lower(module) },
|
||||
private val arrayInlineConstructorLoweringPhase = makeJsModulePhase(
|
||||
::ArrayInlineConstructorLowering,
|
||||
name = "ArrayInlineConstructorLowering",
|
||||
description = "Replace array constructor with platform specific factory functions"
|
||||
)
|
||||
|
||||
private val LateinitLoweringPhase = makeJsPhase(
|
||||
{ context, module -> LateinitLowering(context).lower(module) },
|
||||
private val lateinitLoweringPhase = makeJsModulePhase(
|
||||
::LateinitLowering,
|
||||
name = "LateinitLowering",
|
||||
description = "Insert checks for lateinit field references"
|
||||
)
|
||||
|
||||
private val ModuleCopyingPhase = makeJsPhase(
|
||||
private val moduleCopyingPhase = makeCustomJsModulePhase(
|
||||
{ context, module -> context.moduleFragmentCopy = module.deepCopyWithSymbols() },
|
||||
name = "ModuleCopying",
|
||||
description = "<Supposed to be removed> Copy current module to make it accessible from different one",
|
||||
prerequisite = setOf(LateinitLoweringPhase)
|
||||
prerequisite = setOf(lateinitLoweringPhase)
|
||||
)
|
||||
|
||||
private val FunctionInliningPhase = makeJsPhase(
|
||||
private val functionInliningPhase = makeCustomJsModulePhase(
|
||||
{ context, module ->
|
||||
FunctionInlining(context).inline(module)
|
||||
module.replaceUnboundSymbols(context)
|
||||
@@ -87,190 +113,190 @@ private val FunctionInliningPhase = makeJsPhase(
|
||||
},
|
||||
name = "FunctionInliningPhase",
|
||||
description = "Perform function inlining",
|
||||
prerequisite = setOf(ModuleCopyingPhase, LateinitLoweringPhase, ArrayInlineConstructorLoweringPhase, CoroutineIntrinsicLoweringPhase)
|
||||
prerequisite = setOf(moduleCopyingPhase, lateinitLoweringPhase, arrayInlineConstructorLoweringPhase, coroutineIntrinsicLoweringPhase)
|
||||
)
|
||||
|
||||
private val RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase = makeJsPhase(
|
||||
{ _, module -> RemoveInlineFunctionsWithReifiedTypeParametersLowering().lower(module) },
|
||||
private val removeInlineFunctionsWithReifiedTypeParametersLoweringPhase = makeJsModulePhase(
|
||||
{ RemoveInlineFunctionsWithReifiedTypeParametersLowering() },
|
||||
name = "RemoveInlineFunctionsWithReifiedTypeParametersLowering",
|
||||
description = "Remove Inline functions with reified parameters from context",
|
||||
prerequisite = setOf(FunctionInliningPhase)
|
||||
prerequisite = setOf(functionInliningPhase)
|
||||
)
|
||||
|
||||
private val ThrowableSuccessorsLoweringPhase = makeJsPhase(
|
||||
{ context, module -> ThrowableSuccessorsLowering(context).lower(module) },
|
||||
private val throwableSuccessorsLoweringPhase = makeJsModulePhase(
|
||||
::ThrowableSuccessorsLowering,
|
||||
name = "ThrowableSuccessorsLowering",
|
||||
description = "Link kotlin.Throwable and JavaScript Error together to provide proper interop between language and platform exceptions"
|
||||
)
|
||||
|
||||
private val TailrecLoweringPhase = makeJsPhase(
|
||||
{ context, module -> TailrecLowering(context).lower(module) },
|
||||
private val tailrecLoweringPhase = makeJsModulePhase(
|
||||
::TailrecLowering,
|
||||
name = "TailrecLowering",
|
||||
description = "Replace `tailrec` callsites with equivalent loop"
|
||||
)
|
||||
|
||||
private val UnitMaterializationLoweringPhase = makeJsPhase(
|
||||
{ context, module -> UnitMaterializationLowering(context).lower(module) },
|
||||
private val unitMaterializationLoweringPhase = makeJsModulePhase(
|
||||
::UnitMaterializationLowering,
|
||||
name = "UnitMaterializationLowering",
|
||||
description = "Insert Unit object where it is supposed to be",
|
||||
prerequisite = setOf(TailrecLoweringPhase)
|
||||
prerequisite = setOf(tailrecLoweringPhase)
|
||||
)
|
||||
|
||||
private val EnumClassLoweringPhase = makeJsPhase(
|
||||
{ context, module -> EnumClassLowering(context).lower(module) },
|
||||
private val enumClassLoweringPhase = makeJsModulePhase(
|
||||
::EnumClassLowering,
|
||||
name = "EnumClassLowering",
|
||||
description = "Transform Enum Class into regular Class"
|
||||
)
|
||||
|
||||
private val EnumUsageLoweringPhase = makeJsPhase(
|
||||
{ context, module -> EnumUsageLowering(context).lower(module) },
|
||||
private val enumUsageLoweringPhase = makeJsModulePhase(
|
||||
::EnumUsageLowering,
|
||||
name = "EnumUsageLowering",
|
||||
description = "Replace enum access with invocation of corresponding function"
|
||||
)
|
||||
|
||||
private val SharedVariablesLoweringPhase = makeJsPhase(
|
||||
{ context, module -> SharedVariablesLowering(context).lower(module) },
|
||||
private val sharedVariablesLoweringPhase = makeJsModulePhase(
|
||||
::SharedVariablesLowering,
|
||||
name = "SharedVariablesLowering",
|
||||
description = "Box captured mutable variables"
|
||||
)
|
||||
|
||||
private val ReturnableBlockLoweringPhase = makeJsPhase(
|
||||
{ context, module -> ReturnableBlockLowering(context).lower(module) },
|
||||
private val returnableBlockLoweringPhase = makeJsModulePhase(
|
||||
::ReturnableBlockLowering,
|
||||
name = "ReturnableBlockLowering",
|
||||
description = "Replace returnable block with do-while loop",
|
||||
prerequisite = setOf(FunctionInliningPhase)
|
||||
prerequisite = setOf(functionInliningPhase)
|
||||
)
|
||||
|
||||
private val LocalDelegatedPropertiesLoweringPhase = makeJsPhase(
|
||||
{ _, module -> LocalDelegatedPropertiesLowering().lower(module) },
|
||||
private val localDelegatedPropertiesLoweringPhase = makeJsModulePhase(
|
||||
{ LocalDelegatedPropertiesLowering() },
|
||||
name = "LocalDelegatedPropertiesLowering",
|
||||
description = "Transform Local Delegated properties"
|
||||
)
|
||||
|
||||
private val LocalDeclarationsLoweringPhase = makeJsPhase(
|
||||
{ context, module -> LocalDeclarationsLowering(context).lower(module) },
|
||||
private val localDeclarationsLoweringPhase = makeJsModulePhase(
|
||||
::LocalDeclarationsLowering,
|
||||
name = "LocalDeclarationsLowering",
|
||||
description = "Move local declarations into nearest declaration container",
|
||||
prerequisite = setOf(SharedVariablesLoweringPhase)
|
||||
prerequisite = setOf(sharedVariablesLoweringPhase)
|
||||
)
|
||||
|
||||
private val InnerClassesLoweringPhase = makeJsPhase(
|
||||
{ context, module -> InnerClassesLowering(context).lower(module) },
|
||||
private val innerClassesLoweringPhase = makeJsModulePhase(
|
||||
::InnerClassesLowering,
|
||||
name = "InnerClassesLowering",
|
||||
description = "Capture outer this reference to inner class"
|
||||
)
|
||||
|
||||
private val InnerClassConstructorCallsLoweringPhase = makeJsPhase(
|
||||
{ context, module -> InnerClassConstructorCallsLowering(context).lower(module) },
|
||||
private val innerClassConstructorCallsLoweringPhase = makeJsModulePhase(
|
||||
::InnerClassConstructorCallsLowering,
|
||||
name = "InnerClassConstructorCallsLowering",
|
||||
description = "Replace inner class constructor invocation"
|
||||
)
|
||||
|
||||
private val SuspendFunctionsLoweringPhase = makeJsPhase(
|
||||
{ context, module -> SuspendFunctionsLowering(context).lower(module) },
|
||||
private val suspendFunctionsLoweringPhase = makeJsModulePhase(
|
||||
::SuspendFunctionsLowering,
|
||||
name = "SuspendFunctionsLowering",
|
||||
description = "Transform suspend functions into CoroutineImpl instance and build state machine",
|
||||
prerequisite = setOf(UnitMaterializationLoweringPhase, CoroutineIntrinsicLoweringPhase)
|
||||
prerequisite = setOf(unitMaterializationLoweringPhase, coroutineIntrinsicLoweringPhase)
|
||||
)
|
||||
|
||||
private val PrivateMembersLoweringPhase = makeJsPhase(
|
||||
{ context, module -> PrivateMembersLowering(context).lower(module) },
|
||||
private val privateMembersLoweringPhase = makeJsModulePhase(
|
||||
::PrivateMembersLowering,
|
||||
name = "PrivateMembersLowering",
|
||||
description = "Extract private members from classes"
|
||||
)
|
||||
|
||||
private val CallableReferenceLoweringPhase = makeJsPhase(
|
||||
{ context, module -> CallableReferenceLowering(context).lower(module) },
|
||||
private val callableReferenceLoweringPhase = makeJsModulePhase(
|
||||
::CallableReferenceLowering,
|
||||
name = "CallableReferenceLowering",
|
||||
description = "Handle callable references",
|
||||
prerequisite = setOf(
|
||||
SuspendFunctionsLoweringPhase,
|
||||
LocalDeclarationsLoweringPhase,
|
||||
LocalDelegatedPropertiesLoweringPhase,
|
||||
PrivateMembersLoweringPhase
|
||||
suspendFunctionsLoweringPhase,
|
||||
localDeclarationsLoweringPhase,
|
||||
localDelegatedPropertiesLoweringPhase,
|
||||
privateMembersLoweringPhase
|
||||
)
|
||||
)
|
||||
|
||||
private val DefaultArgumentStubGeneratorPhase = makeJsPhase(
|
||||
{ context, module -> JsDefaultArgumentStubGenerator(context).lower(module) },
|
||||
private val defaultArgumentStubGeneratorPhase = makeJsModulePhase(
|
||||
::JsDefaultArgumentStubGenerator,
|
||||
name = "DefaultArgumentStubGenerator",
|
||||
description = "Generate synthetic stubs for functions with default parameter values"
|
||||
)
|
||||
|
||||
private val DefaultParameterInjectorPhase = makeJsPhase(
|
||||
{ context, module -> DefaultParameterInjector(context).lower(module) },
|
||||
private val defaultParameterInjectorPhase = makeJsModulePhase(
|
||||
::DefaultParameterInjector,
|
||||
name = "DefaultParameterInjector",
|
||||
description = "Replace callsite with default parameters with corresponding stub function",
|
||||
prerequisite = setOf(CallableReferenceLoweringPhase, InnerClassesLoweringPhase)
|
||||
prerequisite = setOf(callableReferenceLoweringPhase, innerClassesLoweringPhase)
|
||||
)
|
||||
|
||||
private val DefaultParameterCleanerPhase = makeJsPhase(
|
||||
{ context, module -> DefaultParameterCleaner(context).lower(module) },
|
||||
private val defaultParameterCleanerPhase = makeJsModulePhase(
|
||||
::DefaultParameterCleaner,
|
||||
name = "DefaultParameterCleaner",
|
||||
description = "Clean default parameters up"
|
||||
)
|
||||
|
||||
private val JsDefaultCallbackGeneratorPhase = makeJsPhase(
|
||||
{ context, module -> JsDefaultCallbackGenerator(context).lower(module) },
|
||||
private val jsDefaultCallbackGeneratorPhase = makeJsModulePhase(
|
||||
::JsDefaultCallbackGenerator,
|
||||
name = "JsDefaultCallbackGenerator",
|
||||
description = "Build binding for super calls with default parameters"
|
||||
)
|
||||
|
||||
private val VarargLoweringPhase = makeJsPhase(
|
||||
{ context, module -> VarargLowering(context).lower(module) },
|
||||
private val varargLoweringPhase = makeJsModulePhase(
|
||||
::VarargLowering,
|
||||
name = "VarargLowering",
|
||||
description = "Lower vararg arguments",
|
||||
prerequisite = setOf(CallableReferenceLoweringPhase)
|
||||
prerequisite = setOf(callableReferenceLoweringPhase)
|
||||
)
|
||||
|
||||
private val PropertiesLoweringPhase = makeJsPhase(
|
||||
{ _, module -> PropertiesLowering().lower(module) },
|
||||
private val propertiesLoweringPhase = makeJsModulePhase(
|
||||
{ PropertiesLowering() },
|
||||
name = "PropertiesLowering",
|
||||
description = "Move fields and accessors out from its property"
|
||||
)
|
||||
|
||||
private val InitializersLoweringPhase = makeJsPhase(
|
||||
private val initializersLoweringPhase = makeCustomJsModulePhase(
|
||||
{ context, module -> InitializersLowering(context, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).lower(module) },
|
||||
name = "InitializersLowering",
|
||||
description = "Merge init block and field initializers into [primary] constructor",
|
||||
prerequisite = setOf(EnumClassLoweringPhase)
|
||||
prerequisite = setOf(enumClassLoweringPhase)
|
||||
)
|
||||
|
||||
private val MultipleCatchesLoweringPhase = makeJsPhase(
|
||||
{ context, module -> MultipleCatchesLowering(context).lower(module) },
|
||||
private val multipleCatchesLoweringPhase = makeJsModulePhase(
|
||||
::MultipleCatchesLowering,
|
||||
name = "MultipleCatchesLowering",
|
||||
description = "Replace multiple catches with single one"
|
||||
)
|
||||
|
||||
private val BridgesConstructionPhase = makeJsPhase(
|
||||
{ context, module -> BridgesConstruction(context).lower(module) },
|
||||
private val bridgesConstructionPhase = makeJsModulePhase(
|
||||
::BridgesConstruction,
|
||||
name = "BridgesConstruction",
|
||||
description = "Generate bridges",
|
||||
prerequisite = setOf(SuspendFunctionsLoweringPhase)
|
||||
prerequisite = setOf(suspendFunctionsLoweringPhase)
|
||||
)
|
||||
|
||||
private val TypeOperatorLoweringPhase = makeJsPhase(
|
||||
{ context, module -> TypeOperatorLowering(context).lower(module) },
|
||||
private val typeOperatorLoweringPhase = makeJsModulePhase(
|
||||
::TypeOperatorLowering,
|
||||
name = "TypeOperatorLowering",
|
||||
description = "Lower IrTypeOperator with corresponding logic",
|
||||
prerequisite = setOf(BridgesConstructionPhase, RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase)
|
||||
prerequisite = setOf(bridgesConstructionPhase, removeInlineFunctionsWithReifiedTypeParametersLoweringPhase)
|
||||
)
|
||||
|
||||
private val SecondaryConstructorLoweringPhase = makeJsPhase(
|
||||
{ context, module -> SecondaryConstructorLowering(context).lower(module) },
|
||||
private val secondaryConstructorLoweringPhase = makeJsModulePhase(
|
||||
::SecondaryConstructorLowering,
|
||||
name = "SecondaryConstructorLoweringPhase",
|
||||
description = "Generate static functions for each secondary constructor",
|
||||
prerequisite = setOf(InnerClassesLoweringPhase)
|
||||
prerequisite = setOf(innerClassesLoweringPhase)
|
||||
)
|
||||
|
||||
private val SecondaryFactoryInjectorLoweringPhase = makeJsPhase(
|
||||
{ context, module -> SecondaryFactoryInjectorLowering(context).lower(module) },
|
||||
private val secondaryFactoryInjectorLoweringPhase = makeJsModulePhase(
|
||||
::SecondaryFactoryInjectorLowering,
|
||||
name = "SecondaryFactoryInjectorLoweringPhase",
|
||||
description = "Replace usage of secondary constructor with corresponding static function",
|
||||
prerequisite = setOf(InnerClassesLoweringPhase)
|
||||
prerequisite = setOf(innerClassesLoweringPhase)
|
||||
)
|
||||
|
||||
private val InlineClassLoweringPhase = makeJsPhase(
|
||||
private val inlineClassLoweringPhase = makeCustomJsModulePhase(
|
||||
{ context, module ->
|
||||
InlineClassLowering(context).run {
|
||||
inlineClassDeclarationLowering.runOnFilesPostfix(module)
|
||||
@@ -281,102 +307,95 @@ private val InlineClassLoweringPhase = makeJsPhase(
|
||||
description = "Handle inline classes"
|
||||
)
|
||||
|
||||
private val AutoboxingTransformerPhase = makeJsPhase(
|
||||
{ context, module -> AutoboxingTransformer(context).lower(module) },
|
||||
private val autoboxingTransformerPhase = makeJsModulePhase(
|
||||
::AutoboxingTransformer,
|
||||
name = "AutoboxingTransformer",
|
||||
description = "Insert box/unbox intrinsics"
|
||||
)
|
||||
|
||||
private val BlockDecomposerLoweringPhase = makeJsPhase(
|
||||
private val blockDecomposerLoweringPhase = makeCustomJsModulePhase(
|
||||
{ context, module ->
|
||||
BlockDecomposerLowering(context).lower(module)
|
||||
module.patchDeclarationParents()
|
||||
},
|
||||
name = "BlockDecomposerLowering",
|
||||
description = "Transform statement-like-expression nodes into pure-statement to make it easily transform into JS",
|
||||
prerequisite = setOf(TypeOperatorLoweringPhase, SuspendFunctionsLoweringPhase)
|
||||
prerequisite = setOf(typeOperatorLoweringPhase, suspendFunctionsLoweringPhase)
|
||||
)
|
||||
|
||||
private val ClassReferenceLoweringPhase = makeJsPhase(
|
||||
{ context, module -> ClassReferenceLowering(context).lower(module) },
|
||||
private val classReferenceLoweringPhase = makeJsModulePhase(
|
||||
::ClassReferenceLowering,
|
||||
name = "ClassReferenceLowering",
|
||||
description = "Handle class references"
|
||||
)
|
||||
|
||||
private val PrimitiveCompanionLoweringPhase = makeJsPhase(
|
||||
{ context, module -> PrimitiveCompanionLowering(context).lower(module) },
|
||||
private val primitiveCompanionLoweringPhase = makeJsModulePhase(
|
||||
::PrimitiveCompanionLowering,
|
||||
name = "PrimitiveCompanionLowering",
|
||||
description = "Replace common companion object access with platform one"
|
||||
)
|
||||
|
||||
private val ConstLoweringPhase = makeJsPhase(
|
||||
{ context, module -> ConstLowering(context).lower(module) },
|
||||
private val constLoweringPhase = makeJsModulePhase(
|
||||
::ConstLowering,
|
||||
name = "ConstLowering",
|
||||
description = "Wrap Long and Char constants into constructor invocation"
|
||||
)
|
||||
|
||||
private val CallsLoweringPhase = makeJsPhase(
|
||||
{ context, module -> CallsLowering(context).lower(module) },
|
||||
private val callsLoweringPhase = makeJsModulePhase(
|
||||
::CallsLowering,
|
||||
name = "CallsLowering",
|
||||
description = "Handle intrinsics"
|
||||
)
|
||||
|
||||
object IrModuleEndPhase : CompilerPhase<BackendContext, IrModuleFragment> {
|
||||
override val name = "IrModuleFragment"
|
||||
override val description = "State at end of IrModuleFragment lowering"
|
||||
override val prerequisite = emptySet()
|
||||
override fun invoke(context: BackendContext, input: IrModuleFragment) = input
|
||||
}
|
||||
|
||||
private val IrToJsPhase = makeJsPhase(
|
||||
private val irToJsPhase = makeCustomJsModulePhase(
|
||||
{ context, module -> context.jsProgram = IrModuleToJsTransformer(context).let { module.accept(it, null) } },
|
||||
name = "IrModuleToJsTransformer",
|
||||
description = "Generate JsAst from IrTree"
|
||||
)
|
||||
|
||||
val jsPhases = listOf(
|
||||
IrModuleStartPhase,
|
||||
MoveBodilessDeclarationsToSeparatePlacePhase,
|
||||
ExpectDeclarationsRemovingPhase,
|
||||
CoroutineIntrinsicLoweringPhase,
|
||||
ArrayInlineConstructorLoweringPhase,
|
||||
LateinitLoweringPhase,
|
||||
ModuleCopyingPhase,
|
||||
FunctionInliningPhase,
|
||||
RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase,
|
||||
ThrowableSuccessorsLoweringPhase,
|
||||
TailrecLoweringPhase,
|
||||
UnitMaterializationLoweringPhase,
|
||||
EnumClassLoweringPhase,
|
||||
EnumUsageLoweringPhase,
|
||||
SharedVariablesLoweringPhase,
|
||||
ReturnableBlockLoweringPhase,
|
||||
LocalDelegatedPropertiesLoweringPhase,
|
||||
LocalDeclarationsLoweringPhase,
|
||||
InnerClassesLoweringPhase,
|
||||
InnerClassConstructorCallsLoweringPhase,
|
||||
SuspendFunctionsLoweringPhase,
|
||||
PrivateMembersLoweringPhase,
|
||||
CallableReferenceLoweringPhase,
|
||||
DefaultArgumentStubGeneratorPhase,
|
||||
DefaultParameterInjectorPhase,
|
||||
DefaultParameterCleanerPhase,
|
||||
JsDefaultCallbackGeneratorPhase,
|
||||
VarargLoweringPhase,
|
||||
PropertiesLoweringPhase,
|
||||
InitializersLoweringPhase,
|
||||
MultipleCatchesLoweringPhase,
|
||||
BridgesConstructionPhase,
|
||||
TypeOperatorLoweringPhase,
|
||||
SecondaryConstructorLoweringPhase,
|
||||
SecondaryFactoryInjectorLoweringPhase,
|
||||
ClassReferenceLoweringPhase,
|
||||
InlineClassLoweringPhase,
|
||||
AutoboxingTransformerPhase,
|
||||
BlockDecomposerLoweringPhase,
|
||||
PrimitiveCompanionLoweringPhase,
|
||||
ConstLoweringPhase,
|
||||
CallsLoweringPhase,
|
||||
IrModuleEndPhase,
|
||||
IrToJsPhase
|
||||
)
|
||||
val jsPhases = namedIrModulePhase(
|
||||
name = "IrModuleLowering",
|
||||
description = "IR module lowering",
|
||||
lower = moveBodilessDeclarationsToSeparatePlacePhase then
|
||||
expectDeclarationsRemovingPhase then
|
||||
coroutineIntrinsicLoweringPhase then
|
||||
arrayInlineConstructorLoweringPhase then
|
||||
lateinitLoweringPhase then
|
||||
moduleCopyingPhase then
|
||||
functionInliningPhase then
|
||||
removeInlineFunctionsWithReifiedTypeParametersLoweringPhase then
|
||||
throwableSuccessorsLoweringPhase then
|
||||
tailrecLoweringPhase then
|
||||
unitMaterializationLoweringPhase then
|
||||
enumClassLoweringPhase then
|
||||
enumUsageLoweringPhase then
|
||||
sharedVariablesLoweringPhase then
|
||||
returnableBlockLoweringPhase then
|
||||
localDelegatedPropertiesLoweringPhase then
|
||||
localDeclarationsLoweringPhase then
|
||||
innerClassesLoweringPhase then
|
||||
innerClassConstructorCallsLoweringPhase then
|
||||
suspendFunctionsLoweringPhase then
|
||||
privateMembersLoweringPhase then
|
||||
callableReferenceLoweringPhase then
|
||||
defaultArgumentStubGeneratorPhase then
|
||||
defaultParameterInjectorPhase then
|
||||
defaultParameterCleanerPhase then
|
||||
jsDefaultCallbackGeneratorPhase then
|
||||
varargLoweringPhase then
|
||||
propertiesLoweringPhase then
|
||||
initializersLoweringPhase then
|
||||
multipleCatchesLoweringPhase then
|
||||
bridgesConstructionPhase then
|
||||
typeOperatorLoweringPhase then
|
||||
secondaryConstructorLoweringPhase then
|
||||
secondaryFactoryInjectorLoweringPhase then
|
||||
classReferenceLoweringPhase then
|
||||
inlineClassLoweringPhase then
|
||||
autoboxingTransformerPhase then
|
||||
blockDecomposerLoweringPhase then
|
||||
primitiveCompanionLoweringPhase then
|
||||
constLoweringPhase then
|
||||
callsLoweringPhase then
|
||||
irToJsPhase
|
||||
)
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CheckDeclarationParentsVisitor
|
||||
import org.jetbrains.kotlin.backend.common.DefaultIrPhaseRunner
|
||||
import org.jetbrains.kotlin.backend.common.IrValidator
|
||||
import org.jetbrains.kotlin.backend.common.IrValidatorConfig
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
|
||||
private fun validationCallback(module: IrModuleFragment, context: JsIrBackendContext) {
|
||||
val validatorConfig = IrValidatorConfig(
|
||||
abortOnError = true,
|
||||
ensureAllNodesAreDifferent = true,
|
||||
checkTypes = false,
|
||||
checkDescriptors = false
|
||||
)
|
||||
module.accept(IrValidator(context, validatorConfig), null)
|
||||
module.accept(CheckDeclarationParentsVisitor, null)
|
||||
}
|
||||
|
||||
object JsPhaseRunner : DefaultIrPhaseRunner<JsIrBackendContext, IrModuleFragment>(::validationCallback) {
|
||||
override val startPhaseMarker = IrModuleStartPhase
|
||||
override val endPhaseMarker = IrModuleEndPhase
|
||||
|
||||
override fun phases(context: JsIrBackendContext) = context.phases
|
||||
override fun elementName(input: IrModuleFragment) = input.name.asString()
|
||||
override fun configuration(context: JsIrBackendContext) = context.configuration
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhaseManager
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -62,9 +62,7 @@ fun compile(
|
||||
irDependencyModules
|
||||
)
|
||||
|
||||
CompilerPhaseManager(context, context.phases, moduleFragment, JsPhaseRunner).run {
|
||||
jsPhases.fold(data) { m, p -> phase(p, context, m) }
|
||||
}
|
||||
jsPhases.invokeToplevel(context.phaseConfig, context, moduleFragment)
|
||||
|
||||
return Result(analysisResult.moduleDescriptor, context.jsProgram.toString(), context.moduleFragmentCopy)
|
||||
}
|
||||
+4
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.inline.addChild
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
@@ -18,7 +19,9 @@ import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class MoveBodilessDeclarationsToSeparatePlace : FileLoweringPass {
|
||||
class MoveBodilessDeclarationsToSeparatePlace() : FileLoweringPass {
|
||||
|
||||
constructor(context: JsIrBackendContext) : this()
|
||||
|
||||
private val builtInClasses = listOf(
|
||||
"String",
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhaseManager
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhases
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
@@ -47,19 +46,17 @@ class JvmBackendContext(
|
||||
|
||||
override val ir = JvmIr(irModuleFragment, symbolTable)
|
||||
|
||||
val phases = CompilerPhases(jvmPhases, state.configuration)
|
||||
val phaseConfig = PhaseConfig(jvmPhases, state.configuration)
|
||||
override var inVerbosePhase: Boolean = false
|
||||
|
||||
override val configuration get() = state.configuration
|
||||
|
||||
init {
|
||||
if (state.configuration.get(CommonConfigurationKeys.LIST_PHASES) == true) {
|
||||
phases.list()
|
||||
phaseConfig.list()
|
||||
}
|
||||
}
|
||||
|
||||
var inVerbosePhase = false
|
||||
|
||||
fun rootPhaseManager(irFile: IrFile) = CompilerPhaseManager(this, phases, irFile, JvmPhaseRunner)
|
||||
|
||||
|
||||
private fun find(memberScope: MemberScope, className: String): ClassDescriptor {
|
||||
return find(memberScope, Name.identifier(className))
|
||||
}
|
||||
@@ -146,7 +143,7 @@ class JvmBackendContext(
|
||||
override val coroutineSuspendedGetter: IrSimpleFunctionSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override val lateinitIsInitializedPropertyGetter= symbolTable.referenceSimpleFunction(
|
||||
override val lateinitIsInitializedPropertyGetter = symbolTable.referenceSimpleFunction(
|
||||
state.module.getPackage(FqName("kotlin")).memberScope.getContributedVariables(
|
||||
Name.identifier("isInitialized"), NoLookupLocation.FROM_BACKEND
|
||||
).single {
|
||||
|
||||
@@ -16,32 +16,78 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
fun makePatchParentsPhase(number: Int) = object : CompilerPhase<BackendContext, IrFile> {
|
||||
override val name: String = "PatchParents$number"
|
||||
override val description: String = "Patch parent references in IrFile, pass $number"
|
||||
override val prerequisite: Set<CompilerPhase<BackendContext, *>> = emptySet()
|
||||
private fun makePatchParentsPhase(number: Int) = namedIrFilePhase(
|
||||
lower = object : SameTypeCompilerPhase<CommonBackendContext, IrFile> {
|
||||
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: CommonBackendContext, input: IrFile): IrFile {
|
||||
input.acceptVoid(PatchDeclarationParentsVisitor())
|
||||
return input
|
||||
}
|
||||
},
|
||||
name = "PatchParents$number",
|
||||
description = "Patch parent references in IrFile, pass $number",
|
||||
nlevels = 0
|
||||
)
|
||||
|
||||
override fun invoke(context: BackendContext, input: IrFile): IrFile {
|
||||
input.acceptVoid(PatchDeclarationParentsVisitor())
|
||||
return input
|
||||
}
|
||||
}
|
||||
internal val jvmPhases = namedIrFilePhase(
|
||||
name = "IrLowering",
|
||||
description = "IR lowering",
|
||||
lower = jvmCoercionToUnitPhase then
|
||||
fileClassPhase then
|
||||
kCallableNamePropertyPhase then
|
||||
|
||||
jvmLateinitPhase then
|
||||
|
||||
moveCompanionObjectFieldsPhase then
|
||||
constAndJvmFieldPropertiesPhase then
|
||||
propertiesPhase then
|
||||
annotationPhase then
|
||||
|
||||
jvmDefaultArgumentStubPhase then
|
||||
|
||||
interfacePhase then
|
||||
interfaceDelegationPhase then
|
||||
sharedVariablesPhase then
|
||||
|
||||
makePatchParentsPhase(1) then
|
||||
|
||||
jvmLocalDeclarationsPhase then
|
||||
callableReferencePhase then
|
||||
functionNVarargInvokePhase then
|
||||
|
||||
innerClassesPhase then
|
||||
innerClassConstructorCallsPhase then
|
||||
|
||||
makePatchParentsPhase(2) then
|
||||
|
||||
enumClassPhase then
|
||||
objectClassPhase then
|
||||
makeInitializersPhase(JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true) then
|
||||
singletonReferencesPhase then
|
||||
syntheticAccessorPhase then
|
||||
bridgePhase then
|
||||
jvmOverloadsAnnotationPhase then
|
||||
jvmStaticAnnotationPhase then
|
||||
staticDefaultFunctionPhase then
|
||||
|
||||
tailrecPhase then
|
||||
toArrayPhase then
|
||||
jvmTypeOperatorLoweringPhase then
|
||||
jvmBuiltinOptimizationLoweringPhase then
|
||||
|
||||
makePatchParentsPhase(3)
|
||||
)
|
||||
|
||||
class JvmLower(val context: JvmBackendContext) {
|
||||
fun lower(irFile: IrFile) {
|
||||
var state = irFile
|
||||
// TODO run lowering passes as callbacks in bottom-up visitor
|
||||
|
||||
context.rootPhaseManager(irFile).apply {
|
||||
for (jvmPhase in jvmPhases) {
|
||||
state = phase(jvmPhase, context, state)
|
||||
}
|
||||
}
|
||||
jvmPhases.invokeToplevel(context.phaseConfig, context, irFile)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,288 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
|
||||
object IrFileStartPhase : CompilerPhase<BackendContext, IrFile> {
|
||||
override val name = "IrFileStart"
|
||||
override val description = "State at start of IrFile lowering"
|
||||
override val prerequisite = emptySet()
|
||||
override fun invoke(context: BackendContext, input: IrFile) = input
|
||||
}
|
||||
|
||||
private fun makeJvmPhase(
|
||||
lowering: (JvmBackendContext, IrFile) -> Unit,
|
||||
description: String,
|
||||
name: String,
|
||||
prerequisite: Set<CompilerPhase<JvmBackendContext, IrFile>> = emptySet()
|
||||
) = makePhase(lowering, description, name, prerequisite)
|
||||
|
||||
private val JvmCoercionToUnitPhase = makeJvmPhase(
|
||||
{ context, file -> JvmCoercionToUnitPatcher(context).lower(file) },
|
||||
name = "JvmCoercionToUnit",
|
||||
description = "Insert conversions to unit after IrCalls where needed"
|
||||
)
|
||||
|
||||
private val FileClassPhase = makeJvmPhase(
|
||||
{ context, file -> FileClassLowering(context).lower(file) },
|
||||
name = "FileClass",
|
||||
description = "Put file level function and property declaration into a class"
|
||||
)
|
||||
|
||||
private val KCallableNamePropertyPhase = makeJvmPhase(
|
||||
{ context, file -> KCallableNamePropertyLowering(context).lower(file) },
|
||||
name = "KCallableNameProperty",
|
||||
description = "Replace name references for callables with constants"
|
||||
)
|
||||
|
||||
private val LateinitPhase = makeJvmPhase(
|
||||
{ context, file -> LateinitLowering(context).lower(file) },
|
||||
name = "Lateinit",
|
||||
description = "Insert checks for lateinit field references"
|
||||
)
|
||||
|
||||
private val MoveCompanionObjectFieldsPhase = makeJvmPhase(
|
||||
{ context, file -> MoveCompanionObjectFieldsLowering(context).runOnFilePostfix(file) },
|
||||
name = "MoveCompanionObjectFields",
|
||||
description = "Move companion object fields to static fields of companion's owner"
|
||||
)
|
||||
|
||||
|
||||
private val ConstAndJvmFieldPropertiesPhase = makeJvmPhase(
|
||||
{ context, file -> ConstAndJvmFieldPropertiesLowering(context).lower(file) },
|
||||
name = "ConstAndJvmFieldProperties",
|
||||
description = "Substitute calls to const and Jvm>Field properties with const/field access"
|
||||
)
|
||||
|
||||
|
||||
private val PropertiesPhase = makeJvmPhase(
|
||||
{ context, file -> PropertiesLowering(context).lower(file) },
|
||||
name = "Properties",
|
||||
description = "move fields and accessors for properties to their classes"
|
||||
)
|
||||
|
||||
|
||||
private val AnnotationPhase = makeJvmPhase(
|
||||
{ _, file -> AnnotationLowering().lower(file) },
|
||||
name = "Annotation",
|
||||
description = "Remove constructors from annotation classes"
|
||||
)
|
||||
|
||||
private val DefaultArgumentStubPhase = makeJvmPhase(
|
||||
{ context, file -> DefaultArgumentStubGenerator(context, false).lower(file) },
|
||||
name = "DefaultArgumentsStubGenerator",
|
||||
description = "Generate synthetic stubs for functions with default parameter values"
|
||||
)
|
||||
|
||||
private val InterfacePhase = makeJvmPhase(
|
||||
{ context, file -> InterfaceLowering(context).lower(file) },
|
||||
name = "Interface",
|
||||
description = "Move default implementations of interface members to DefaultImpls class"
|
||||
)
|
||||
|
||||
private val InterfaceDelegationPhase = makeJvmPhase(
|
||||
{ context, file -> InterfaceDelegationLowering(context).lower(file) },
|
||||
name = "InterfaceDelegation",
|
||||
description = "Delegate calls to interface members with default implementations to DefaultImpls"
|
||||
)
|
||||
|
||||
private val SharedVariablesPhase = makeJvmPhase(
|
||||
{ context, file -> SharedVariablesLowering(context).lower(file) },
|
||||
name = "SharedVariables",
|
||||
description = "Transform shared variables"
|
||||
)
|
||||
|
||||
private val LocalDeclarationsPhase = makeJvmPhase(
|
||||
{ context, data ->
|
||||
LocalDeclarationsLowering(context, object : LocalNameProvider {
|
||||
override fun localName(declaration: IrDeclarationWithName): String =
|
||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(declaration))
|
||||
}, Visibilities.PUBLIC, true).lower(data)
|
||||
},
|
||||
name = "JvmLocalDeclarations",
|
||||
description = "Move local declarations to classes",
|
||||
prerequisite = setOf(SharedVariablesPhase)
|
||||
)
|
||||
|
||||
private val CallableReferencePhase = makeJvmPhase(
|
||||
{ context, file -> CallableReferenceLowering(context).lower(file) },
|
||||
name = "CallableReference",
|
||||
description = "Handle callable references"
|
||||
)
|
||||
|
||||
private val FunctionNVarargInvokePhase = makeJvmPhase(
|
||||
{ context, file -> FunctionNVarargInvokeLowering(context).lower(file) },
|
||||
name = "FunctionNVarargInvoke",
|
||||
description = "Handle invoke functions with large number of arguments"
|
||||
)
|
||||
|
||||
|
||||
private val InnerClassesPhase = makeJvmPhase(
|
||||
{ context, file -> InnerClassesLowering(context).lower(file) },
|
||||
name = "InnerClasses",
|
||||
description = "Move inner classes to toplevel"
|
||||
)
|
||||
|
||||
private val InnerClassConstructorCallsPhase = makeJvmPhase(
|
||||
{ context, file -> InnerClassConstructorCallsLowering(context).lower(file) },
|
||||
name = "InnerClassConstructorCalls",
|
||||
description = "Handle constructor calls for inner classes"
|
||||
)
|
||||
|
||||
|
||||
private val EnumClassPhase = makeJvmPhase(
|
||||
{ context, file -> EnumClassLowering(context).lower(file) },
|
||||
name = "EnumClass",
|
||||
description = "Handle enum classes"
|
||||
)
|
||||
|
||||
|
||||
private val ObjectClassPhase = makeJvmPhase(
|
||||
{ context, file -> ObjectClassLowering(context).lower(file) },
|
||||
name = "ObjectClass",
|
||||
description = "Handle object classes"
|
||||
)
|
||||
|
||||
private val InitializersPhase = makeJvmPhase(
|
||||
{ context, file -> InitializersLowering(context, JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true).lower(file) },
|
||||
name = "Initializers",
|
||||
description = "Handle initializer statements"
|
||||
)
|
||||
|
||||
|
||||
private val SingletonReferencesPhase = makeJvmPhase(
|
||||
{ context, file -> SingletonReferencesLowering(context).lower(file) },
|
||||
name = "SingletonReferences",
|
||||
description = "Handle singleton references"
|
||||
)
|
||||
|
||||
|
||||
private val SyntheticAccessorPhase = makeJvmPhase(
|
||||
{ context, file -> SyntheticAccessorLowering(context).lower(file) },
|
||||
name = "SyntheticAccessor",
|
||||
description = "Introduce synthetic accessors",
|
||||
prerequisite = setOf(ObjectClassPhase)
|
||||
)
|
||||
|
||||
private val BridgePhase = makeJvmPhase(
|
||||
{ context, file -> BridgeLowering(context).lower(file) },
|
||||
name = "Bridge",
|
||||
description = "Generate bridges"
|
||||
)
|
||||
|
||||
private val JvmOverloadsAnnotationPhase = makeJvmPhase(
|
||||
{ context, file -> JvmOverloadsAnnotationLowering(context).lower(file) },
|
||||
name = "JvmOverloadsAnnotation",
|
||||
description = "Handle JvmOverloads annotations"
|
||||
)
|
||||
|
||||
|
||||
private val JvmStaticAnnotationPhase = makeJvmPhase(
|
||||
{ context, file -> JvmStaticAnnotationLowering(context).lower(file) },
|
||||
name = "JvmStaticAnnotation",
|
||||
description = "Handle JvmStatic annotations"
|
||||
)
|
||||
|
||||
|
||||
private val StaticDefaultFunctionPhase = makeJvmPhase(
|
||||
{ _, file -> StaticDefaultFunctionLowering().lower(file) },
|
||||
name = "StaticDefaultFunction",
|
||||
description = "Generate static functions for default parameters"
|
||||
)
|
||||
|
||||
|
||||
private val TailrecPhase = makeJvmPhase(
|
||||
{ context, file -> TailrecLowering(context).lower(file) },
|
||||
name = "Tailrec",
|
||||
description = "Handle tailrec calls"
|
||||
)
|
||||
|
||||
private val ToArrayPhase = makeJvmPhase(
|
||||
{ context, file -> ToArrayLowering(context).lower(file) },
|
||||
name = "ToArray",
|
||||
description = "Handle toArray functions"
|
||||
)
|
||||
|
||||
private val JvmTypeOperatorLowering = makeJvmPhase(
|
||||
{ context, file -> JvmTypeOperatorLowering(context).lower(file) },
|
||||
name = "JvmTypeOperatorLoweringPhase",
|
||||
description = "Handle JVM-specific type operator lowerings"
|
||||
)
|
||||
|
||||
|
||||
private val JvmBuiltinOptimizationLowering = makeJvmPhase(
|
||||
{ context, file -> JvmBuiltinOptimizationLowering(context).lower(file) },
|
||||
name = "JvmBuiltinOptimizationLowering",
|
||||
description = "Optimize builtin calls for JVM code generation"
|
||||
)
|
||||
|
||||
object IrFileEndPhase : CompilerPhase<BackendContext, IrFile> {
|
||||
override val name = "IrFileEnd"
|
||||
override val description = "State at end of IrFile lowering"
|
||||
override val prerequisite = emptySet()
|
||||
override fun invoke(context: BackendContext, input: IrFile) = input
|
||||
}
|
||||
|
||||
val jvmPhases = listOf(
|
||||
IrFileStartPhase,
|
||||
|
||||
JvmCoercionToUnitPhase,
|
||||
FileClassPhase,
|
||||
KCallableNamePropertyPhase,
|
||||
|
||||
LateinitPhase,
|
||||
|
||||
MoveCompanionObjectFieldsPhase,
|
||||
ConstAndJvmFieldPropertiesPhase,
|
||||
PropertiesPhase,
|
||||
AnnotationPhase,
|
||||
|
||||
DefaultArgumentStubPhase,
|
||||
|
||||
InterfacePhase,
|
||||
InterfaceDelegationPhase,
|
||||
SharedVariablesPhase,
|
||||
|
||||
makePatchParentsPhase(1),
|
||||
|
||||
LocalDeclarationsPhase,
|
||||
CallableReferencePhase,
|
||||
FunctionNVarargInvokePhase,
|
||||
|
||||
InnerClassesPhase,
|
||||
InnerClassConstructorCallsPhase,
|
||||
|
||||
makePatchParentsPhase(2),
|
||||
|
||||
EnumClassPhase,
|
||||
ObjectClassPhase,
|
||||
InitializersPhase,
|
||||
SingletonReferencesPhase,
|
||||
SyntheticAccessorPhase,
|
||||
BridgePhase,
|
||||
JvmOverloadsAnnotationPhase,
|
||||
JvmStaticAnnotationPhase,
|
||||
StaticDefaultFunctionPhase,
|
||||
|
||||
TailrecPhase,
|
||||
ToArrayPhase,
|
||||
JvmTypeOperatorLowering,
|
||||
JvmBuiltinOptimizationLowering,
|
||||
|
||||
makePatchParentsPhase(3),
|
||||
|
||||
IrFileEndPhase
|
||||
)
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DefaultIrPhaseRunner
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.name
|
||||
|
||||
object JvmPhaseRunner : DefaultIrPhaseRunner<JvmBackendContext, IrFile>() {
|
||||
override val startPhaseMarker = IrFileStartPhase
|
||||
override val endPhaseMarker = IrFileEndPhase
|
||||
|
||||
override fun phases(context: JvmBackendContext) = context.phases
|
||||
override fun elementName(input: IrFile) = input.name
|
||||
override fun configuration(context: JvmBackendContext) = context.state.configuration
|
||||
}
|
||||
+8
-2
@@ -7,12 +7,18 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
|
||||
class AnnotationLowering() : ClassLoweringPass {
|
||||
internal val annotationPhase = makeIrFilePhase(
|
||||
::AnnotationLowering,
|
||||
name = "Annotation",
|
||||
description = "Remove constructors from annotation classes"
|
||||
)
|
||||
|
||||
private class AnnotationLowering() : ClassLoweringPass {
|
||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
|
||||
+8
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl
|
||||
@@ -55,7 +56,13 @@ import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
internal val bridgePhase = makeIrFilePhase(
|
||||
::BridgeLowering,
|
||||
name = "Bridge",
|
||||
description = "Generate bridges"
|
||||
)
|
||||
|
||||
private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
private val state = context.state
|
||||
|
||||
|
||||
+8
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
@@ -51,8 +52,14 @@ class CrIrType(val type: Type) : IrType {
|
||||
override val annotations = emptyList()
|
||||
}
|
||||
|
||||
internal val callableReferencePhase = makeIrFilePhase(
|
||||
::CallableReferenceLowering,
|
||||
name = "CallableReference",
|
||||
description = "Handle callable references"
|
||||
)
|
||||
|
||||
//Originally was copied from K/Native
|
||||
class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
internal class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
|
||||
private var functionReferenceCount = 0
|
||||
|
||||
|
||||
+8
-2
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -20,7 +20,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
|
||||
class ConstAndJvmFieldPropertiesLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
internal val constAndJvmFieldPropertiesPhase = makeIrFilePhase(
|
||||
::ConstAndJvmFieldPropertiesLowering,
|
||||
name = "ConstAndJvmFieldProperties",
|
||||
description = "Substitute calls to const and Jvm>Field properties with const/field access"
|
||||
)
|
||||
|
||||
private class ConstAndJvmFieldPropertiesLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(this)
|
||||
}
|
||||
|
||||
+8
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import gnu.trove.TObjectIntHashMap
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.createValueParameter
|
||||
@@ -33,7 +33,13 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.util.*
|
||||
|
||||
class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
internal val enumClassPhase = makeIrFilePhase(
|
||||
::EnumClassLowering,
|
||||
name = "EnumClass",
|
||||
description = "Handle enum classes"
|
||||
)
|
||||
|
||||
private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (!irClass.isEnumClass) return
|
||||
|
||||
|
||||
+8
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -34,7 +35,13 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import java.util.*
|
||||
|
||||
class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
internal val fileClassPhase = makeIrFilePhase(
|
||||
::FileClassLowering,
|
||||
name = "FileClass",
|
||||
description = "Put file level function and property declaration into a class"
|
||||
)
|
||||
|
||||
private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
val classes = ArrayList<IrClass>()
|
||||
val fileClassMembers = ArrayList<IrDeclaration>()
|
||||
|
||||
+8
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDesc
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -30,7 +31,13 @@ import org.jetbrains.kotlin.ir.util.findDeclaration
|
||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLoweringPass {
|
||||
internal val functionNVarargInvokePhase = makeIrFilePhase(
|
||||
::FunctionNVarargInvokeLowering,
|
||||
name = "FunctionNVarargInvoke",
|
||||
description = "Handle invoke functions with large number of arguments"
|
||||
)
|
||||
|
||||
private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
val invokeFunctions = irClass.filterDeclarations<IrSimpleFunction> { it.name.toString() == "invoke" }
|
||||
|
||||
+9
-1
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
@@ -34,7 +36,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
internal val interfaceDelegationPhase = makeIrFilePhase(
|
||||
::InterfaceDelegationLowering,
|
||||
name = "InterfaceDelegation",
|
||||
description = "Delegate calls to interface members with default implementations to DefaultImpls"
|
||||
)
|
||||
|
||||
private class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
|
||||
val state: GenerationState = context.state
|
||||
|
||||
|
||||
+8
-1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering.Companion.clinitName
|
||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -23,7 +24,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
internal val interfacePhase = makeIrFilePhase(
|
||||
::InterfaceLowering,
|
||||
name = "Interface",
|
||||
description = "Move default implementations of interface members to DefaultImpls class"
|
||||
)
|
||||
|
||||
private class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
|
||||
val state = context.state
|
||||
|
||||
|
||||
+7
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.Not
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -24,6 +25,12 @@ import org.jetbrains.kotlin.ir.util.isTrueConst
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
internal val jvmBuiltinOptimizationLoweringPhase = makeIrFilePhase(
|
||||
::JvmBuiltinOptimizationLowering,
|
||||
name = "JvmBuiltinOptimizationLowering",
|
||||
description = "Optimize builtin calls for JVM code generation"
|
||||
)
|
||||
|
||||
class JvmBuiltinOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
|
||||
companion object {
|
||||
|
||||
+7
-1
@@ -6,8 +6,8 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
@@ -18,6 +18,12 @@ import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.InsertImplicitCasts
|
||||
|
||||
internal val jvmCoercionToUnitPhase = makeIrFilePhase(
|
||||
::JvmCoercionToUnitPatcher,
|
||||
name = "JvmCoercionToUnit",
|
||||
description = "Insert conversions to unit after IrCalls where needed"
|
||||
)
|
||||
|
||||
class JvmCoercionToUnitPatcher(val context: JvmBackendContext) :
|
||||
InsertImplicitCasts(
|
||||
context.builtIns, context.irBuiltIns,
|
||||
|
||||
+8
-2
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
@@ -35,7 +35,13 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
|
||||
class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
internal val jvmOverloadsAnnotationPhase = makeIrFilePhase(
|
||||
::JvmOverloadsAnnotationLowering,
|
||||
name = "JvmOverloadsAnnotation",
|
||||
description = "Handle JvmOverloads annotations"
|
||||
)
|
||||
|
||||
private class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
val functions = irClass.declarations.filterIsInstance<IrFunction>().filter {
|
||||
|
||||
+8
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
@@ -36,12 +36,18 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
internal val jvmStaticAnnotationPhase = makeIrFilePhase(
|
||||
::JvmStaticAnnotationLowering,
|
||||
name = "JvmStaticAnnotation",
|
||||
description = "Handle JvmStatic annotations"
|
||||
)
|
||||
|
||||
/*
|
||||
* For @JvmStatic functions within companion objects of classes, we synthesize proxy static functions that redirect
|
||||
* to the actual implementation.
|
||||
* For @JvmStatic functions within static objects, we make the actual function static and modify all call sites.
|
||||
*/
|
||||
class JvmStaticAnnotationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
private class JvmStaticAnnotationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
CompanionObjectJvmStaticLowering(context).runOnFilePostfix(irFile)
|
||||
|
||||
|
||||
+8
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -15,7 +16,13 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrElseBranchImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
class JvmTypeOperatorLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
internal val jvmTypeOperatorLoweringPhase = makeIrFilePhase(
|
||||
::JvmTypeOperatorLowering,
|
||||
name = "JvmTypeOperatorLoweringPhase",
|
||||
description = "Handle JVM-specific type operator lowerings"
|
||||
)
|
||||
|
||||
private class JvmTypeOperatorLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
|
||||
|
||||
+8
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedFieldDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -33,7 +33,13 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass {
|
||||
internal val moveCompanionObjectFieldsPhase = makeIrFilePhase(
|
||||
::MoveCompanionObjectFieldsLowering,
|
||||
name = "MoveCompanionObjectFields",
|
||||
description = "Move companion object fields to static fields of companion's owner"
|
||||
)
|
||||
|
||||
private class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
|
||||
if (irClass.isObject && !irClass.isCompanion && irClass.visibility != Visibilities.LOCAL) {
|
||||
|
||||
+8
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -25,7 +25,13 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
|
||||
class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
internal val objectClassPhase = makeIrFilePhase(
|
||||
::ObjectClassLowering,
|
||||
name = "ObjectClass",
|
||||
description = "Handle object classes"
|
||||
)
|
||||
|
||||
private class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
|
||||
private var pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||
|
||||
|
||||
+8
-2
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -16,7 +16,13 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLoweringPass, IrElementTransformerVoid() {
|
||||
internal val singletonReferencesPhase = makeIrFilePhase(
|
||||
::SingletonReferencesLowering,
|
||||
name = "SingletonReferences",
|
||||
description = "Handle singleton references"
|
||||
)
|
||||
|
||||
private class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLoweringPass, IrElementTransformerVoid() {
|
||||
override fun lower(irBody: IrBody) {
|
||||
irBody.transformChildrenVoid(this)
|
||||
}
|
||||
|
||||
+9
-2
@@ -18,13 +18,20 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
|
||||
class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
internal val staticDefaultFunctionPhase = makeIrFilePhase(
|
||||
::StaticDefaultFunctionLowering,
|
||||
name = "StaticDefaultFunction",
|
||||
description = "Generate static functions for default parameters"
|
||||
)
|
||||
|
||||
private class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
@@ -38,4 +45,4 @@ class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLowerin
|
||||
super.visitFunction(declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDe
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
|
||||
@@ -37,7 +38,14 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
internal val syntheticAccessorPhase = makeIrFilePhase(
|
||||
::SyntheticAccessorLowering,
|
||||
name = "SyntheticAccessor",
|
||||
description = "Introduce synthetic accessors",
|
||||
prerequisite = setOf(objectClassPhase)
|
||||
)
|
||||
|
||||
private class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
private val pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||
private val inlinedLambdasCollector = InlinedLambdasCollector()
|
||||
|
||||
|
||||
+8
-2
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownClassDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
@@ -43,7 +43,13 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||
internal val toArrayPhase = makeIrFilePhase(
|
||||
::ToArrayLowering,
|
||||
name = "ToArray",
|
||||
description = "Handle toArray functions"
|
||||
)
|
||||
|
||||
private class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (irClass.isJvmInterface) return
|
||||
|
||||
Reference in New Issue
Block a user