Reorganize phaser
This commit is contained in:
+4
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.common
|
package org.jetbrains.kotlin.backend.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
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.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
@@ -13,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
interface LoggingContext {
|
interface LoggingContext {
|
||||||
|
var inVerbosePhase: Boolean
|
||||||
fun log(message: () -> String)
|
fun log(message: () -> String)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,4 +30,6 @@ interface CommonBackendContext : BackendContext, LoggingContext {
|
|||||||
fun getInternalFunctions(name: String): List<FunctionDescriptor>
|
fun getInternalFunctions(name: String): List<FunctionDescriptor>
|
||||||
|
|
||||||
fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean)
|
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
|
package org.jetbrains.kotlin.backend.common
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
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.expressions.IrBody
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
@@ -54,6 +51,8 @@ interface BodyLoweringPass : FileLoweringPass {
|
|||||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FileLoweringPass.lower(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { lower(it) }
|
||||||
|
|
||||||
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||||
irFile.acceptVoid(object : IrElementVisitorVoid {
|
irFile.acceptVoid(object : IrElementVisitorVoid {
|
||||||
override fun visitElement(element: IrElement) {
|
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.copyTo
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
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.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
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.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
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
|
// TODO: fix expect/actual default parameters
|
||||||
|
|
||||||
open class DefaultArgumentStubGenerator(
|
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.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.deepCopyWithWrappedDescriptors
|
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.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.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.IrBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
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.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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")
|
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(
|
class InitializersLowering(
|
||||||
val context: CommonBackendContext,
|
val context: CommonBackendContext,
|
||||||
val declarationOrigin: IrDeclarationOrigin,
|
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.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
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.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
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 org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
val innerClassesPhase = makeIrFilePhase(
|
||||||
|
::InnerClassesLowering,
|
||||||
|
name = "InnerClasses",
|
||||||
|
description = "Move inner classes to toplevel"
|
||||||
|
)
|
||||||
|
|
||||||
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
InnerClassTransformer(irClass).lowerInnerClass()
|
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 {
|
class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass {
|
||||||
override fun lower(irBody: IrBody) {
|
override fun lower(irBody: IrBody) {
|
||||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
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.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(KCallableNamePropertyTransformer(this))
|
irFile.transformChildrenVoid(KCallableNamePropertyTransformer(this))
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-10
@@ -17,8 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
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.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
fun makeLateinitPhase() = object : CompilerPhase<CommonBackendContext, IrFile> {
|
val jvmLateinitPhase = makeIrFilePhase(
|
||||||
override val name = "Lateinit"
|
::LateinitLowering,
|
||||||
override val description = "Insert checks for lateinit field references"
|
name = "Lateinit",
|
||||||
|
description = "Insert checks for lateinit field references"
|
||||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
)
|
||||||
LateinitLowering(context).lower(input)
|
|
||||||
return input
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
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.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
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.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
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.util.transformDeclarationsFlat
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.name.NameUtils
|
||||||
import java.util.*
|
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 {
|
interface LocalNameProvider {
|
||||||
fun localName(declaration: IrDeclarationWithName): String =
|
fun localName(declaration: IrDeclarationWithName): String =
|
||||||
declaration.name.asString()
|
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.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
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.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -18,6 +18,12 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
val propertiesPhase = makeIrFilePhase(
|
||||||
|
::PropertiesLowering,
|
||||||
|
name = "Properties",
|
||||||
|
description = "Move fields and accessors for properties to their classes"
|
||||||
|
)
|
||||||
|
|
||||||
class PropertiesLowering() : IrElementTransformerVoid(), FileLoweringPass {
|
class PropertiesLowering() : IrElementTransformerVoid(), FileLoweringPass {
|
||||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||||
|
|
||||||
|
|||||||
+9
-1
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
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.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
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 org.jetbrains.kotlin.ir.visitors.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
val sharedVariablesPhase = makeIrFilePhase(
|
||||||
|
::SharedVariablesLowering,
|
||||||
|
name = "SharedVariables",
|
||||||
|
description = "Transform shared variables"
|
||||||
|
)
|
||||||
|
|
||||||
object CoroutineIntrinsicLambdaOrigin : IrStatementOriginImpl("Coroutine intrinsic lambda")
|
object CoroutineIntrinsicLambdaOrigin : IrStatementOriginImpl("Coroutine intrinsic lambda")
|
||||||
|
|
||||||
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
||||||
|
|||||||
+7
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
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.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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.
|
* 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
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
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.atMostOne
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
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.backend.js.JsDeclarationFactory
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
@@ -47,13 +47,14 @@ class JsIrBackendContext(
|
|||||||
override val irBuiltIns: IrBuiltIns,
|
override val irBuiltIns: IrBuiltIns,
|
||||||
val symbolTable: SymbolTable,
|
val symbolTable: SymbolTable,
|
||||||
irModuleFragment: IrModuleFragment,
|
irModuleFragment: IrModuleFragment,
|
||||||
val configuration: CompilerConfiguration,
|
override val configuration: CompilerConfiguration,
|
||||||
val dependencies: List<IrModuleFragment>
|
val dependencies: List<IrModuleFragment>
|
||||||
) : CommonBackendContext {
|
) : CommonBackendContext {
|
||||||
|
|
||||||
override val builtIns = module.builtIns
|
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 internalPackageFragmentDescriptor = KnownPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
|
||||||
val implicitDeclarationFile by lazy {
|
val implicitDeclarationFile by lazy {
|
||||||
@@ -283,7 +284,7 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
override fun log(message: () -> String) {
|
override fun log(message: () -> String) {
|
||||||
/*TODO*/
|
/*TODO*/
|
||||||
print(message())
|
if (inVerbosePhase) print(message())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean) {
|
override fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean) {
|
||||||
|
|||||||
+180
-161
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
|
import org.jetbrains.kotlin.ir.backend.js.lower.calls.CallsLowering
|
||||||
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.CoroutineIntrinsicLowering
|
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.deepCopyWithSymbols
|
||||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
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 DeclarationContainerLoweringPass.runOnFilesPostfix(files: Iterable<IrFile>) = files.forEach { runOnFilePostfix(it) }
|
||||||
|
|
||||||
private fun ClassLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { runOnFilePostfix(it) }
|
private fun ClassLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { runOnFilePostfix(it) }
|
||||||
|
|
||||||
|
private fun validationCallback(context: JsIrBackendContext, module: IrModuleFragment) {
|
||||||
object IrModuleStartPhase : CompilerPhase<BackendContext, IrModuleFragment> {
|
val validatorConfig = IrValidatorConfig(
|
||||||
override val name = "IrModuleFragment"
|
abortOnError = true,
|
||||||
override val description = "State at start of IrModuleFragment lowering"
|
ensureAllNodesAreDifferent = true,
|
||||||
override val prerequisite = emptySet()
|
checkTypes = false,
|
||||||
override fun invoke(context: BackendContext, input: IrModuleFragment) = input
|
checkDescriptors = false
|
||||||
|
)
|
||||||
|
module.accept(IrValidator(context, validatorConfig), null)
|
||||||
|
module.accept(CheckDeclarationParentsVisitor, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeJsPhase(
|
private fun makeJsModulePhase(
|
||||||
lowering: (JsIrBackendContext, IrModuleFragment) -> Unit,
|
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,
|
description: String,
|
||||||
name: String,
|
name: String,
|
||||||
prerequisite: Set<CompilerPhase<JsIrBackendContext, IrModuleFragment>> = emptySet()
|
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||||
) = makePhase(lowering, description, name, prerequisite)
|
) = 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(
|
private val moveBodilessDeclarationsToSeparatePlacePhase = makeJsModulePhase(
|
||||||
{ _, module -> MoveBodilessDeclarationsToSeparatePlace().lower(module) },
|
::MoveBodilessDeclarationsToSeparatePlace,
|
||||||
name = "MoveBodilessDeclarationsToSeparatePlace",
|
name = "MoveBodilessDeclarationsToSeparatePlace",
|
||||||
description = "Move `external` and `built-in` declarations into separate place to make the following lowerings do not care about them"
|
description = "Move `external` and `built-in` declarations into separate place to make the following lowerings do not care about them"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ExpectDeclarationsRemovingPhase = makeJsPhase(
|
private val expectDeclarationsRemovingPhase = makeJsModulePhase(
|
||||||
{ context, module -> ExpectDeclarationsRemoving(context).lower(module) },
|
::ExpectDeclarationsRemoving,
|
||||||
name = "ExpectDeclarationsRemoving",
|
name = "ExpectDeclarationsRemoving",
|
||||||
description = "Remove expect declaration from module fragment"
|
description = "Remove expect declaration from module fragment"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val CoroutineIntrinsicLoweringPhase = makeJsPhase(
|
private val coroutineIntrinsicLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> CoroutineIntrinsicLowering(context).lower(module) },
|
::CoroutineIntrinsicLowering,
|
||||||
name = "CoroutineIntrinsicLowering",
|
name = "CoroutineIntrinsicLowering",
|
||||||
description = "Replace common coroutine intrinsics with platform specific ones"
|
description = "Replace common coroutine intrinsics with platform specific ones"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ArrayInlineConstructorLoweringPhase = makeJsPhase(
|
private val arrayInlineConstructorLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> ArrayInlineConstructorLowering(context).lower(module) },
|
::ArrayInlineConstructorLowering,
|
||||||
name = "ArrayInlineConstructorLowering",
|
name = "ArrayInlineConstructorLowering",
|
||||||
description = "Replace array constructor with platform specific factory functions"
|
description = "Replace array constructor with platform specific factory functions"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val LateinitLoweringPhase = makeJsPhase(
|
private val lateinitLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> LateinitLowering(context).lower(module) },
|
::LateinitLowering,
|
||||||
name = "LateinitLowering",
|
name = "LateinitLowering",
|
||||||
description = "Insert checks for lateinit field references"
|
description = "Insert checks for lateinit field references"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ModuleCopyingPhase = makeJsPhase(
|
private val moduleCopyingPhase = makeCustomJsModulePhase(
|
||||||
{ context, module -> context.moduleFragmentCopy = module.deepCopyWithSymbols() },
|
{ context, module -> context.moduleFragmentCopy = module.deepCopyWithSymbols() },
|
||||||
name = "ModuleCopying",
|
name = "ModuleCopying",
|
||||||
description = "<Supposed to be removed> Copy current module to make it accessible from different one",
|
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 ->
|
{ context, module ->
|
||||||
FunctionInlining(context).inline(module)
|
FunctionInlining(context).inline(module)
|
||||||
module.replaceUnboundSymbols(context)
|
module.replaceUnboundSymbols(context)
|
||||||
@@ -87,190 +113,190 @@ private val FunctionInliningPhase = makeJsPhase(
|
|||||||
},
|
},
|
||||||
name = "FunctionInliningPhase",
|
name = "FunctionInliningPhase",
|
||||||
description = "Perform function inlining",
|
description = "Perform function inlining",
|
||||||
prerequisite = setOf(ModuleCopyingPhase, LateinitLoweringPhase, ArrayInlineConstructorLoweringPhase, CoroutineIntrinsicLoweringPhase)
|
prerequisite = setOf(moduleCopyingPhase, lateinitLoweringPhase, arrayInlineConstructorLoweringPhase, coroutineIntrinsicLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase = makeJsPhase(
|
private val removeInlineFunctionsWithReifiedTypeParametersLoweringPhase = makeJsModulePhase(
|
||||||
{ _, module -> RemoveInlineFunctionsWithReifiedTypeParametersLowering().lower(module) },
|
{ RemoveInlineFunctionsWithReifiedTypeParametersLowering() },
|
||||||
name = "RemoveInlineFunctionsWithReifiedTypeParametersLowering",
|
name = "RemoveInlineFunctionsWithReifiedTypeParametersLowering",
|
||||||
description = "Remove Inline functions with reified parameters from context",
|
description = "Remove Inline functions with reified parameters from context",
|
||||||
prerequisite = setOf(FunctionInliningPhase)
|
prerequisite = setOf(functionInliningPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ThrowableSuccessorsLoweringPhase = makeJsPhase(
|
private val throwableSuccessorsLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> ThrowableSuccessorsLowering(context).lower(module) },
|
::ThrowableSuccessorsLowering,
|
||||||
name = "ThrowableSuccessorsLowering",
|
name = "ThrowableSuccessorsLowering",
|
||||||
description = "Link kotlin.Throwable and JavaScript Error together to provide proper interop between language and platform exceptions"
|
description = "Link kotlin.Throwable and JavaScript Error together to provide proper interop between language and platform exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val TailrecLoweringPhase = makeJsPhase(
|
private val tailrecLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> TailrecLowering(context).lower(module) },
|
::TailrecLowering,
|
||||||
name = "TailrecLowering",
|
name = "TailrecLowering",
|
||||||
description = "Replace `tailrec` callsites with equivalent loop"
|
description = "Replace `tailrec` callsites with equivalent loop"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val UnitMaterializationLoweringPhase = makeJsPhase(
|
private val unitMaterializationLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> UnitMaterializationLowering(context).lower(module) },
|
::UnitMaterializationLowering,
|
||||||
name = "UnitMaterializationLowering",
|
name = "UnitMaterializationLowering",
|
||||||
description = "Insert Unit object where it is supposed to be",
|
description = "Insert Unit object where it is supposed to be",
|
||||||
prerequisite = setOf(TailrecLoweringPhase)
|
prerequisite = setOf(tailrecLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val EnumClassLoweringPhase = makeJsPhase(
|
private val enumClassLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> EnumClassLowering(context).lower(module) },
|
::EnumClassLowering,
|
||||||
name = "EnumClassLowering",
|
name = "EnumClassLowering",
|
||||||
description = "Transform Enum Class into regular Class"
|
description = "Transform Enum Class into regular Class"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val EnumUsageLoweringPhase = makeJsPhase(
|
private val enumUsageLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> EnumUsageLowering(context).lower(module) },
|
::EnumUsageLowering,
|
||||||
name = "EnumUsageLowering",
|
name = "EnumUsageLowering",
|
||||||
description = "Replace enum access with invocation of corresponding function"
|
description = "Replace enum access with invocation of corresponding function"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val SharedVariablesLoweringPhase = makeJsPhase(
|
private val sharedVariablesLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> SharedVariablesLowering(context).lower(module) },
|
::SharedVariablesLowering,
|
||||||
name = "SharedVariablesLowering",
|
name = "SharedVariablesLowering",
|
||||||
description = "Box captured mutable variables"
|
description = "Box captured mutable variables"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ReturnableBlockLoweringPhase = makeJsPhase(
|
private val returnableBlockLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> ReturnableBlockLowering(context).lower(module) },
|
::ReturnableBlockLowering,
|
||||||
name = "ReturnableBlockLowering",
|
name = "ReturnableBlockLowering",
|
||||||
description = "Replace returnable block with do-while loop",
|
description = "Replace returnable block with do-while loop",
|
||||||
prerequisite = setOf(FunctionInliningPhase)
|
prerequisite = setOf(functionInliningPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val LocalDelegatedPropertiesLoweringPhase = makeJsPhase(
|
private val localDelegatedPropertiesLoweringPhase = makeJsModulePhase(
|
||||||
{ _, module -> LocalDelegatedPropertiesLowering().lower(module) },
|
{ LocalDelegatedPropertiesLowering() },
|
||||||
name = "LocalDelegatedPropertiesLowering",
|
name = "LocalDelegatedPropertiesLowering",
|
||||||
description = "Transform Local Delegated properties"
|
description = "Transform Local Delegated properties"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val LocalDeclarationsLoweringPhase = makeJsPhase(
|
private val localDeclarationsLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> LocalDeclarationsLowering(context).lower(module) },
|
::LocalDeclarationsLowering,
|
||||||
name = "LocalDeclarationsLowering",
|
name = "LocalDeclarationsLowering",
|
||||||
description = "Move local declarations into nearest declaration container",
|
description = "Move local declarations into nearest declaration container",
|
||||||
prerequisite = setOf(SharedVariablesLoweringPhase)
|
prerequisite = setOf(sharedVariablesLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val InnerClassesLoweringPhase = makeJsPhase(
|
private val innerClassesLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> InnerClassesLowering(context).lower(module) },
|
::InnerClassesLowering,
|
||||||
name = "InnerClassesLowering",
|
name = "InnerClassesLowering",
|
||||||
description = "Capture outer this reference to inner class"
|
description = "Capture outer this reference to inner class"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val InnerClassConstructorCallsLoweringPhase = makeJsPhase(
|
private val innerClassConstructorCallsLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> InnerClassConstructorCallsLowering(context).lower(module) },
|
::InnerClassConstructorCallsLowering,
|
||||||
name = "InnerClassConstructorCallsLowering",
|
name = "InnerClassConstructorCallsLowering",
|
||||||
description = "Replace inner class constructor invocation"
|
description = "Replace inner class constructor invocation"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val SuspendFunctionsLoweringPhase = makeJsPhase(
|
private val suspendFunctionsLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> SuspendFunctionsLowering(context).lower(module) },
|
::SuspendFunctionsLowering,
|
||||||
name = "SuspendFunctionsLowering",
|
name = "SuspendFunctionsLowering",
|
||||||
description = "Transform suspend functions into CoroutineImpl instance and build state machine",
|
description = "Transform suspend functions into CoroutineImpl instance and build state machine",
|
||||||
prerequisite = setOf(UnitMaterializationLoweringPhase, CoroutineIntrinsicLoweringPhase)
|
prerequisite = setOf(unitMaterializationLoweringPhase, coroutineIntrinsicLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val PrivateMembersLoweringPhase = makeJsPhase(
|
private val privateMembersLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> PrivateMembersLowering(context).lower(module) },
|
::PrivateMembersLowering,
|
||||||
name = "PrivateMembersLowering",
|
name = "PrivateMembersLowering",
|
||||||
description = "Extract private members from classes"
|
description = "Extract private members from classes"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val CallableReferenceLoweringPhase = makeJsPhase(
|
private val callableReferenceLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> CallableReferenceLowering(context).lower(module) },
|
::CallableReferenceLowering,
|
||||||
name = "CallableReferenceLowering",
|
name = "CallableReferenceLowering",
|
||||||
description = "Handle callable references",
|
description = "Handle callable references",
|
||||||
prerequisite = setOf(
|
prerequisite = setOf(
|
||||||
SuspendFunctionsLoweringPhase,
|
suspendFunctionsLoweringPhase,
|
||||||
LocalDeclarationsLoweringPhase,
|
localDeclarationsLoweringPhase,
|
||||||
LocalDelegatedPropertiesLoweringPhase,
|
localDelegatedPropertiesLoweringPhase,
|
||||||
PrivateMembersLoweringPhase
|
privateMembersLoweringPhase
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val DefaultArgumentStubGeneratorPhase = makeJsPhase(
|
private val defaultArgumentStubGeneratorPhase = makeJsModulePhase(
|
||||||
{ context, module -> JsDefaultArgumentStubGenerator(context).lower(module) },
|
::JsDefaultArgumentStubGenerator,
|
||||||
name = "DefaultArgumentStubGenerator",
|
name = "DefaultArgumentStubGenerator",
|
||||||
description = "Generate synthetic stubs for functions with default parameter values"
|
description = "Generate synthetic stubs for functions with default parameter values"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val DefaultParameterInjectorPhase = makeJsPhase(
|
private val defaultParameterInjectorPhase = makeJsModulePhase(
|
||||||
{ context, module -> DefaultParameterInjector(context).lower(module) },
|
::DefaultParameterInjector,
|
||||||
name = "DefaultParameterInjector",
|
name = "DefaultParameterInjector",
|
||||||
description = "Replace callsite with default parameters with corresponding stub function",
|
description = "Replace callsite with default parameters with corresponding stub function",
|
||||||
prerequisite = setOf(CallableReferenceLoweringPhase, InnerClassesLoweringPhase)
|
prerequisite = setOf(callableReferenceLoweringPhase, innerClassesLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val DefaultParameterCleanerPhase = makeJsPhase(
|
private val defaultParameterCleanerPhase = makeJsModulePhase(
|
||||||
{ context, module -> DefaultParameterCleaner(context).lower(module) },
|
::DefaultParameterCleaner,
|
||||||
name = "DefaultParameterCleaner",
|
name = "DefaultParameterCleaner",
|
||||||
description = "Clean default parameters up"
|
description = "Clean default parameters up"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val JsDefaultCallbackGeneratorPhase = makeJsPhase(
|
private val jsDefaultCallbackGeneratorPhase = makeJsModulePhase(
|
||||||
{ context, module -> JsDefaultCallbackGenerator(context).lower(module) },
|
::JsDefaultCallbackGenerator,
|
||||||
name = "JsDefaultCallbackGenerator",
|
name = "JsDefaultCallbackGenerator",
|
||||||
description = "Build binding for super calls with default parameters"
|
description = "Build binding for super calls with default parameters"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val VarargLoweringPhase = makeJsPhase(
|
private val varargLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> VarargLowering(context).lower(module) },
|
::VarargLowering,
|
||||||
name = "VarargLowering",
|
name = "VarargLowering",
|
||||||
description = "Lower vararg arguments",
|
description = "Lower vararg arguments",
|
||||||
prerequisite = setOf(CallableReferenceLoweringPhase)
|
prerequisite = setOf(callableReferenceLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val PropertiesLoweringPhase = makeJsPhase(
|
private val propertiesLoweringPhase = makeJsModulePhase(
|
||||||
{ _, module -> PropertiesLowering().lower(module) },
|
{ PropertiesLowering() },
|
||||||
name = "PropertiesLowering",
|
name = "PropertiesLowering",
|
||||||
description = "Move fields and accessors out from its property"
|
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) },
|
{ context, module -> InitializersLowering(context, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).lower(module) },
|
||||||
name = "InitializersLowering",
|
name = "InitializersLowering",
|
||||||
description = "Merge init block and field initializers into [primary] constructor",
|
description = "Merge init block and field initializers into [primary] constructor",
|
||||||
prerequisite = setOf(EnumClassLoweringPhase)
|
prerequisite = setOf(enumClassLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val MultipleCatchesLoweringPhase = makeJsPhase(
|
private val multipleCatchesLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> MultipleCatchesLowering(context).lower(module) },
|
::MultipleCatchesLowering,
|
||||||
name = "MultipleCatchesLowering",
|
name = "MultipleCatchesLowering",
|
||||||
description = "Replace multiple catches with single one"
|
description = "Replace multiple catches with single one"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val BridgesConstructionPhase = makeJsPhase(
|
private val bridgesConstructionPhase = makeJsModulePhase(
|
||||||
{ context, module -> BridgesConstruction(context).lower(module) },
|
::BridgesConstruction,
|
||||||
name = "BridgesConstruction",
|
name = "BridgesConstruction",
|
||||||
description = "Generate bridges",
|
description = "Generate bridges",
|
||||||
prerequisite = setOf(SuspendFunctionsLoweringPhase)
|
prerequisite = setOf(suspendFunctionsLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val TypeOperatorLoweringPhase = makeJsPhase(
|
private val typeOperatorLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> TypeOperatorLowering(context).lower(module) },
|
::TypeOperatorLowering,
|
||||||
name = "TypeOperatorLowering",
|
name = "TypeOperatorLowering",
|
||||||
description = "Lower IrTypeOperator with corresponding logic",
|
description = "Lower IrTypeOperator with corresponding logic",
|
||||||
prerequisite = setOf(BridgesConstructionPhase, RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase)
|
prerequisite = setOf(bridgesConstructionPhase, removeInlineFunctionsWithReifiedTypeParametersLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val SecondaryConstructorLoweringPhase = makeJsPhase(
|
private val secondaryConstructorLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> SecondaryConstructorLowering(context).lower(module) },
|
::SecondaryConstructorLowering,
|
||||||
name = "SecondaryConstructorLoweringPhase",
|
name = "SecondaryConstructorLoweringPhase",
|
||||||
description = "Generate static functions for each secondary constructor",
|
description = "Generate static functions for each secondary constructor",
|
||||||
prerequisite = setOf(InnerClassesLoweringPhase)
|
prerequisite = setOf(innerClassesLoweringPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val SecondaryFactoryInjectorLoweringPhase = makeJsPhase(
|
private val secondaryFactoryInjectorLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> SecondaryFactoryInjectorLowering(context).lower(module) },
|
::SecondaryFactoryInjectorLowering,
|
||||||
name = "SecondaryFactoryInjectorLoweringPhase",
|
name = "SecondaryFactoryInjectorLoweringPhase",
|
||||||
description = "Replace usage of secondary constructor with corresponding static function",
|
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 ->
|
{ context, module ->
|
||||||
InlineClassLowering(context).run {
|
InlineClassLowering(context).run {
|
||||||
inlineClassDeclarationLowering.runOnFilesPostfix(module)
|
inlineClassDeclarationLowering.runOnFilesPostfix(module)
|
||||||
@@ -281,102 +307,95 @@ private val InlineClassLoweringPhase = makeJsPhase(
|
|||||||
description = "Handle inline classes"
|
description = "Handle inline classes"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val AutoboxingTransformerPhase = makeJsPhase(
|
private val autoboxingTransformerPhase = makeJsModulePhase(
|
||||||
{ context, module -> AutoboxingTransformer(context).lower(module) },
|
::AutoboxingTransformer,
|
||||||
name = "AutoboxingTransformer",
|
name = "AutoboxingTransformer",
|
||||||
description = "Insert box/unbox intrinsics"
|
description = "Insert box/unbox intrinsics"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val BlockDecomposerLoweringPhase = makeJsPhase(
|
private val blockDecomposerLoweringPhase = makeCustomJsModulePhase(
|
||||||
{ context, module ->
|
{ context, module ->
|
||||||
BlockDecomposerLowering(context).lower(module)
|
BlockDecomposerLowering(context).lower(module)
|
||||||
module.patchDeclarationParents()
|
module.patchDeclarationParents()
|
||||||
},
|
},
|
||||||
name = "BlockDecomposerLowering",
|
name = "BlockDecomposerLowering",
|
||||||
description = "Transform statement-like-expression nodes into pure-statement to make it easily transform into JS",
|
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(
|
private val classReferenceLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> ClassReferenceLowering(context).lower(module) },
|
::ClassReferenceLowering,
|
||||||
name = "ClassReferenceLowering",
|
name = "ClassReferenceLowering",
|
||||||
description = "Handle class references"
|
description = "Handle class references"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val PrimitiveCompanionLoweringPhase = makeJsPhase(
|
private val primitiveCompanionLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> PrimitiveCompanionLowering(context).lower(module) },
|
::PrimitiveCompanionLowering,
|
||||||
name = "PrimitiveCompanionLowering",
|
name = "PrimitiveCompanionLowering",
|
||||||
description = "Replace common companion object access with platform one"
|
description = "Replace common companion object access with platform one"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ConstLoweringPhase = makeJsPhase(
|
private val constLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> ConstLowering(context).lower(module) },
|
::ConstLowering,
|
||||||
name = "ConstLowering",
|
name = "ConstLowering",
|
||||||
description = "Wrap Long and Char constants into constructor invocation"
|
description = "Wrap Long and Char constants into constructor invocation"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val CallsLoweringPhase = makeJsPhase(
|
private val callsLoweringPhase = makeJsModulePhase(
|
||||||
{ context, module -> CallsLowering(context).lower(module) },
|
::CallsLowering,
|
||||||
name = "CallsLowering",
|
name = "CallsLowering",
|
||||||
description = "Handle intrinsics"
|
description = "Handle intrinsics"
|
||||||
)
|
)
|
||||||
|
|
||||||
object IrModuleEndPhase : CompilerPhase<BackendContext, IrModuleFragment> {
|
private val irToJsPhase = makeCustomJsModulePhase(
|
||||||
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(
|
|
||||||
{ context, module -> context.jsProgram = IrModuleToJsTransformer(context).let { module.accept(it, null) } },
|
{ context, module -> context.jsProgram = IrModuleToJsTransformer(context).let { module.accept(it, null) } },
|
||||||
name = "IrModuleToJsTransformer",
|
name = "IrModuleToJsTransformer",
|
||||||
description = "Generate JsAst from IrTree"
|
description = "Generate JsAst from IrTree"
|
||||||
)
|
)
|
||||||
|
|
||||||
val jsPhases = listOf(
|
val jsPhases = namedIrModulePhase(
|
||||||
IrModuleStartPhase,
|
name = "IrModuleLowering",
|
||||||
MoveBodilessDeclarationsToSeparatePlacePhase,
|
description = "IR module lowering",
|
||||||
ExpectDeclarationsRemovingPhase,
|
lower = moveBodilessDeclarationsToSeparatePlacePhase then
|
||||||
CoroutineIntrinsicLoweringPhase,
|
expectDeclarationsRemovingPhase then
|
||||||
ArrayInlineConstructorLoweringPhase,
|
coroutineIntrinsicLoweringPhase then
|
||||||
LateinitLoweringPhase,
|
arrayInlineConstructorLoweringPhase then
|
||||||
ModuleCopyingPhase,
|
lateinitLoweringPhase then
|
||||||
FunctionInliningPhase,
|
moduleCopyingPhase then
|
||||||
RemoveInlineFunctionsWithReifiedTypeParametersLoweringPhase,
|
functionInliningPhase then
|
||||||
ThrowableSuccessorsLoweringPhase,
|
removeInlineFunctionsWithReifiedTypeParametersLoweringPhase then
|
||||||
TailrecLoweringPhase,
|
throwableSuccessorsLoweringPhase then
|
||||||
UnitMaterializationLoweringPhase,
|
tailrecLoweringPhase then
|
||||||
EnumClassLoweringPhase,
|
unitMaterializationLoweringPhase then
|
||||||
EnumUsageLoweringPhase,
|
enumClassLoweringPhase then
|
||||||
SharedVariablesLoweringPhase,
|
enumUsageLoweringPhase then
|
||||||
ReturnableBlockLoweringPhase,
|
sharedVariablesLoweringPhase then
|
||||||
LocalDelegatedPropertiesLoweringPhase,
|
returnableBlockLoweringPhase then
|
||||||
LocalDeclarationsLoweringPhase,
|
localDelegatedPropertiesLoweringPhase then
|
||||||
InnerClassesLoweringPhase,
|
localDeclarationsLoweringPhase then
|
||||||
InnerClassConstructorCallsLoweringPhase,
|
innerClassesLoweringPhase then
|
||||||
SuspendFunctionsLoweringPhase,
|
innerClassConstructorCallsLoweringPhase then
|
||||||
PrivateMembersLoweringPhase,
|
suspendFunctionsLoweringPhase then
|
||||||
CallableReferenceLoweringPhase,
|
privateMembersLoweringPhase then
|
||||||
DefaultArgumentStubGeneratorPhase,
|
callableReferenceLoweringPhase then
|
||||||
DefaultParameterInjectorPhase,
|
defaultArgumentStubGeneratorPhase then
|
||||||
DefaultParameterCleanerPhase,
|
defaultParameterInjectorPhase then
|
||||||
JsDefaultCallbackGeneratorPhase,
|
defaultParameterCleanerPhase then
|
||||||
VarargLoweringPhase,
|
jsDefaultCallbackGeneratorPhase then
|
||||||
PropertiesLoweringPhase,
|
varargLoweringPhase then
|
||||||
InitializersLoweringPhase,
|
propertiesLoweringPhase then
|
||||||
MultipleCatchesLoweringPhase,
|
initializersLoweringPhase then
|
||||||
BridgesConstructionPhase,
|
multipleCatchesLoweringPhase then
|
||||||
TypeOperatorLoweringPhase,
|
bridgesConstructionPhase then
|
||||||
SecondaryConstructorLoweringPhase,
|
typeOperatorLoweringPhase then
|
||||||
SecondaryFactoryInjectorLoweringPhase,
|
secondaryConstructorLoweringPhase then
|
||||||
ClassReferenceLoweringPhase,
|
secondaryFactoryInjectorLoweringPhase then
|
||||||
InlineClassLoweringPhase,
|
classReferenceLoweringPhase then
|
||||||
AutoboxingTransformerPhase,
|
inlineClassLoweringPhase then
|
||||||
BlockDecomposerLoweringPhase,
|
autoboxingTransformerPhase then
|
||||||
PrimitiveCompanionLoweringPhase,
|
blockDecomposerLoweringPhase then
|
||||||
ConstLoweringPhase,
|
primitiveCompanionLoweringPhase then
|
||||||
CallsLoweringPhase,
|
constLoweringPhase then
|
||||||
IrModuleEndPhase,
|
callsLoweringPhase then
|
||||||
IrToJsPhase
|
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
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
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.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
@@ -62,9 +62,7 @@ fun compile(
|
|||||||
irDependencyModules
|
irDependencyModules
|
||||||
)
|
)
|
||||||
|
|
||||||
CompilerPhaseManager(context, context.phases, moduleFragment, JsPhaseRunner).run {
|
jsPhases.invokeToplevel(context.phaseConfig, context, moduleFragment)
|
||||||
jsPhases.fold(data) { m, p -> phase(p, context, m) }
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result(analysisResult.moduleDescriptor, context.jsProgram.toString(), context.moduleFragmentCopy)
|
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.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
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.backend.js.lower.inline.addChild
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
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.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class MoveBodilessDeclarationsToSeparatePlace : FileLoweringPass {
|
class MoveBodilessDeclarationsToSeparatePlace() : FileLoweringPass {
|
||||||
|
|
||||||
|
constructor(context: JsIrBackendContext) : this()
|
||||||
|
|
||||||
private val builtInClasses = listOf(
|
private val builtInClasses = listOf(
|
||||||
"String",
|
"String",
|
||||||
|
|||||||
@@ -6,10 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
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.Ir
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
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.JvmDeclarationFactory
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager
|
||||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||||
@@ -47,19 +46,17 @@ class JvmBackendContext(
|
|||||||
|
|
||||||
override val ir = JvmIr(irModuleFragment, symbolTable)
|
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 {
|
init {
|
||||||
if (state.configuration.get(CommonConfigurationKeys.LIST_PHASES) == true) {
|
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 {
|
private fun find(memberScope: MemberScope, className: String): ClassDescriptor {
|
||||||
return find(memberScope, Name.identifier(className))
|
return find(memberScope, Name.identifier(className))
|
||||||
}
|
}
|
||||||
@@ -146,7 +143,7 @@ class JvmBackendContext(
|
|||||||
override val coroutineSuspendedGetter: IrSimpleFunctionSymbol
|
override val coroutineSuspendedGetter: IrSimpleFunctionSymbol
|
||||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
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(
|
state.module.getPackage(FqName("kotlin")).memberScope.getContributedVariables(
|
||||||
Name.identifier("isInitialized"), NoLookupLocation.FROM_BACKEND
|
Name.identifier("isInitialized"), NoLookupLocation.FROM_BACKEND
|
||||||
).single {
|
).single {
|
||||||
|
|||||||
@@ -16,32 +16,78 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.*
|
||||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
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.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
|
||||||
fun makePatchParentsPhase(number: Int) = object : CompilerPhase<BackendContext, IrFile> {
|
private fun makePatchParentsPhase(number: Int) = namedIrFilePhase(
|
||||||
override val name: String = "PatchParents$number"
|
lower = object : SameTypeCompilerPhase<CommonBackendContext, IrFile> {
|
||||||
override val description: String = "Patch parent references in IrFile, pass $number"
|
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: CommonBackendContext, input: IrFile): IrFile {
|
||||||
override val prerequisite: Set<CompilerPhase<BackendContext, *>> = emptySet()
|
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 {
|
internal val jvmPhases = namedIrFilePhase(
|
||||||
input.acceptVoid(PatchDeclarationParentsVisitor())
|
name = "IrLowering",
|
||||||
return input
|
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) {
|
class JvmLower(val context: JvmBackendContext) {
|
||||||
fun lower(irFile: IrFile) {
|
fun lower(irFile: IrFile) {
|
||||||
var state = irFile
|
|
||||||
// TODO run lowering passes as callbacks in bottom-up visitor
|
// TODO run lowering passes as callbacks in bottom-up visitor
|
||||||
|
jvmPhases.invokeToplevel(context.phaseConfig, context, irFile)
|
||||||
context.rootPhaseManager(irFile).apply {
|
|
||||||
for (jvmPhase in jvmPhases) {
|
|
||||||
state = phase(jvmPhase, context, state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
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()
|
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
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.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl
|
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.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
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
|
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.copyTo
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||||
@@ -51,8 +52,14 @@ class CrIrType(val type: Type) : IrType {
|
|||||||
override val annotations = emptyList()
|
override val annotations = emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val callableReferencePhase = makeIrFilePhase(
|
||||||
|
::CallableReferenceLowering,
|
||||||
|
name = "CallableReference",
|
||||||
|
description = "Handle callable references"
|
||||||
|
)
|
||||||
|
|
||||||
//Originally was copied from K/Native
|
//Originally was copied from K/Native
|
||||||
class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPass {
|
internal class CallableReferenceLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||||
|
|
||||||
private var functionReferenceCount = 0
|
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.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
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.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
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) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(this)
|
irFile.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
|
|
||||||
import gnu.trove.TObjectIntHashMap
|
import gnu.trove.TObjectIntHashMap
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.createValueParameter
|
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 org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import java.util.*
|
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) {
|
override fun lower(irClass: IrClass) {
|
||||||
if (!irClass.isEnumClass) return
|
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.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
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.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -34,7 +35,13 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
|||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
import java.util.*
|
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) {
|
override fun lower(irFile: IrFile) {
|
||||||
val classes = ArrayList<IrClass>()
|
val classes = ArrayList<IrClass>()
|
||||||
val fileClassMembers = ArrayList<IrDeclaration>()
|
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.descriptors.WrappedValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
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.ir.util.isSubclassOf
|
||||||
import org.jetbrains.kotlin.name.Name
|
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) {
|
override fun lower(irClass: IrClass) {
|
||||||
val invokeFunctions = irClass.filterDeclarations<IrSimpleFunction> { it.name.toString() == "invoke" }
|
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.descriptors.WrappedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
|
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
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.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
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
|
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.ir.copyTypeParametersFrom
|
||||||
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering.Companion.clinitName
|
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering.Companion.clinitName
|
||||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
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.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
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.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
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
|
val state = context.state
|
||||||
|
|
||||||
|
|||||||
+7
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
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.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.Not
|
import org.jetbrains.kotlin.codegen.intrinsics.Not
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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 {
|
class JvmBuiltinOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
+7
-1
@@ -6,8 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
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.utils.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.backend.common.makePhase
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
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.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.InsertImplicitCasts
|
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) :
|
class JvmCoercionToUnitPatcher(val context: JvmBackendContext) :
|
||||||
InsertImplicitCasts(
|
InsertImplicitCasts(
|
||||||
context.builtIns, context.irBuiltIns,
|
context.builtIns, context.irBuiltIns,
|
||||||
|
|||||||
+8
-2
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
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.calls.components.hasDefaultValue
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
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) {
|
override fun lower(irClass: IrClass) {
|
||||||
val functions = irClass.declarations.filterIsInstance<IrFunction>().filter {
|
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.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
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.common.runOnFilePostfix
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
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.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
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
|
* For @JvmStatic functions within companion objects of classes, we synthesize proxy static functions that redirect
|
||||||
* to the actual implementation.
|
* to the actual implementation.
|
||||||
* For @JvmStatic functions within static objects, we make the actual function static and modify all call sites.
|
* 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) {
|
override fun lower(irFile: IrFile) {
|
||||||
CompanionObjectJvmStaticLowering(context).runOnFilePostfix(irFile)
|
CompanionObjectJvmStaticLowering(context).runOnFilePostfix(irFile)
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
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.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
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.WrappedFieldDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
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.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
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.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.name.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) {
|
override fun lower(irClass: IrClass) {
|
||||||
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
|
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
|
||||||
if (irClass.isObject && !irClass.isCompanion && irClass.visibility != Visibilities.LOCAL) {
|
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.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
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.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
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.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.isObject
|
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>>()
|
private var pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
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.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
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) {
|
override fun lower(irBody: IrBody) {
|
||||||
irBody.transformChildrenVoid(this)
|
irBody.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -18,13 +18,20 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
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.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
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()
|
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
|
|||||||
+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.WrappedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.*
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
|
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.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
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 pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||||
private val inlinedLambdasCollector = InlinedLambdasCollector()
|
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.KnownClassDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
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.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
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.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||||
import org.jetbrains.kotlin.types.Variance
|
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) {
|
override fun lower(irClass: IrClass) {
|
||||||
if (irClass.isJvmInterface) return
|
if (irClass.isJvmInterface) return
|
||||||
|
|||||||
Reference in New Issue
Block a user