Move most of ir utils from backend.common to ir.tree
This commit is contained in:
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyTypeRemapper
|
||||
import org.jetbrains.kotlin.ir.util.NullDescriptorsRemapper
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : IrElement> T.deepCopyWithVariables(): T {
|
||||
val symbolsRemapper = DeepCopySymbolRemapper(NullDescriptorsRemapper)
|
||||
acceptVoid(symbolsRemapper)
|
||||
|
||||
val typesRemapper = DeepCopyTypeRemapper(symbolsRemapper)
|
||||
|
||||
return this.transform(
|
||||
object : DeepCopyIrTreeWithSymbols(symbolsRemapper, typesRemapper) {
|
||||
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
||||
return irLoop
|
||||
}
|
||||
},
|
||||
null
|
||||
) as T
|
||||
}
|
||||
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.getPackageFragment
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
// This is what Context collects about IR.
|
||||
|
||||
@@ -6,96 +6,16 @@
|
||||
package org.jetbrains.kotlin.backend.common.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.IrValueParameterBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.io.StringWriter
|
||||
|
||||
fun ir2string(ir: IrElement?): String = ir?.render() ?: ""
|
||||
|
||||
@Suppress("unused") // Used in kotlin-native
|
||||
fun ir2stringWhole(ir: IrElement?): String {
|
||||
val strWriter = StringWriter()
|
||||
ir?.accept(DumpIrTreeVisitor(strWriter), "")
|
||||
return strWriter.toString()
|
||||
}
|
||||
|
||||
fun IrClass.addSimpleDelegatingConstructor(
|
||||
superConstructor: IrConstructor,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
isPrimary: Boolean = false,
|
||||
origin: IrDeclarationOrigin? = null
|
||||
): IrConstructor =
|
||||
addConstructor {
|
||||
val klass = this@addSimpleDelegatingConstructor
|
||||
this.startOffset = klass.startOffset
|
||||
this.endOffset = klass.endOffset
|
||||
this.origin = origin ?: klass.origin
|
||||
this.visibility = superConstructor.visibility
|
||||
this.isPrimary = isPrimary
|
||||
}.also { constructor ->
|
||||
constructor.valueParameters = superConstructor.valueParameters.mapIndexed { index, parameter ->
|
||||
parameter.copyTo(constructor, index = index)
|
||||
}
|
||||
|
||||
constructor.body = factory.createBlockBody(
|
||||
startOffset, endOffset,
|
||||
listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset, irBuiltIns.unitType,
|
||||
superConstructor.symbol, 0,
|
||||
superConstructor.valueParameters.size
|
||||
).apply {
|
||||
constructor.valueParameters.forEachIndexed { idx, parameter ->
|
||||
putValueArgument(idx, IrGetValueImpl(startOffset, endOffset, parameter.type, parameter.symbol))
|
||||
}
|
||||
},
|
||||
IrInstanceInitializerCallImpl(startOffset, endOffset, this.symbol, irBuiltIns.unitType)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val IrCall.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
|
||||
val IrFunctionReference.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
|
||||
|
||||
val IrSimpleFunction.isOverridable: Boolean
|
||||
get() = visibility != DescriptorVisibilities.PRIVATE && modality != Modality.FINAL && (parent as? IrClass)?.isFinalClass != true
|
||||
|
||||
val IrSimpleFunction.isOverridableOrOverrides: Boolean get() = isOverridable || overriddenSymbols.isNotEmpty()
|
||||
|
||||
val IrDeclaration.isMemberOfOpenClass: Boolean
|
||||
get() {
|
||||
val parentClass = this.parent as? IrClass ?: return false
|
||||
return !parentClass.isFinalClass
|
||||
}
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
|
||||
fun IrReturnTarget.returnType(context: CommonBackendContext) =
|
||||
when (this) {
|
||||
@@ -105,548 +25,26 @@ fun IrReturnTarget.returnType(context: CommonBackendContext) =
|
||||
else -> error("Unknown ReturnTarget: $this")
|
||||
}
|
||||
|
||||
val IrClass.isFinalClass: Boolean
|
||||
get() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS
|
||||
|
||||
val IrTypeParametersContainer.classIfConstructor get() = if (this is IrConstructor) parentAsClass else this
|
||||
|
||||
fun IrValueParameter.copyTo(
|
||||
irFunction: IrFunction,
|
||||
origin: IrDeclarationOrigin = this.origin,
|
||||
index: Int = this.index,
|
||||
startOffset: Int = this.startOffset,
|
||||
endOffset: Int = this.endOffset,
|
||||
name: Name = this.name,
|
||||
remapTypeMap: Map<IrTypeParameter, IrTypeParameter> = mapOf(),
|
||||
type: IrType = this.type.remapTypeParameters(
|
||||
(parent as IrTypeParametersContainer).classIfConstructor,
|
||||
irFunction.classIfConstructor,
|
||||
remapTypeMap
|
||||
),
|
||||
varargElementType: IrType? = this.varargElementType, // TODO: remapTypeParameters here as well
|
||||
defaultValue: IrExpressionBody? = this.defaultValue,
|
||||
isCrossinline: Boolean = this.isCrossinline,
|
||||
isNoinline: Boolean = this.isNoinline,
|
||||
isAssignable: Boolean = this.isAssignable
|
||||
): IrValueParameter {
|
||||
val symbol = IrValueParameterSymbolImpl()
|
||||
val defaultValueCopy = defaultValue?.let { originalDefault ->
|
||||
factory.createExpressionBody(originalDefault.startOffset, originalDefault.endOffset) {
|
||||
expression = originalDefault.expression.deepCopyWithVariables().also {
|
||||
it.patchDeclarationParents(irFunction)
|
||||
}
|
||||
}
|
||||
}
|
||||
return factory.createValueParameter(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
name, index, type, varargElementType, isCrossinline = isCrossinline,
|
||||
isNoinline = isNoinline, isHidden = false, isAssignable = isAssignable
|
||||
).also {
|
||||
it.parent = irFunction
|
||||
it.defaultValue = defaultValueCopy
|
||||
it.copyAnnotationsFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrTypeParameter.copyToWithoutSuperTypes(
|
||||
target: IrTypeParametersContainer,
|
||||
index: Int = this.index,
|
||||
origin: IrDeclarationOrigin = this.origin
|
||||
): IrTypeParameter = buildTypeParameter(target) {
|
||||
updateFrom(this@copyToWithoutSuperTypes)
|
||||
this.name = this@copyToWithoutSuperTypes.name
|
||||
this.origin = origin
|
||||
this.index = index
|
||||
}
|
||||
|
||||
fun IrFunction.copyReceiverParametersFrom(from: IrFunction, substitutionMap: Map<IrTypeParameterSymbol, IrType>) {
|
||||
dispatchReceiverParameter = from.dispatchReceiverParameter?.run {
|
||||
factory.createValueParameter(
|
||||
startOffset, endOffset, origin,
|
||||
IrValueParameterSymbolImpl(),
|
||||
name, index,
|
||||
type.substitute(substitutionMap),
|
||||
varargElementType?.substitute(substitutionMap),
|
||||
isCrossinline, isNoinline,
|
||||
isHidden, isAssignable
|
||||
).also { parameter ->
|
||||
parameter.parent = this@copyReceiverParametersFrom
|
||||
}
|
||||
}
|
||||
extensionReceiverParameter = from.extensionReceiverParameter?.copyTo(this)
|
||||
}
|
||||
|
||||
fun IrFunction.copyValueParametersFrom(from: IrFunction, substitutionMap: Map<IrTypeParameterSymbol, IrType>) {
|
||||
copyReceiverParametersFrom(from, substitutionMap)
|
||||
val shift = valueParameters.size
|
||||
valueParameters += from.valueParameters.map {
|
||||
it.copyTo(this, index = it.index + shift, type = it.type.substitute(substitutionMap))
|
||||
}
|
||||
}
|
||||
|
||||
fun IrFunction.copyParameterDeclarationsFrom(from: IrFunction) {
|
||||
assert(typeParameters.isEmpty())
|
||||
copyTypeParametersFrom(from)
|
||||
val substitutionMap = makeTypeParameterSubstitutionMap(from, this)
|
||||
copyValueParametersFrom(from, substitutionMap)
|
||||
}
|
||||
|
||||
fun IrTypeParametersContainer.copyTypeParameters(
|
||||
srcTypeParameters: List<IrTypeParameter>,
|
||||
origin: IrDeclarationOrigin? = null,
|
||||
parameterMap: Map<IrTypeParameter, IrTypeParameter>? = null
|
||||
): List<IrTypeParameter> {
|
||||
val shift = typeParameters.size
|
||||
val oldToNewParameterMap = parameterMap.orEmpty().toMutableMap()
|
||||
// Any type parameter can figure in a boundary type for any other parameter.
|
||||
// Therefore, we first copy the parameters themselves, then set up their supertypes.
|
||||
val newTypeParameters = srcTypeParameters.mapIndexed { i, sourceParameter ->
|
||||
sourceParameter.copyToWithoutSuperTypes(this, index = i + shift, origin = origin ?: sourceParameter.origin).also {
|
||||
oldToNewParameterMap[sourceParameter] = it
|
||||
}
|
||||
}
|
||||
typeParameters += newTypeParameters
|
||||
srcTypeParameters.zip(newTypeParameters).forEach { (srcParameter, dstParameter) ->
|
||||
dstParameter.copySuperTypesFrom(srcParameter, oldToNewParameterMap)
|
||||
}
|
||||
return newTypeParameters
|
||||
}
|
||||
|
||||
fun IrTypeParametersContainer.copyTypeParametersFrom(
|
||||
source: IrTypeParametersContainer,
|
||||
origin: IrDeclarationOrigin? = null,
|
||||
parameterMap: Map<IrTypeParameter, IrTypeParameter>? = null
|
||||
) = copyTypeParameters(source.typeParameters, origin, parameterMap)
|
||||
|
||||
private fun IrTypeParameter.copySuperTypesFrom(source: IrTypeParameter, srcToDstParameterMap: Map<IrTypeParameter, IrTypeParameter>) {
|
||||
val target = this
|
||||
val sourceParent = source.parent as IrTypeParametersContainer
|
||||
val targetParent = target.parent as IrTypeParametersContainer
|
||||
target.superTypes = source.superTypes.map {
|
||||
it.remapTypeParameters(sourceParent, targetParent, srcToDstParameterMap)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrAnnotationContainer.copyAnnotations(): List<IrConstructorCall> {
|
||||
return annotations.map { it.deepCopyWithSymbols(this as? IrDeclarationParent) }
|
||||
}
|
||||
|
||||
fun IrAnnotationContainer.copyAnnotationsWhen(filter: IrConstructorCall.() -> Boolean): List<IrConstructorCall> {
|
||||
return annotations.mapNotNull { if (it.filter()) it.deepCopyWithSymbols(this as? IrDeclarationParent) else null }
|
||||
}
|
||||
|
||||
fun IrMutableAnnotationContainer.copyAnnotationsFrom(source: IrAnnotationContainer) {
|
||||
annotations += source.copyAnnotations()
|
||||
}
|
||||
|
||||
fun makeTypeParameterSubstitutionMap(
|
||||
original: IrTypeParametersContainer,
|
||||
transformed: IrTypeParametersContainer
|
||||
): Map<IrTypeParameterSymbol, IrType> =
|
||||
original.typeParameters
|
||||
.map { it.symbol }
|
||||
.zip(transformed.typeParameters.map { it.defaultType })
|
||||
.toMap()
|
||||
|
||||
|
||||
// Copy value parameters, dispatch receiver, and extension receiver from source to value parameters of this function.
|
||||
// Type of dispatch receiver defaults to source's dispatch receiver. It is overridable in case the new function and the old one are used in
|
||||
// different contexts and expect different type of dispatch receivers. The overriding type should be assign compatible to the old type.
|
||||
fun IrFunction.copyValueParametersToStatic(
|
||||
source: IrFunction,
|
||||
origin: IrDeclarationOrigin,
|
||||
dispatchReceiverType: IrType? = source.dispatchReceiverParameter?.type,
|
||||
numValueParametersToCopy: Int = source.valueParameters.size
|
||||
) {
|
||||
val target = this
|
||||
assert(target.valueParameters.isEmpty())
|
||||
|
||||
var shift = 0
|
||||
source.dispatchReceiverParameter?.let { originalDispatchReceiver ->
|
||||
assert(dispatchReceiverType!!.isSubtypeOfClass(originalDispatchReceiver.type.classOrNull!!))
|
||||
val type = dispatchReceiverType.remapTypeParameters(
|
||||
(originalDispatchReceiver.parent as IrTypeParametersContainer).classIfConstructor,
|
||||
target.classIfConstructor
|
||||
)
|
||||
|
||||
target.valueParameters += originalDispatchReceiver.copyTo(
|
||||
target,
|
||||
origin = originalDispatchReceiver.origin,
|
||||
index = shift++,
|
||||
type = type,
|
||||
name = Name.identifier("\$this")
|
||||
)
|
||||
}
|
||||
source.extensionReceiverParameter?.let { originalExtensionReceiver ->
|
||||
target.valueParameters += originalExtensionReceiver.copyTo(
|
||||
target,
|
||||
origin = originalExtensionReceiver.origin,
|
||||
index = shift++,
|
||||
name = Name.identifier("\$receiver")
|
||||
)
|
||||
}
|
||||
|
||||
for (oldValueParameter in source.valueParameters) {
|
||||
if (oldValueParameter.index >= numValueParametersToCopy) break
|
||||
target.valueParameters += oldValueParameter.copyTo(
|
||||
target,
|
||||
origin = origin,
|
||||
index = oldValueParameter.index + shift
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrFunctionAccessExpression.passTypeArgumentsFrom(irFunction: IrTypeParametersContainer, offset: Int = 0) {
|
||||
irFunction.typeParameters.forEachIndexed { i, param ->
|
||||
putTypeArgument(i + offset, param.defaultType)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a substitution of type parameters occuring in [this]. In order of
|
||||
* precedence, parameter `P` is substituted with...
|
||||
*
|
||||
* 1) `T`, if `srcToDstParameterMap.get(P) == T`
|
||||
* 2) `T`, if `source.typeParameters[i] == P` and
|
||||
* `target.typeParameters[i] == T`
|
||||
* 3) `P`
|
||||
*
|
||||
* If [srcToDstParameterMap] is total on the domain of type parameters in
|
||||
* [this], this effectively performs a substitution according to that map.
|
||||
*/
|
||||
fun IrType.remapTypeParameters(
|
||||
source: IrTypeParametersContainer,
|
||||
target: IrTypeParametersContainer,
|
||||
srcToDstParameterMap: Map<IrTypeParameter, IrTypeParameter>? = null
|
||||
): IrType =
|
||||
when (this) {
|
||||
is IrSimpleType -> {
|
||||
val classifier = classifier.owner
|
||||
when {
|
||||
classifier is IrTypeParameter -> {
|
||||
val newClassifier =
|
||||
srcToDstParameterMap?.get(classifier) ?: if (classifier.parent == source)
|
||||
target.typeParameters[classifier.index]
|
||||
else
|
||||
classifier
|
||||
IrSimpleTypeImpl(newClassifier.symbol, nullability, arguments, annotations)
|
||||
}
|
||||
|
||||
classifier is IrClass ->
|
||||
IrSimpleTypeImpl(
|
||||
classifier.symbol,
|
||||
nullability,
|
||||
arguments.map {
|
||||
when (it) {
|
||||
is IrTypeProjection -> makeTypeProjection(
|
||||
it.type.remapTypeParameters(source, target, srcToDstParameterMap),
|
||||
it.variance
|
||||
)
|
||||
else -> it
|
||||
}
|
||||
},
|
||||
annotations
|
||||
)
|
||||
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
|
||||
/* Copied from K/N */
|
||||
fun IrDeclarationContainer.addChild(declaration: IrDeclaration) {
|
||||
this.declarations += declaration
|
||||
declaration.setDeclarationsParent(this)
|
||||
}
|
||||
|
||||
fun <T : IrElement> T.setDeclarationsParent(parent: IrDeclarationParent): T {
|
||||
accept(SetDeclarationsParentVisitor, parent)
|
||||
return this
|
||||
}
|
||||
|
||||
object SetDeclarationsParentVisitor : IrElementVisitor<Unit, IrDeclarationParent> {
|
||||
override fun visitElement(element: IrElement, data: IrDeclarationParent) {
|
||||
if (element !is IrDeclarationParent) {
|
||||
element.acceptChildren(this, data)
|
||||
inline fun IrSimpleFunction.addDispatchReceiver(builder: IrValueParameterBuilder.() -> Unit): IrValueParameter =
|
||||
IrValueParameterBuilder().run {
|
||||
builder()
|
||||
index = -1
|
||||
name = "this".synthesizedName
|
||||
factory.buildValueParameter(this, this@addDispatchReceiver).also { receiver ->
|
||||
dispatchReceiverParameter = receiver
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclarationBase, data: IrDeclarationParent) {
|
||||
declaration.parent = data
|
||||
super.visitDeclaration(declaration, data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val IrFunction.isStatic: Boolean
|
||||
get() = parent is IrClass && dispatchReceiverParameter == null
|
||||
|
||||
val IrDeclaration.isTopLevel: Boolean
|
||||
get() {
|
||||
if (parent is IrPackageFragment) return true
|
||||
val parentClass = parent as? IrClass
|
||||
return parentClass?.isFileClass == true && parentClass.parent is IrPackageFragment
|
||||
}
|
||||
|
||||
fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
|
||||
thisReceiver = buildReceiverParameter(this, IrDeclarationOrigin.INSTANCE_RECEIVER, symbol.typeWithParameters(typeParameters))
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun isElseBranch(branch: IrBranch) = branch is IrElseBranch || ((branch.condition as? IrConst<Boolean>)?.value == true)
|
||||
|
||||
fun IrFunction.isMethodOfAny(): Boolean =
|
||||
extensionReceiverParameter == null && dispatchReceiverParameter != null &&
|
||||
when (name) {
|
||||
OperatorNameConventions.HASH_CODE, OperatorNameConventions.TO_STRING -> valueParameters.isEmpty()
|
||||
OperatorNameConventions.EQUALS -> valueParameters.singleOrNull()?.type?.isNullableAny() == true
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun IrDeclarationContainer.simpleFunctions() = declarations.flatMap {
|
||||
when (it) {
|
||||
is IrSimpleFunction -> listOf(it)
|
||||
is IrProperty -> listOfNotNull(it.getter, it.setter)
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun IrClass.createParameterDeclarations() {
|
||||
assert(thisReceiver == null)
|
||||
thisReceiver = buildReceiverParameter(this, IrDeclarationOrigin.INSTANCE_RECEIVER, symbol.typeWithParameters(typeParameters))
|
||||
}
|
||||
|
||||
fun IrFunction.createDispatchReceiverParameter(origin: IrDeclarationOrigin? = null) {
|
||||
assert(dispatchReceiverParameter == null)
|
||||
|
||||
dispatchReceiverParameter = factory.createValueParameter(
|
||||
startOffset, endOffset,
|
||||
origin ?: parentAsClass.origin,
|
||||
IrValueParameterSymbolImpl(),
|
||||
SpecialNames.THIS,
|
||||
-1,
|
||||
parentAsClass.defaultType,
|
||||
null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
isHidden = false,
|
||||
isAssignable = false
|
||||
).apply {
|
||||
parent = this@createDispatchReceiverParameter
|
||||
}
|
||||
}
|
||||
|
||||
val IrFunction.allParameters: List<IrValueParameter>
|
||||
get() = if (this is IrConstructor) {
|
||||
ArrayList<IrValueParameter>(allParametersCount).also {
|
||||
it.add(
|
||||
this.constructedClass.thisReceiver
|
||||
?: error(this.render())
|
||||
)
|
||||
addExplicitParametersTo(it)
|
||||
}
|
||||
} else {
|
||||
explicitParameters
|
||||
}
|
||||
|
||||
val IrFunction.allParametersCount: Int
|
||||
get() = if (this is IrConstructor) explicitParametersCount + 1 else explicitParametersCount
|
||||
|
||||
// This is essentially the same as FakeOverrideBuilder,
|
||||
// but it bypasses SymbolTable.
|
||||
// TODO: merge it with FakeOverrideBuilder.
|
||||
private class FakeOverrideBuilderForLowerings : FakeOverrideBuilderStrategy(emptyMap()) {
|
||||
|
||||
override fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction, compatibilityMode: Boolean) {
|
||||
declaration.acquireSymbol(IrSimpleFunctionSymbolImpl())
|
||||
}
|
||||
|
||||
override fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty, compatibilityMode: Boolean) {
|
||||
val propertySymbol = IrPropertySymbolImpl()
|
||||
declaration.getter?.let { it.correspondingPropertySymbol = propertySymbol }
|
||||
declaration.setter?.let { it.correspondingPropertySymbol = propertySymbol }
|
||||
|
||||
declaration.acquireSymbol(propertySymbol)
|
||||
|
||||
declaration.getter?.let {
|
||||
it.correspondingPropertySymbol = declaration.symbol
|
||||
linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it"), compatibilityMode)
|
||||
}
|
||||
declaration.setter?.let {
|
||||
it.correspondingPropertySymbol = declaration.symbol
|
||||
linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it"), compatibilityMode)
|
||||
fun IrSimpleFunction.addExtensionReceiver(type: IrType, origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED): IrValueParameter =
|
||||
IrValueParameterBuilder().run {
|
||||
this.type = type
|
||||
this.origin = origin
|
||||
this.index = -1
|
||||
this.name = "receiver".synthesizedName
|
||||
factory.buildValueParameter(this, this@addExtensionReceiver).also { receiver ->
|
||||
extensionReceiverParameter = receiver
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun IrClass.addFakeOverrides(typeSystem: IrTypeSystemContext, implementedMembers: List<IrOverridableMember> = emptyList()) {
|
||||
IrOverridingUtil(typeSystem, FakeOverrideBuilderForLowerings())
|
||||
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers, compatibilityMode = false)
|
||||
.forEach { addChild(it) }
|
||||
}
|
||||
|
||||
fun IrFactory.createStaticFunctionWithReceivers(
|
||||
irParent: IrDeclarationParent,
|
||||
name: Name,
|
||||
oldFunction: IrFunction,
|
||||
dispatchReceiverType: IrType? = oldFunction.dispatchReceiverParameter?.type,
|
||||
origin: IrDeclarationOrigin = oldFunction.origin,
|
||||
modality: Modality = Modality.FINAL,
|
||||
visibility: DescriptorVisibility = oldFunction.visibility,
|
||||
isFakeOverride: Boolean = oldFunction.isFakeOverride,
|
||||
copyMetadata: Boolean = true,
|
||||
typeParametersFromContext: List<IrTypeParameter> = listOf()
|
||||
): IrSimpleFunction {
|
||||
return createFunction(
|
||||
oldFunction.startOffset, oldFunction.endOffset,
|
||||
origin,
|
||||
IrSimpleFunctionSymbolImpl(),
|
||||
name,
|
||||
visibility,
|
||||
modality,
|
||||
oldFunction.returnType,
|
||||
isInline = oldFunction.isInline,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = oldFunction.isSuspend,
|
||||
isExpect = oldFunction.isExpect,
|
||||
isFakeOverride = isFakeOverride,
|
||||
isOperator = oldFunction is IrSimpleFunction && oldFunction.isOperator,
|
||||
isInfix = oldFunction is IrSimpleFunction && oldFunction.isInfix,
|
||||
containerSource = oldFunction.containerSource,
|
||||
).apply {
|
||||
parent = irParent
|
||||
|
||||
val newTypeParametersFromContext = copyAndRenameConflictingTypeParametersFrom(
|
||||
typeParametersFromContext,
|
||||
oldFunction.typeParameters
|
||||
)
|
||||
val newTypeParametersFromFunction = copyTypeParametersFrom(oldFunction)
|
||||
val typeParameterMap =
|
||||
(typeParametersFromContext + oldFunction.typeParameters)
|
||||
.zip(newTypeParametersFromContext + newTypeParametersFromFunction).toMap()
|
||||
|
||||
fun remap(type: IrType): IrType =
|
||||
type.remapTypeParameters(oldFunction, this, typeParameterMap)
|
||||
|
||||
typeParameters.forEach { it.superTypes = it.superTypes.map(::remap) }
|
||||
|
||||
annotations = oldFunction.annotations
|
||||
|
||||
var offset = 0
|
||||
val dispatchReceiver = oldFunction.dispatchReceiverParameter?.copyTo(
|
||||
this,
|
||||
name = Name.identifier("\$this"),
|
||||
index = offset++,
|
||||
type = remap(dispatchReceiverType!!),
|
||||
origin = IrDeclarationOrigin.MOVED_DISPATCH_RECEIVER
|
||||
)
|
||||
val extensionReceiver = oldFunction.extensionReceiverParameter?.copyTo(
|
||||
this,
|
||||
name = Name.identifier("\$receiver"),
|
||||
index = offset++,
|
||||
origin = IrDeclarationOrigin.MOVED_EXTENSION_RECEIVER,
|
||||
remapTypeMap = typeParameterMap
|
||||
)
|
||||
valueParameters = listOfNotNull(dispatchReceiver, extensionReceiver) +
|
||||
oldFunction.valueParameters.map {
|
||||
it.copyTo(
|
||||
this,
|
||||
index = it.index + offset,
|
||||
remapTypeMap = typeParameterMap
|
||||
)
|
||||
}
|
||||
|
||||
if (copyMetadata) metadata = oldFunction.metadata
|
||||
|
||||
copyAttributes(oldFunction as? IrAttributeContainer)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the parameters in [contextParameters] to the type parameters of
|
||||
* [this] function, renaming those that may clash with a provided collection of
|
||||
* [existingParameters] (e.g. type parameters of the function itself, when
|
||||
* creating DefaultImpls).
|
||||
*
|
||||
* @returns List of newly created, possibly renamed, copies of type parameters
|
||||
* in order of the corresponding parameters in [context].
|
||||
*/
|
||||
private fun IrSimpleFunction.copyAndRenameConflictingTypeParametersFrom(
|
||||
contextParameters: List<IrTypeParameter>,
|
||||
existingParameters: Collection<IrTypeParameter>
|
||||
): List<IrTypeParameter> {
|
||||
val newParameters = mutableListOf<IrTypeParameter>()
|
||||
|
||||
val existingNames =
|
||||
(contextParameters.map { it.name.asString() } + existingParameters.map { it.name.asString() }).toMutableSet()
|
||||
|
||||
contextParameters.forEach { contextType ->
|
||||
val newName = if (existingParameters.any { it.name.asString() == contextType.name.asString() }) {
|
||||
val newNamePrefix = contextType.name.asString() + "_I"
|
||||
val newName = newNamePrefix + generateSequence(1) { x -> x + 1 }.first { n ->
|
||||
(newNamePrefix + n) !in existingNames
|
||||
}
|
||||
existingNames.add(newName)
|
||||
newName
|
||||
} else {
|
||||
contextType.name.asString()
|
||||
}
|
||||
|
||||
newParameters.add(buildTypeParameter(this) {
|
||||
updateFrom(contextType)
|
||||
name = Name.identifier(newName)
|
||||
})
|
||||
}
|
||||
|
||||
val zipped = contextParameters.zip(newParameters)
|
||||
val parameterMap = zipped.toMap()
|
||||
for ((oldParameter, newParameter) in zipped) {
|
||||
newParameter.copySuperTypesFrom(oldParameter, parameterMap)
|
||||
}
|
||||
|
||||
typeParameters = typeParameters + newParameters
|
||||
|
||||
return newParameters
|
||||
}
|
||||
|
||||
val IrSymbol.isSuspend: Boolean
|
||||
get() = this is IrSimpleFunctionSymbol && owner.isSuspend
|
||||
|
||||
fun IrSimpleFunction.allOverridden(includeSelf: Boolean = false): List<IrSimpleFunction> {
|
||||
val result = mutableListOf<IrSimpleFunction>()
|
||||
if (includeSelf) {
|
||||
result.add(this)
|
||||
}
|
||||
|
||||
var current = this
|
||||
while (true) {
|
||||
val overridden = current.overriddenSymbols
|
||||
when (overridden.size) {
|
||||
0 -> return result
|
||||
1 -> {
|
||||
current = overridden[0].owner
|
||||
result.add(current)
|
||||
}
|
||||
else -> {
|
||||
val resultSet = result.toMutableSet()
|
||||
computeAllOverridden(current, resultSet)
|
||||
return resultSet.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun computeAllOverridden(function: IrSimpleFunction, result: MutableSet<IrSimpleFunction>) {
|
||||
for (overriddenSymbol in function.overriddenSymbols) {
|
||||
val override = overriddenSymbol.owner
|
||||
if (result.add(override)) {
|
||||
computeAllOverridden(override, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: support more cases like built-in operator call and so on
|
||||
fun IrExpression?.isPure(
|
||||
@@ -721,6 +119,3 @@ fun CommonBackendContext.createArrayOfExpression(
|
||||
putValueArgument(0, arg0)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrBuiltIns.getKFunctionType(returnType: IrType, parameterTypes: List<IrType>) =
|
||||
kFunctionN(parameterTypes.size).typeWith(parameterTypes + returnType)
|
||||
-2
@@ -8,8 +8,6 @@ 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.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
|
||||
+1
-5
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.asInlinable
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyValueParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.ir.inline
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -20,10 +19,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
+1
-1
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -26,6 +25,7 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.ir2string
|
||||
import org.jetbrains.kotlin.ir.util.isLocal
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
+1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||
|
||||
-1
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.getOrPut
|
||||
import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
|
||||
+2
-2
@@ -6,13 +6,13 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.addChild
|
||||
import org.jetbrains.kotlin.backend.common.ir.setDeclarationsParent
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.util.addChild
|
||||
import org.jetbrains.kotlin.ir.util.setDeclarationsParent
|
||||
|
||||
//This lower takes part of old LocalDeclarationLowering job to pop up local classes from functions
|
||||
open class LocalClassPopupLowering(
|
||||
|
||||
-3
@@ -9,9 +9,6 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ScopeWithIr
|
||||
import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.MethodsFromAnyGeneratorForLowerings.Companion.isHashCode
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
|
||||
+1
-1
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.allOverridden
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
@@ -15,6 +14,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.util.allOverridden
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
+1
-1
@@ -19,7 +19,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.collectTailRecursionCalls
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.ir.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
|
||||
+1
-1
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower.inline
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.ir.setDeclarationsParent
|
||||
import org.jetbrains.kotlin.backend.common.lower.LocalClassPopupLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -18,6 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.util.setDeclarationsParent
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.common.lower.optimizations
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
@@ -22,6 +21,7 @@ import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.backend.common.ir.isPure
|
||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.isTopLevel
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.SimpleTypeNullability
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||
|
||||
fun IrBuilderWithScope.irDoWhile(origin: IrStatementOrigin? = null) =
|
||||
IrDoWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||
|
||||
fun IrBuilderWithScope.irBreak(loop: IrLoop) =
|
||||
IrBreakImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
||||
IrContinueImpl(startOffset, endOffset, context.irBuiltIns.nothingType, loop)
|
||||
|
||||
fun IrBuilderWithScope.irGetObject(classSymbol: IrClassSymbol) =
|
||||
IrGetObjectValueImpl(startOffset, endOffset, IrSimpleTypeImpl(classSymbol, SimpleTypeNullability.NOT_SPECIFIED, emptyList(), emptyList()), classSymbol)
|
||||
|
||||
// Also adds created variable into building block
|
||||
fun <T : IrElement> IrStatementsBuilder<T>.createTmpVariable(
|
||||
irExpression: IrExpression,
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
irType: IrType? = null
|
||||
): IrVariable {
|
||||
val variable = scope.createTmpVariable(irExpression, nameHint, isMutable, origin, irType)
|
||||
+variable
|
||||
return variable
|
||||
}
|
||||
|
||||
fun Scope.createTmpVariable(
|
||||
irType: IrType,
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
initializer: IrExpression? = null,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
): IrVariable =
|
||||
buildVariable(
|
||||
getLocalDeclarationParent(), startOffset, endOffset, origin, Name.identifier(nameHint ?: "tmp"),
|
||||
irType, isMutable
|
||||
).apply {
|
||||
this.initializer = initializer
|
||||
}
|
||||
|
||||
fun Scope.createTmpVariable(
|
||||
irExpression: IrExpression,
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
irType: IrType? = null
|
||||
): IrVariable =
|
||||
buildVariable(
|
||||
getLocalDeclarationParent(), irExpression.startOffset, irExpression.endOffset, origin, Name.identifier(nameHint ?: "tmp"),
|
||||
irType ?: irExpression.type, isMutable
|
||||
).apply {
|
||||
initializer = irExpression
|
||||
}
|
||||
-362
@@ -1,362 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders.declarations
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildClass(builder: IrClassBuilder): IrClass = with(builder) {
|
||||
createClass(
|
||||
startOffset, endOffset, origin,
|
||||
IrClassSymbolImpl(),
|
||||
name, kind, visibility, modality,
|
||||
isCompanion, isInner, isData, isExternal, isValue, isExpect, isFun
|
||||
)
|
||||
}
|
||||
|
||||
inline fun IrFactory.buildClass(builder: IrClassBuilder.() -> Unit) =
|
||||
IrClassBuilder().run {
|
||||
builder()
|
||||
buildClass(this)
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildField(builder: IrFieldBuilder): IrField = with(builder) {
|
||||
createField(
|
||||
startOffset, endOffset, origin,
|
||||
IrFieldSymbolImpl(),
|
||||
name, type, visibility, isFinal, isExternal, isStatic,
|
||||
).also {
|
||||
it.metadata = metadata
|
||||
}
|
||||
}
|
||||
|
||||
inline fun IrFactory.buildField(builder: IrFieldBuilder.() -> Unit) =
|
||||
IrFieldBuilder().run {
|
||||
builder()
|
||||
buildField(this)
|
||||
}
|
||||
|
||||
inline fun IrClass.addField(builder: IrFieldBuilder.() -> Unit) =
|
||||
factory.buildField(builder).also { field ->
|
||||
field.parent = this
|
||||
declarations.add(field)
|
||||
}
|
||||
|
||||
fun IrClass.addField(fieldName: Name, fieldType: IrType, fieldVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE): IrField =
|
||||
addField {
|
||||
name = fieldName
|
||||
type = fieldType
|
||||
visibility = fieldVisibility
|
||||
}
|
||||
|
||||
fun IrClass.addField(
|
||||
fieldName: String,
|
||||
fieldType: IrType,
|
||||
fieldVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE
|
||||
): IrField =
|
||||
addField(Name.identifier(fieldName), fieldType, fieldVisibility)
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildProperty(builder: IrPropertyBuilder): IrProperty = with(builder) {
|
||||
createProperty(
|
||||
startOffset, endOffset, origin,
|
||||
IrPropertySymbolImpl(),
|
||||
name, visibility, modality,
|
||||
isVar, isConst, isLateinit, isDelegated, isExternal, isExpect, isFakeOverride,
|
||||
containerSource,
|
||||
)
|
||||
}
|
||||
|
||||
inline fun IrFactory.buildProperty(builder: IrPropertyBuilder.() -> Unit) =
|
||||
IrPropertyBuilder().run {
|
||||
builder()
|
||||
buildProperty(this)
|
||||
}
|
||||
|
||||
inline fun IrClass.addProperty(builder: IrPropertyBuilder.() -> Unit): IrProperty =
|
||||
factory.buildProperty(builder).also { property ->
|
||||
declarations.add(property)
|
||||
property.parent = this@addProperty
|
||||
}
|
||||
|
||||
inline fun IrProperty.addGetter(builder: IrFunctionBuilder.() -> Unit = {}): IrSimpleFunction =
|
||||
IrFunctionBuilder().run {
|
||||
name = Name.special("<get-${this@addGetter.name}>")
|
||||
builder()
|
||||
factory.buildFunction(this).also { getter ->
|
||||
this@addGetter.getter = getter
|
||||
getter.correspondingPropertySymbol = this@addGetter.symbol
|
||||
getter.parent = this@addGetter.parent
|
||||
}
|
||||
}
|
||||
|
||||
fun IrProperty.addDefaultGetter(parentClass: IrClass, builtIns: IrBuiltIns) {
|
||||
val field = backingField!!
|
||||
addGetter {
|
||||
origin = IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR
|
||||
returnType = field.type
|
||||
}.apply {
|
||||
dispatchReceiverParameter = parentClass.thisReceiver!!.copyTo(this)
|
||||
body = factory.createBlockBody(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf(
|
||||
IrReturnImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
builtIns.nothingType,
|
||||
symbol,
|
||||
IrGetFieldImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
field.symbol,
|
||||
field.type,
|
||||
IrGetValueImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
dispatchReceiverParameter!!.type,
|
||||
dispatchReceiverParameter!!.symbol
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildFunction(builder: IrFunctionBuilder): IrSimpleFunction = with(builder) {
|
||||
createFunction(
|
||||
startOffset, endOffset, origin,
|
||||
IrSimpleFunctionSymbolImpl(),
|
||||
name, visibility, modality, returnType,
|
||||
isInline, isExternal, isTailrec, isSuspend, isOperator, isInfix, isExpect, isFakeOverride,
|
||||
containerSource,
|
||||
)
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildConstructor(builder: IrFunctionBuilder): IrConstructor = with(builder) {
|
||||
return createConstructor(
|
||||
startOffset, endOffset, origin,
|
||||
IrConstructorSymbolImpl(),
|
||||
SpecialNames.INIT,
|
||||
visibility, returnType,
|
||||
isInline = isInline, isExternal = isExternal, isPrimary = isPrimary, isExpect = isExpect,
|
||||
containerSource = containerSource
|
||||
)
|
||||
}
|
||||
|
||||
inline fun IrFactory.buildFun(builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
|
||||
IrFunctionBuilder().run {
|
||||
builder()
|
||||
buildFunction(this)
|
||||
}
|
||||
|
||||
inline fun IrFactory.addFunction(klass: IrDeclarationContainer, builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
|
||||
buildFun(builder).also { function ->
|
||||
klass.declarations.add(function)
|
||||
function.parent = klass
|
||||
}
|
||||
|
||||
inline fun IrClass.addFunction(builder: IrFunctionBuilder.() -> Unit): IrSimpleFunction =
|
||||
factory.addFunction(this, builder)
|
||||
|
||||
fun IrClass.addFunction(
|
||||
name: String,
|
||||
returnType: IrType,
|
||||
modality: Modality = Modality.FINAL,
|
||||
visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC,
|
||||
isStatic: Boolean = false,
|
||||
isSuspend: Boolean = false,
|
||||
isFakeOverride: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
): IrSimpleFunction =
|
||||
addFunction {
|
||||
this.startOffset = startOffset
|
||||
this.endOffset = endOffset
|
||||
this.name = Name.identifier(name)
|
||||
this.returnType = returnType
|
||||
this.modality = modality
|
||||
this.visibility = visibility
|
||||
this.isSuspend = isSuspend
|
||||
this.isFakeOverride = isFakeOverride
|
||||
this.origin = origin
|
||||
}.apply {
|
||||
if (!isStatic) {
|
||||
val thisReceiver = parentAsClass.thisReceiver!!
|
||||
dispatchReceiverParameter = thisReceiver.copyTo(this, type = thisReceiver.type)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun IrFactory.buildConstructor(builder: IrFunctionBuilder.() -> Unit): IrConstructor =
|
||||
IrFunctionBuilder().run {
|
||||
builder()
|
||||
buildConstructor(this)
|
||||
}
|
||||
|
||||
inline fun IrClass.addConstructor(builder: IrFunctionBuilder.() -> Unit = {}): IrConstructor =
|
||||
factory.buildConstructor {
|
||||
builder()
|
||||
returnType = defaultType
|
||||
}.also { constructor ->
|
||||
declarations.add(constructor)
|
||||
constructor.parent = this@addConstructor
|
||||
}
|
||||
|
||||
fun <D> buildReceiverParameter(
|
||||
parent: D,
|
||||
origin: IrDeclarationOrigin,
|
||||
type: IrType,
|
||||
startOffset: Int = parent.startOffset,
|
||||
endOffset: Int = parent.endOffset
|
||||
): IrValueParameter
|
||||
where D : IrDeclaration, D : IrDeclarationParent =
|
||||
parent.factory.createValueParameter(
|
||||
startOffset, endOffset, origin,
|
||||
IrValueParameterSymbolImpl(),
|
||||
SpecialNames.THIS, -1, type, null, isCrossinline = false, isNoinline = false,
|
||||
isHidden = false, isAssignable = false
|
||||
).also {
|
||||
it.parent = parent
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildValueParameter(builder: IrValueParameterBuilder, parent: IrDeclarationParent): IrValueParameter =
|
||||
with(builder) {
|
||||
return createValueParameter(
|
||||
startOffset, endOffset, origin,
|
||||
IrValueParameterSymbolImpl(),
|
||||
name, index, type, varargElementType, isCrossInline, isNoinline, isHidden, isAssignable
|
||||
).also {
|
||||
it.parent = parent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline fun <D> buildValueParameter(declaration: D, builder: IrValueParameterBuilder.() -> Unit): IrValueParameter
|
||||
where D : IrDeclaration, D : IrDeclarationParent =
|
||||
IrValueParameterBuilder().run {
|
||||
builder()
|
||||
declaration.factory.buildValueParameter(this, declaration)
|
||||
}
|
||||
|
||||
inline fun IrFunction.addValueParameter(builder: IrValueParameterBuilder.() -> Unit): IrValueParameter =
|
||||
IrValueParameterBuilder().run {
|
||||
builder()
|
||||
if (index == UNDEFINED_PARAMETER_INDEX) {
|
||||
index = valueParameters.size
|
||||
}
|
||||
factory.buildValueParameter(this, this@addValueParameter).also { valueParameter ->
|
||||
valueParameters = valueParameters + valueParameter
|
||||
}
|
||||
}
|
||||
|
||||
fun IrFunction.addValueParameter(name: String, type: IrType, origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED): IrValueParameter =
|
||||
addValueParameter(Name.identifier(name), type, origin)
|
||||
|
||||
fun IrFunction.addValueParameter(name: Name, type: IrType, origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED): IrValueParameter =
|
||||
addValueParameter {
|
||||
this.name = name
|
||||
this.type = type
|
||||
this.origin = origin
|
||||
}
|
||||
|
||||
inline fun IrSimpleFunction.addDispatchReceiver(builder: IrValueParameterBuilder.() -> Unit): IrValueParameter =
|
||||
IrValueParameterBuilder().run {
|
||||
builder()
|
||||
index = -1
|
||||
name = "this".synthesizedName
|
||||
factory.buildValueParameter(this, this@addDispatchReceiver).also { receiver ->
|
||||
dispatchReceiverParameter = receiver
|
||||
}
|
||||
}
|
||||
|
||||
fun IrSimpleFunction.addExtensionReceiver(type: IrType, origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED): IrValueParameter =
|
||||
IrValueParameterBuilder().run {
|
||||
this.type = type
|
||||
this.origin = origin
|
||||
this.index = -1
|
||||
this.name = "receiver".synthesizedName
|
||||
factory.buildValueParameter(this, this@addExtensionReceiver).also { receiver ->
|
||||
extensionReceiverParameter = receiver
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun IrFactory.buildTypeParameter(builder: IrTypeParameterBuilder, parent: IrDeclarationParent): IrTypeParameter =
|
||||
with(builder) {
|
||||
createTypeParameter(
|
||||
startOffset, endOffset, origin,
|
||||
IrTypeParameterSymbolImpl(),
|
||||
name, index, isReified, variance
|
||||
).also {
|
||||
it.superTypes = superTypes
|
||||
it.parent = parent
|
||||
}
|
||||
}
|
||||
|
||||
inline fun buildTypeParameter(parent: IrTypeParametersContainer, builder: IrTypeParameterBuilder.() -> Unit): IrTypeParameter =
|
||||
IrTypeParameterBuilder().run {
|
||||
builder()
|
||||
parent.factory.buildTypeParameter(this, parent)
|
||||
}
|
||||
|
||||
inline fun IrTypeParametersContainer.addTypeParameter(builder: IrTypeParameterBuilder.() -> Unit): IrTypeParameter =
|
||||
IrTypeParameterBuilder().run {
|
||||
builder()
|
||||
if (index == UNDEFINED_PARAMETER_INDEX) {
|
||||
index = typeParameters.size
|
||||
}
|
||||
factory.buildTypeParameter(this, this@addTypeParameter).also { typeParameter ->
|
||||
typeParameters = typeParameters + typeParameter
|
||||
}
|
||||
}
|
||||
|
||||
fun IrTypeParametersContainer.addTypeParameter(name: String, upperBound: IrType, variance: Variance = Variance.INVARIANT): IrTypeParameter =
|
||||
addTypeParameter {
|
||||
this.name = Name.identifier(name)
|
||||
this.variance = variance
|
||||
this.superTypes.add(upperBound)
|
||||
}
|
||||
|
||||
fun buildVariable(
|
||||
parent: IrDeclarationParent?,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
origin: IrDeclarationOrigin,
|
||||
name: Name,
|
||||
type: IrType,
|
||||
isVar: Boolean = false,
|
||||
isConst: Boolean = false,
|
||||
isLateinit: Boolean = false,
|
||||
): IrVariable {
|
||||
return IrVariableImpl(
|
||||
startOffset, endOffset, origin,
|
||||
IrVariableSymbolImpl(),
|
||||
name, type, isVar, isConst, isLateinit
|
||||
).also {
|
||||
if (parent != null) {
|
||||
it.parent = parent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
|
||||
val kotlinPackageFqn = FqName.fromSegments(listOf("kotlin"))
|
||||
private val kotlinReflectionPackageFqn = kotlinPackageFqn.child(Name.identifier("reflect"))
|
||||
private val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier("coroutines"))
|
||||
|
||||
fun IrType.isFunctionMarker(): Boolean = classifierOrNull?.isClassWithName("Function", kotlinPackageFqn) == true
|
||||
fun IrType.isFunction(): Boolean = classifierOrNull?.isClassWithNamePrefix("Function", kotlinPackageFqn) == true
|
||||
fun IrType.isKFunction(): Boolean = classifierOrNull?.isClassWithNamePrefix("KFunction", kotlinReflectionPackageFqn) == true
|
||||
fun IrType.isSuspendFunction(): Boolean = classifierOrNull?.isClassWithNamePrefix("SuspendFunction", kotlinCoroutinesPackageFqn) == true
|
||||
fun IrType.isKSuspendFunction(): Boolean = classifierOrNull?.isClassWithNamePrefix("KSuspendFunction", kotlinReflectionPackageFqn) == true
|
||||
|
||||
fun IrClassifierSymbol.isFunctionMarker(): Boolean = this.isClassWithName("Function", kotlinPackageFqn)
|
||||
fun IrClassifierSymbol.isFunction(): Boolean = this.isClassWithNamePrefix("Function", kotlinPackageFqn)
|
||||
fun IrClassifierSymbol.isKFunction(): Boolean = this.isClassWithNamePrefix("KFunction", kotlinReflectionPackageFqn)
|
||||
fun IrClassifierSymbol.isSuspendFunction(): Boolean = this.isClassWithNamePrefix("SuspendFunction", kotlinCoroutinesPackageFqn)
|
||||
fun IrClassifierSymbol.isKSuspendFunction(): Boolean = this.isClassWithNamePrefix("KSuspendFunction", kotlinReflectionPackageFqn)
|
||||
|
||||
private fun IrClassifierSymbol.isClassWithName(name: String, packageFqName: FqName): Boolean {
|
||||
val declaration = owner as IrDeclarationWithName
|
||||
return name == declaration.name.asString() && (declaration.parent as? IrPackageFragment)?.fqName == packageFqName
|
||||
}
|
||||
|
||||
private fun IrClassifierSymbol.isClassWithNamePrefix(prefix: String, packageFqName: FqName): Boolean {
|
||||
val declaration = owner as IrDeclarationWithName
|
||||
return declaration.name.asString().startsWith(prefix) && (declaration.parent as? IrPackageFragment)?.fqName == packageFqName
|
||||
}
|
||||
|
||||
fun IrType.superTypes(): List<IrType> = classifierOrNull?.superTypes() ?: emptyList()
|
||||
|
||||
fun IrType.isFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isFunction)
|
||||
fun IrType.isSuspendFunctionTypeOrSubtype(): Boolean = DFS.ifAny(listOf(this), IrType::superTypes, IrType::isSuspendFunction)
|
||||
|
||||
fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol
|
||||
|
||||
fun IrType.isInterface() = classOrNull?.owner?.kind == ClassKind.INTERFACE
|
||||
|
||||
fun IrType.isAnnotation() = classOrNull?.owner?.kind == ClassKind.ANNOTATION_CLASS
|
||||
|
||||
fun IrType.isFunctionOrKFunction() = isFunction() || isKFunction()
|
||||
|
||||
fun IrType.isSuspendFunctionOrKFunction() = isSuspendFunction() || isKSuspendFunction()
|
||||
|
||||
fun IrType.isThrowable(): Boolean = isTypeFromKotlinPackage { name -> name.asString() == "Throwable" }
|
||||
|
||||
fun IrType.isUnsigned(): Boolean = isTypeFromKotlinPackage { name -> UnsignedTypes.isShortNameOfUnsignedType(name) }
|
||||
|
||||
fun IrType.isUnsignedArray(): Boolean = isTypeFromKotlinPackage { name -> UnsignedTypes.isShortNameOfUnsignedArray(name) }
|
||||
|
||||
private inline fun IrType.isTypeFromKotlinPackage(namePredicate: (Name) -> Boolean): Boolean {
|
||||
if (this is IrSimpleType) {
|
||||
val classClassifier = classifier as? IrClassSymbol ?: return false
|
||||
if (!namePredicate(classClassifier.owner.name)) return false
|
||||
val parent = classClassifier.owner.parent as? IrPackageFragment ?: return false
|
||||
return parent.fqName == kotlinPackageFqn
|
||||
} else return false
|
||||
}
|
||||
|
||||
fun IrType.isPrimitiveArray() = isTypeFromKotlinPackage { it in FqNames.primitiveArrayTypeShortNames }
|
||||
|
||||
fun IrType.getPrimitiveArrayElementType() = (this as? IrSimpleType)?.let {
|
||||
(it.classifier.owner as? IrClass)?.fqNameWhenAvailable?.toUnsafe()?.let { fqn -> FqNames.arrayClassFqNameToPrimitiveType[fqn] }
|
||||
}
|
||||
|
||||
fun IrType.substitute(params: List<IrTypeParameter>, arguments: List<IrType>): IrType =
|
||||
substitute(params.map { it.symbol }.zip(arguments).toMap())
|
||||
|
||||
fun IrType.substitute(substitutionMap: Map<IrTypeParameterSymbol, IrType>): IrType {
|
||||
if (this !is IrSimpleType || substitutionMap.isEmpty()) return this
|
||||
|
||||
val newAnnotations = annotations.map { it.deepCopyWithSymbols() }
|
||||
|
||||
substitutionMap[classifier]?.let { substitutedType ->
|
||||
// Add nullability and annotations from original type
|
||||
return substitutedType
|
||||
.mergeNullability(this)
|
||||
.addAnnotations(newAnnotations)
|
||||
}
|
||||
|
||||
val newArguments = arguments.map {
|
||||
if (it is IrTypeProjection) {
|
||||
makeTypeProjection(it.type.substitute(substitutionMap), it.variance)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
return IrSimpleTypeImpl(
|
||||
classifier,
|
||||
nullability,
|
||||
newArguments,
|
||||
newAnnotations
|
||||
)
|
||||
}
|
||||
|
||||
private fun getImmediateSupertypes(irType: IrSimpleType): List<IrSimpleType> {
|
||||
val irClass = irType.getClass()
|
||||
?: throw AssertionError("Not a class type: ${irType.render()}")
|
||||
val originalSupertypes = irClass.superTypes
|
||||
val arguments =
|
||||
irType.arguments.map {
|
||||
it.typeOrNull
|
||||
?: throw AssertionError("*-projection in supertype arguments: ${irType.render()}")
|
||||
}
|
||||
return originalSupertypes
|
||||
.filter { it.classOrNull != null }
|
||||
.map { superType ->
|
||||
superType.substitute(irClass.typeParameters, arguments) as IrSimpleType
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectAllSupertypes(irType: IrSimpleType, result: MutableSet<IrSimpleType>) {
|
||||
val immediateSupertypes = getImmediateSupertypes(irType)
|
||||
result.addAll(immediateSupertypes)
|
||||
for (supertype in immediateSupertypes) {
|
||||
collectAllSupertypes(supertype, result)
|
||||
}
|
||||
}
|
||||
|
||||
// Given the following classes:
|
||||
// open class A<X>
|
||||
// open class B<Y> : A<List<Y>>
|
||||
// class C<Z> : B<List<Z>>
|
||||
// for the class C, this function constructs:
|
||||
// { B<List<Z>>, A<List<List<Z>>, Any }
|
||||
// where Z is a type parameter of class C.
|
||||
fun getAllSubstitutedSupertypes(irClass: IrClass): Set<IrSimpleType> {
|
||||
val result = HashSet<IrSimpleType>()
|
||||
collectAllSupertypes(irClass.defaultType, result)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun collectAllSuperclasses(irClass: IrClass, set: MutableSet<IrClass>) {
|
||||
for (superType in irClass.superTypes) {
|
||||
val classifier = superType.classifierOrNull as? IrClassSymbol ?: continue
|
||||
val superClass = classifier.owner
|
||||
if (set.add(superClass)) {
|
||||
collectAllSuperclasses(superClass, set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun IrClass.getAllSuperclasses(): Set<IrClass> {
|
||||
val result = HashSet<IrClass>()
|
||||
collectAllSuperclasses(this, result)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user