Add CompilerPhase and corresponding compiler keys
This commit is contained in:
+42
@@ -196,6 +196,48 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
)
|
||||
var allowResultReturnType: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xlist-phases",
|
||||
description = "List backend phases"
|
||||
)
|
||||
var listPhases: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xdisable-phases",
|
||||
description = "Disable backend phases"
|
||||
)
|
||||
var disablePhases: Array<String> by FreezableVar(emptyArray())
|
||||
|
||||
@Argument(
|
||||
value = "-Xverbose-phases",
|
||||
description = "Be verbose while performing these backend phases"
|
||||
)
|
||||
var verbosePhases: Array<String> by FreezableVar(emptyArray())
|
||||
|
||||
@Argument(
|
||||
value = "-Xphases-to-dump-before",
|
||||
description = "Dump backend state before these phases"
|
||||
)
|
||||
var phasesToDumpBefore: Array<String> by FreezableVar(emptyArray())
|
||||
|
||||
@Argument(
|
||||
value = "-Xphases-to-dump-after",
|
||||
description = "Dump backend state after these phases"
|
||||
)
|
||||
var phasesToDumpAfter: Array<String> by FreezableVar(emptyArray())
|
||||
|
||||
@Argument(
|
||||
value = "-Xphases-to-dump",
|
||||
description = "Dump backend state both before and after these phases"
|
||||
)
|
||||
var phasesToDump: Array<String> by FreezableVar(emptyArray())
|
||||
|
||||
@Argument(
|
||||
value = "-Xprofile-phases",
|
||||
description = "Profile backend phases"
|
||||
)
|
||||
var profilePhases: Boolean by FreezableVar(false)
|
||||
|
||||
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
return HashMap<AnalysisFlag<*>, Any>().apply {
|
||||
put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck)
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.common;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import kotlin.collections.SetsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -160,6 +161,14 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
}
|
||||
|
||||
setupLanguageVersionSettings(configuration, arguments);
|
||||
|
||||
configuration.put(CommonConfigurationKeys.LIST_PHASES, arguments.getListPhases());
|
||||
configuration.put(CommonConfigurationKeys.DISABLED_PHASES, SetsKt.setOf(arguments.getDisablePhases()));
|
||||
configuration.put(CommonConfigurationKeys.VERBOSE_PHASES, SetsKt.setOf(arguments.getVerbosePhases()));
|
||||
configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_BEFORE, SetsKt.setOf(arguments.getPhasesToDumpBefore()));
|
||||
configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE_AFTER, SetsKt.setOf(arguments.getPhasesToDumpAfter()));
|
||||
configuration.put(CommonConfigurationKeys.PHASES_TO_DUMP_STATE, SetsKt.setOf(arguments.getPhasesToDump()));
|
||||
configuration.put(CommonConfigurationKeys.PROFILE_PHASES, arguments.getProfilePhases());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -41,6 +41,27 @@ object CommonConfigurationKeys {
|
||||
|
||||
@JvmField
|
||||
val METADATA_VERSION = CompilerConfigurationKey.create<BinaryVersion>("metadata version")
|
||||
|
||||
@JvmField
|
||||
val LIST_PHASES = CompilerConfigurationKey.create<Boolean>("list names of backend phases")
|
||||
|
||||
@JvmField
|
||||
val DISABLED_PHASES = CompilerConfigurationKey.create<Set<String>>("disable backend phases")
|
||||
|
||||
@JvmField
|
||||
val PHASES_TO_DUMP_STATE_BEFORE = CompilerConfigurationKey.create<Set<String>>("backend phases where we dump compiler state before the phase")
|
||||
|
||||
@JvmField
|
||||
val PHASES_TO_DUMP_STATE_AFTER = CompilerConfigurationKey.create<Set<String>>("backend phases where we dump compiler state after the phase")
|
||||
|
||||
@JvmField
|
||||
val PHASES_TO_DUMP_STATE = CompilerConfigurationKey.create<Set<String>>("backend phases where we dump compiler state both before and after the phase")
|
||||
|
||||
@JvmField
|
||||
val VERBOSE_PHASES = CompilerConfigurationKey.create<Set<String>>("verbose backend phases")
|
||||
|
||||
@JvmField
|
||||
val PROFILE_PHASES = CompilerConfigurationKey.create<Boolean>("profile backend phase execution")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.declarations.IrFile
|
||||
|
||||
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>
|
||||
|
||||
init {
|
||||
with(CommonConfigurationKeys) {
|
||||
val beforeSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_BEFORE)
|
||||
val afterSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_AFTER)
|
||||
val bothSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE)
|
||||
toDumpStateBefore = beforeSet + bothSet
|
||||
toDumpStateAfter = afterSet + bothSet
|
||||
}
|
||||
}
|
||||
|
||||
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 reportBefore(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
||||
fun runBody(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data
|
||||
fun reportAfter(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
||||
}
|
||||
|
||||
/* We assume that `element` is being modified by each phase, retaining its identity in the process. */
|
||||
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.reportBefore(phase, depth, context, source)
|
||||
val result = phaseRunner.runBody(phase, context, source)
|
||||
phaseRunner.reportAfter(phase, depth, context, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun <Context : BackendContext> makePhase(
|
||||
loweringConstructor: (Context) -> FileLoweringPass,
|
||||
description: String,
|
||||
name: String,
|
||||
prerequisite: Set<CompilerPhase<*, *>> = emptySet()
|
||||
) = object : CompilerPhase<Context, IrFile> {
|
||||
override val name = name
|
||||
override val description = description
|
||||
override val prerequisite = prerequisite
|
||||
|
||||
override fun invoke(context: Context, input: IrFile): IrFile {
|
||||
loweringConstructor(context).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -30,20 +30,28 @@ interface FileLoweringPass {
|
||||
fun lower(irFile: IrFile)
|
||||
}
|
||||
|
||||
interface ClassLoweringPass {
|
||||
interface ClassLoweringPass : FileLoweringPass {
|
||||
fun lower(irClass: IrClass)
|
||||
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
interface DeclarationContainerLoweringPass {
|
||||
interface DeclarationContainerLoweringPass : FileLoweringPass {
|
||||
fun lower(irDeclarationContainer: IrDeclarationContainer)
|
||||
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
interface FunctionLoweringPass {
|
||||
interface FunctionLoweringPass : FileLoweringPass {
|
||||
fun lower(irFunction: IrFunction)
|
||||
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
interface BodyLoweringPass {
|
||||
interface BodyLoweringPass : FileLoweringPass {
|
||||
fun lower(irBody: IrBody)
|
||||
|
||||
override fun lower(irFile: IrFile) = runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
fun ClassLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||
@@ -67,7 +75,7 @@ fun DeclarationContainerLoweringPass.asClassLoweringPass() = object : ClassLower
|
||||
|
||||
fun DeclarationContainerLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||
this.asClassLoweringPass().runOnFilePostfix(irFile)
|
||||
this.lower(irFile)
|
||||
this.lower(irFile as IrDeclarationContainer)
|
||||
}
|
||||
|
||||
fun BodyLoweringPass.runOnFilePostfix(irFile: IrFile) {
|
||||
|
||||
+11
-4
@@ -5,10 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
@@ -39,6 +36,16 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun makeDefaultArgumentStubPhase(skipInlineMethods: Boolean) = object : CompilerPhase<CommonBackendContext, IrFile> {
|
||||
override val name = "DefaultArgumentsStubGenerator"
|
||||
override val description = "Generate synthetic stubs for functions with default parameter values"
|
||||
|
||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
||||
DefaultArgumentStubGenerator(context, skipInlineMethods).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: fix expect/actual default parameters
|
||||
|
||||
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
||||
|
||||
+12
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.ir.SetDeclarationsParentVisitor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -29,6 +30,17 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
|
||||
fun makeInitializersPhase(declarationOrigin: IrDeclarationOrigin, clinitNeeded: Boolean) = object :
|
||||
CompilerPhase<CommonBackendContext, IrFile> {
|
||||
override val name = "Initializers"
|
||||
override val description = "Handle initializer statements"
|
||||
|
||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
||||
InitializersLowering(context, declarationOrigin, clinitNeeded).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
object SYNTHESIZED_INIT_BLOCK: IrStatementOriginImpl("SYNTHESIZED_INIT_BLOCK")
|
||||
|
||||
class InitializersLowering(
|
||||
|
||||
+13
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
@@ -26,6 +27,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import java.util.*
|
||||
|
||||
val InnerClassesPhase = makePhase(
|
||||
::InnerClassesLowering,
|
||||
name = "InnerClasses",
|
||||
description = "Move inner classes to toplevel"
|
||||
)
|
||||
|
||||
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
InnerClassTransformer(irClass).lowerInnerClass()
|
||||
@@ -167,6 +174,12 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
}
|
||||
}
|
||||
|
||||
val InnerClassConstructorCallsPhase = makePhase(
|
||||
::InnerClassConstructorCallsLowering,
|
||||
name = "InnerClassConstructorCalls",
|
||||
description = "Handle constructor calls for inner classes"
|
||||
)
|
||||
|
||||
class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass {
|
||||
override fun lower(irBody: IrBody) {
|
||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
|
||||
+7
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
@@ -37,6 +38,12 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
val KCallableNamePropertyPhase = makePhase(
|
||||
::KCallableNamePropertyLowering,
|
||||
name = "KCallableNameProperty",
|
||||
description = "Replace name references for callables with constants"
|
||||
)
|
||||
|
||||
class KCallableNamePropertyLowering(val context: BackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(KCallableNamePropertyTransformer(this))
|
||||
|
||||
+12
-1
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -33,6 +34,16 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
fun makeLateinitPhase(generateParameterNameInAssertion: Boolean) = object : CompilerPhase<CommonBackendContext, IrFile> {
|
||||
override val name = "Lateinit"
|
||||
override val description = "Insert checks for lateinit field references"
|
||||
|
||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
||||
LateinitLowering(context, generateParameterNameInAssertion).lower(input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
class LateinitLowering(
|
||||
val context: CommonBackendContext,
|
||||
private val generateParameterNameInAssertion: Boolean = false
|
||||
@@ -130,4 +141,4 @@ class LateinitLowering(
|
||||
}
|
||||
|
||||
private val throwErrorFunction = context.ir.symbols.ThrowUninitializedPropertyAccessException.owner
|
||||
}
|
||||
}
|
||||
|
||||
+29
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.DeclarationContainerLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
@@ -35,9 +36,24 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
||||
import java.util.*
|
||||
|
||||
val LocalDeclarationsPhase = makePhase(
|
||||
::LocalDeclarationsLowering,
|
||||
name = "LocalDeclarations",
|
||||
description = "Move local declarations to classes",
|
||||
prerequisite = setOf(SharedVariablesPhase)
|
||||
)
|
||||
|
||||
val JvmLocalDeclarationsPhase = makePhase(
|
||||
::JvmLocalDeclarationsLowering,
|
||||
name = "JvmLocalDeclarations",
|
||||
description = "Move local declarations to classes",
|
||||
prerequisite = setOf(SharedVariablesPhase)
|
||||
)
|
||||
|
||||
interface LocalNameProvider {
|
||||
fun localName(descriptor: DeclarationDescriptor): String =
|
||||
descriptor.name.asString()
|
||||
@@ -55,7 +71,18 @@ val IrDeclaration.parents: Sequence<IrDeclarationParent>
|
||||
|
||||
object BOUND_VALUE_PARAMETER: IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER")
|
||||
|
||||
class LocalDeclarationsLowering(
|
||||
class JvmLocalDeclarationsLowering(context: BackendContext) :
|
||||
LocalDeclarationsLowering(
|
||||
context,
|
||||
object : LocalNameProvider {
|
||||
override fun localName(descriptor: DeclarationDescriptor): String =
|
||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
|
||||
},
|
||||
Visibilities.PUBLIC, //TODO properly figure out visibility
|
||||
true
|
||||
)
|
||||
|
||||
open class LocalDeclarationsLowering(
|
||||
val context: BackendContext,
|
||||
val localNameProvider: LocalNameProvider = LocalNameProvider.DEFAULT,
|
||||
val loweredConstructorVisibility: Visibility = Visibilities.PRIVATE,
|
||||
@@ -773,4 +800,4 @@ class LocalDeclarationsLowering(
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+11
-1
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -16,7 +18,15 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
class PropertiesLowering : IrElementTransformerVoid(), FileLoweringPass {
|
||||
val PropertiesPhase = makePhase(
|
||||
::PropertiesLowering,
|
||||
name = "Properties",
|
||||
description = "move fields and accessors for properties to their classes"
|
||||
)
|
||||
|
||||
class PropertiesLowering() : IrElementTransformerVoid(), FileLoweringPass {
|
||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.accept(this, null)
|
||||
}
|
||||
|
||||
+7
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
@@ -33,6 +34,12 @@ import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import java.util.*
|
||||
|
||||
val SharedVariablesPhase = makePhase(
|
||||
::SharedVariablesLowering,
|
||||
name = "SharedVariables",
|
||||
description = "Transform shared variables"
|
||||
)
|
||||
|
||||
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
||||
override fun lower(irFunction: IrFunction) {
|
||||
SharedVariablesTransformer(irFunction).lowerSharedVariables()
|
||||
|
||||
+6
@@ -27,6 +27,12 @@ import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
val TailrecPhase = makePhase(
|
||||
::TailrecLowering,
|
||||
name = "Tailrec",
|
||||
description = "Handle tailrec calls"
|
||||
)
|
||||
|
||||
/**
|
||||
* This pass lowers tail recursion calls in `tailrec` functions.
|
||||
*
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
package org.jetbrains.kotlin.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhaseManager
|
||||
import org.jetbrains.kotlin.backend.common.CompilerPhases
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmDeclarationFactory
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmSharedVariablesManager
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||
@@ -44,6 +47,19 @@ class JvmBackendContext(
|
||||
|
||||
override val ir = JvmIr(irModuleFragment, symbolTable)
|
||||
|
||||
val phases = CompilerPhases(jvmPhases, state.configuration)
|
||||
|
||||
init {
|
||||
if (state.configuration.get(CommonConfigurationKeys.LIST_PHASES) == true) {
|
||||
phases.list()
|
||||
}
|
||||
}
|
||||
|
||||
var inVerbosePhase = false
|
||||
|
||||
fun rootPhaseManager(irFile: IrFile) = CompilerPhaseManager(this, phases, irFile, JvmPhaseRunner)
|
||||
|
||||
|
||||
private fun find(memberScope: MemberScope, className: String): ClassDescriptor {
|
||||
return find(memberScope, Name.identifier(className))
|
||||
}
|
||||
@@ -73,7 +89,9 @@ class JvmBackendContext(
|
||||
|
||||
override fun log(message: () -> String) {
|
||||
/*TODO*/
|
||||
print(message())
|
||||
if (inVerbosePhase) {
|
||||
print(message())
|
||||
}
|
||||
}
|
||||
|
||||
override fun report(element: IrElement?, irFile: IrFile?, message: String, isError: Boolean) {
|
||||
|
||||
@@ -16,71 +16,85 @@
|
||||
|
||||
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.IrFileEndPhase
|
||||
import org.jetbrains.kotlin.backend.common.IrFileStartPhase
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
|
||||
val jvmPhases = listOf(
|
||||
IrFileStartPhase,
|
||||
|
||||
JvmCoercionToUnitPhase,
|
||||
FileClassPhase,
|
||||
KCallableNamePropertyPhase,
|
||||
|
||||
makeLateinitPhase(true),
|
||||
|
||||
MoveCompanionObjectFieldsPhase,
|
||||
ConstAndJvmFieldPropertiesPhase,
|
||||
PropertiesPhase,
|
||||
AnnotationPhase,
|
||||
|
||||
makeDefaultArgumentStubPhase(false),
|
||||
|
||||
InterfacePhase,
|
||||
InterfaceDelegationPhase,
|
||||
SharedVariablesPhase,
|
||||
|
||||
makePatchParentsPhase(1),
|
||||
|
||||
JvmLocalDeclarationsPhase,
|
||||
CallableReferencePhase,
|
||||
FunctionNVarargInvokePhase,
|
||||
|
||||
InnerClassesPhase,
|
||||
InnerClassConstructorCallsPhase,
|
||||
|
||||
makePatchParentsPhase(2),
|
||||
|
||||
EnumClassPhase,
|
||||
ObjectClassPhase,
|
||||
makeInitializersPhase(JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true),
|
||||
SingletonReferencesPhase,
|
||||
SyntheticAccessorPhase,
|
||||
BridgePhase,
|
||||
JvmOverloadsAnnotationPhase,
|
||||
JvmStaticAnnotationPhase,
|
||||
StaticDefaultFunctionPhase,
|
||||
|
||||
TailrecPhase,
|
||||
ToArrayPhase,
|
||||
|
||||
makePatchParentsPhase(3),
|
||||
|
||||
IrFileEndPhase
|
||||
)
|
||||
|
||||
fun makePatchParentsPhase(number: Int) = object : CompilerPhase<BackendContext, IrFile> {
|
||||
override val name: String = "PatchParents$number"
|
||||
override val description: String = "Patch parent references in IrFile, pass $number"
|
||||
override val prerequisite: Set<CompilerPhase<BackendContext, *>> = emptySet()
|
||||
|
||||
override fun invoke(context: BackendContext, input: IrFile): IrFile {
|
||||
input.acceptVoid(PatchDeclarationParentsVisitor())
|
||||
return input
|
||||
}
|
||||
}
|
||||
|
||||
class JvmLower(val context: JvmBackendContext) {
|
||||
fun lower(irFile: IrFile) {
|
||||
var state = irFile
|
||||
// TODO run lowering passes as callbacks in bottom-up visitor
|
||||
JvmCoercionToUnitPatcher(context).lower(irFile)
|
||||
FileClassLowering(context).lower(irFile)
|
||||
KCallableNamePropertyLowering(context).lower(irFile)
|
||||
|
||||
LateinitLowering(context, true).lower(irFile)
|
||||
|
||||
MoveCompanionObjectFieldsLowering(context).runOnFilePostfix(irFile)
|
||||
ConstAndJvmFieldPropertiesLowering(context).lower(irFile)
|
||||
PropertiesLowering().lower(irFile)
|
||||
AnnotationLowering().runOnFilePostfix(irFile) //should be run before defaults lowering
|
||||
|
||||
//Should be before interface lowering
|
||||
DefaultArgumentStubGenerator(context, false).runOnFilePostfix(irFile)
|
||||
|
||||
InterfaceLowering(context).runOnFilePostfix(irFile)
|
||||
InterfaceDelegationLowering(context).runOnFilePostfix(irFile)
|
||||
SharedVariablesLowering(context).runOnFilePostfix(irFile)
|
||||
|
||||
irFile.acceptVoid(PatchDeclarationParentsVisitor())
|
||||
|
||||
LocalDeclarationsLowering(
|
||||
context,
|
||||
object : LocalNameProvider {
|
||||
override fun localName(descriptor: DeclarationDescriptor): String =
|
||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
|
||||
},
|
||||
Visibilities.PUBLIC, //TODO properly figure out visibility
|
||||
true
|
||||
).runOnFilePostfix(irFile)
|
||||
CallableReferenceLowering(context).lower(irFile)
|
||||
FunctionNVarargInvokeLowering(context).runOnFilePostfix(irFile)
|
||||
|
||||
InnerClassesLowering(context).runOnFilePostfix(irFile)
|
||||
InnerClassConstructorCallsLowering(context).runOnFilePostfix(irFile)
|
||||
|
||||
irFile.acceptVoid(PatchDeclarationParentsVisitor())
|
||||
|
||||
EnumClassLowering(context).runOnFilePostfix(irFile)
|
||||
//Should be before SyntheticAccessorLowering cause of synthetic accessor for companion constructor
|
||||
ObjectClassLowering(context).lower(irFile)
|
||||
InitializersLowering(context, JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true).runOnFilePostfix(irFile)
|
||||
SingletonReferencesLowering(context).runOnFilePostfix(irFile)
|
||||
SyntheticAccessorLowering(context).lower(irFile)
|
||||
BridgeLowering(context).runOnFilePostfix(irFile)
|
||||
JvmOverloadsAnnotationLowering(context).runOnFilePostfix(irFile)
|
||||
JvmStaticAnnotationLowering(context).lower(irFile)
|
||||
StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile)
|
||||
|
||||
TailrecLowering(context).runOnFilePostfix(irFile)
|
||||
ToArrayLowering(context).runOnFilePostfix(irFile)
|
||||
|
||||
irFile.acceptVoid(PatchDeclarationParentsVisitor())
|
||||
|
||||
context.rootPhaseManager(irFile).apply {
|
||||
for (jvmPhase in jvmPhases) {
|
||||
state = phase(jvmPhase, context, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.*
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.name
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
enum class BeforeOrAfter { BEFORE, AFTER }
|
||||
|
||||
object JvmPhaseRunner : PhaseRunner<JvmBackendContext, IrFile> {
|
||||
override fun reportBefore(phase: CompilerPhase<JvmBackendContext, IrFile>, depth: Int, context: JvmBackendContext, data: IrFile) {
|
||||
if (phase in context.phases.toDumpStateBefore) {
|
||||
dumpFile(data, phase, BeforeOrAfter.BEFORE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun runBody(phase: CompilerPhase<JvmBackendContext, IrFile>, context: JvmBackendContext, source: IrFile): IrFile {
|
||||
val runner = when {
|
||||
phase === IrFileStartPhase -> ::justRun
|
||||
phase === IrFileEndPhase -> ::justRun
|
||||
(context.state.configuration.get(CommonConfigurationKeys.PROFILE_PHASES) == true) -> ::runAndProfile
|
||||
else -> ::justRun
|
||||
}
|
||||
|
||||
context.inVerbosePhase = (phase in context.phases.verbose)
|
||||
|
||||
val result = runner(phase, context, source)
|
||||
|
||||
context.inVerbosePhase = false
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun reportAfter(phase: CompilerPhase<JvmBackendContext, IrFile>, depth: Int, context: JvmBackendContext, data: IrFile) {
|
||||
if (phase in context.phases.toDumpStateAfter) {
|
||||
dumpFile(data, phase, BeforeOrAfter.AFTER)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runAndProfile(phase: CompilerPhase<JvmBackendContext, IrFile>, context: JvmBackendContext, source: IrFile): IrFile {
|
||||
var result: IrFile = source
|
||||
val msec = measureTimeMillis { result = phase.invoke(context, source) }
|
||||
println("${phase.description}: $msec msec")
|
||||
return result
|
||||
}
|
||||
|
||||
private fun justRun(phase: CompilerPhase<JvmBackendContext, IrFile>, context: JvmBackendContext, source: IrFile) =
|
||||
phase.invoke(context, source)
|
||||
|
||||
private fun separator(title: String) {
|
||||
println("\n\n--- $title ----------------------\n")
|
||||
}
|
||||
|
||||
private fun dumpFile(irFile: IrFile, phase: CompilerPhase<JvmBackendContext, IrFile>, beforeOrAfter: BeforeOrAfter) {
|
||||
// Exclude nonsensical combinations
|
||||
if (phase === IrFileStartPhase && beforeOrAfter == BeforeOrAfter.AFTER) return
|
||||
if (phase === IrFileEndPhase && beforeOrAfter == BeforeOrAfter.BEFORE) return
|
||||
|
||||
val title = when (phase) {
|
||||
IrFileStartPhase -> "IR for ${irFile.name} at the start of lowering process"
|
||||
IrFileEndPhase -> "IR for ${irFile.name} at the end of lowering process"
|
||||
else -> {
|
||||
val beforeOrAfterStr = beforeOrAfter.name.toLowerCase()
|
||||
"IR for ${irFile.name} $beforeOrAfterStr ${phase.description}"
|
||||
}
|
||||
}
|
||||
separator(title)
|
||||
println(irFile.dump())
|
||||
}
|
||||
+10
-1
@@ -5,12 +5,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
|
||||
class AnnotationLowering : ClassLoweringPass {
|
||||
val AnnotationPhase = makePhase(
|
||||
::AnnotationLowering,
|
||||
name = "Annotation",
|
||||
description = "Remove constructors from annotation classes"
|
||||
)
|
||||
|
||||
class AnnotationLowering() : ClassLoweringPass {
|
||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (!irClass.isAnnotationClass) return
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.bridges.generateBridgesForFunctionDes
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl
|
||||
@@ -59,6 +60,12 @@ import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
val BridgePhase = makePhase(
|
||||
::BridgeLowering,
|
||||
name = "Bridge",
|
||||
description = "Generate bridges"
|
||||
)
|
||||
|
||||
class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
private val state = context.state
|
||||
|
||||
+7
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.createFakeOverrideDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineCall
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
@@ -59,6 +60,12 @@ import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
val CallableReferencePhase = makePhase(
|
||||
::CallableReferenceLowering,
|
||||
name = "CallableReference",
|
||||
description = "Handle callable references"
|
||||
)
|
||||
|
||||
//Hack implementation to support CR java types in lower
|
||||
class CrIrType(val type: Type) : IrType {
|
||||
override val annotations = emptyList()
|
||||
|
||||
+7
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -21,6 +22,12 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
|
||||
val ConstAndJvmFieldPropertiesPhase = makePhase(
|
||||
::ConstAndJvmFieldPropertiesLowering,
|
||||
name = "ConstAndJvmFieldProperties",
|
||||
description = "Substitute calls to const and Jvm>Field properties with const/field access"
|
||||
)
|
||||
|
||||
class ConstAndJvmFieldPropertiesLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(this)
|
||||
|
||||
+7
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import gnu.trove.TObjectIntHashMap
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmPropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.createValueParameter
|
||||
@@ -32,6 +33,12 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.util.*
|
||||
|
||||
val EnumClassPhase = makePhase(
|
||||
::EnumClassLowering,
|
||||
name = "EnumClass",
|
||||
description = "Handle enum classes"
|
||||
)
|
||||
|
||||
class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (!irClass.isEnumClass) return
|
||||
|
||||
+7
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -33,6 +34,12 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import java.util.*
|
||||
|
||||
val FileClassPhase = makePhase(
|
||||
::FileClassLowering,
|
||||
name = "FileClass",
|
||||
description = "Put file level function and property declaration into a class"
|
||||
)
|
||||
|
||||
class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
val classes = ArrayList<IrClass>()
|
||||
|
||||
+7
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDesc
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
@@ -29,6 +30,12 @@ import org.jetbrains.kotlin.ir.util.findDeclaration
|
||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val FunctionNVarargInvokePhase = makePhase(
|
||||
::FunctionNVarargInvokeLowering,
|
||||
name = "FunctionNVarargInvoke",
|
||||
description = "Handle invoke functions with large number of arguments"
|
||||
)
|
||||
|
||||
class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
|
||||
+6
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
@@ -28,6 +29,11 @@ import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
val InterfaceDelegationPhase = makePhase(
|
||||
::InterfaceDelegationLowering,
|
||||
name = "InterfaceDelegation",
|
||||
description = "Delegate calls to interface members with default implementations to DefaultImpls"
|
||||
)
|
||||
|
||||
class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
|
||||
|
||||
+7
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
|
||||
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering.Companion.clinitName
|
||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapperDesc
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -27,6 +28,12 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
val InterfacePhase = makePhase(
|
||||
::InterfaceLowering,
|
||||
name = "Interface",
|
||||
description = "Move default implementations of interface members to DefaultImpls class"
|
||||
)
|
||||
|
||||
class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
|
||||
val state = context.state
|
||||
|
||||
+8
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
@@ -16,6 +17,12 @@ import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.psi2ir.transformations.InsertImplicitCasts
|
||||
|
||||
val JvmCoercionToUnitPhase = makePhase(
|
||||
::JvmCoercionToUnitPatcher,
|
||||
name = "JvmCoercionToUnit",
|
||||
description = "Insert conversions to unit after IrCalls where needed"
|
||||
)
|
||||
|
||||
class JvmCoercionToUnitPatcher(val context: JvmBackendContext) :
|
||||
InsertImplicitCasts(
|
||||
context.builtIns, context.irBuiltIns,
|
||||
@@ -34,4 +41,4 @@ class JvmCoercionToUnitPatcher(val context: JvmBackendContext) :
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
@@ -34,6 +35,11 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||
|
||||
val JvmOverloadsAnnotationPhase = makePhase(
|
||||
::JvmOverloadsAnnotationLowering,
|
||||
name = "JvmOverloadsAnnotation",
|
||||
description = "Handle JvmOverloads annotations"
|
||||
)
|
||||
|
||||
class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
|
||||
+7
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
@@ -29,13 +30,18 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
val JvmStaticAnnotationPhase = makePhase(
|
||||
::JvmStaticAnnotationLowering,
|
||||
name = "JvmStaticAnnotation",
|
||||
description = "Handle JvmStatic annotations"
|
||||
)
|
||||
|
||||
/*
|
||||
* For @JvmStatic functions within companion objects of classes, we synthesize proxy static functions that redirect
|
||||
* to the actual implementation.
|
||||
|
||||
+7
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.replaceThisByStaticReference
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -32,6 +33,12 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
val MoveCompanionObjectFieldsPhase = makePhase(
|
||||
::MoveCompanionObjectFieldsLowering,
|
||||
name = "MoveCompanionObjectFields",
|
||||
description = "Move companion object fields to static fields of companion's owner"
|
||||
)
|
||||
|
||||
class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
|
||||
|
||||
+7
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -24,6 +25,12 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
|
||||
val ObjectClassPhase = makePhase(
|
||||
::ObjectClassLowering,
|
||||
name = "ObjectClass",
|
||||
description = "Handle object classes"
|
||||
)
|
||||
|
||||
class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
|
||||
private var pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||
|
||||
+7
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -15,6 +16,12 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
val SingletonReferencesPhase = makePhase(
|
||||
::SingletonReferencesLowering,
|
||||
name = "SingletonReferences",
|
||||
description = "Handle singleton references"
|
||||
)
|
||||
|
||||
class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLoweringPass, IrElementTransformerVoid() {
|
||||
override fun lower(irBody: IrBody) {
|
||||
irBody.transformChildrenVoid(this)
|
||||
|
||||
+11
-2
@@ -16,9 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
@@ -26,7 +27,15 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
|
||||
class StaticDefaultFunctionLowering(val state: GenerationState) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
val StaticDefaultFunctionPhase = makePhase(
|
||||
::StaticDefaultFunctionLowering,
|
||||
name = "StaticDefaultFunction",
|
||||
description = "Generate static functions for default parameters"
|
||||
)
|
||||
|
||||
class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
irClass.accept(this, null)
|
||||
|
||||
+8
-4
@@ -5,10 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.IrElementVisitorVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
@@ -39,6 +36,13 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
val SyntheticAccessorPhase = makePhase(
|
||||
::SyntheticAccessorLowering,
|
||||
name = "SyntheticAccessor",
|
||||
description = "Introduce synthetic accessors",
|
||||
prerequisite = setOf(ObjectClassPhase)
|
||||
)
|
||||
|
||||
class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||
private val pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||
private val inlinedLambdasCollector = InlinedLambdasCollector()
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownClassDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.KnownPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
@@ -42,6 +43,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
val ToArrayPhase = makePhase(
|
||||
::ToArrayLowering,
|
||||
name = "ToArray",
|
||||
description = "Handle toArray functions"
|
||||
)
|
||||
|
||||
class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
|
||||
Reference in New Issue
Block a user